def mergeSolids(list_of_solids_compsolids, flag_single=False, split_connections=[], bool_compsolid=False): """mergeSolids(list_of_solids, flag_single = False): merges touching solids that share faces. If flag_single is True, it is assumed that all solids touch, and output is a single solid. If flag_single is False, the output is a compound containing all resulting solids. Note. CompSolids are treated as lists of solids - i.e., merged into solids.""" solids = [] for sh in list_of_solids_compsolids: solids.extend(sh.Solids) if flag_single: cs = Part.CompSolid(solids) return cs if bool_compsolid else Part.makeSolid(cs) else: if len(solids) == 0: return Part.Compound([]) groups = splitIntoGroupsBySharing(solids, lambda sh: sh.Faces, split_connections) if bool_compsolid: merged_solids = [Part.CompSolid(group) for group in groups] else: merged_solids = [ Part.makeSolid(Part.CompSolid(group)) for group in groups ] return Part.makeCompound(merged_solids)
def computeShape(self, solid): """ Create faces shape. This method also calls to generate boxes. @param solid Solid shape that represent the tank. @return Computed solid shape. None if can't build it. """ # Study input to try to build a solid if solid.isDerivedFrom('Part::Feature'): # Get shape shape = solid.Shape if not shape: return None solid = shape if not solid.isDerivedFrom('Part::TopoShape'): return None # Get shells shells = solid.Shells if not shells: return None # Build solids solids = [] for s in shells: solid = Part.Solid(s) if solid.Volume < 0.0: solid.reverse() solids.append(solid) # Create compound shape = Part.CompSolid(solids) return shape
def initValues(self): """ Get selected geometry. @return False if sucessfully find valid geometry. """ self.solid = None solids = [] selObjs = Gui.Selection.getSelection() if not selObjs: msg = Translator.translate( "Tank objects can only be created on top of structure geometry (no object selected).\n" ) App.Console.PrintError(msg) msg = Translator.translate( "Please create a tank geometry before using this tool.\n") App.Console.PrintError(msg) return True for i in range(0, len(selObjs)): solid = selObjs[i] if solid.isDerivedFrom('Part::Feature'): # Get shape shape = solid.Shape if not shape: continue solid = shape if not solid.isDerivedFrom('Part::TopoShape'): return None # Get shells shells = solid.Shells if not shells: continue # Build solids for s in shells: solids.append(Part.Solid(s)) if not solids: msg = Translator.translate( "Ship objects can only be created on top of structure geometry (no solids can't be computed).\n" ) App.Console.PrintError(msg) msg = Translator.translate( "Please create or download a tank geometry before using this tool\n" ) App.Console.PrintError(msg) return True self.solid = Part.CompSolid(solids) msg = Translator.translate("Ready to work\n") App.Console.PrintMessage(msg) return False
def initValues(self): """ Get selected geometry. @return False if sucessfully find valid geometry. """ self.solid = None solids = [] selObjs = Gui.Selection.getSelection() if not selObjs: msg = QtGui.QApplication.translate("ship_console", "Tank objects can only be created on top of structure geometry (no object selected)", None,QtGui.QApplication.UnicodeUTF8) App.Console.PrintError(msg + '\n') msg = QtGui.QApplication.translate("ship_console", "Please create a tank geometry before using this tool", None,QtGui.QApplication.UnicodeUTF8) App.Console.PrintError(msg + '\n') return True for i in range(0, len(selObjs)): solid = selObjs[i] if solid.isDerivedFrom('Part::Feature'): # Get shape shape = solid.Shape if not shape: continue solid = shape if not solid.isDerivedFrom('Part::TopoShape'): return None # Get shells shells = solid.Shells if not shells: continue # Build solids for s in shells: solids.append(Part.Solid(s)) if not solids: msg = QtGui.QApplication.translate("ship_console", "Tank objects can only be created on top of structure geometry (no solids can't be computed)", None,QtGui.QApplication.UnicodeUTF8) App.Console.PrintError(msg + '\n') msg = QtGui.QApplication.translate("ship_console", "Please create a tank geometry before using this tool", None,QtGui.QApplication.UnicodeUTF8) App.Console.PrintError(msg + '\n') return True self.solid = Part.CompSolid(solids) return False
def upgradeToAggregateIfNeeded(list_of_shapes, types=None): """upgradeToAggregateIfNeeded(list_of_shapes, types = None): upgrades non-aggregate type shapes to aggregate-type shapes if the list has a mix of aggregate and non-aggregate type shapes. Returns the new list. Recursively traverses into compounds. aggregate shape types are Wire, Shell, CompSolid non-aggregate shape types are Vertex, Edge, Face, Solid Compounds are something special: they are recursively traversed to upgrade the contained shapes. Examples: list_of_shapes contains only faces -> nothing happens list_of_shapes contains faces and shells -> faces are converted to shells 'types' argument is needed for recursive traversal. Do not supply.""" import Part if types is None: types = set() for shape in list_of_shapes: types.add(shape.ShapeType) subshapes = compoundLeaves(shape) for subshape in subshapes: types.add(subshape.ShapeType) if "Wire" in types: list_of_shapes = [ (Part.Wire([shape]) if shape.ShapeType == "Edge" else shape) for shape in list_of_shapes ] if "Shell" in types: list_of_shapes = [ (Part.Shell([shape]) if shape.ShapeType == "Face" else shape) for shape in list_of_shapes ] if "CompSolid" in types: list_of_shapes = [ (Part.CompSolid([shape]) if shape.ShapeType == "Solid" else shape) for shape in list_of_shapes ] if "Compound" in types: list_of_shapes = [(Part.Compound( upgradeToAggregateIfNeeded(shape.childShapes(), types)) if shape.ShapeType == "Compound" else shape) for shape in list_of_shapes] return list_of_shapes
def parse_shape(shape, selected_subelements, vector): """ Parse the given shape and rebuild it according to its original topological structure """ print('Parsing ' + shape.ShapeType + '\n') if shape.ShapeType in ("Compound", "CompSolid", "Solid", "Shell", "Wire"): # No geometry involved new_sub_shapes, touched_subshapes = parse_sub_shapes( shape, selected_subelements, vector) if shape.ShapeType == "Compound": new_shape = Part.Compound(new_sub_shapes) elif shape.ShapeType == "CompSolid": new_shape = Part.CompSolid(new_sub_shapes) elif shape.ShapeType == "Solid": if isinstance(new_sub_shapes, list) and len(new_sub_shapes) == 1: # check if shell object is given inside a list new_sub_shapes = new_sub_shapes[0] new_shape = Part.Solid(new_sub_shapes) elif shape.ShapeType == "Shell": new_shape = Part.Shell(new_sub_shapes) elif shape.ShapeType == "Wire": new_sub_shapes = Part.__sortEdges__(new_sub_shapes) new_shape = Part.Wire(new_sub_shapes) print(shape.ShapeType + " re-created.") touched = True elif shape.ShapeType == "Face": new_sub_shapes, touched_subshapes = parse_sub_shapes( shape, selected_subelements, vector) if touched_subshapes == 1 or touched_subshapes == 2: print("some subshapes touched " + shape.ShapeType + " recreated.") if shape.Surface.TypeId == 'Part::GeomPlane': new_sub_shapes = sort_wires(new_sub_shapes) new_shape = Part.Face(new_sub_shapes) touched = True # TODO: handle the usecase when the Face is not planar anymore after modification else: print("Face geometry not supported") elif touched_subshapes == 0: print("subshapes not touched " + shape.ShapeType + " not touched.") new_shape = shape touched = False elif shape.ShapeType == "Edge": # TODO: Add geometry check new_sub_shapes, touched_subshapes = parse_sub_shapes( shape, selected_subelements, vector) if touched_subshapes == 2: print("all subshapes touched. " + shape.ShapeType + " translated.") # all subshapes touched new_shape = shape.translate(vector) touched = True elif touched_subshapes == 1: # some subshapes touched: recreate the edge as a straight vector: TODO Add geometry check print("some subshapes touched " + shape.ShapeType + " recreated.") new_shape = Part.makeLine(new_sub_shapes[0].Point, new_sub_shapes[1].Point) touched = True elif touched_subshapes == 0: # subshapes not touched print("subshapes not touched " + shape.ShapeType + " not touched.") new_shape = shape touched = False elif shape.ShapeType == "Vertex": # TODO: Add geometry check touched = False for s in selected_subelements: if shape.isSame(s): touched = True if touched: print(shape.ShapeType + " translated.") new_shape = shape.translate(vector) else: print(shape.ShapeType + " not touched.") new_shape = shape return new_shape, touched