Esempio n. 1
0
def write_stl_file(compound, filename, tolerance=None, angular_tolerance=None):

    # Remove previous mesh data
    BRepTools.Clean_s(compound)

    mesh = BRepMesh_IncrementalMesh(compound, tolerance, True, angular_tolerance)
    mesh.Perform()

    writer = StlAPI_Writer()

    result = writer.Write(compound, filename)

    # Remove the mesh data again
    BRepTools.Clean_s(compound)
    return result
Esempio n. 2
0
    def compute(
        self,
        shape,
        quality,
        angular_tolerance,
        tessellate=True,
        compute_edges=True,
        normals_len=0,
        debug=False,
    ):
        self.shape = shape
        self.normals_len = normals_len
        self.edges = []

        count = self.number_solids(shape)
        with Timer(debug, "", f"mesh incrementally {'(parallel)' if count > 1 else ''}", 3):
            # Remove previous mesh data
            BRepTools.Clean_s(shape)
            BRepMesh_IncrementalMesh(shape, quality, False, angular_tolerance, count > 1)

        if tessellate:
            with Timer(debug, "", "get nodes, triangles and normals", 3):
                self.tessellate()

        if compute_edges:
            with Timer(debug, "", "get edges", 3):
                self.compute_edges()
Esempio n. 3
0
    def _fromTopoDS(
        cls: Type["BoundBox"],
        shape: TopoDS_Shape,
        tol: Optional[float] = None,
        optimal: bool = True,
    ):
        """
        Constructs a bounding box from a TopoDS_Shape
        """
        tol = TOL if tol is None else tol  # tol = TOL (by default)
        bbox = Bnd_Box()

        if optimal:
            BRepBndLib.AddOptimal_s(
                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_s(shape, bbox, True)

        return cls(bbox)
Esempio n. 4
0
def tessellate(shape, tolerance: float, angularTolerance: float = 0.1):

    # Remove previous mesh data
    BRepTools.Clean_s(shape)

    triangulated = BRepTools.Triangulation_s(shape, tolerance)
    if not triangulated:
        # this will add mesh data to the shape and prevent calculating an exact bounding box after this call
        BRepMesh_IncrementalMesh(shape, tolerance, True, angularTolerance)

    vertices = []
    triangles = []
    normals = []

    offset = 0

    for face in get_faces(shape):
        loc = TopLoc_Location()
        poly = BRep_Tool.Triangulation_s(face, loc)
        Trsf = loc.Transformation()

        reverse = face.Orientation() == TopAbs_Orientation.TopAbs_REVERSED
        internal = face.Orientation() == TopAbs_Orientation.TopAbs_INTERNAL

        # add vertices
        if poly is not None:
            vertices += [(v.X(), v.Y(), v.Z())
                         for v in (v.Transformed(Trsf) for v in poly.Nodes())]

            # add triangles
            triangles += [(
                t.Value(1) + offset - 1,
                t.Value(3 if reverse else 2) + offset - 1,
                t.Value(2 if reverse else 3) + offset - 1,
            ) for t in poly.Triangles()]

            # add normals
            if poly.HasUVNodes():
                prop = BRepGProp_Face(face)
                uvnodes = poly.UVNodes()
                for uvnode in uvnodes:
                    p = gp_Pnt()
                    n = gp_Vec()
                    prop.Normal(uvnode.X(), uvnode.Y(), p, n)

                    if n.SquareMagnitude() > 0:
                        n.Normalize()
                    if internal:
                        n.Reverse()

                    normals.append((n.X(), n.Y(), n.Z()))

            offset += poly.NbNodes()

    if not triangulated:
        # Remove the mesh data again
        BRepTools.Clean_s(shape)

    return (
        np.asarray(vertices, dtype=np.float32),
        np.asarray(triangles, dtype=np.uint32),
        np.asarray(normals, dtype=np.float32),
    )