def addBrepOfSubsetOfFaces_RemoveAt(): rgBrep1 = rgBrep_In.Duplicate() # Create list of non-extracted faces. # This is faster than looping through all faces while testing each. idx_rgFaces_ToRemove = list( set(range(rgBrep1.Faces.Count)) - set(idxFaces)) idx_rgFaces_ToRemove.sort(reverse=True) stopwatch = Stopwatch() stopwatch.Start() [rgBrep1.Faces.RemoveAt(idx) for idx in idx_rgFaces_ToRemove] stopwatch.Stop() if bDebug: print "{} seconds for Faces.RemoveAt".format(stopwatch.Elapsed.TotalSeconds) # Separate any brep shells of modified brep and act based on shell quantity. stopwatch.Restart() rgBreps_per_shell = rg.Brep.CreateBooleanUnion( [rgBrep1], tolerance=0.0, manifoldOnly=False) stopwatch.Stop() if bDebug: print "{} seconds for CreateBooleanUnion".format( stopwatch.Elapsed.TotalSeconds) if rgBreps_per_shell is None: if bDebug: print "Error in attempting to separate brep shells. No objects have been modified." return rgBrep1.Dispose() attr = rdBrep_In.Attributes.Duplicate() if not bRetainLayer: attr.LayerIndex = sc.doc.Layers.CurrentLayerIndex if not bRetainColor: attr.ColorSource = rd.ObjectColorSource.ColorFromLayer stopwatch.Restart() gBreps_1Shell = map(lambda x: sc.doc.Objects.AddBrep(x, attr), rgBreps_per_shell) stopwatch.Stop() if bDebug: print "{:.1f} seconds for AddBrep".format(stopwatch.Elapsed.TotalSeconds) map(lambda x: x.Dispose(), rgBreps_per_shell) return gBreps_1Shell
def addFromSubsetOfFaces(rhBrep, idxFaces, bAddOnlyMonofaces=True, bRetainLayer=True, bRetainColor=True, bDebug=False): """ """ rdBrep_In = coerceBrepObject(rhBrep) if rdBrep_In is None: return rgBrep_In = rdBrep_In.BrepGeometry if not rgBrep_In.IsValid: return def addBrepOfSubsetOfFaces_JoinBreps(): # Duplicate faces to their own breps to be joined. rgBreps1 = [] # Faces (breps) to be duplicated. for i in idxFaces: rgFace = rgBrep_In.Faces[i] rgBrep_1Face = rgFace.DuplicateFace(True) if rgBrep_1Face is None: if bDebug: print "Face {} could not be duplicated as a brep!".format(i) return None rgBreps1.append(rgBrep_1Face) # Join monoface breps. # Using a tight tolerance to rejoin only existing shared edges. fTol_Join = 1e-9 rgBreps_Joined = rg.Brep.JoinBreps(rgBreps1, tolerance=fTol_Join) if rgBreps_Joined is None: if bDebug: print "Joining breps failed!" return for rgB in rgBreps_Joined: if not rgB.IsValid: if bDebug: print "Joined brep not valid. Exiting..." return if any(b.Faces.Count > 1 for b in rgBreps_Joined): # Separate any brep shells of modified brep and act based on shell quantity. rgBreps_per_shell = rg.Brep.CreateBooleanUnion( rgBreps_Joined, tolerance=0.0, manifoldOnly=False) if rgBreps_per_shell is None: if bDebug: print "Error in attempting to separate brep shells. No objects have been modified." return else: # Skipped attempting to Boolean union monoface breps in case any contact are in contact with one another. rgBreps_per_shell = rgBreps_Joined[:] attr = rdBrep_In.Attributes.Duplicate() if not bRetainLayer: attr.LayerIndex = sc.doc.Layers.CurrentLayerIndex if not bRetainColor: attr.ColorSource = rd.ObjectColorSource.ColorFromLayer gBreps_1Shell = map(lambda x: sc.doc.Objects.AddBrep(x, attr), rgBreps_per_shell) map(lambda x: x.Dispose(), rgBreps_per_shell) return gBreps_1Shell def addBrepOfSubsetOfFaces_RemoveAt(): rgBrep1 = rgBrep_In.Duplicate() # Create list of non-extracted faces. # This is faster than looping through all faces while testing each. idx_rgFaces_ToRemove = list( set(range(rgBrep1.Faces.Count)) - set(idxFaces)) idx_rgFaces_ToRemove.sort(reverse=True) stopwatch = Stopwatch() stopwatch.Start() [rgBrep1.Faces.RemoveAt(idx) for idx in idx_rgFaces_ToRemove] stopwatch.Stop() if bDebug: print "{} seconds for Faces.RemoveAt".format(stopwatch.Elapsed.TotalSeconds) # Separate any brep shells of modified brep and act based on shell quantity. stopwatch.Restart() rgBreps_per_shell = rg.Brep.CreateBooleanUnion( [rgBrep1], tolerance=0.0, manifoldOnly=False) stopwatch.Stop() if bDebug: print "{} seconds for CreateBooleanUnion".format( stopwatch.Elapsed.TotalSeconds) if rgBreps_per_shell is None: if bDebug: print "Error in attempting to separate brep shells. No objects have been modified." return rgBrep1.Dispose() attr = rdBrep_In.Attributes.Duplicate() if not bRetainLayer: attr.LayerIndex = sc.doc.Layers.CurrentLayerIndex if not bRetainColor: attr.ColorSource = rd.ObjectColorSource.ColorFromLayer stopwatch.Restart() gBreps_1Shell = map(lambda x: sc.doc.Objects.AddBrep(x, attr), rgBreps_per_shell) stopwatch.Stop() if bDebug: print "{:.1f} seconds for AddBrep".format(stopwatch.Elapsed.TotalSeconds) map(lambda x: x.Dispose(), rgBreps_per_shell) return gBreps_1Shell nFaces = rgBrep_In.Faces.Count # If brep has only 1 face, return the brep's GUID. if nFaces == 1: return [rdBrep_In.Id] idxFaces = list(set(idxFaces)) if not bAddOnlyMonofaces: stopwatch = Stopwatch() # Create brep(s) of extracted faces using method chosen by whether number of # extracted faces is less or more than the remaining number of faces. if len(idxFaces) < nFaces // 2 : stopwatch.Restart() gBreps1_Extracted = addBrepOfSubsetOfFaces_JoinBreps() stopwatch.Stop() if bDebug: print "{} seconds for addBrepOfSubsetOfFaces_JoinBreps".format( stopwatch.Elapsed.TotalSeconds) if gBreps1_Extracted is not None: return gBreps1_Extracted if bDebug: print "addBrepOfSubsetOfFaces_JoinBreps returned None." # Since addBrepOfSubsetOfFaces_JoinBreps failed, will try RemoveAt instead. # Either the number of faces to add > half the total number of faces in the brep or addBrepOfSubsetOfFaces_JoinBreps had returned None. stopwatch.Restart() gBreps1_Extracted = addBrepOfSubsetOfFaces_RemoveAt() stopwatch.Stop() if bDebug: print "{} seconds for addBrepOfSubsetOfFaces_RemoveAt".format( stopwatch.Elapsed.TotalSeconds) if gBreps1_Extracted is not None: return gBreps1_Extracted if bDebug: print "addBrepOfSubsetOfFaces_RemoveAt returned None." # Add only monoface breps. attr = rdBrep_In.Attributes.Duplicate() if not bRetainLayer: attr.LayerIndex = sc.doc.Layers.CurrentLayerIndex if not bRetainColor: attr.ColorSource = rd.ObjectColorSource.ColorFromLayer gBreps1_Extracted = [] for idx in idxFaces: rgFace = rgBrep_In.Faces[idx] # Duplicate face to its own brep. rgBrep1 = rgFace.DuplicateFace(duplicateMeshes=True) if not rgBrep1.IsValid: gBrep1 = None else: gBrep1 = sc.doc.Objects.AddBrep(rgBrep1, attr) if gBrep1 is None: s = "Brep face {} from {} could not be added to document.".format( idx, rdBrep_In.Id) print s rc = rs.MessageBox( s + "\nContinue extracting faces, skipping this one?", buttons=4, title="xBrepObject.addFromSubsetOfFaces") if rc is not None and rc == 6: continue #if not bDebug: rs.DeleteObjects(gBreps1_Extracted) return gBreps1_Extracted.append(gBrep1) rgBrep1.Dispose() return gBreps1_Extracted