def get_mesh_precision(shape, quality_factor): bbox = Bnd_Box() BRepBndLib_Add(shape, bbox) x_min, y_min, z_min, x_max, y_max, z_max = bbox.Get() diagonal_length = gp_Vec(gp_Pnt(x_min, y_min, z_min), gp_Pnt(x_max, y_max, z_max)).Magnitude() return (diagonal_length / 20.) / quality_factor
def bndBox_is_interfered(shp1, shp2): brepbnd = brepbndlib() bndBox1 = Bnd_Box() bndBox2 = Bnd_Box() brepbnd.Add(shp1, bndBox1) brepbnd.Add(shp2, bndBox2) return not (bndBox1.IsOut(bndBox2))
def build_bounding_box(self, shape, tol=1e-6, triangulate=False, triangulate_tol=1e-1): """ Builds a bounding box around the given shape. All parameters are set to match the computed box, the deformed FFD points are reset. :param shape: the shape to compute the bounding box. :type shape: TopoDS_Shape or its subclass :param float tol: tolerance of the computed bounding box. :param bool triangulate: if True, shape is triangulated before the bouning box creation. :param float triangulate_tol: tolerance of triangulation (size of created triangles). .. note:: Every UV-Surface has to be rectangular. When a solid is created surfaces are trimmed. The trimmed part, however, is still saved inside a file. It is just *invisible* when drawn in a program. """ bbox = Bnd_Box() bbox.SetGap(tol) if triangulate: BRepMesh_IncrementalMesh(shape, triangulate_tol) brepbndlib_Add(shape, bbox, triangulate) xmin, ymin, zmin, xmax, ymax, zmax = bbox.Get() min_xyz = np.array([xmin, ymin, zmin]) max_xyz = np.array([xmax, ymax, zmax]) self.origin_box = min_xyz self.lenght_box = max_xyz - min_xyz self.reset_deformation()
def _calculate_bb_dimension(shape, tol=1e-6, triangulate=False, triangulate_tol=1e-1): """ Calculate dimensions (minima and maxima) of a box bounding the :param TopoDS_Shape shape: or a subclass such as TopoDS_Face the shape to compute the bounding box from :param float tol: tolerance of the computed bounding box :param bool triangulate: Should shape be triangulated before the boudning box is created. If ``True`` only the dimensions of the bb will take into account every part of the shape (also not *visible*) If ``False`` only the *visible* part is taken into account \*See :meth:`~params.FFDParameters.build_bounding_box` :param float triangulate_tol: tolerance of triangulation (size of created triangles) :return: coordinates of minima and maxima along XYZ :rtype: tuple """ bbox = Bnd_Box() bbox.SetGap(tol) if triangulate: BRepMesh_IncrementalMesh(shape, triangulate_tol) brepbndlib_Add(shape, bbox, triangulate) xmin, ymin, zmin, xmax, ymax, zmax = bbox.Get() xyz_min = np.array([xmin, ymin, zmin]) xyz_max = np.array([xmax, ymax, zmax]) return xyz_min, xyz_max
def get_boundingbox(shape, tol=1e-6, as_vec=False): """ return the bounding box of the TopoDS_Shape `shape` Parameters ---------- shape : TopoDS_Shape or a subclass such as TopoDS_Face the shape to compute the bounding box from tol: float tolerance of the computed boundingbox as_vec : bool wether to return the lower and upper point of the bounding box as gp_Vec instances Returns ------- if `as_vec` is True, return a tuple of gp_Vec instances for the lower and another for the upper X,Y,Z values representing the bounding box if `as_vec` is False, return a tuple of lower and then upper X,Y,Z values representing the bounding box """ bbox = Bnd_Box() bbox.SetGap(tol) brepbndlib_Add(shape, bbox) xmin, ymin, zmin, xmax, ymax, zmax = bbox.Get() if as_vec is False: return xmin, ymin, zmin, xmax, ymax, zmax else: return gp_Vec(xmin, ymin, zmin), gp_Vec(xmax, ymax, zmax)
def get_boundingbox(shape, tol=1e-6, use_mesh=True): """ return the bounding box of the TopoDS_Shape `shape` Parameters ---------- shape : TopoDS_Shape or a subclass such as TopoDS_Face the shape to compute the bounding box from tol: float tolerance of the computed boundingbox use_mesh : bool a flag that tells whether or not the shape has first to be meshed before the bbox computation. This produces more accurate results """ bbox = Bnd_Box() bbox.SetGap(tol) if use_mesh: mesh = BRepMesh_IncrementalMesh() mesh.SetParallel(True) mesh.SetShape(shape) mesh.Perform() if not mesh.IsDone(): raise AssertionError("Mesh not done.") brepbndlib_Add(shape, bbox, use_mesh) xmin, ymin, zmin, xmax, ymax, zmax = bbox.Get() return xmin, ymin, zmin, xmax, ymax, zmax, xmax - xmin, ymax - ymin, zmax - zmin
def __init__(self, shape_or_values, tol=1.e-5): if isinstance(shape_or_values, tuple): self.values = shape_or_values else: bbox = Bnd_Box() bbox.SetGap(tol) brepbndlib_Add(shape_or_values, bbox, True) # use the shape triangulation self.values = bbox.Get()
def bbx(shape: TopoDS_Shape, tol=TOLERANCE): bbox = Bnd_Box() bbox.SetGap(tol) brepbndlib_Add(shape, bbox) # print(bbox.IsVoid()) if bbox.IsVoid() is True: return None return bbox
def get_bounding_box(self, shape=None): shape = shape or self.shape if not shape: return BBox() bbox = Bnd_Box() if hasattr(shape, 'Shape'): brepbndlib_Add(shape.Shape(), bbox) else: brepbndlib_Add(shape, bbox) return BBox(*bbox.Get())
def get_boundingbox(shape, tol=TOLERANCE): ''' :param shape: TopoDS_Shape such as TopoDS_Face :param tol: tolerance :return: xmin, ymin, zmin, xmax, ymax, zmax ''' bbox = Bnd_Box() bbox.SetGap(tol) brepbndlib_Add(shape, bbox) xmin, ymin, zmin, xmax, ymax, zmax = bbox.Get() return xmin, ymin, zmin, xmax, ymax, zmax
def analyze_file(filename): step_reader = STEPControl_Reader() status = step_reader.ReadFile(str(filename)) result = None if status == IFSelect_RetDone: # check status number_of_roots = step_reader.NbRootsForTransfer() ok = False i = 1 while i <= number_of_roots and not ok: ok = step_reader.TransferRoot(i) i += 1 if (not ok): return { 'error': 'Failed to find a suitable root for the STEP file' } number_of_shapes = step_reader.NbShapes() if (number_of_shapes > 1): return {'error': 'Cannot handle more than one shape in a file'} aResShape = step_reader.Shape(1) # bounding box bbox = Bnd_Box() deflection = 0.01 BRepMesh_IncrementalMesh(aResShape, deflection) brepbndlib_Add(aResShape, bbox) xmin, ymin, zmin, xmax, ymax, zmax = bbox.Get() bounding_box = calculate_bnd_box(bbox) result = { 'x0': bounding_box['x_min'], 'x1': bounding_box['x_max'], 'y0': bounding_box['y_min'], 'y1': bounding_box['y_max'], 'z0': bounding_box['z_min'], 'z1': bounding_box['z_max'], 'length': bounding_box['x_length'], 'width': bounding_box['z_length'], 'height': bounding_box['y_length'], 'volume': calculate_volume(aResShape) } else: result = {'error': 'Cannot read file'} return result
def slicing(wing_shape, eta_position): """This method puts cuts the wing shape into sections. Each section\ stores the following information: id, y-position and profile\ information. The latter is an instance of the class Profile. :param wing_shape: Shape of the wing :type wing_shape: OCC.TopoDS.TopoDS_Shape :param eta_positions: List from 0 to 1 :type eta_positions: numpy.ndarray of shape N :return: List of sections :rtype: list """ def create_cutting_plane_xz(y_pos, bounding_box): """Creates a face in the x-z plane at a given y-position. :param y_pos: y position :type y_pos: float :param bounding_box: Surrounding box of the wing :type bounding_box: instance of OCC.Bnd.Bnd_Box :return: face :rtype: instance of OCC.TopoDS.TopoDS_Face or None """ plane = gp_Pln(gp_Pnt(0, y_pos, 0), gp_Dir(0, 1, 0)) face_builder = BRepBuilderAPI_MakeFace(plane) if face_builder.IsDone(): return face_builder.Face() else: raise Exception('Could not build face') return None 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 wing_bounding_box = Bnd_Box() brepbndlib_Add(wing_shape, wing_bounding_box) x1, y1, z1, x2, y2, z2 = wing_bounding_box.Get() y = eta_position * y2 cutting_plane = create_cutting_plane_xz(y, wing_bounding_box) cutted_face = intersect_shape_face(wing_shape, cutting_plane) return cutted_face.Shape()
def compute_bbox(shp, *kwargs): print("Compute bbox for %s " % shp) for shape in shp: bbox = Bnd_Box() brepbndlib_Add(shape, bbox) xmin, ymin, zmin, xmax, ymax, zmax = bbox.Get() dx = xmax - xmin dy = ymax - ymin dz = zmax - zmin print("Selected shape bounding box : dx=%f, dy=%f, dz=%f." % (dx, dy, dz)) print(" bounding box center: x=%f, y=%f, z=%f" % (xmin + dx / 2., ymin + dy / 2., zmin + dz / 2.))
def point_in_boundingbox(solid, pnt, tolerance=1e-5): """returns True if *pnt* lies in *boundingbox*, False if not this is a much speedier test than checking the TopoDS_Solid Args: solid TopoDS_Solid pnt: gp_Pnt Returns: bool """ bbox = Bnd_Box() bbox.SetGap(tolerance) brepbndlib_Add(solid, bbox) return not bbox.IsOut(pnt)
def __init__(self, shape, tol=OCCUTILS_DEFAULT_TOLERANCE): if isinstance(shape, TopoDS_Shape) or issubclass(shape.__class__, TopoDS_Shape): self._shape = shape else: msg = "Expecting a TopoDS_Shape (or a subclass), " \ "got a %s" % str(shape.__class__) logger.error(msg) raise WrongTopologicalType(msg) # self._shape = shape self._tol = tol self._bbox = Bnd_Box() self._bbox.SetGap(tol) brepbndlib_Add(self._shape, self._bbox) self._x_min, self._y_min, self._z_min, self._x_max, self._y_max, self._z_max = self._bbox.Get()
def _fromTopoDS(cls, shape, tol=TOL, optimal=False): ''' Constructs a bounnding box from a TopoDS_Shape ''' bbox = Bnd_Box() bbox.SetGap(tol) if optimal: raise NotImplementedError # brepbndlib_AddOptimal(shape, bbox) #this is 'exact' but expensive - not yet wrapped by PythonOCC else: mesh = BRepMesh_IncrementalMesh(shape, TOL, True) mesh.Perform() # this is adds +margin but is faster brepbndlib_Add(shape, bbox, True) return cls(bbox)
def sampleSolid(n, solid, vertexList=None): # Create a bounding box for the shape boundingBox = Bnd_Box() brepbndlib_Add(solid, boundingBox) xMin, yMin, zMin, xMax, yMax, zMax = boundingBox.Get() xSideLength = xMax - xMin ySideLength = yMax - yMin zSideLength = zMax - zMin # Create extrema sampler to measure if the point is in the shape. For now, # just initialize it with the same shape. We'll load the vertex later. brepDistShapeShape = BRepExtrema_DistShapeShape(solid, solid) # Create a random number of vertices and check to see which ones are # in the shape. vertices = createPointsDataFrame(n) vertices.inShape = vertices.inShape.astype('int') # Loop over the vertices for i in range(0, n): # Pick a random point x = xMin + random() * xSideLength y = yMin + random() * ySideLength z = zMin + random() * zSideLength # Create a vertex from a geometric point gpPoint = gp_Pnt(x, y, z) vertexBuilder = BRepBuilderAPI_MakeVertex(gpPoint) vertex = vertexBuilder.Vertex() # Load the vertex into the extrema calculator brepDistShapeShape.LoadS2(vertex) brepDistShapeShape.Perform() # Compute the containment with the box and store the value inShape = 1 if brepDistShapeShape.InnerSolution() else 0 # Store the shape value vertices.set_value(i, 'x', x) vertices.set_value(i, 'y', y) vertices.set_value(i, 'z', z) vertices.set_value(i, 'inShape', inShape) if inShape != 0: vertexList.append(vertex) # Slice the data frame so that only the x,y,z variables for points in the box are saved. innerVertices = vertices[vertices.inShape == 1] innerCoords = innerVertices[['x', 'y', 'z']] return innerCoords
def test_bndBox(): # simple interference check through bounding box shp = read_step_file("/home/lenty/exchange/tempData/models/lf064-01.stp") brepbnd = brepbndlib() bndBox = Bnd_Box() # display = Display(shp, run_display=True) brepbnd.Add(shp, bndBox) p1 = gp_Pnt(55, 30, 7) print(bndBox.IsOut(p1)) b3f = Bnd_B3f() p2 = gp_Pnt(0, 0, 0) b3f.Add(p2) print(b3f.IsOut(gp_XYZ(0, 0, 1))) ipdb.set_trace() print(b3f.IsOut(gp_Pnt(0, 0, 1)))
def get_bounding_box(self, shapes): """ Compute the bounding box for the given list of shapes. Return values are in 3d coordinate space. Parameters ---------- shapes: List A list of TopoDS_Shape to compute a bbox for Returns ------- bbox: Tuple A tuple of (xmin, ymin, zmin, xmax, ymax, zmax). """ bbox = Bnd_Box() for shape in shapes: brepbndlib_Add(shape, bbox) return bbox.Get()
def get_boundingbox(shape: TopoDS_Shape, tol=TOLERANCE): """ :param shape: TopoDS_Shape such as TopoDS_Face :param tol: tolerance :return: [xmin, ymin, zmin, xmax, ymax, zmax] """ bbox = Bnd_Box() bbox.SetGap(tol) brepbndlib_Add(shape, bbox) # print(bbox.IsVoid()) if bbox.IsVoid() is True: return None # xmin, ymin, zmin, xmax, ymax, zmax = bbox.Get() cmin = bbox.CornerMin() cmax = bbox.CornerMax() xmin, ymin, zmin = cmin.X(), cmin.Y(), cmin.Z() xmax, ymax, zmax = cmax.X(), cmax.Y(), cmax.Z() return xmin, ymin, zmin, xmax, ymax, zmax
def add(self, obj, tol=1e-8): """Returns a modified (expanded) bounding box obj can be one of several things: 1. a 3-tuple corresponding to x,y, and z amounts to add 2. a vector, containing the x,y,z values to add 3. another bounding box, where a new box will be created that encloses both. This bounding box is not changed. """ tmp = Bnd_Box() tmp.SetGap(tol) tmp.Add(self.wrapped) if isinstance(obj, tuple): tmp.Update(*obj) elif isinstance(obj, Vector): tmp.Update(*obj.toTuple()) elif isinstance(obj, BoundBox): tmp.Add(obj.wrapped) return BoundBox(tmp)
def __init__(self, file_path, id=None): self.file = file_path.encode("utf-8") self.id = id self.shapes_simples = [] self.main_product = None basename = os.path.basename(self.file) self.fileName = os.path.splitext(basename)[0] self.STEPReader = STEPCAFControl_Reader() if self.STEPReader.ReadFile(self.file) != 1: raise OCCReadingStepError self.h_doc = TDocStd.Handle_TDocStd_Document() self.app = XCAFApp.GetApplication().GetObject() self.app.NewDocument(TCollection_ExtendedString("MDTV-XCAF"), self.h_doc) self.STEPReader.Transfer(self.h_doc) self.doc = self.h_doc.GetObject() self.h_shape_tool = XCAFDoc.XCAFDoc_DocumentTool_ShapeTool( self.doc.Main()) self.h_colors_tool = XCAFDoc.XCAFDoc_DocumentTool_ColorTool( self.doc.Main()) self.shape_tool = self.h_shape_tool.GetObject() self.color_tool = self.h_colors_tool.GetObject() self.shapes = TDF_LabelSequence() self.shape_tool.GetShapes(self.shapes) for i in range(self.shapes.Length()): shape = self.shapes.Value(i + 1) if self.shape_tool.IsSimpleShape(shape): compShape = self.shape_tool.GetShape(shape) t = Topo(compShape) if t.number_of_vertices() > 0: label = get_label_name(shape) color = find_color(shape, self.color_tool, self.shape_tool) self.shapes_simples.append( SimpleShape(label, compShape, color)) roots = TDF_LabelSequence() self.shape_tool.GetFreeShapes(roots) self.thumbnail_valid = False if roots.Length() == 1: shape = self.shape_tool.GetShape(roots.Value(1)) t = Topo(shape) if t.number_of_vertices() > 0: bbox = Bnd_Box() gap = 0 bbox.SetGap(gap) BRepMesh_Mesh(shape, get_mesh_precision(shape, 1)) faces_iterator = Topo(shape).faces() for F in faces_iterator: face_location = TopLoc_Location() BRep_Tool_Triangulation(F, face_location) BRepBndLib_Add(shape, bbox) x_min, y_min, z_min, x_max, y_max, z_max = bbox.Get() diagonal = max(x_max - x_min, y_max - y_min, z_max - z_min) if diagonal > 0: self.scale = 200. / diagonal self.trans = ((x_max - x_min) / 2. - x_max, (y_max - y_min) / 2. - y_max, (z_max - z_min) / 2. - z_max) self.thumbnail_valid = True ws = self.STEPReader.Reader().WS().GetObject() model = ws.Model().GetObject() model.Clear()
def deduce_parameters(aircraft): """ Given a tigl handle to the cpacs node of the aircraft, try to deduce the parameters to get initial conditions for the animation. Note that this only works well for the simple initial geometries. :param aircraft: a tigl handle to the cpacs node of the aircraft :return: a parameters dictionary """ params = {"fuselage": {}, "wing_main": {}, "wing_htp": {}, "wing_vtp": {}} # deduce fuselage parameters fuselage = aircraft.get_fuselages().get_fuselage("fuselage") shape = fuselage.get_loft().shape() bbox = Bnd_Box() brepbndlib_Add(shape, bbox) xmin, ymin, zmin, xmax, ymax, zmax = bbox.Get() params["fuselage"]["length"] = xmax - xmin params["fuselage"]["section_height"] = zmax - zmin params["fuselage"]["section_width"] = ymax - ymin c = fuselage.get_circumference(1, 0) params["fuselage"]["nose_area"] = 0.25*c**2/np.pi s = fuselage.get_section(1) e = s.get_section_element(1) ce = e.get_ctigl_section_element() params["fuselage"]["nose_center"] = ce.get_center() s = fuselage.get_section(2) e = s.get_section_element(1) ce = e.get_ctigl_section_element() params["fuselage"]["section_2_center"] = ce.get_center() c = fuselage.get_circumference(1, 1) params["fuselage"]["section_2_area"] = 0.25 * c ** 2 / np.pi s = fuselage.get_section(3) e = s.get_section_element(1) ce = e.get_ctigl_section_element() params["fuselage"]["section_3_center"] = ce.get_center() c = fuselage.get_circumference(2, 1) params["fuselage"]["section_3_area"] = 0.25 * c ** 2 / np.pi s = fuselage.get_section(4) e = s.get_section_element(1) ce = e.get_ctigl_section_element() params["fuselage"]["section_4_center"] = ce.get_center() c = fuselage.get_circumference(3, 1) params["fuselage"]["section_4_area"] = 0.25 * c ** 2 / np.pi tail_idx = fuselage.get_section_count() s = fuselage.get_section(tail_idx) e = s.get_section_element(1) ce = e.get_ctigl_section_element() params["fuselage"]["tail_width"] = ymax - ymin params["fuselage"]["tail_height"] = zmax - zmin params["fuselage"]["tail_angle"] = 0 params["fuselage"]["tail_center"] = ce.get_center() # deduce main wing parameters wing_main = aircraft.get_wings().get_wing("wing_main") shape = wing_main.get_loft().shape() bbox = Bnd_Box() brepbndlib_Add(shape, bbox) xmin, ymin, zmin, xmax, ymax, zmax = bbox.Get() params["wing_main"]["root_leposition"] = wing_main.get_root_leposition() params["wing_main"]["scale"] = 1 params["wing_main"]["half_span"] = ymax - ymin params["wing_main"]["section_2_rel_pos"] = 0.5 params["wing_main"]["root_width"] = xmax - xmin params["wing_main"]["root_height"] = zmax - zmin params["wing_main"]["tip_width"] = xmax - xmin params["wing_main"]["tip_height"] = zmax - zmin params["wing_main"]["sweep"] = 0 params["wing_main"]["dihedral"] = 0 params["wing_main"]["winglet_rotation"] = tigl3.geometry.CTiglPoint(0, 0, 0) tip_idx = wing_main.get_section_count() tip = wing_main.get_section(tip_idx).get_section_element(1).get_ctigl_section_element().get_center() pre_tip = wing_main.get_section(tip_idx-1).get_section_element(1).get_ctigl_section_element().get_center() params["wing_main"]["winglet_center_translation"] = tip - pre_tip params["wing_main"]["winglet_width"] = xmax - xmin # deduce htp wing parameters wing_htp = aircraft.get_wings().get_wing("wing_htp") shape = wing_htp.get_loft().shape() bbox = Bnd_Box() brepbndlib_Add(shape, bbox) xmin, ymin, zmin, xmax, ymax, zmax = bbox.Get() params["wing_htp"]["root_leposition"] = wing_htp.get_root_leposition() params["wing_htp"]["sweep"] = 0 params["wing_htp"]["dihedral"] = 0 params["wing_htp"]["tip_width"] = xmax - xmin params["wing_htp"]["tip_height"] = zmax - zmin # deduce vtp wing parameters wing_vtp = aircraft.get_wings().get_wing("wing_vtp") shape = wing_vtp.get_loft().shape() bbox = Bnd_Box() brepbndlib_Add(shape, bbox) xmin, ymin, zmin, xmax, ymax, zmax = bbox.Get() params["wing_vtp"]["root_leposition"] = wing_vtp.get_root_leposition() params["wing_vtp"]["rotation"] = tigl3.geometry.CTiglPoint(0, 0, 0) params["wing_vtp"]["sweep"] = 0 params["wing_vtp"]["dihedral"] = 0 params["wing_vtp"]["tip_width"] = xmax - xmin params["wing_vtp"]["tip_height"] = zmax - zmin return params
def analyze_file(filename): step_reader = STEPControl_Reader() status = step_reader.ReadFile(filename) result = None if status == IFSelect_RetDone: # check status number_of_roots = step_reader.NbRootsForTransfer() ok = False i = 1 while i <= number_of_roots and not ok: ok = step_reader.TransferRoot(i) i += 1 if (not ok): return { 'error': 'Failed to find a suitable root for the STEP file' } number_of_shapes = step_reader.NbShapes() if (number_of_shapes > 1): return {'error': 'Cannot handle more than one shape in a file'} aResShape = step_reader.Shape(1) # Units length = TColStd_SequenceOfAsciiString() angles = TColStd_SequenceOfAsciiString() solid_angles = TColStd_SequenceOfAsciiString() step_reader.FileUnits(length, angles, solid_angles) # bounding box bbox = Bnd_Box() deflection = 0.01 BRepMesh_IncrementalMesh(aResShape, deflection) brepbndlib_Add(aResShape, bbox) xmin, ymin, zmin, xmax, ymax, zmax = bbox.Get() bounding_box = calculate_bnd_box(bbox) bounding_cylinder = calculate_bounding_cylinder( aResShape, bounding_box) result = { 'bounding_box_volume': bounding_box['volume'], 'bounding_box_x_length': bounding_box['x_length'], 'bounding_box_y_length': bounding_box['y_length'], 'bounding_box_z_length': bounding_box['z_length'], 'mesh_volume': calculate_volume(aResShape), 'mesh_surface_area': None, 'cylinder_volume': bounding_cylinder['cylinder_volume'], 'cylinder_diameter': bounding_cylinder['radius'] * 2, 'cylinder_length': bounding_cylinder['height'], 'convex_hull_volume': None, 'euler_number': None, 'units': length.First().ToCString().lower() } else: result = {'error': 'Cannot read file'} return result
class BoundingBox(AbstractBoundingBox): r"""Wrapper class for a bounding box Notes ----- Mesh the shape before instantiating a BoundingBox if required, infinite recursion would be created by calling mesh.py's mesh() method """ def __init__(self, shape, tol=OCCUTILS_DEFAULT_TOLERANCE): if isinstance(shape, TopoDS_Shape) or issubclass(shape.__class__, TopoDS_Shape): self._shape = shape else: msg = "Expecting a TopoDS_Shape (or a subclass), " \ "got a %s" % str(shape.__class__) logger.error(msg) raise WrongTopologicalType(msg) # self._shape = shape self._tol = tol self._bbox = Bnd_Box() self._bbox.SetGap(tol) brepbndlib_Add(self._shape, self._bbox) self._x_min, self._y_min, self._z_min, self._x_max, self._y_max, self._z_max = self._bbox.Get() @property def x_min(self): r"""Minimum x""" return self._x_min @property def x_max(self): r"""Maximum x""" return self._x_max @property def y_min(self): r"""Minimum y""" return self._y_min @property def y_max(self): r"""Maximum y""" return self._y_max @property def z_min(self): r"""Minimum z""" return self._z_min @property def z_max(self): r"""Maximum z""" return self._z_max @property def bnd_box(self): r"""The OCC bounding box object Returns ------- OCC.Bnd.Bnd_Box """ return self._bbox @property def x_span(self): r"""x dimension of bounding box""" return self.x_max - self.x_min @property def y_span(self): r"""y dimension of bounding box""" return self.y_max - self.y_min @property def z_span(self): r"""z dimension of bounding box""" return self.z_max - self.z_min @property def max_dimension(self): r"""Maximum dimension""" return max([self.x_span, self.y_span, self.z_span]) @property def min_dimension(self): r"""Minimum dimension""" return min([self.x_span, self.y_span, self.z_span]) @property def aspect_ratio(self): r"""Aspect ratio""" return self.max_dimension / self.min_dimension @property def as_tuple(self): r"""bounding box as the original tuple""" return (self.x_min, self.y_min, self.z_min, self.x_max, self.y_max, self.z_max) @property def centre(self): r"""Centre of the bounding box Returns ------- gp_Pnt """ return Point.midpoint(gp_Pnt(self.x_min, self.y_min, self.z_min), gp_Pnt(self.x_max, self.y_max, self.z_max))
#my_box = BRepPrimAPI_MakeBox(10., 20., 30.).Shape() stl_reader = StlAPI_Reader() stl_box = TopoDS_Shape() stl_reader.Read(stl_box, './models/box.stl') axe = gp_Ax2(gp_Pnt(-10, 1, 1), gp_Dir(0, 0, 1)) box = BRepPrimAPI_MakeBox(axe, 50, 15, 15).Shape() CommonSurface = BRepAlgoAPI_Common(box, stl_box).Shape() topo = Topo(CommonSurface) display.EraseAll() x_mid_max = -100 front_face = None for face in topo.faces(): bbox = Bnd_Box() OCC.BRepBndLib.brepbndlib_Add(face, bbox) xmin, ymin, zmin, xmax, ymax, zmax = bbox.Get() x_mid = (xmin + xmax) / 2 if x_mid > x_mid_max: x_mid_max = x_mid front_face = face t_face = Topo(front_face) OCCUtils.Topology.dumpTopology(front_face) wires = t_face.wires() z_center_min_edge = 1000 lowest_edge = None lowest_wire = None for w in wires: #display.DisplayShape(w)