# How-to: Finding the nearest feature to a point (HPS)

**URL:** <https://forum.techsoft3d.com/t/how-to-finding-the-nearest-feature-to-a-point-hps/3231>\
**Category:** HOOPS Visualize Desktop\
**Tags:** code, sample, learn, knowledge-base, how-to\
**Created:** [January 30, 2024, 10:38pm UTC](https://forum.techsoft3d.com/t/how-to-finding-the-nearest-feature-to-a-point-hps/3231 "2024-01-30T22:38:25Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![beau.trifiro](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.techsoft3d.com/beau.trifiro/32/1205_2.png) [@beau.trifiro](https://forum.techsoft3d.com/u/beau.trifiro)\
**Post date:** [January 30, 2024, 10:38pm UTC](https://forum.techsoft3d.com/t/how-to-finding-the-nearest-feature-to-a-point-hps/3231/1 "2024-01-30T22:38:25Z")

</div>

The following sample code demonstrates two methods to **find the closest feature to a 3D point** in the scene using [HOOPS Visualize (HPS)](https://www.techsoft3d.com/products/hoops/visualize). This code can be copied and pasted into the [**wpf\_sandbox**](https://docs.techsoft3d.com/hps/latest/general/sandboxes.html#wpf-sandbox) project (DemoUserCommands.cs) included in your HPS package.

_Note: this sample code requires [HOOPS Exchange](https://www.techsoft3d.com/products/hoops/exchange) as well and references a model provided in the Exchange download package. This was built with [HNP](https://www.techsoft3d.com/products/hoops/native-platform) 2024._

* * *

In the first method, a small simple sphere is defined and inserted into the scene. [SelectByShell()](https://docs.techsoft3d.com/hps/latest/prog_guide/0603_selection.html#collision-detection) is used to return all selections within that sphere. If this returns nothing, the sphere is deleted and a new, slightly larger sphere is created – this process repeats until a selection result is returned.

```auto

HPS.View myView = GetCanvas().GetAttachedLayout().GetFrontView();

myView.AttachModel(myModel);

// Insert a sample model to test:

try
{
	string file_in = "<ExchangeInstallDirectory>/samples/data/pmi/PMI_Sample/CV5_Sample.CATPart";

	HPS.Exchange.ImportOptionsKit iok = new HPS.Exchange.ImportOptionsKit();
	iok.SetBRepMode(HPS.Exchange.BRepMode.BRepAndTessellation);

	HPS.Exchange.ImportNotifier exchangeNotifier = HPS.Exchange.File.Import(file_in, iok);
	exchangeNotifier.Wait();

	HPS.Exchange.CADModel modelFile = exchangeNotifier.GetCADModel();
	
	myModel = modelFile.GetModel();
	myView.AttachModel(myModel);

	HPS.SegmentKey myModelKey = myModel.GetSegmentKey();

	myModelKey.InsertDistantLight(new HPS.Vector(1, 1, -1));

	// Given a point in space, find the closest feature by iteratively increasing the size of a sphere
	// with its center at that point until it hits a feature, then highlight that feature:
	HPS.Point pointToTest = new HPS.Point(10, 0, 50);

	bool isHit = false;
	int upperBound = 1000; // Max distance the point can be from the model we're checking against
	int i = 0;

	while (!isHit && i<upperBound)
	{
		// Define the sphere we will use to perform a shell selection (collision check)
		HPS.SphereKit mySphereKit= new HPS.SphereKit();
		float radius = (float) (i + 1) / 2;
		mySphereKit.SetCenter(pointToTest);
		mySphereKit.SetRadius(radius);
		mySphereKit.SetBasis(new HPS.Vector(0, 1, 0), new HPS.Vector(1, 0, 0)); // "axis" and "up" vectors

		System.Diagnostics.Debug.Write("Radius:");
		System.Diagnostics.Debug.WriteLine(radius);
		
		// Create a reference sphere 
		HPS.SegmentKey referenceSphereSegKey = HPS.Database.CreateRootSegment();
		HPS.SphereKey mySphereKey = referenceSphereSegKey.InsertSphere(mySphereKit);

		// Insert the reference sphere into the scene
		HPS.SegmentKey sphereSubSeg = myModelKey.Subsegment();
		HPS.ShellKey mySphereShell = sphereSubSeg.InsertShellFromGeometry(mySphereKey);

		
		// Perform a select by shell selection:
		HPS.SelectionOptionsKit selectionOptions = new HPS.SelectionOptionsKit();
		selectionOptions.SetAlgorithm(HPS.Selection.Algorithm.Analytic);
		selectionOptions.SetLevel(HPS.Selection.Level.Subentity);
		selectionOptions.SetProximity(0);
		selectionOptions.SetScope(myModelKey);
		
		HPS.SelectionResults selectionResults;
		ulong numSelectedItems = GetCanvas().GetWindowKey().GetSelectionControl().SelectByShell(mySphereShell, selectionOptions, out selectionResults);

		HPS.SelectionResultsIterator srIterator = selectionResults.GetIterator();

		if (!srIterator.IsValid()) // If nothing is returned
		{
			System.Diagnostics.Debug.WriteLine("miss");
			referenceSphereSegKey.Delete(); // Delete the offscreen root segment and its subsegments
			sphereSubSeg.Delete(); // Delete the branch containing the sphere
			i++;

		}
		else
		{
			isHit = true;

			var highlightOptions = new HighlightOptionsKit("highlight_style");
			highlightOptions.SetOverlay(Drawing.Overlay.InPlace);

			while (srIterator.IsValid())
			{
				HPS.SelectionItem selectionItem = srIterator.GetItem();

				var componentPath = modelFile.GetComponentPath(selectionItem);
				if (!componentPath.Empty())
				{
					highlightOptions.SetNotification(true);
					componentPath.Highlight(GetCanvas(), highlightOptions);
				}
				
				srIterator.Next();
			}
			
		}
		myView.FitWorld();
		GetCanvas().Update();
	}

}
catch (HPS.IOException ioe)
{
	System.Diagnostics.Debug.WriteLine(ioe.Message);
}

```

 ![Screenshot 2024-01-30 143015](https://us1.discourse-cdn.com/flex020/uploads/techsoft3d/original/2X/4/461c795a749d43b53c6b19b8db09b0453320e796.png)  
_Sphere shown for reference - query point is at center of sphere. The highlighted face is the closest feature to the point._

* * *

In the second method, [SelectByVolume()](https://docs.techsoft3d.com/hps/latest/prog_guide/0603_selection.html#selection-by-area-and-volume) is used with a similar process. However, this method only allows for cuboid selection geometry, so it will not return a result as precise as a method using a sphere.

```auto

HPS.View myView = GetCanvas().GetAttachedLayout().GetFrontView();

myView.AttachModel(myModel);

// Insert a sample model to test:

try
{
	string file_in = "<ExchangeInstallDirectory>/samples/data/pmi/PMI_Sample/CV5_Sample.CATPart";

	HPS.Exchange.ImportOptionsKit iok = new HPS.Exchange.ImportOptionsKit();
	iok.SetBRepMode(HPS.Exchange.BRepMode.BRepAndTessellation);

	HPS.Exchange.ImportNotifier exchangeNotifier = HPS.Exchange.File.Import(file_in, iok);
	exchangeNotifier.Wait();

	HPS.Exchange.CADModel modelFile = exchangeNotifier.GetCADModel();

	myModel = modelFile.GetModel();
	myView.AttachModel(myModel);

	HPS.SegmentKey myModelKey = myModel.GetSegmentKey();

	myModelKey.InsertDistantLight(new HPS.Vector(1, 1, -1));

	// Given a point in space, find the closest feature by iteratively increasing the size of a cuboid volume
	// with its center at that point until it hits a feature, then highlight that feature:
	HPS.Point pointToTest = new HPS.Point(35, 0, 30);

	bool isHit = false;
	int upperBound = 1000; // Max distance the point can be from the model we're checking against
	int i = 1;

	while (!isHit && i < upperBound)
	{
		// Define the cuboid for volumetric selection
		HPS.SimpleCuboid boundingCuboid = new HPS.SimpleCuboid(new HPS.Point(-i + pointToTest.x, -i + pointToTest.y, -i + pointToTest.z), new HPS.Point(i + pointToTest.x, i + pointToTest.y, i + pointToTest.z));

		System.Diagnostics.Debug.Write("Length: ");
		System.Diagnostics.Debug.WriteLine(i*2);

		// Perform a select by volume selection:
		HPS.SelectionOptionsKit selectionOptions = new HPS.SelectionOptionsKit();
		selectionOptions.SetAlgorithm(HPS.Selection.Algorithm.Analytic);
		selectionOptions.SetLevel(HPS.Selection.Level.Subentity);
		selectionOptions.SetScope(myModelKey);

		HPS.SelectionResults selectionResults;
		ulong numSelectedItems = GetCanvas().GetWindowKey().GetSelectionControl().SelectByVolume(boundingCuboid, selectionOptions, out selectionResults);

		HPS.SelectionResultsIterator srIterator = selectionResults.GetIterator();

		if (!srIterator.IsValid()) // If nothing is returned
		{
			System.Diagnostics.Debug.WriteLine("miss");
			i++;

		}
		else
		{
			isHit = true;

			var highlightOptions = new HighlightOptionsKit("highlight_style");
			highlightOptions.SetOverlay(Drawing.Overlay.InPlace);
		

			while (srIterator.IsValid())
			{
				HPS.SelectionItem selectionItem = srIterator.GetItem();

				var componentPath = modelFile.GetComponentPath(selectionItem);
				if (!componentPath.Empty())
				{
					highlightOptions.SetNotification(true);
					componentPath.Highlight(GetCanvas(), highlightOptions);
				}

				srIterator.Next();
			}

			// Insert the cube for reference:
			HPS.ShellKit myShellKit = new HPS.ShellKit();
			HPS.Point[] shellPoints = {
				new HPS.Point(-i + pointToTest.x, -i + pointToTest.y, -i + pointToTest.z),
				new HPS.Point(i + pointToTest.x, -i + pointToTest.y, -i + pointToTest.z),
				new HPS.Point(i + pointToTest.x, i + pointToTest.y, -i + pointToTest.z),
				new HPS.Point(-i + pointToTest.x, i + pointToTest.y, -i + pointToTest.z),
				new HPS.Point(-i + pointToTest.x, -i + pointToTest.y, i + pointToTest.z),
				new HPS.Point(i + pointToTest.x, -i + pointToTest.y, i + pointToTest.z),
				new HPS.Point(i + pointToTest.x, i + pointToTest.y, i + pointToTest.z),
				new HPS.Point(-i + pointToTest.x, i + pointToTest.y, i + pointToTest.z)
			};
			int[] shellFaceList = {
				4, 0, 1, 2, 3,
				4, 1, 5, 6, 2,
				4, 5, 4, 7, 6,
				4, 4, 0, 3, 7,
				4, 3, 2, 6, 7,
				4, 0, 4, 5, 1
			};

			myShellKit.SetPoints(shellPoints);
			myShellKit.SetFacelist(shellFaceList);
			HPS.SegmentKey myShellSegKey = myModelKey.Subsegment();
			HPS.ShellKey cubeShellKey = myShellSegKey.InsertShell(myShellKit);

		}

		myView.FitWorld();
		GetCanvas().Update();
	}

}
catch (HPS.IOException ioe)
{
	System.Diagnostics.Debug.WriteLine(ioe.Message);
}

```

 ![Screenshot 2024-01-30 143028](https://us1.discourse-cdn.com/flex020/uploads/techsoft3d/original/2X/d/dc8227ebeb50025c794c0224febb4750e7a10582.png)  
_Cube shown for reference - query point is at center of cube. The highlighted face is the closest feature to the point._

---

<div class="post-metadata">

**Author:** ![gabriel.peragine](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.techsoft3d.com/gabriel.peragine/32/1535_2.png) [@gabriel.peragine](https://forum.techsoft3d.com/u/gabriel.peragine)\
**Post date:** [January 31, 2024, 2:31pm UTC](https://forum.techsoft3d.com/t/how-to-finding-the-nearest-feature-to-a-point-hps/3231/2 "2024-01-31T14:31:08Z")

</div>

Thanks for sharing this Beau!
