def createPoint3d(rgFace, fMinDistFromBorder=None, bDebug=False): """ Parameters: rgFace: BrepFace fMinDistFromBorder: float Returns: Point3d on success, None on failure """ if fMinDistFromBorder is None: fMinDistFromBorder = 10.0 * sc.doc.ModelAbsoluteTolerance rgBrep = rgFace.Brep iDomainU = rgFace.Domain(0) iDomainV = rgFace.Domain(1) areaMassProp = Rhino.Geometry.AreaMassProperties.Compute(rgFace) if areaMassProp is None: print "Face[{}]'s AreaMassProperties cannot be calculated.".format( rgFace.FaceIndex) u = iDomainU.Mid v = iDomainV.Mid else: ptCentrdW = areaMassProp.Centroid bSuccess, u, v = rgFace.ClosestPoint(ptCentrdW) rgEdges = [rgBrep.Edges[idxEdge] for idxEdge in rgFace.AdjacentEdges()] rand = Random() for i in xrange(10000): pointFaceRelation = rgFace.IsPointOnFace(u, v) if bDebug: sEval = "pointFaceRelation" print sEval + ':', eval(sEval) if pointFaceRelation == rg.PointFaceRelation.Interior: pt = rgFace.PointAt(u, v) # If point is not at least fMinDistFromBorder from border (all edges), # continue searching. for rgEdge in rgEdges: b, t = rgEdge.ClosestPoint(pt) if b: dist = pt.DistanceTo(rgEdge.PointAt(t)) if dist < fMinDistFromBorder: break # to get another u and v. else: # Good point map(lambda x: x.Dispose(), rgEdges) rgFace.Dispose() return pt # Get new parameters for point. u = rand.NextDouble() * iDomainU.Length + iDomainU.Min v = rand.NextDouble() * iDomainV.Length + iDomainV.Min
def createPoint3dOnInterior(rgFace, fMinDistFromBorder=None, bDebug=False): """ Parameters: rgFace: BrepFace fMinDistFromBorder: float or (None to loop through various) Returns: Point3d on success, None on failure """ fMinDistFromBorder_In = fMinDistFromBorder rgB_1F = rgFace.DuplicateFace(duplicateMeshes=False) rgB_1F.Faces.ShrinkFaces() rgB_1F.Compact() # Is this cecessary to remove duplicate surfaces? rgSrf_Shrunk = rgB_1F.Surfaces[0] domU_Shrunk = rgSrf_Shrunk.Domain(0) domV_Shrunk = rgSrf_Shrunk.Domain(1) #areaMassProp = rg.AreaMassProperties.Compute(rgFace.DuplicateFace(True)) # Otherwise, Compute uses underlying Surface for BrepFace. #if areaMassProp is None: # print "Face[{}]'s AreaMassProperties cannot be calculated.".format( # rgFace.FaceIndex) # u = domU_Shrunk.Mid # v = domV_Shrunk.Mid #else: # ptCentrdW = areaMassProp.Centroid # bSuccess, u, v = rgFace.ClosestPoint(ptCentrdW) u_Shrunk = domU_Shrunk.Mid v_Shrunk = domV_Shrunk.Mid # To3dCurve will include curves of seams. This is advantageous in this circumstance. rgCrvs_fromLoops = [loop.To3dCurve() for loop in rgFace.Loops] rand = Random() if fMinDistFromBorder_In is None: rangeTol = (10.0 * sc.doc.ModelAbsoluteTolerance, sc.doc.ModelAbsoluteTolerance, 0.5 * sc.doc.ModelAbsoluteTolerance) else: rangeTol = fMinDistFromBorder_In, for fMinDistFromBorder in rangeTol: for i in xrange(1000): pt = rgSrf_Shrunk.PointAt(u_Shrunk, v_Shrunk) b, u, v = rgFace.ClosestPoint(pt) if not b: raise ValueError("ClosestPoint failed in createPointOnFace.") ptFaceRel = rgFace.IsPointOnFace(u, v) #sc.doc.Objects.AddPoint(pt); sc.doc.Views.Redraw() if bDebug: sEval = "ptFaceRel" print sEval + ':', eval(sEval) if ptFaceRel == rg.PointFaceRelation.Interior: # If point is not at least fMinDistFromBorder from border (all edges), # continue searching. for c in rgCrvs_fromLoops: b, t = c.ClosestPoint(pt) if not b: raise ValueError( "ClosestPoint failed in createPointOnFace.") dist = pt.DistanceTo(c.PointAt(t)) if dist < fMinDistFromBorder: break # to get another u and v. else: # Good point for c in rgCrvs_fromLoops: c.Dispose() rgB_1F.Dispose() if bDebug: sEval = "i" print sEval + ':', eval(sEval) return pt # Get new parameters for point. u_Shrunk = rand.NextDouble() * domU_Shrunk.Length + domU_Shrunk.Min v_Shrunk = rand.NextDouble() * domV_Shrunk.Length + domV_Shrunk.Min # sc.doc.Objects.AddBrep(rgFace.DuplicateFace(duplicateMeshes=True)) # sc.doc.Views.Redraw() raise ValueError("Failed to find an interior point on face[{}].".format( rgFace.FaceIndex))