def MeshOutline(object_ids, view=None): """Creates polyline curve outlines of mesh objects Parameters: objects_ids = identifiers of meshes to outline view(opt) = view to use for outline direction Returns: list of polyline curve id on success Example: import rhinoscriptsyntax as rs objs = rs.GetObjects("Select mesh objects to outline", rs.filter.mesh) if objs: rs.MeshOutline(objs) See Also: IsMesh """ viewport = __viewhelper(view).MainViewport meshes = [] mesh = rhutil.coercemesh(object_ids, False) if mesh: meshes.append(mesh) else: meshes = [rhutil.coercemesh(id,True) for id in object_ids] rc = [] for mesh in meshes: polylines = mesh.GetOutlines(viewport) if not polylines: continue for polyline in polylines: id = scriptcontext.doc.Objects.AddPolyline(polyline) rc.append(id) scriptcontext.doc.Views.Redraw() return rc
def MeshBooleanSplit(input0, input1, delete_input=True): """Performs a boolean split operation on two sets of input meshes Parameters: input0, input1 = identifiers of meshes delete_input[opt] = delete the input meshes Returns: list of identifiers of new meshes on success None on error """ id = rhutil.coerceguid(input0) if id: input0 = [id] id = rhutil.coerceguid(input1) if id: input1 = [id] meshes0 = [rhutil.coercemesh(id, True) for id in input0] meshes1 = [rhutil.coercemesh(id, True) for id in input1] if not meshes0 or not meshes1: raise ValueError("no meshes to work with") newmeshes = Rhino.Geometry.Mesh.CreateBooleanSplit(meshes0, meshes1) rc = [] for mesh in newmeshes: id = scriptcontext.doc.Objects.AddMesh(mesh) if id!=System.Guid.Empty: rc.append(id) if rc and delete_input: input = input0 + input1 for id in input: id = rhutil.coerceguid(id, True) scriptcontext.doc.Objects.Delete(id, True) scriptcontext.doc.Views.Redraw() return rc
def MeshMeshIntersection(mesh1, mesh2, tolerance=None): """Calculates the intersections of a mesh object with another mesh object Parameters: mesh1, mesh2 = identifiers of meshes tolerance[opt] = the intersection tolerance Returns: List of 3d point arrays that define the vertices of the intersection curves """ mesh1 = rhutil.coercemesh(mesh1, True) mesh2 = rhutil.coercemesh(mesh2, True) if tolerance is None: tolerance = Rhino.RhinoMath.ZeroTolerance polylines = Rhino.Geometry.Intersect.Intersection.MeshMeshAccurate(mesh1, mesh2, tolerance) if polylines: return list(polylines)
def MeshQuadCount(object_id): """Returns the number of quad faces of a mesh object Parameters: object_id = identifier of a mesh object """ mesh = rhutil.coercemesh(object_id, True) return mesh.Faces.QuadCount
def MeshHasVertexNormals(object_id): """Verifies a mesh object has vertex normals Parameters: object_id = identifier of a mesh object """ mesh = rhutil.coercemesh(object_id, True) return mesh.Normals.Count > 0
def MeshHasVertexColors(object_id): """Verifies a mesh object has vertex colors Parameters: object_id = identifier of a mesh object """ mesh = rhutil.coercemesh(object_id, True) return mesh.VertexColors.Count > 0
def MeshHasTextureCoordinates(object_id): """Verifies a mesh object has texture coordinates Parameters: object_id = identifier of a mesh object """ mesh = rhutil.coercemesh(object_id, True) return mesh.TextureCoordinates.Count > 0
def MeshFaces(object_id, face_type=True): """Returns the face vertices of a mesh Parameters: object_id = identifier of a mesh object face_type[opt] = The face type to be returned. True = both triangles and quads. False = only triangles Returns: a list of 3D points that define the face vertices of the mesh. If face_type is True, then faces are returned as both quads and triangles (4 3D points). For triangles, the third and fourth vertex will be identical. If face_type is False, then faces are returned as only triangles(3 3D points). Quads will be converted to triangles. """ mesh = rhutil.coercemesh(object_id, True) rc = [] for i in xrange(mesh.Faces.Count): getrc, p0, p1, p2, p3 = mesh.Faces.GetFaceVertices(i) p0 = Rhino.Geometry.Point3d(p0) p1 = Rhino.Geometry.Point3d(p1) p2 = Rhino.Geometry.Point3d(p2) p3 = Rhino.Geometry.Point3d(p3) rc.append(p0) rc.append(p1) rc.append(p2) if face_type: rc.append(p3) else: if p2 != p3: rc.append(p2) rc.append(p3) rc.append(p0) return rc
def MeshFaceCount(object_id): """Returns the total face count of a mesh object Parameters: object_id = identifier of a mesh object """ mesh = rhutil.coercemesh(object_id, True) return mesh.Faces.Count
def IsMeshClosed(object_id): """Verifies a mesh object is closed Parameters: object_id = identifier of a mesh object """ mesh = rhutil.coercemesh(object_id, True) return mesh.IsClosed
def ExplodeMeshes(mesh_ids, delete=False): """Explodes a mesh object, or mesh objects int submeshes. A submesh is a collection of mesh faces that are contained within a closed loop of unwelded mesh edges. Unwelded mesh edges are where the mesh faces that share the edge have unique mesh vertices (not mesh topology vertices) at both ends of the edge Parameters: mesh_ids = list of mesh identifiers delete[opt] = delete the input meshes Returns: List of identifiers """ id = rhutil.coerceguid(mesh_ids) if id: mesh_ids = [mesh_ids] rc = [] for mesh_id in mesh_ids: mesh = rhutil.coercemesh(mesh_id, True) if mesh: submeshes = mesh.ExplodeAtUnweldedEdges() if submeshes: for submesh in submeshes: id = scriptcontext.doc.Objects.AddMesh(submesh) if id != System.Guid.Empty: rc.append(id) if rc: scriptcontext.doc.Views.Redraw() return rc
def MeshVolume(object_ids): """ Returns the approximate volume of one or more closed meshes Parameters: object_ids = identifiers of one or more mesh objects Returns: tuple containing 3 numbers if successful where element[0] = number of meshes used in volume calculation element[1] = total volume of all meshes element[2] = the error estimate None if not successful """ id = rhutil.coerceguid(object_ids) if id: object_ids = [id] meshes_used = 0 total_volume = 0.0 error_estimate = 0.0 for id in object_ids: mesh = rhutil.coercemesh(id, True) mp = Rhino.Geometry.VolumeMassProperties.Compute(mesh) if mp: meshes_used += 1 total_volume += mp.Volume error_estimate += mp.VolumeError if meshes_used==0: return scriptcontext.errorhandler() return meshes_used, total_volume, error_estimate
def CurveMeshIntersection(curve_id, mesh_id, return_faces=False): """Calculates the intersection of a curve object and a mesh object Parameters: curve_id = identifier of a curve object mesh_id = identifier or a mesh object return_faces[opt] = return both intersection points and face indices. If False, then just the intersection points are returned Returns: if return_false is omitted or False, then a list of intersection points if return_false is True, the a one-dimensional list containing information about each intersection. Each element contains the following two elements (point of intersection, mesh face index where intersection lies) None on error """ curve = rhutil.coercecurve(curve_id, -1, True) mesh = rhutil.coercemesh(mesh_id, True) tolerance = scriptcontext.doc.ModelAbsoluteTolerance polylinecurve = curve.ToPolyline(0,0,0,0,0.0,tolerance,0.0,0.0,True) pts, faceids = Rhino.Geometry.Intersect.Intersection.MeshPolyline(mesh, polylinecurve) if not pts: return scriptcontext.errorhandler() pts = list(pts) if return_faces: faceids = list(faceids) return zip(pts, faceids) return pts
def MeshVertexCount(object_id): """Returns the vertex count of a mesh Parameters: object_id = identifier of a mesh object """ mesh = rhutil.coercemesh(object_id, True) return mesh.Vertices.Count
def MeshVertexColors(mesh_id, colors=0): """Returns of modifies vertex colors of a mesh Parameters: mesh_id = identifier of a mesh object colors[opt] = A list of color values. Note, for each vertex, there must be a corresponding vertex color. If the value is None, then any existing vertex colors will be removed from the mesh Returns: if colors is not specified, the current vertex colors if colors is specified, the previous vertex colors """ mesh = rhutil.coercemesh(mesh_id, True) rc = [mesh.VertexColors[i] for i in range(mesh.VertexColors.Count)] if colors==0: return rc if colors is None: mesh.VertexColors.Clear() else: color_count = len(colors) if color_count!=mesh.Vertices.Count: raise ValueError("length of colors must match vertex count") colors = [rhutil.coercecolor(c) for c in colors] mesh.VertexColors.Clear() for c in colors: mesh.VertexColors.Add(c) id = rhutil.coerceguid(mesh_id, True) scriptcontext.doc.Objects.Replace(id, mesh) scriptcontext.doc.Views.Redraw() return rc
def MeshTriangleCount(object_id): """Returns the number of triangular faces of a mesh object Parameters: object_id = identifier of a mesh object """ mesh = rhutil.coercemesh(object_id, True) return mesh.Faces.TriangleCount
def MeshArea(object_ids): """Returns the approximate area of one or more mesh objects Parameters: object_ids = identifiers of one or more mesh objects Returns: a list containing 3 numbers if successful where element[0] = number of meshes used in calculation element[1] = total area of all meshes element[2] = the error estimate None if not successful """ id = rhutil.coerceguid(object_ids) if id: object_ids = [object_ids] meshes_used = 0 total_area = 0.0 error_estimate = 0.0 for id in object_ids: mesh = rhutil.coercemesh(id, True) if mesh: mp = Rhino.Geometry.AreaMassProperties.Compute(mesh) if mp: meshes_used += 1 total_area += mp.Area error_estimate += mp.AreaError if meshes_used == 0: return scriptcontext.errorhandler() return meshes_used, total_area, error_estimate
def MeshVolume(object_ids): """Returns the approximate volume of one or more closed meshes Parameters: object_ids = identifiers of one or more mesh objects Returns: tuple containing 3 numbers if successful where element[0] = number of meshes used in volume calculation element[1] = total volume of all meshes element[2] = the error estimate None if not successful Example: import rhinoscriptsyntax as rs obj = rs.GetObject("Select mesh", rs.filter.mesh ) if obj and rs.IsMeshClosed(obj): volume = rs.MeshVolume(obj) if volume: print "Mesh volume:", volume[1] See Also: IsMeshClosed MeshArea """ id = rhutil.coerceguid(object_ids) if id: object_ids = [id] meshes_used = 0 total_volume = 0.0 error_estimate = 0.0 for id in object_ids: mesh = rhutil.coercemesh(id, True) mp = Rhino.Geometry.VolumeMassProperties.Compute(mesh) if mp: meshes_used += 1 total_volume += mp.Volume error_estimate += mp.VolumeError if meshes_used==0: return scriptcontext.errorhandler() return meshes_used, total_volume, error_estimate
def ProjectPointToMesh(points, mesh_ids, direction): """Projects one or more points onto one or more meshes Parameters: points ([point, ...]): one or more 3D points mesh_ids ([guid, ...]): identifiers of one or more meshes direction (vector): direction vector to project the points Returns: list(point, ...): projected points on success Example: import rhinoscriptsyntax as rs mesh = rs.GetObject("Select mesh to project onto", rs.filter.mesh) objects = rs.GetObjects("Select points to project", rs.filter.point) points = [rs.PointCoordinates(obj) for obj in objects] # project down... results = rs.ProjectPointToMesh(points, mesh, (0,0,-1)) rs.AddPoints( results ) See Also: ProjectCurveToMesh ProjectCurveToSurface ProjectPointToSurface """ pts = rhutil.coerce3dpointlist(points, False) if pts is None: pts = [rhutil.coerce3dpoint(points, True)] direction = rhutil.coerce3dvector(direction, True) id = rhutil.coerceguid(mesh_ids, False) if id: mesh_ids = [id] meshes = [rhutil.coercemesh(id, True) for id in mesh_ids] tolerance = scriptcontext.doc.ModelAbsoluteTolerance rc = Rhino.Geometry.Intersect.Intersection.ProjectPointsToMeshes( meshes, pts, direction, tolerance) return rc
def JoinMeshes(object_ids, delete_input=False): """Joins two or or more mesh objects together Parameters: object_ids = identifiers of two or more mesh objects delete_input[opt] = delete input after joining Returns: identifier of newly created mesh on success Example: import rhinoscriptsyntax as rs objs = rs.GetObjects("Select meshes to join", rs.filter.mesh) if objs and len(objs)>1: rs.JoinMeshes(objs, True) See Also: JoinCurves JoinSurfaces """ meshes = [rhutil.coercemesh(id,True) for id in object_ids] joined_mesh = Rhino.Geometry.Mesh() for mesh in meshes: joined_mesh.Append(mesh) rc = scriptcontext.doc.Objects.AddMesh(joined_mesh) if delete_input: for id in object_ids: guid = rhutil.coerceguid(id) scriptcontext.doc.Objects.Delete(guid,True) scriptcontext.doc.Views.Redraw() return rc
def MeshFaces(object_id, face_type=True): """Returns the face vertices of a mesh Parameters: object_id = identifier of a mesh object face_type[opt] = The face type to be returned. True = both triangles and quads. False = only triangles Returns: a list of 3D points that define the face vertices of the mesh. If face_type is True, then faces are returned as both quads and triangles (4 3D points). For triangles, the third and fourth vertex will be identical. If face_type is False, then faces are returned as only triangles(3 3D points). Quads will be converted to triangles. """ mesh = rhutil.coercemesh(object_id, True) rc = [] for i in xrange(mesh.Faces.Count): getrc, p0, p1, p2, p3 = mesh.Faces.GetFaceVertices(i) p0 = Rhino.Geometry.Point3d(p0) p1 = Rhino.Geometry.Point3d(p1) p2 = Rhino.Geometry.Point3d(p2) p3 = Rhino.Geometry.Point3d(p3) rc.append( p0 ) rc.append( p1 ) rc.append( p2 ) if face_type: rc.append(p3) else: if p2!=p3: rc.append( p2 ) rc.append( p3 ) rc.append( p0 ) return rc
def MeshVolume(object_ids): """ Returns the approximate volume of one or more closed mesh objects Parameters: object_ids = identifiers of one or more mesh objects Returns: a tuple containing 3 numbers if successful where element[0] = number of meshes used in volume calculation element[1] = total volume of all meshes element[2] = the error estimate None if not successful """ id = rhutil.coerceguid(object_ids) if id: object_ids = [id] meshes_used = 0 total_volume = 0.0 error_estimate = 0.0 for id in object_ids: mesh = rhutil.coercemesh(id, True) mp = Rhino.Geometry.VolumeMassProperties.Compute(mesh) if mp: meshes_used += 1 total_volume += mp.Volume error_estimate += mp.VolumeError if meshes_used==0: return scriptcontext.errorhandler() return meshes_used, total_volume, error_estimate
def MeshClosestPoint(object_id, point, maximum_distance=None): """Returns the point on a mesh that is closest to a test point Parameters: object_id = identifier of a mesh object point = point to test maximum_distance[opt] = upper bound used for closest point calculation. If you are only interested in finding a point Q on the mesh when point.DistanceTo(Q) < maximum_distance, then set maximum_distance to that value Returns: Tuple containing the results of the calculation where element[0] = the 3-D point on the mesh element[1] = the index of the mesh face on which the 3-D point lies None on error Example: import rhinocriptsyntax as rs obj = rs.GetObject("Select mesh", rs.filter.mesh) point = rs.GetPoint("Pick test point") intersect = rs.MeshClosestPoint(obj, point) if intersect: rs.AddPoint(intersect) See Also: MeshFaceCount MeshFaces """ mesh = rhutil.coercemesh(object_id, True) point = rhutil.coerce3dpoint(point, True) tolerance=maximum_distance if maximum_distance else 0.0 face, closest_point = mesh.ClosestPoint(point, tolerance) if face<0: return scriptcontext.errorhandler() return closest_point, face
def MeshHasTextureCoordinates(object_id): """Verifies a mesh object has texture coordinates Parameters: object_id = identifier of a mesh object """ mesh = rhutil.coercemesh(object_id, True) return mesh.TextureCoordinates.Count>0
def MeshArea(object_ids): """Returns approximate area of one or more mesh objects Parameters: object_ids = identifiers of one or more mesh objects Returns: list containing 3 numbers if successful where element[0] = number of meshes used in calculation element[1] = total area of all meshes element[2] = the error estimate None if not successful Example: import rhinoscriptsyntax as rs obj = rs.GetObject("Select mesh", rs.filter.mesh ) if obj: area_rc = rs.MeshArea(obj) if area_rc: print "Mesh area:", area_rc[1] See Also: MeshVolume """ id = rhutil.coerceguid(object_ids) if id: object_ids = [object_ids] meshes_used = 0 total_area = 0.0 error_estimate = 0.0 for id in object_ids: mesh = rhutil.coercemesh(id, True) if mesh: mp = Rhino.Geometry.AreaMassProperties.Compute(mesh) if mp: meshes_used += 1 total_area += mp.Area error_estimate += mp.AreaError if meshes_used==0: return scriptcontext.errorhandler() return meshes_used, total_area, error_estimate
def PullCurveToMesh(mesh_id, curve_id): """Pulls a curve to a mesh. The function makes a polyline approximation of the input curve and gets the closest point on the mesh for each point on the polyline. Then it "connects the points" to create a polyline on the mesh Parameters: mesh_id = identifier of mesh that pulls curve_id = identifier of curve to pull Returns: Guid of new curve on success None on error Example: import rhinoscriptsyntax as rs mesh = rs.GetObject("Select mesh that pulls", rs.filter.mesh) curve = rs.GetObject("Select curve to pull", rs.filter.curve) rs.PullCurveToMesh( mesh, curve ) See Also: IsMesh """ mesh = rhutil.coercemesh(mesh_id, True) curve = rhutil.coercecurve(curve_id, -1, True) tol = scriptcontext.doc.ModelAbsoluteTolerance polyline = curve.PullToMesh(mesh, tol) if not polyline: return scriptcontext.errorhandler() rc = scriptcontext.doc.Objects.AddCurve(polyline) if rc==System.Guid.Empty: raise Exception("unable to add polyline to document") scriptcontext.doc.Views.Redraw() return rc
def IsPointOnMesh(object_id, point): """Verifies a point is on a mesh Parameters: object_id = identifier of a mesh object point = test point Returns: True if successful, otherwise False. None on error. Example: import rhinoscriptsyntax as rs obj = rs.GetObject("Select a mesh") if rs.IsMesh(obj): point = rs.GetPointOnMesh(strObject, "Pick a test point") if point: if rs.IsPointOnMesh(obj, point): print "The point is on the mesh" else: print "The point is not on the mesh" See Also: IsMesh MeshClosestPoint """ mesh = rhutil.coercemesh(object_id, True) point = rhutil.coerce3dpoint(point, True) max_distance = Rhino.RhinoMath.SqrtEpsilon face, pt = mesh.ClosestPoint(point, max_distance) return face>=0
def PullPoints(object_id, points): """Pulls an array of points to a surface or mesh object. For more information, see the Rhino help file Pull command Parameters: object_id = the identifier of the surface or mesh object that pulls points = list of 3D points Returns: list of 3D points Example: import rhinoscriptsyntax as rs surface = rs.GetObject("Select surface that pulls", rs.filter.surface) objects = rs.GetObjects("Select points to pull", rs.filter.point) points = [rs.PointCoordinates(obj) for obj in objects] results = rs.PullPoints( surface, points ) rs.AddPoints( results ) See Also: PullCurve """ id = rhutil.coerceguid(object_id, True) points = rhutil.coerce3dpointlist(points, True) mesh = rhutil.coercemesh(id, False) if mesh: points = mesh.PullPointsToMesh(points) return list(points) brep = rhutil.coercebrep(id, False) if brep and brep.Faces.Count==1: tolerance = scriptcontext.doc.ModelAbsoluteTolerance points = brep.Faces[0].PullPointsToFace(points, tolerance) return list(points) return []
def MeshHasVertexNormals(object_id): """Verifies a mesh object has vertex normals Parameters: object_id = identifier of a mesh object """ mesh = rhutil.coercemesh(object_id, True) return mesh.Normals.Count>0
def ProjectPointToMesh(points, mesh_ids, direction): """Projects one or more points onto one or more meshes Parameters: points = one or more 3D points mesh_ids = identifiers of one or more meshes direction = direction vector to project the points Returns: list of projected points on success Example: import rhinoscriptsyntax as rs mesh = rs.GetObject("Select mesh to project onto", rs.filter.mesh) objects = rs.GetObjects("Select points to project", rs.filter.point) points = [rs.PointCoordinates(obj) for obj in objects] # project down... results = rs.ProjectPointToMesh(points, mesh, (0,0,-1)) rs.AddPoints( results ) See Also: ProjectCurveToMesh ProjectCurveToSurface ProjectPointToSurface """ pts = rhutil.coerce3dpointlist(points, False) if pts is None: pts = [rhutil.coerce3dpoint(points, True)] direction = rhutil.coerce3dvector(direction, True) id = rhutil.coerceguid(mesh_ids, False) if id: mesh_ids = [id] meshes = [rhutil.coercemesh(id, True) for id in mesh_ids] tolerance = scriptcontext.doc.ModelAbsoluteTolerance rc = Rhino.Geometry.Intersect.Intersection.ProjectPointsToMeshes(meshes, pts, direction, tolerance) return rc
def MeshVertexColors(mesh_id, colors=0): """Returns of modifies the vertex colors of a mesh object Parameters: mesh_id = identifier of a mesh object colors[opt] = A list of color values. Note, for each vertex, there must be a corresponding vertex color. If the value is None, then any existing vertex colors will be removed from the mesh Returns: if colors is not specified, the current vertex colors if colors is specified, the previous vertex colors """ mesh = rhutil.coercemesh(mesh_id, True) rc = [mesh.VertexColors[i] for i in range(mesh.VertexColors.Count)] if colors==0: return rc if colors is None: mesh.VertexColors.Clear() else: color_count = len(colors) if color_count!=mesh.Vertices.Count: raise ValueError("length of colors must match vertex count") colors = [rhutil.coercecolor(c) for c in colors] mesh.VertexColors.Clear() for c in colors: mesh.VertexColors.Add(c) id = rhutil.coerceguid(mesh_id, True) scriptcontext.doc.Objects.Replace(id, mesh) scriptcontext.doc.Views.Redraw() return rc
def MeshVertexCount(object_id): """Returns the vertex count of a mesh object Parameters: object_id = identifier of a mesh object """ mesh = rhutil.coercemesh(object_id, True) return mesh.Vertices.Count
def MeshFaceNormals(mesh_id): """Returns the face unit normal for each face of a mesh object Parameters: mesh_id = identifier of a mesh object Returns: List of 3D vectors that define the face unit normals of the mesh None on error Example: import rhinoscriptsyntax as rs obj = rs.GetObject("Select mesh", rs.filter.mesh) normals = rs.MeshFaceNormals(obj) if normals: for vector in normals: print vector See Also: MeshHasFaceNormals MeshFaceCount MeshFaces """ mesh = rhutil.coercemesh(mesh_id, True) if mesh.FaceNormals.Count != mesh.Faces.Count: mesh.FaceNormals.ComputeFaceNormals() rc = [] for i in xrange(mesh.FaceNormals.Count): normal = mesh.FaceNormals[i] rc.append(Rhino.Geometry.Vector3d(normal)) return rc
def PullPoints(object_id, points): """Pulls an array of points to a surface or mesh object. For more information, see the Rhino help file Pull command Parameters: object_id (guid): the identifier of the surface or mesh object that pulls points ([point, ...]): list of 3D points Returns: list(point, ...): 3D points pulled onto surface or mesh Example: import rhinoscriptsyntax as rs surface = rs.GetObject("Select surface that pulls", rs.filter.surface) objects = rs.GetObjects("Select points to pull", rs.filter.point) points = [rs.PointCoordinates(obj) for obj in objects] results = rs.PullPoints( surface, points ) rs.AddPoints( results ) See Also: PullCurve """ id = rhutil.coerceguid(object_id, True) points = rhutil.coerce3dpointlist(points, True) mesh = rhutil.coercemesh(id, False) if mesh: points = mesh.PullPointsToMesh(points) return list(points) brep = rhutil.coercebrep(id, False) if brep and brep.Faces.Count == 1: tolerance = scriptcontext.doc.ModelAbsoluteTolerance points = brep.Faces[0].PullPointsToFace(points, tolerance) return list(points) return []
def MeshFaceVertices(object_id): """Returns the vertex indices of all faces of a mesh object Parameters: object_id = identifier of a mesh object Returns: A list containing tuples of 4 numbers that define the vertex indices for each face of the mesh. Both quad and triangle faces are returned. If the third and fourth vertex indices are identical, the face is a triangle. Example: import rhinoscriptsyntax as rs obj = rs.GetObject("Select mesh", rs.filter.mesh) faceVerts = rs.MeshFaceVertices( obj ) if faceVerts: for count, face in enumerate(faceVerts): print "face(", count, ") = (", face[0], ",", face[1], ",", face[2], ",", face[3], ")" See Also: IsMesh MeshFaceCount MeshFaces """ mesh = rhutil.coercemesh(object_id, True) rc = [] for i in xrange(mesh.Faces.Count): face = mesh.Faces.GetFace(i) rc.append( (face.A, face.B, face.C, face.D) ) return rc
def MeshBooleanUnion(mesh_ids, delete_input=True): """Performs boolean union operation on a set of input meshes Parameters: mesh_ids = identifiers of meshes delete_input[opt] = delete the input meshes Returns: list of identifiers of new meshes Example: import rhinoscriptsyntax as rs input = rs.GetObjects("Select meshes to union", rs.filter.mesh) if input: rs.MeshBooleanUnion(input) See Also: MeshBooleanDifference MeshBooleanIntersection MeshBooleanSplit """ if len(mesh_ids)<2: raise ValueError("mesh_ids must contain at least 2 meshes") meshes = [rhutil.coercemesh(id, True) for id in mesh_ids] newmeshes = Rhino.Geometry.Mesh.CreateBooleanUnion(meshes) rc = [] for mesh in newmeshes: id = scriptcontext.doc.Objects.AddMesh(mesh) if id!=System.Guid.Empty: rc.append(id) if rc and delete_input: for id in mesh_ids: id = rhutil.coerceguid(id, True) scriptcontext.doc.Objects.Delete(id, True) scriptcontext.doc.Views.Redraw() return rc
def MeshNakedEdgePoints(object_id): """Identifies the naked edge points of a mesh object. This function shows where mesh vertices are not completely surrounded by faces. Joined meshes, such as are made by MeshBox, have naked mesh edge points where the sub-meshes are joined Parameters: object_id = identifier of a mesh object Returns: List of boolean values that represent whether or not a mesh vertex is naked or not. The number of elements in the list will be equal to the value returned by MeshVertexCount. In which case, the list will identify the naked status for each vertex returned by MeshVertices None on error Example: import rhinoscriptsyntax as rs obj = rs.GetObject("Select mesh", rs.filter.mesh) vertices = rs.MeshVertices( obj ) naked = rs.MeshNakedEdgePoints( obj ) for i, vertex in enumerate(vertices): if naked[i]: rs.AddPoint(vertex) See Also: IsMesh MeshVertexCount MeshVertices """ mesh = rhutil.coercemesh(object_id, True) rc = mesh.GetNakedEdgePointStatus() return rc
def MeshHasVertexColors(object_id): """Verifies a mesh object has vertex colors Parameters: object_id = identifier of a mesh object """ mesh = rhutil.coercemesh(object_id, True) return mesh.VertexColors.Count>0
def MeshArea(object_ids): """Returns the approximate area of one or more mesh objects Parameters: object_ids = identifiers of one or more mesh objects Returns: a list containing 3 numbers if successful where element[0] = number of meshes used in calculation element[1] = total area of all meshes element[2] = the error estimate None if not successful """ id = rhutil.coerceguid(object_ids) if id: object_ids = [object_ids] meshes_used = 0 total_area = 0.0 error_estimate = 0.0 for id in object_ids: mesh = rhutil.coercemesh(id, True) if mesh: mp = Rhino.Geometry.AreaMassProperties.Compute(mesh) if mp: meshes_used += 1 total_area += mp.Area error_estimate += mp.AreaError if meshes_used==0: return scriptcontext.errorhandler() return meshes_used, total_area, error_estimate
def ExplodeMeshes(mesh_ids, delete=False): """Explodes a mesh object, or mesh objects int submeshes. A submesh is a collection of mesh faces that are contained within a closed loop of unwelded mesh edges. Unwelded mesh edges are where the mesh faces that share the edge have unique mesh vertices (not mesh topology vertices) at both ends of the edge Parameters: mesh_ids = list of mesh identifiers delete[opt] = delete the input meshes Returns: List of identifiers """ id = rhutil.coerceguid(mesh_ids) if id: mesh_ids = [mesh_ids] rc = [] for mesh_id in mesh_ids: mesh = rhutil.coercemesh(mesh_id, True) if mesh: submeshes = mesh.ExplodeAtUnweldedEdges() if submeshes: for submesh in submeshes: id = scriptcontext.doc.Objects.AddMesh(submesh) if id!=System.Guid.Empty: rc.append(id) if rc: scriptcontext.doc.Views.Redraw() return rc
def MeshToNurb(object_id, trimmed_triangles=True, delete_input=False): """Duplicates each polygon in a mesh with a NURBS surface. The resulting surfaces are then joined into a polysurface and added to the document Parameters: object_id = identifier of a mesh object trimmed_triangles[opt] = if True, triangles in the mesh will be represented by a trimmed plane delete_input[opt] = delete input object Returns: list of identifiers for the new breps on success Example: import rhinoscriptsyntax as rs obj = rs.GetObject("Select mesh", rs.filter.mesh) if obj: rs.MeshToNurb(obj) See Also: IsMesh MeshFaces MeshVertices """ mesh = rhutil.coercemesh(object_id, True) pieces = mesh.SplitDisjointPieces() breps = [Rhino.Geometry.Brep.CreateFromMesh(piece,trimmed_triangles) for piece in pieces] rhobj = rhutil.coercerhinoobject(object_id, True, True) attr = rhobj.Attributes ids = [scriptcontext.doc.Objects.AddBrep(brep, attr) for brep in breps] if delete_input: scriptcontext.doc.Objects.Delete(rhobj, True) scriptcontext.doc.Views.Redraw() return ids
def MeshFaceCenters(mesh_id): """Returns the center of each face of the mesh object Parameters: mesh_id = identifier of a mesh object Returns: list of 3d points defining the center of each face """ mesh = rhutil.coercemesh(mesh_id, True) return [mesh.Faces.GetFaceCenter(i) for i in range(mesh.Faces.Count)]
def DisjointMeshCount(object_id): """Returns number of meshes that could be created by calling SplitDisjointMesh Parameters: object_id = identifier of a mesh object Returns: The number of meshes that could be created """ mesh = rhutil.coercemesh(object_id, True) return mesh.DisjointMeshCount
def IsMeshManifold(object_id): """Verifies a mesh object is manifold. A mesh for which every edge is shared by at most two faces is called manifold. If a mesh has at least one edge that is shared by more than two faces, then that mesh is called non-manifold Parameters: object_id = identifier of a mesh object """ mesh = rhutil.coercemesh(object_id, True) rc = mesh.IsManifold(True) return rc[0]
def MeshVertexNormals(mesh_id): """Returns the vertex unit normal for each vertex of a mesh Parameters: mesh_id = identifier of a mesh object Returns: list of vertex normals, (empty list if no normals exist) """ mesh = rhutil.coercemesh(mesh_id, True) count = mesh.Normals.Count if count < 1: return [] return [Rhino.Geometry.Vector3d(mesh.Normals[i]) for i in xrange(count)]
def MeshVertexFaces(mesh_id, vertex_index): """Returns the mesh faces that share a specified mesh vertex Parameters: mesh_id = identifier of a mesh object vertex_index = index of the mesh vertex to find faces for Returns: list of face indices on success None on error """ mesh = rhutil.coercemesh(mesh_id, True) return mesh.Vertices.GetVertexFaces(vertex_index)
def IsPointOnMesh(object_id, point): """Verifies a point is on a mesh Parameters: object_id = identifier of a mesh object point = test point """ mesh = rhutil.coercemesh(object_id, True) point = rhutil.coerce3dpoint(point, True) max_distance = Rhino.RhinoMath.SqrtEpsilon face, pt = mesh.ClosestPoint(point, max_distance) return face >= 0
def MeshAreaCentroid(object_id): """Calculates the area centroid of a mesh object Parameters: object_id = identifier of a mesh object Returns: Point3d representing the area centroid if successful None on error """ mesh = rhutil.coercemesh(object_id, True) mp = Rhino.Geometry.AreaMassProperties.Compute(mesh) if mp is None: return scriptcontext.errorhandler() return mp.Centroid
def MeshVolumeCentroid(object_id): """Calculates the volume centroid of a mesh Parameters: object_id = identifier of a mesh object Returns: Point3d representing the volume centroid None on error """ mesh = rhutil.coercemesh(object_id, True) mp = Rhino.Geometry.VolumeMassProperties.Compute(mesh) if mp: return mp.Centroid return scriptcontext.errorhandler()
def MeshOutline(object_ids, view=None): """Creates polyline curve outlines of mesh objects Parameters: objects_ids = identifiers of meshes to outline view(opt) = view to use for outline direction Returns: list of polyline curve id on success """ viewport = __viewhelper(view).MainViewport meshes = [] mesh = rhutil.coercemesh(object_ids, False) if mesh: meshes.append(mesh) else: meshes = [rhutil.coercemesh(id, True) for id in object_ids] rc = [] for mesh in meshes: polylines = mesh.GetOutlines(viewport) for polyline in polylines: id = scriptcontext.doc.Objects.AddPolyline(polyline) rc.append(id) scriptcontext.doc.Views.Redraw() return rc
def MeshBooleanDifference(input0, input1, delete_input=True, tolerance=None): """Performs boolean difference operation on two sets of input meshes Parameters: input0, input1 (guid): identifiers of meshes delete_input (bool, optional): delete the input meshes tolerance (float, optional): this value is ignored. The parameter is only there to keep the function signature the same, The build in tolerenace always is used. Returns: list(guid, ...): identifiers of newly created meshes Example: import rhinoscriptsyntax as rs input0 = rs.GetObjects("Select first set of meshes", rs.filter.mesh) if input0: input1 = rs.GetObjects("Select second set of meshes", rs.filter.mesh) if input1: rs.MeshBooleanDifference(input0, input1) See Also: MeshBooleanIntersection MeshBooleanSplit MeshBooleanUnion """ id = rhutil.coerceguid(input0) if id: input0 = [id] id = rhutil.coerceguid(input1) if id: input1 = [id] meshes0 = [rhutil.coercemesh(id, True) for id in input0] meshes1 = [rhutil.coercemesh(id, True) for id in input1] if not meshes0 or not meshes1: raise ValueError("no meshes to work with") newmeshes = Rhino.Geometry.Mesh.CreateBooleanDifference(meshes0, meshes1) rc = [] for mesh in newmeshes: id = scriptcontext.doc.Objects.AddMesh(mesh) if id != System.Guid.Empty: rc.append(id) if rc and delete_input: input = input0 + input1 for id in input: id = rhutil.coerceguid(id, True) scriptcontext.doc.Objects.Delete(id, True) scriptcontext.doc.Views.Redraw() return rc
def MeshBooleanSplit(input0, input1, delete_input=True): """Performs boolean split operation on two sets of input meshes Parameters: input0, input1 (guid): identifiers of meshes delete_input (bool, optional): delete the input meshes Returns: list(guid, ...): identifiers of new meshes on success None: on error Example: import rhinoscriptsyntax as rs input0 = rs.GetObjects("Select first set of meshes", rs.filter.mesh) if input0: input1 = rs.GetObjects("Select second set of meshes", rs.filter.mesh) if input1: rs.MeshBooleanSplit(input0, input1) See Also: MeshBooleanDifference MeshBooleanIntersection MeshBooleanUnion """ id = rhutil.coerceguid(input0) if id: input0 = [id] id = rhutil.coerceguid(input1) if id: input1 = [id] meshes0 = [rhutil.coercemesh(id, True) for id in input0] meshes1 = [rhutil.coercemesh(id, True) for id in input1] if not meshes0 or not meshes1: raise ValueError("no meshes to work with") newmeshes = Rhino.Geometry.Mesh.CreateBooleanSplit(meshes0, meshes1) rc = [] for mesh in newmeshes: id = scriptcontext.doc.Objects.AddMesh(mesh) if id!=System.Guid.Empty: rc.append(id) if rc and delete_input: input = input0 + input1 for id in input: id = rhutil.coerceguid(id, True) scriptcontext.doc.Objects.Delete(id, True) scriptcontext.doc.Views.Redraw() return rc
def MeshMeshIntersection(mesh1, mesh2, tolerance=None): """Calculates the intersections of a mesh object with another mesh object Parameters: mesh1, mesh2 (guid): identifiers of meshes tolerance (number, optional): the intersection tolerance Returns: list(point, ...): of points that define the vertices of the intersection curves Example: import rhinoscriptsyntax as rs mesh1 = rs.GetObject("Select first mesh to intersect", rs.filter.mesh) mesh2 = rs.GetObject("Select second mesh to intersect", rs.filter.mesh) results = rs.MeshMeshIntersection(mesh1, mesh2) if results: for points in results: rs.AddPolyline(points) See Also: CurveMeshIntersection MeshClosestPoint """ mesh1 = rhutil.coercemesh(mesh1, True) mesh2 = rhutil.coercemesh(mesh2, True) if tolerance is None: tolerance = Rhino.RhinoMath.ZeroTolerance polylines = Rhino.Geometry.Intersect.Intersection.MeshMeshAccurate(mesh1, mesh2, tolerance) if polylines: return list(polylines)
def MeshVertices(object_id): """Returns the vertices of a mesh Parameters: object_id = identifier of a mesh object Returns: list of 3D points """ mesh = rhutil.coercemesh(object_id, True) count = mesh.Vertices.Count rc = [] for i in xrange(count): vertex = mesh.Vertices[i] rc.append(Rhino.Geometry.Point3d(vertex)) return rc
def UnifyMeshNormals(object_id): """Fixes inconsistencies in the directions of faces of a mesh Parameters: object_id = identifier of a mesh object Returns: number of faces that were modified """ mesh = rhutil.coercemesh(object_id, True) rc = mesh.UnifyNormals() if rc > 0: id = rhutil.coerceguid(object_id, True) scriptcontext.doc.Objects.Replace(id, mesh) scriptcontext.doc.Views.Redraw() return rc