I want to check whether a point (or line) is inside or outside a body, but I can't find any clues in the API document for doing this, can anyone help?
Sub main() Dim MyPoint(0 To 2) As Double ' xyz coordinate of your point MyPoint(0) = 1 MyPoint(1) = 1 MyPoint(2) = 1 Dim swApp As SldWorks.SldWorks Dim myModel As SldWorks.ModelDoc2 Dim myPart As SldWorks.PartDoc Dim mathUtils As SldWorks.MathUtility Set swApp = Application.SldWorks Set myModel = swApp.ActiveDoc Set myPart = myModel Set mathUtils = swApp.GetMathUtility()
' Do the ray intersection operation Dim rayDir1(0 To 2) As Double Dim vMyPoint As Variant Dim vVector As Variant Dim rayPoint As SldWorks.MathPoint Dim rayVector As SldWorks.MathVector Dim intersectPt As SldWorks.MathPoint
Dim vPoint2 As Variant Dim xPt As Double, yPt As Double, zPt As Double Dim vBodies As Variant Dim vBody As Variant Dim swBody As SldWorks.Body2 Dim faceToUse As SldWorks.Face2 Dim surfaceToUse As SldWorks.Surface Dim counter As Integer vBodies = myPart.GetBodies2(swAllBodies, False) For Each vBody In vBodies Set swBody = vBody Set faceToUse = swBody.GetFirstFace counter = 0 Do While Not faceToUse Is Nothing vMyPoint = MyPoint Set rayPoint = mathUtils.CreatePoint(vMyPoint) rayDir1(0) = 0 rayDir1(1) = -1 rayDir1(2) = 0 vVector = rayDir1 Set rayVector = mathUtils.CreateVector(vVector) Set surfaceToUse = faceToUse.GetSurface() If Not surfaceToUse Is Nothing Then Set intersectPt = surfaceToUse.GetProjectedPointOn(rayPoint, rayVector)
While Not intersectPt Is Nothing 'ToDo: if intersectPt just on edge, then it should be counted only once .....
counter = counter + 1 vPoint2 = intersectPt.ArrayData xPt = vPoint2(0) yPt = vPoint2(1) zPt = vPoint2(2) If xPt = MyPoint(0) And yPt = MyPoint(1) And zPt = MyPoint(2) Then Debug.Print "Point on face of body: " & swBody.Name counter = 0 Exit Do End If If Not surfaceToUse.IsPlane Then vPoint2(1) = vPoint2(1) - 0.0000001 vMyPoint = vPoint2 Set rayPoint = mathUtils.CreatePoint(vMyPoint) Set intersectPt = surfaceToUse.GetProjectedPointOn(rayPoint, rayVector) End If Wend End If Set faceToUse = faceToUse.GetNextFace Loop If counter Mod 2 = 0 Then Debug.Print "Point outside of body: " & swBody.Name End If If counter > 0 And counter Mod 2 = 1 Then Debug.Print "Point inside of body: " & swBody.Name End If NextEnd Sub
Thanks for your advice, however, I could not find how to get the contain relationship (i.e, a point in inside a body) by using the IMeasure interface. The property IsIntersect of the IMeasure is true only when the point is on the face of a body.
I found that the the command Tools-->Measure could give this information "The larger component part contains the other selected item." when I select the part and a reference point inside the part.
Therefore, how to get this contain relationship information through API?
I have the same problem that you.
Did you find the solution of this problem.
You might try getting the closest point on the surface of the body and then comparing the vector from the point to the surface point to the normal of the surface at the surface point. I believe the surface normal to a body always points away from the material. Unfortunately I don't see a get closest point on method for body so you would have to drill down to each face and use the method there.
Thank you for this Ivana but there is one problem. With a Concave Shape this may incorrectly determine that a point lies within a body since it is using ray intersection points with the Face's Surface which extends beyond the bounds of the face itself. Unfortunately I do not yet know a method to find ray intersections with the trimmed surface of the face. So for example a point at the center of mass of a U shaped Extrusion will give a false positive for being inside the U shaped body.
Check out GetRayIntersectionsPoints Method:
it return if the ray as enter, exit or grazed the solid at each intersection
Excellent suggestion Fifi. I now also realize there is also a GetProjectedPointOn method which can be used on a Face object rather than a surface object. I imagine that would be a direct substitution into the existing code from Ivana.
Ivana's solution seems very professional ...
however ... you could consider an empirical method: make a small circle on a sketch inside a plane passing through your point. Then cut your body with a small cut extrusion generated from the sketch. If the cut operation gives you an error, this probably means that the point is outsite the body ... otherwise it's inside!
Not professional at all, but maybe it works
Retrieving data ...