Determining if a point is on a face in Ansys Mechanical Scripting / ACT
I am currently working on a script where I would like to determine if a point is on a face. Edges and Faces have the ability to perform projection efficiently using ParamAtPoint and PointAtParam, however it is possible for these projections to be created off of the face.
Right now I am performing a check using Ray Casting, but as soon as I put the code into a loop to check multiple points it quickly becomes unusable as it takes too long per iteration. The ray casting code looks like this:
`def check_if_point_is_on_face(point, face):
face_param = face.ParamAtPoint(point) normal_vec = face.NormalAtParam(*face_param) inward_vec = -Vector3D(*normal_vec) shifted_point = shift_point_along_unit_vector(point, normal_vec, 0.001) a_point = Point(list(shifted_point), 'm') a_bound_vector = Ansys.Mechanical.Math.BoundVector(a_point, inward_vec) cast_settings = Ansys.Mechanical.Selection.GeometryRayCastSettings() cast_settings.MaxHits = 1 geom_hit = Ansys.Mechanical.Selection.SelectionHelper.CastRayOnGeometry(a_bound_vector, cast_settings) if len(geom_hit) == 1: if geom_hit[0].Entity.Id == face.Id: return True return False`
Any help to either understand how to make Ray Casting "Faster" or how to check whether a PointAtParam is actually on a face would be greatly appreciated!
Answers
-
@Nick Ramseyer one thing you could to is to first filter our any faces that you know the point will not lay on. A Face entity in mechanical has a method to get a bounding box which will return 6 numbers indicating the XYZ of the diagonal corners of a box in global coordinates. If your point is outside that box, you can neglect this face for your ray casting. This may drastically reduce the number of faces you need to check when reviewing a point.
You could further make evaluations for simple shapes like planar faces faster with geom math instead of ray casting.
If you are searching many points it may also be most efficient to capture all the face bounding boxes and sort them in a logical order. You can then use bisection on the sequential data to see which bounding boxes the point is within.
Lastly,
Although Mechanical does have lots of good geometry interrogation tools in the API, Ansys Spaceclaim and/or Discover is a more robust and likely will have more options. If you are limited by Mechanical you could make a script to do a batch run in one of those tools with the exported geom from mechanical. Let the other tool do the processing and store results in a file that you read back into mechanical for your future uses.Example of simple SC/Disco script to determine if a point is on a face:
MyFace = Selection.GetActive().Items[0] #Get the active face selection from UI
P = Point.Create(0,0,0)
print MyFace.Shape.ContainsPoint(P)0