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 put_shape_to_bounding_box(element, bounding_box): if not element.is_decomposed: for shape in element.topods_shapes: brepbndlib_Add(shape["topods_shape"], bounding_box) else: for child in element.children: BuildingElement.put_shape_to_bounding_box(child, bounding_box)
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.box_origin = min_xyz self.box_length = 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 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
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 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 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 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 __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 ObjectsExtents(breps, tol=1e-6, as_vec=False): """Compute the extents in the X, Y and Z direction (in the current coordinate system) of the objects listed in the argument. Parameters ---------- breps : list of TopoDS_Shape The shapes to be added for bounding box calculation tol : float (default=1e-6) Tolerance for bounding box calculation as_vec : bool (default=False) If true, returns minimum and maximum points as tuple of gp_Vec Returns ------- xmin, ymin, zmin, xmax, ymax, zmax : scalar the min and max points of bbox (returned if as_vec=False) ( gp_Vec(xmin, ymin, zmin), gp_Vec(xmax, ymax, zmax) ) : tuple of gp_Vec the min and max points of bbox (returned in as_vec=True) Notes ----- Due to the underlying OCC.Bnd.Bnd_Box functions, the bounding box is calculated via triangulation of the shapes to avoid inclusion of the control points of NURBS curves in bounding box calculation """ bbox = OCC.Bnd.Bnd_Box() bbox.SetGap(tol) try: for shape in breps: brepbndlib_Add(shape, bbox, True) except TypeError: # Assume not iterable: brepbndlib_Add(breps, bbox, True) 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: 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 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 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
def bounds(self): box = Bnd_Box() brepbndlib_Add(self.shape, box) coords=box.Get() return Bounds(min=coords[:3], max=coords[3:])