def slicer(event=None): # Param Zmin, Zmax, deltaZ = -100, 100, 5 # Note: the shape can also come from a shape selected from InteractiveViewer if 'display' in dir(): shape = display.GetSelectedShape() else: # Create the shape to slice shape = BRepPrimAPI_MakeSphere(60.).Shape() # Define the direction D = gp_Dir(0., 0., 1.) # the z direction # Perform slice sections = [] init_time = time.time() # for total time computation for z in range(Zmin, Zmax, deltaZ): # Create Plane defined by a point and the perpendicular direction P = gp_Pnt(0, 0, z) Pln = gp_Pln(P, D) face = BRepBuilderAPI_MakeFace(Pln).Shape() # Computes Shape/Plane intersection section_shp = BRepAlgoAPI_Section(shape, face) if section_shp.IsDone(): sections.append(section_shp) total_time = time.time() - init_time print("%.3fs necessary to perform slice." % total_time) display.EraseAll() display.DisplayShape(shape) for section_ in sections: display.DisplayShape(section_.Shape()) display.FitAll()
def split2(base, cutters): # https://www.opencascade.com/doc/occt-7.0.0/overview/html/ # occt_user_guides__boolean_operations.html#occt_algorithms_10a builder = BRepAlgoAPI_Section() tools = TopTools_ListOfShape() for cutter in cutters: tools.Append(cutter) builder.ComputePCurveOn1()
def vectorized_slicer(li): # Create Plane defined by a point and the perpendicular direction z_values, shape = li _slices = [] for z in z_values: #print 'slicing index:', z, 'sliced by process:', os.getpid() plane = gp_Pln(gp_Pnt(0., 0., z), gp_Dir(0., 0., 1.)) face = BRepBuilderAPI_MakeFace(plane).Shape() # Computes Shape/Plane intersection section = BRepAlgoAPI_Section(shape, face) section.Build() if section.IsDone(): _slices.append(section.Shape()) return _slices
def intersection(shp1: TopoDS_Shape, shp2: Union[TopoDS_Shape, gp.GP3d]) -> TopoDS_Shape: """ Most Robust TopoDS intersection BRepAlgoAPI_Common will only return if the intersection is solid. BRepAlgoAPI_Section will work for face-on-face similar issue with GeomAPI is documented here: https://www.opencascade.com/content/use-brepalgosection-instead-brepalgoapisection :param: shp1 - TopoDS_Shape1 :param: shp2 - TopoDS_Shape2 BRepAlgoAPI_Section(TopoDS_Shape const &,TopoDS_Shape const &,BOPAlgo_PaveFiller const &,Standard_Boolean const) BRepAlgoAPI_Section(TopoDS_Shape const &,TopoDS_Shape const &,Standard_Boolean const) BRepAlgoAPI_Section(TopoDS_Shape const &,gp_Pln const &,Standard_Boolean const) BRepAlgoAPI_Section(TopoDS_Shape const &,Handle_Geom_Surface const &,Standard_Boolean const) BRepAlgoAPI_Section(Handle_Geom_Surface const &,TopoDS_Shape const &,Standard_Boolean const) BRepAlgoAPI_Section(Handle_Geom_Surface const &,Handle_Geom_Surface const &,Standard_Boolean const) returns wires representing the intersection """ intrs = BRepAlgoAPI_Section(shp1, shp2) if intrs.BuilderCanWork() is True: intrs.Build() # todo add isDone check (maybe ??) # intrs.FuseEdges() intrs.RefineEdges() shp = intrs.Shape() intrs.Destroy() return shp
def section(event=None): torus = BRepPrimAPI_MakeTorus(120, 20).Shape() radius = 120.0 sections = [] for i in range(-3, 4): # Create Sphere sphere = BRepPrimAPI_MakeSphere(gp_Pnt(26 * 3 * i, 0, 0), radius).Shape() # Computes Torus/Sphere section section_shp = BRepAlgoAPI_Section(torus, sphere, False) section_shp.ComputePCurveOn1(True) section_shp.Approximation(True) section_shp.Build() sections.append(section_shp) display.EraseAll() display.DisplayShape(torus) for section_ in sections: display.DisplayShape(section_.Shape()) display.FitAll()
def __call__(self, plane: gp.gp_Pln, vertex=None, edge_dict=None, **kwargs): splt = BRepFeat_SplitShape() if isinstance(self._base, TopoDS_Shape): base_shape = self._base else: base_shape = self._base.Shape() splt.Init(base_shape) sect = BRepAlgoAPI_Section(base_shape, plane, False) sect.ComputePCurveOn1(True) sect.Approximation(True) sect.Build() self.cutting_edge = sect.Shape() ancestors = set() new_faces = [] edge_iter = TopExp_Explorer(self.cutting_edge, TopAbs_EDGE) while edge_iter.More(): base_iter = TopExp_Explorer(base_shape, TopAbs_FACE) curr_edge = edge_iter.Current() while base_iter.More(): curr_face = base_iter.Current() if sect.HasAncestorFaceOn1(curr_edge, curr_face): k, v = hash(curr_face), hash(curr_edge) if (k, v) not in self.ancestors: ancestors.add((k, v)) e = topods.Edge(curr_edge) f = topods.Face(curr_face) splt.Add(e, f) # todo - only add the closest one !!!! new_faces.append(f) self.added.append(e) break # if sect.HasAncestorFaceOn2(curr_edge, curr_face): # print('has2', curr_edge, curr_face) # pass base_iter.Next() edge_iter.Next() # ------------------------------------- splt.Build() new_shape = splt.Shape() sect.Destroy() return new_shape
def intersect_shape_face(shape, face): """Intersects a shape with a given face :param shape: shape :type shape: instance of OCC.TopoDS.TopoDS_Shape :param face: face :type face: instance of OCC.TopoDS.TopoDS_Face :return: section :rtype: instance of OCC.BRepAlgoAPI.BRepAlgoAPI_Section """ section = BRepAlgoAPI_Section(shape, face) return section
def CutSect(Shape, SpanStation): """ Parameters ---------- Shape : TopoDS_Shape The Shape to find planar cut section (parallel to xz plane) SpanStation : scalar in range (0, 1) y-direction location at which to cut Shape Returns ------- Section : result of OCC.BRepAlgoAPI.BRepAlgoAPI_Section (TopoDS_Shape) The cut section of shape given a cut plane parallel to xz at input Spanstation. Chord : result of OCC.GC.GC_MakeSegment.Value (Geom_TrimmedCurve) The Chord line between x direction extremeties """ (Xmin, Ymin, Zmin, Xmax, Ymax, Zmax) = ObjectsExtents([Shape]) YStation = Ymin + (Ymax - Ymin) * SpanStation OriginX = Xmin - 1 OriginZ = Zmin - 1 P = gp_Pln(gp_Pnt(OriginX, YStation, OriginZ), gp_Dir(gp_Vec(0, 1, 0))) # Note: using 2*extents here as previous +1 trimmed plane too short CutPlaneSrf = make_face(P, 0, Zmax + 2, 0, Xmax + 2) I = BRepAlgoAPI_Section(Shape, CutPlaneSrf) I.ComputePCurveOn1(True) I.Approximation(True) I.Build() Section = I.Shape() (Xmin, Ymin, Zmin, Xmax, Ymax, Zmax) = ObjectsExtents([Section]) # Currently assume only one edge exists in the intersection: exp = TopExp_Explorer(Section, TopAbs_EDGE) edge = topods_Edge(exp.Current()) # Find the apparent chord of the section (that is, the line connecting the # fore most and aftmost points on the curve DivPoints = Uniform_Points_on_Curve(edge, 200) Xs = np.array([pt.X() for pt in DivPoints]) min_idx = np.argmin(Xs) LeadingPoint = gp_Pnt(Xs[min_idx], DivPoints[min_idx].Y(), DivPoints[min_idx].Z()) max_idx = np.argmax(Xs) TrailingPoint = gp_Pnt(Xs[max_idx], DivPoints[max_idx].Y(), DivPoints[max_idx].Z()) HChord = GC_MakeSegment(TrailingPoint, LeadingPoint).Value() # Chord = HChord.GetObject() return Section, HChord
def split_solid(base, plane): splt = BRepFeat_SplitShape() splt.Init(base) sect = BRepAlgoAPI_Section(base, plane, False) sect.ComputePCurveOn1(True) sect.Approximation(True) sect.Build() edge = sect.Shape() rdict = set() # print(Topo(edge).number_of_edges()) Ex = TopExp_Explorer(edge, TopAbs_EDGE) while Ex.More(): # print('edge', Ex.Current()) base_iter = TopExp_Explorer(base, TopAbs_FACE) curr = Ex.Current() while base_iter.More(): # print('face', base_iter.Current()) bface = base_iter.Current() if sect.HasAncestorFaceOn1(curr, bface): # print('has1', curr, bface) k, v = hash(bface), hash(curr) if (k, v) not in rdict: rdict.add((k, v)) e = topods.Edge(curr) f = topods.Face(bface) splt.Add(e, f) if sect.HasAncestorFaceOn2(curr, bface): # print('has2', curr, bface) pass base_iter.Next() Ex.Next() splt.Build() return splt.Shape()
def split_shape(event=None): S = BRepPrimAPI_MakeBox(gp_Pnt(-100, -60, -80), 150, 200, 170).Shape() asect = BRepAlgoAPI_Section(S, gp_Pln(1, 2, 1, -15), False) asect.ComputePCurveOn1(True) asect.Approximation(True) asect.Build() R = asect.Shape() asplit = BRepFeat_SplitShape(S) for edg in Topo(R).edges(): face = TopoDS_Face() if asect.HasAncestorFaceOn1(edg, face): asplit.Add(edg, face) asplit.Build() display.EraseAll() display.DisplayShape(asplit.Shape()) display.FitAll()
def splitwire(base, in_edge): sect = BRepAlgoAPI_Section(base, in_edge) sect.Build() sect.RefineEdges() edge = sect.Shape() splt = BRepFeat_SplitShape(base) Ex = TopExp_Explorer(edge, TopAbs_VERTEX) while Ex.More(): # print(Ex.Current()) Sx = TopExp_Explorer(base, TopAbs_EDGE) while Sx.More(): if sect.HasAncestorFaceOn1(Ex.Current(), Sx.Current()): print('add', Ex.Current(), Sx.Current()) splt.Add(Ex.Current(), Sx.Current()) Sx.Next() Ex.Next() splt.Build() return splt.Shape()
# Quick way to specify the Y axis xAxis = gp_OY() # Set up the mirror aTrsf = gp_Trsf() aTrsf.SetMirror(xAxis) # Explore the faces of the shape (these are known to be named) exp = TopExp_Explorer(shape, TopAbs_FACE) while exp.More(): s = exp.Current() tp = Topo(s) for face in tp.faces(): section = BRepAlgoAPI_Section(section_face, face).Shape() # Apply the mirror transformation aBRespTrsf = BRepBuilderAPI_Transform(section, aTrsf) # Get the mirrored shape back out of the transformation and convert back to a wire aMirroredShape = aBRespTrsf.Shape() section_edges = list(Topo(aMirroredShape).edges()) for edge in section_edges: obj = EdgeOnSurface(edge, section_plane, lim_coord1, lim_coord2, XYZ) if type(obj) == Line3D: x1, y1 = obj.get_v1(XYZ) x2, y2 = obj.get_v2(XYZ) plt.plot([x1, x2], [y1, y2], color="red")
BconeSm = BRepPrimAPI_MakeCone(p, BIRSm, BCR, BIHSm).Shape() bushing = BRepAlgoAPI_Fuse(bushing, BconeSm).Shape() BSIN = BOR * math.sin(math.radians(BA)) BCOS = BOR * math.cos(math.radians(BA)) # create and set up transformation for leftBush ltrsf = gp_Trsf() ltrsf.SetRotation(gp_Ax1(gp_Pnt(0, 0, 0), gp_Dir(1, 0, 0)), math.radians(BA)) leftBush = BRepBuilderAPI_Transform(bushing, ltrsf).Shape() ltrsf.SetTranslation(gp_Vec(BIn + BOR, float(TW) / 2 - BS - BCOS, TH - BSIN)) leftBush = BRepBuilderAPI_Transform(leftBush, ltrsf).Shape() leftBush = BRepAlgoAPI_Cut(leftBush, tank).Shape() # cut common part of bushing and tank mooh = BRepAlgoAPI_Section(leftBush, tank).Shape() wire = topods_Wire(mooh) face = BRepBuilderAPI_MakeFace(wire).Face() #leftBush = BRepAlgoAPI_Cut(leftBush,face).Shape() # create and set up transformation for midBush mtrsf = gp_Trsf() mtrsf.SetTranslation(gp_Vec(BIn + BOR, float(TW) / 2, TH)) midBush = BRepBuilderAPI_Transform(bushing, mtrsf).Shape() # create and set up transformation for rightBush rtrsf = gp_Trsf() rtrsf.SetRotation(gp_Ax1(gp_Pnt(0, 0, 0), gp_Dir(1, 0, 0)), math.radians(360 - BA)) rightBush = BRepBuilderAPI_Transform(bushing, rtrsf).Shape() rtrsf.SetTranslation(gp_Vec(BIn + BOR, float(TW) / 2 + BS + BCOS, TH - BSIN))
def __init__(self, shp1, shp2): # self.shp1 = shp1 # self.shp2 = shp2 self.algo = BRepAlgoAPI_Section(shp1, shp2, True) self.algo.ComputePCurveOn1(True) self.algo.ComputePCurveOn2(True)
class Intersector: """ given shape1 and shape2, form the intersection need to be able to return which 'topo' of """ def __init__(self, shp1, shp2): # self.shp1 = shp1 # self.shp2 = shp2 self.algo = BRepAlgoAPI_Section(shp1, shp2, True) self.algo.ComputePCurveOn1(True) self.algo.ComputePCurveOn2(True) # self.algo.Approximation(True) @property def shp1(self): return self.algo.Shape1() @property def shp2(self): return self.algo.Shape2() def Shape(self): return self.algo.Shape() def faces_on(self): self.algo.Build() from OCC.TopTools import TopTools_ListIteratorOfListOfShape seen = set() edge_list = self.algo.Modified(self.shp1) itre = TopTools_ListIteratorOfListOfShape(edge_list) while itre.More(): print(itre.Value()) itre.Next() print('-') edge_list = self.algo.Modified(self.shp2) itre = TopTools_ListIteratorOfListOfShape(edge_list) while itre.More(): print(itre.Value()) itre.Next() # edge_list = self.algo.SectionEdges() # itr = TopTools_ListIteratorOfListOfShape(edge_list) # edge_list = self.algo.SectionEdges() res = self.Shape() itr = TopExp_Explorer(res, TopAbs_EDGE) faces1, faces2 = [], [] while itr.More(): curr_edge = itr.Current() s1_iter = TopExp_Explorer(self.shp1, TopAbs_FACE) s2_iter = TopExp_Explorer(self.shp2, TopAbs_FACE) while s1_iter.More(): curr_face1 = s1_iter.Current() if self.algo.HasAncestorFaceOn1(curr_edge, curr_face1): k, v = hash(curr_face1), hash(curr_edge) if (k, v) not in seen: seen.add((k, v)) faces1.append(curr_face1) s1_iter.Next() while s2_iter.More(): curr_face2 = s2_iter.Current() if self.algo.HasAncestorFaceOn2(curr_edge, curr_face2): k, v = hash(curr_face2), hash(curr_edge) if (k, v) not in seen: seen.add((k, v)) faces2.append(curr_face2) s2_iter.Next() # s2_iter.ReInit() # s1_iter.ReInit() itr.Next() return faces1, faces2 def commonface(self): w = Construct.make_wirex(*Topo(self.Shape()).edges()) f = Construct.make_face(w) return f
def display_ifc(file): # Specify to return pythonOCC shapes from ifcopenshell.geom.create_shape() settings = ifcopenshell.geom.settings() settings.set(settings.USE_PYTHON_OPENCASCADE, True) # Initialize a graphical display window #occ_display = ifcopenshell.geom.utils.initialize_display() # Open the IFC file using IfcOpenShell ifc_file = ifcopenshell.open(file) # The geometric elements in an IFC file are the IfcProduct elements. So these are # opened and displayed. products = ifc_file.by_type("IfcProduct") product_shapes = [] # For every product a shape is created if the shape has a Representation. i = 0 for product in products: if product.is_a("IfcOpeningElement") or product.is_a("IfcSite"): continue if product.Representation is not None: shape = ifcopenshell.geom.create_shape(settings, product).geometry product_shapes.append((product, shape)) i += 1 print(i) # Two list are initialized to calculate the surface area to be printed. surface_areas_per_section = [] surface_areas_per_building = [] # In this part the sections are created. You can enter the starting height, the # maximum height and the height difference between each section. starting_height = 0 maximum_height = 3 height_step = 0.5 section_height = starting_height while section_height <= maximum_height: print("Section height: " + str(section_height)) # A horizontal plane is created from which a face is constructed to intersect with # the building. The face is transparently displayed along with the building. section_plane = OCC.gp.gp_Pln(OCC.gp.gp_Pnt(0, 0, section_height), OCC.gp.gp_Dir(0, 0, 1)) section_face = BRepBuilderAPI_MakeFace(section_plane, -10, 10, -10, 10).Face() #section_face_display = ifcopenshell.geom.utils.display_shape(section_face) #ifcopenshell.geom.utils.set_shape_transparency(section_face_display, 0.5) #for shape in product_shapes: # ifcopenshell.geom.utils.display_shape(shape[1]) # Each product of the building is intersected with the horizontal face for product, shape in product_shapes: section = BRepAlgoAPI_Section(section_face, shape).Shape() # The edges of the intersection are stored in a list section_edges = list(Topo(section).edges()) # If the length of the section_edges list is greater than 0 there is an # intersection between the plane (at current height) and the product. Only in that # case the product needs to be printed. if len(section_edges) > 0: print(" {:<20}: {}".format(product.is_a(), product.Name)) # Open Cascade has a function to turn loose unconnected edges into a list of # connected wires. This function takes handles (pointers) to Open Cascade's native # sequence type. Hence, two sequences and handles, one for the input, one for the # output, are created. edges = OCC.TopTools.TopTools_HSequenceOfShape() edges_handle = OCC.TopTools.Handle_TopTools_HSequenceOfShape(edges) wires = OCC.TopTools.TopTools_HSequenceOfShape() wires_handle = OCC.TopTools.Handle_TopTools_HSequenceOfShape(wires) # The edges are copied to the sequence for edge in section_edges: edges.Append(edge) # A wire is formed by connecting the edges OCC.ShapeAnalysis.ShapeAnalysis_FreeBounds.ConnectEdgesToWires( edges_handle, 1e-5, True, wires_handle) wires = wires_handle.GetObject() # From each wire a face is created print(" number of faces = %d" % wires.Length()) for i in range(wires.Length()): wire_shape = wires.Value(i + 1) wire = OCC.TopoDS.wire(wire_shape) face = OCC.BRepBuilderAPI.BRepBuilderAPI_MakeFace(wire).Face() # The wires and the faces are displayed #ifcopenshell.geom.utils.display_shape(wire) #face_display = ifcopenshell.geom.utils.display_shape(face) #ifcopenshell.geom.utils.set_shape_transparency(face_display, 0.5) # Data about the wire is created to calculate the area wire_data = OCC.ShapeExtend.ShapeExtend_WireData( wire, True, True) wire_data_handle = OCC.ShapeExtend.Handle_ShapeExtend_WireData( wire_data) # The surface area of the face is calculated and appended to the list surface_area = abs( OCC.ShapeAnalysis.ShapeAnalysis_TotCross2D( wire_data_handle, face)) print(" surface area =", surface_area) surface_areas_per_section.append(surface_area)