Hello, I’m developing a tool for internal use to create a distance map between two meshes by Z axys. So I scripted it with python but the performance is very poor because there are a lot of pooints to evaluate. Here my script code:
import math
import rhinoscriptsyntax as rs
passo = 0.02 #map resolution
meshApp = rs.GetObject("Mesh iniziale", rs.filter.mesh) #import upper mesh
meshInc = rs.GetObject("Mesh incisa", rs.filter.mesh) #import lower mesh
startPoint = rs.GetPoint("Start point alto dx") #upper right corner
endPoint = rs.GetPoint("End point basso sx") #lower left corner
scanAreaX = abs(endPoint[0]-startPoint[0])
scanAreaY = abs(endPoint[1]-startPoint[1])
samplesX = int(math.ceil(scanAreaX/passo)) #sample points X
samplesY = int(math.ceil(scanAreaY/passo)) #sample points Y
file = open("c:\\test.txt", "w")
for i in range(0,samplesX): #to iterate between 0 to samplesX
for j in range(0,samplesY):
file = open("c:\\test.txt", "a")
basePoint = (endPoint[0]+i*passo,endPoint[1]+j*passo,0)
# project down...
point1 = rs.ProjectPointToMesh(basePoint, meshApp, (0,0,-1))[0]
point2 = rs.ProjectPointToMesh(basePoint, meshInc, (0,0,-1))[0]
distance = rs.Distance(point1, point2)
file.write(str(distance))
file.write('\n')
file.close()
So the script get two meshes and, starting from lower left corner, begins to project a point on the two meshes and calculates the distance between the points. The result is outputted to a TXT file. Each line a distance.
Looks like the projectPointToMesh is very heavy. I’m thinking about building the same tool as a C# plugin but I’d like to know if this could lead to a good performance impovement. Also maybe there is a way to achieve the same result in a faster way.
Thank you very much!
If you’re going to open a file every time the inner loop runs then I’m not surprised it’s slow. You should collect your results in a list during the looping and only write it to a file afterwards.
Yep you’re right! I used it for some kind of debug (watching hte file grow in size) because on first trial it seemed frozen… I changed it but the speed is still far from my dreams. Do you think making the same stuff with a c# plugin would be faster?
OK. If some points are not “over” the mesh I want to project on and the projection fails do I get an error for all the projections or I get a list with the projected points? The mesh could be not a complete square and I need to know wich points are off the mesh.
Newer version of Rhino (and RhinoCommon) have a new ProjectPointsToMeshesEx function that will not only project points to meshes, it will return he indices of the input points that actually hit something.
There is no Python support for this new function at this time. But, you can write your own easy-to-use wrapper (see below).
In this example, the main function adds the projected points and then draws a line between the projected point and the source point.
import Rhino
import rhinoscriptsyntax as rs
import scriptcontext
# Our new and improved ProjectPointToMeshEx function
def ProjectPointToMeshEx(points, mesh_ids, direction):
pts = rs.coerce3dpointlist(points, False)
if pts is None:
pts = [rs.coerce3dpoint(points, True)]
direction = rs.coerce3dvector(direction, True)
id = rs.coerceguid(mesh_ids, False)
if id: mesh_ids = [id]
meshes = [rs.coercemesh(id, True) for id in mesh_ids]
tolerance = scriptcontext.doc.ModelAbsoluteTolerance
rc = Rhino.Geometry.Intersect.Intersection.ProjectPointsToMeshesEx(meshes, pts, direction, tolerance)
return rc
if __name__ == "__main__":
points = rs.GetPointCoordinates("Select points to project")
mesh = rs.GetObject("Select mesh to project onto", rs.filter.mesh)
rc = ProjectPointToMeshEx(points, mesh, (0,0,-1))
if rc:
pts = rc[0]
idx = rc[1]
for i in range(len(pts)):
rs.AddPoint(pts[i])
rs.AddLine(pts[i], points[idx[i]])
I’m trying to move to C# to get everything on a plugin because actually the pythonscript write a txt that I process with a c# application for my needed final result. I’m having problems with
Point3d projectedPoint1 = new Point3d(Rhino.Geometry.Intersect.Intersection.ProjectPointsToMeshes(meshApp,pointToProject,projDir,0.0));
because “meshApp” is a Rhino.Geometry.mesh object while the method requires a Syste.Colletions.Generic.IEnumerable<Rhino.Geometry.mesh> and I don’t understand how to cast it.
About “ProjectPointsToMeshesEx” it could be useful if going this way speeds up everything a lot. Also I need to keep order because the txt will generate a bitmap… something like a displacement map.
Thank you Dale, actually ProjectPointsToMeshesEx() doesen’t exist on my SDK (RH5 SR9). Should I wait for next SR relase or can I pick the library somewhere?
Thak you!