def IsPointInside(meshId, pt, tolerance = 1e-6): faceVerts = rs.MeshFaces(meshId, face_type=False) totalAngle = 0 i = 0 while i < len(faceVerts): ptA = faceVerts[i] ptB = faceVerts[i + 1] ptC = faceVerts[i + 2] a = rs.VectorSubtract(ptA, pt) b = rs.VectorSubtract(ptB, pt) c = rs.VectorSubtract(ptC, pt) angle = GetSolidAngle(a,b,c) normal = Normal(ptA, ptB, ptC) center = Centroid(ptA, ptB, ptC) faceVec = rs.VectorSubtract(pt, center) dot = rs.VectorDotProduct(normal, faceVec) factor = 1 if dot > 0 else -1 totalAngle += angle * factor i += 3 absTotal = abs(totalAngle) inside = abs(absTotal - (4*math.pi)) < tolerance print("The total solid angle is %.02fPI"%(absTotal/math.pi)) return inside
def get_mesh_faces(mesh): """ Takes a mesh and convert its faces into individual meshes. :param mesh: mesh :return: list of "face" meshes """ mesh_faces = rs.MeshFaces(mesh) faces = [] for i in range(0, len(mesh_faces), 4): vertices = [mesh_faces[i], mesh_faces[i + 1], mesh_faces[i + 2], mesh_faces[i + 3]] added_mesh = rs.AddMesh(vertices, [[0, 1, 2, 3]]) faces.append(added_mesh) return faces
import rhinoscriptsyntax as rs idSurface = rs.GetObject("Surface to frame", 8, True, True) faces = [] intCount = rs.GetInteger("Number of iterations per direction", 20, 2) uDomain = rs.SurfaceDomain(idSurface, 0) vDomain = rs.SurfaceDomain(idSurface, 1) uStep = int((uDomain[1] - uDomain[0]) / intCount) vStep = int((vDomain[1] - vDomain[0]) / intCount) rs.EnableRedraw(False) for u in range(int(uDomain[0]), int(uDomain[1]), int(uStep)): for v in range(int(vDomain[0]), int(vDomain[1]), int(vStep)): pt = rs.EvaluateSurface(idSurface, u, v) srfFrame = rs.SurfaceFrame(idSurface, [u, v]) rs.AddPlaneSurface(srfFrame, 2.0, 2.0) #rs.AddEllipse(srfFrame, 1.0, 3.0) component = rs.GetObject("component to populate", rs.filter.mesh) faces = rs.MeshFaces(component, False) rs.AddMesh(faces, srfFrame) rs.EnableRedraw(True)
def ScatterBlocks(): try: ################################################################################ # GET OBJECTS AND VARIABLE # ################################################################################ obj = rs.GetObject(message="Select surface to scatter on", filter=8 | 16 | 32, preselect=False, select=False, custom_filter=None, subobjects=False) if not obj: return blocks = rs.GetObjects(message="Select blocks to scatter", filter=4096, group=True, preselect=False, select=False, objects=None, minimum_count=1, maximum_count=0, custom_filter=None) if not blocks: return scatterNum = rs.GetInteger( message="Enter scatter amount", number=100, minimum=1, maximum=10000) if not scatterNum: return userScale = rs.GetReal( "enter scale multiplyer (0 for no scaling)", number=0, minimum=None, maximum=None) userRotation = rs.GetBoolean( "random rotation of blocks?", ("Rotation", "No", "Yes"), (True)) if not userRotation: return isMesh = rs.IsMesh(obj) ptBucket = 0 pointList = [] blockList = [] worldZVector = (rs.WorldXYPlane()).ZAxis rs.EnableRedraw(False) def MeshBrep(brep_id, params): brep = rs.coercebrep(brep_id) if brep: mesh = Rhino.Geometry.Mesh() mesh_parts = Rhino.Geometry.Mesh.CreateFromBrep(brep, params) for mesh_part in mesh_parts: mesh.Append(mesh_part) mesh.Compact() return mesh def TestMeshBrep(): mesh_params = Rhino.Geometry.MeshingParameters.Coarse mesh_brep = MeshBrep(obj, mesh_params) if mesh_brep: mesh = sc.doc.Objects.AddMesh(mesh_brep) return mesh def chunks(lst, n): # list split generator for i in xrange(0, len(lst), n): yield lst[i:i + n] if isMesh == False: mesh = TestMeshBrep() else: mesh = obj # Get and format vertex points in mesh, format from point3d object to float list meshVerts = rs.MeshFaces(mesh, face_type=False) totalArea = rs.MeshArea(mesh) meshFaceCount = rs.MeshFaceCount(mesh) PT01 = meshVerts[0::3] PT01S = [] for i in PT01: i = (i.X, i.Y, i.Z) PT01S.append(i) PT02 = meshVerts[1::3] PT02S = [] for i in PT02: i = (i.X, i.Y, i.Z) PT02S.append(i) PT03 = meshVerts[2::3] PT03S = [] for i in PT03: i = (i.X, i.Y, i.Z) PT03S.append(i) # format list together in order to loop through triangleList = zip(PT01S, PT02S, PT03S) ################################################################################ # POINT SCATTER LOOP # ################################################################################ # loop through the three vertexes forming individual triangles for i in triangleList: a = i[0] # triangle vert 1 b = i[1] # triangle vert 2 c = i[2] # triangle vert 3 # Find area of triangle dist01 = rs.Distance(a, b) dist02 = rs.Distance(a, c) dist03 = rs.Distance(b, c) # Herons formula to find area of triangle by sides s = (dist01 + dist02 + dist03) / 2 tArea = math.sqrt(s*(s-dist01)*(s-dist02)*(s-dist03)) # assign portion of points base on area of triangle, if assignment of points is lower then one, add that to the next assignment numPtsPerUnit = totalArea[1] / scatterNum ptAllocation = tArea / numPtsPerUnit ptBucket = ptBucket + ptAllocation if ptBucket < 1: continue else: pointShare = int(math.floor(ptBucket)) ptBucket = 0 # Vectors from origin to either corner of triangle ac = rs.VectorCreate(c, a) ab = rs.VectorCreate(b, a) originVector = rs.VectorCreate(a, (0, 0, 0)) # Generate random numbers between 0,1. Random scatter onto triangle for i in range(pointShare): r1 = random.random() r2 = random.random() if r1 + r2 < 1: p = r1 * ac + r2 * ab else: p = (1 - r1) * ac + (1 - r2) * ab points = rs.AddPoint(p) pointList.append(points) rs.MoveObjects(points, originVector) ################################################################################ # MOVE BLOCKS TO POINTS WITH ROTATION / SCALE # ################################################################################ # shuffle point list then split list by the number of blocks to scatter. Copy blocks to split lists random.shuffle(pointList) ptDivision = int(len(pointList) / len(blocks)) genList = chunks(pointList, ptDivision) blockIndex = 0 for pts in genList: # looping through split point list and blocks and copying blocks to scatter blockPt = rs.BlockInstanceInsertPoint(blocks[blockIndex]) for pt in pts: vector = rs.VectorCreate(pt, blockPt) newBlock = rs.CopyObject(blocks[blockIndex], vector) # create list of blocks for later modification blockList.append(newBlock) if blockIndex < (len(blocks) - 1): blockIndex += 1 # apply random scaling and rotation to blocks if userRotation[0] == True: for block in blockList: centerPt = rs.BlockInstanceInsertPoint(block) angle = random.randint(0, 360) rs.RotateObject(block, centerPt, angle, worldZVector) for block in blockList: centerPt = rs.BlockInstanceInsertPoint(block) scale = random.uniform((userScale/4), userScale) rs.ScaleObject(block, centerPt, (scale, scale, scale)) # If a mesh was created, delete it, general cleanup if isMesh == False: rs.DeleteObject(mesh) rs.DeleteObjects(pointList) rs.EnableRedraw(True) except: print("Failed to execute") rs.EnableRedraw(True) return