def finalSurfStuff(cullPts, delaunayHeight, offsetFactor, shadeSurface): worldPlane = rc.Geometry.Plane.WorldXY if shadeSurface == None: # In case no shading surface was provided #$print 'None' planeFromPoints = rc.Geometry.Plane.FitPlaneToPoints(cullPts) else: # In case shading surface was provided #$print 'WITH' points_surface = ghc.SurfacePoints(shadeSurface).points planeFromPoints = rc.Geometry.Plane.FitPlaneToPoints( points_surface) ## #planeFromPoints = rc.Geometry.Plane.FitPlaneToPoints(points_surface)[1]## if planeFromPoints: wp = worldPlane.Normal if shadeSurface == None: # In case no shading surface was provided myPlane = planeFromPoints[1] # extract plane from FitPlaneToPoints else: # In case shading surface was provided myPlane = planeFromPoints[ 1] # extract plane from FitPlaneToPoints###########################################???????????????????????? ##myPlane = planeFromPoints # extract plane from FitPlaneToPoints #print type(myPlane), planeFromPoints pfp = rc.Geometry.Plane.Normal.GetValue(myPlane) vectorAngle = rc.Geometry.Vector3d.VectorAngle(pfp, wp) tolAngle = 70 # Tolerance angle. Right now I set it to 70 but this should be followed up if ((vectorAngle >= tolAngle) and (vectorAngle <= 90)) or (vectorAngle >= tolAngle and (vectorAngle < (90 + (90 - tolAngle)))): flag = 0 #0 is for VERTICAL shading surface elif (vectorAngle < tolAngle) or (vectorAngle > (90 + (90 - tolAngle))): flag = 1 #1 is for NON VERTICAL shading surface if flag == 0: worldZXPlane = rc.Geometry.Plane.WorldZX worldYZPlane = rc.Geometry.Plane.WorldYZ wp_ZX = worldZXPlane.Normal * -(1) wp_YZ = worldYZPlane.Normal * -(1) vectorAngle_ZX = rc.Geometry.Vector3d.VectorAngle(pfp, wp_ZX) vectorAngle_YZ = rc.Geometry.Vector3d.VectorAngle(pfp, wp_YZ) if vectorAngle_ZX <= 45 or vectorAngle_ZX >= 135 and worldYZPlane <= 225: basePlane = worldZXPlane convexHullPlane = cutPlane = rc.Geometry.Plane.WorldZX convexHullPlane = rc.Geometry.Plane.Translate( convexHullPlane, worldZXPlane.Normal * -delaunayHeight) convex_Trim_Plane = convexHullPlane cutPlane = rc.Geometry.Plane.Translate( cutPlane, worldZXPlane.Normal * -(delaunayHeight - .01)) directionPlane = cutPlane else: basePlane = worldYZPlane G, X = ghc.MoveToPlane(cullPts, convexHullPlane, True, True) delaunayPoints1 = G flatPts = [rc.Geometry.Point3d(p) for p in delaunayPoints1] elif flag == 1: convex_Trim_Plane = rc.Geometry.Plane.WorldXY # Connect to ConvexHull and MeshPlaneSec convexHullPlane = convex_Trim_Plane p1 = rc.Geometry.Point3d(0, 0, delaunayHeight - 0.01) v1 = rc.Geometry.Vector3d(1, 0, 0) v2 = rc.Geometry.Vector3d(0, 1, 0) directionPlane = rc.Geometry.Plane( p1, v1, v2) # Connect to Direction input of Project direction = rc.Geometry.Vector3d.Add(rc.Geometry.Vector3d( 0, 0, 0), rc.Geometry.Vector3d( 0, 0, delaunayHeight)) # Connect to Direction input of Project #Using RS the direction is 0,0,5. Using RC direction is 0,0,-5. Be aware of this, maybe we need to multiply by (-1) flatPts = [rc.Geometry.Point3d(p) for p in cullPts] for i in range( len(cullPts) ): # Flat Z axis point to some height for the DelaunayMesh action flatPts[i][2] = delaunayHeight trimPlanePoint = rc.Geometry.Point3d(0, 0, delaunayHeight - 0.01) ################### spans = 20 flexibility = 1 points_CULL = [rc.Geometry.Point(pt) for pt in cullPts] patch = ghc.Patch(None, cullPts, spans, flexibility, True) if flag == 0: H, Hz, I = ghc.ConvexHull( cullPts, rc.Geometry.Plane.WorldZX ) # CHECK THIS LATER FOR OTHER CASES or UNIFY WITH FLAG 1 elif flag == 1: H, Hz, I = ghc.ConvexHull(cullPts, convexHullPlane) points_PV = [] count = H.PointCount for i in range(count): points_PV.append(H.Point(i)) H_alt = rc.Geometry.PolylineCurve(points_PV) areaH = rc.Geometry.AreaMassProperties.Compute(H).Area centH_alt = rc.Geometry.AreaMassProperties.Compute(H).Centroid scaleH = rc.Geometry.Transform.Scale(centH_alt, offsetFactor) dupH_alt = rc.Geometry.PolylineCurve.Duplicate(H_alt) dupH_alt.Transform(scaleH) offsetCrv = [dupH_alt] areaHalt = rc.Geometry.AreaMassProperties.Compute(H_alt).Area areaoffsetCrv = rc.Geometry.AreaMassProperties.Compute(offsetCrv[0]).Area if (areaHalt > areaoffsetCrv): print "Case BAD offset" scaleH = rc.Geometry.Transform.Scale(centH_alt, offsetFactor * (-1)) dupH_alt = rc.Geometry.PolylineCurve.Duplicate(H_alt) dupH_alt.Transform(scaleH) offsetCrv = [dupH_alt] delaunayPoints = [] for i in range( len(cullPts) ): # Flat Z axis point to some height for the DelaunayMesh action delaunayPoints.append(flatPts[i]) res = 40 divCrv = offsetCrv[0].DivideByCount(res, True) for p in divCrv: delaunayPoints.append(offsetCrv[0].PointAt(p)) delaunayMesh = ghc.DelaunayMesh(delaunayPoints, convex_Trim_Plane) M = delaunayMesh trimCurve = ghc.MeshXPlane(delaunayMesh, directionPlane) projectedCrv = ghc.Project(trimCurve, patch, directionPlane) splitSrf = ghc.SurfaceSplit(patch, projectedCrv) H1, Hz1, I1 = ghc.ConvexHull(cullPts, myPlane) #planeFromPoints cen = rc.Geometry.AreaMassProperties.Compute(H1).Centroid centerH = rc.Geometry.Point3d(cen) #print centerH distances = [] for srf in splitSrf: cent = rc.Geometry.AreaMassProperties.Compute(srf).Centroid distance = centerH.DistanceTo(cent) distances.append(distance) #print ' Min distance for split surface ', min(distances), distances finalSrf = splitSrf[distances.index(min(distances))] """ # Below the original way to solve the issue ## if shadeSurface: H1, Hz1, I1 = ghc.ConvexHull(cullPts, planeFromPoints) cen = rc.Geometry.AreaMassProperties.Compute(H1).Centroid centerH = rc.Geometry.Point3d(cen) #print centerH uv = rc.Geometry.Surface.ClosestPoint(shadeSurface, centerH) point = rc.Geometry.Surface.Evaluate(shadeSurface, uv[0], uv[1], 10) s0 = splitSrf[0] s1 = splitSrf[1] swapFinalSrf = False if swapFinalSrf ==False: finalSrf = splitSrf[1] else: finalSrf = splitSrf[0] """ return finalSrf
import ghpythonlib.components as ghComp import rhinoscriptsyntax as rs # mesh and faces mesh = ghComp.DelaunayMesh(pts) vertices, faces, colours, normals = ghComp.DeconstructMesh(mesh) # max distance of edges of all faces maxDists = [] for face in faces: dist1 = rs.Distance(pts[face.A], pts[face.B]) dist2 = rs.Distance(pts[face.B], pts[face.C]) dist3 = rs.Distance(pts[face.C], pts[face.A]) maxDist = max(dist1, dist2, dist3) maxDists.append(maxDist) # median sortedDists = sorted(maxDists) medIndex = int(len(sortedDists) / 2) median = sortedDists[medIndex] # keep faces with edges within treshold distTreshold = median * (1.0 + factor) newMesh = [] i = 0 for face in faces: if (maxDists[i] < distTreshold): newMesh.append(face) i += 1 # create final meshes and outlines
import ghpythonlib.components as ghComp import ghpythonlib.parallel as par import rhinoscriptsyntax as rs # DelaunayMesh and get vertices and faces mesh = ghComp.DelaunayMesh(points, rs.WorldXYPlane()) vertices, faces, _, _ = ghComp.DeconstructMesh(mesh) # uses faces if max distance of edges are shorter than or equal to the given threshold(cell size ^2 + 2*cell size^2) newMesh = [] def face_distance(face): dist1 = rs.Distance(points[face.A], points[face.B]) dist2 = rs.Distance(points[face.B], points[face.C]) dist3 = rs.Distance(points[face.C], points[face.A]) maxDist = max(dist1, dist2, dist3) if (maxDist <= threshold): newMesh.append(face) par.run(face_distance, faces) # create final meshes and use naked edges for boundary finalMesh = ghComp.ConstructMesh(vertices, newMesh) nakedEdges = finalMesh.GetNakedEdges()