Beispiel #1
0
    def __init__(self, *args):

        T = gp_Trsf()

        if len(args) == 0:
            pass
        elif len(args) == 1:
            t = args[0]

            if isinstance(t, Vector):
                T.SetTranslationPart(t.wrapped)
            elif isinstance(t, Plane):
                cs = gp_Ax3(t.origin.toPnt(), t.zDir.toDir(), t.xDir.toDir())
                T.SetTransformation(cs)
                T.Invert()
            elif isinstance(t, TopLoc_Location):
                self.wrapped = t
                return
            elif isinstance(t, gp_Trsf):
                T = t
        elif len(args) == 2:
            t, v = args
            cs = gp_Ax3(v.toPnt(), t.zDir.toDir(), t.xDir.toDir())
            T.SetTransformation(cs)
            T.Invert()
        else:
            t, ax, angle = args
            T.SetRotation(gp_Ax1(Vector().toPnt(), ax.toDir()),
                          angle * math.pi / 180.0)
            T.SetTranslationPart(t.wrapped)

        self.wrapped = TopLoc_Location(T)
    def tessellate(self):
        self.vertices = []
        self.triangles = []
        self.normals = []

        # global buffers
        p_buf = gp_Pnt()
        n_buf = gp_Vec()
        loc_buf = TopLoc_Location()

        offset = -1

        # every line below is selected for performance. Do not introduce functions to "beautify" the code

        for face in get_faces(self.shape):
            if face.Orientation() == TopAbs_Orientation.TopAbs_REVERSED:
                i1, i2 = 2, 1
            else:
                i1, i2 = 1, 2

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

            poly = BRep_Tool.Triangulation_s(face, loc_buf)
            if poly is not None:
                Trsf = loc_buf.Transformation()

                # add vertices
                flat = []
                for i in range(1, poly.NbNodes() + 1):
                    flat.extend(poly.Node(i).Transformed(Trsf).Coord())
                self.vertices.extend(flat)

                # add triangles
                flat = []
                for i in range(1, poly.NbTriangles() + 1):
                    coord = poly.Triangle(i).Get()
                    flat.extend((coord[0] + offset, coord[i1] + offset,
                                 coord[i2] + offset))
                self.triangles.extend(flat)

                # add normals
                if poly.HasUVNodes():
                    prop = BRepGProp_Face(face)
                    flat = []
                    for i in range(1, poly.NbNodes() + 1):
                        u, v = poly.UVNode(i).Coord()
                        prop.Normal(u, v, p_buf, n_buf)
                        if n_buf.SquareMagnitude() > 0:
                            n_buf.Normalize()
                        flat.extend(n_buf.Reverse().Coord(
                        ) if internal else n_buf.Coord())
                    self.normals.extend(flat)

                offset += poly.NbNodes()
Beispiel #3
0
    def compute_edges(self):
        edge_map = TopTools_IndexedMapOfShape()
        face_map = TopTools_IndexedDataMapOfShapeListOfShape()

        TopExp.MapShapes_s(self.shape, TopAbs_EDGE, edge_map)
        TopExp.MapShapesAndAncestors_s(self.shape, TopAbs_EDGE, TopAbs_FACE, face_map)

        for i in range(1, edge_map.Extent() + 1):
            edge = TopoDS.Edge_s(edge_map.FindKey(i))

            face_list = face_map.FindFromKey(edge)
            if face_list.Extent() == 0:
                # print("no faces")
                continue

            loc = TopLoc_Location()
            poly = BRep_Tool.Polygon3D_s(edge, loc)

            if poly is not None:
                # print("Polygon3D successful")
                nodes = poly.Nodes()
                transf = loc.Transformation()
                v1 = None
                for j in range(1, poly.NbNodes() + 1):
                    v2 = nodes.Value(j)
                    v2.Transform(transf)
                    v2 = v2.Coord()
                    if v1 is not None:
                        self.edges.append((v1, v2))
                    v1 = v2
            else:
                face = TopoDS.Face_s(face_list.First())
                triang = BRep_Tool.Triangulation_s(face, loc)
                poly = BRep_Tool.PolygonOnTriangulation_s(edge, triang, loc)
                if poly is None:
                    continue

                indices = poly.Nodes()
                nodes = triang.Nodes()
                transf = loc.Transformation()
                v1 = None
                for j in range(indices.Lower(), indices.Upper() + 1):
                    v2 = nodes.Value(indices.Value(j))
                    v2.Transform(transf)
                    v2 = v2.Coord()
                    if v1 is not None:
                        self.edges.append((v1, v2))
                    v1 = v2
Beispiel #4
0
def toCAF(assy: AssemblyProtocol,
          coloredSTEP: bool = False) -> Tuple[TDF_Label, TDocStd_Document]:

    # prepare a doc
    app = XCAFApp_Application.GetApplication_s()

    doc = TDocStd_Document(TCollection_ExtendedString("XmlOcaf"))
    app.InitDocument(doc)

    tool = XCAFDoc_DocumentTool.ShapeTool_s(doc.Main())
    tool.SetAutoNaming_s(False)
    ctool = XCAFDoc_DocumentTool.ColorTool_s(doc.Main())

    # add root
    top = tool.NewShape()
    TDataStd_Name.Set_s(top, TCollection_ExtendedString("CQ assembly"))

    # add leafs and subassemblies
    subassys: Dict[str, Tuple[TDF_Label, Location]] = {}
    for k, v in assy.traverse():
        # leaf part
        lab = tool.NewShape()
        tool.SetShape(lab, Compound.makeCompound(v.shapes).wrapped)
        setName(lab, f"{k}_part", tool)

        # assy part
        subassy = tool.NewShape()
        tool.AddComponent(subassy, lab, TopLoc_Location())
        setName(subassy, k, tool)

        # handle colors - this logic is needed for proper STEP export
        color = v.color
        tmp = v
        if coloredSTEP:
            while not color and tmp.parent:
                tmp = tmp.parent
                color = tmp.color
            if color:
                setColor(lab, color, ctool)
        else:
            if color:
                setColor(subassy, color, ctool)

        subassys[k] = (subassy, v.loc)

        for ch in v.children:
            tool.AddComponent(subassy, subassys[ch.name][0],
                              subassys[ch.name][1].wrapped)

    tool.AddComponent(top, subassys[assy.name][0], assy.loc.wrapped)
    tool.UpdateAssemblies()

    return top, doc
    def compute_edges(self):
        edge_map = TopTools_IndexedMapOfShape()
        face_map = TopTools_IndexedDataMapOfShapeListOfShape()

        TopExp.MapShapes_s(self.shape, TopAbs_EDGE, edge_map)
        TopExp.MapShapesAndAncestors_s(self.shape, TopAbs_EDGE, TopAbs_FACE,
                                       face_map)

        for i in range(1, edge_map.Extent() + 1):
            edge = TopoDS.Edge_s(edge_map.FindKey(i))

            face_list = face_map.FindFromKey(edge)
            if face_list.Extent() == 0:
                # print("no faces")
                continue

            loc = TopLoc_Location()

            face = TopoDS.Face_s(face_list.First())
            triangle = BRep_Tool.Triangulation_s(face, loc)
            poly = BRep_Tool.PolygonOnTriangulation_s(edge, triangle, loc)

            if poly is None:
                continue

            if hasattr(poly, "Node"):  # OCCT > 7.5
                nrange = range(1, poly.NbNodes() + 1)
                index = poly.Node
            else:  # OCCT == 7.5
                indices = poly.Nodes()
                nrange = range(indices.Lower(), indices.Upper() + 1)
                index = indices.Value

            transf = loc.Transformation()
            v1 = None
            for j in nrange:
                v2 = triangle.Node(index(j)).Transformed(transf).Coord()
                if v1 is not None:
                    self.edges.append((v1, v2))
                v1 = v2
Beispiel #6
0
    def __init__(self, *args):

        T = gp_Trsf()

        if len(args) == 0:
            pass
        elif len(args) == 1:
            t = args[0]

            if isinstance(t, Vector):
                T.SetTranslationPart(t.wrapped)
            elif isinstance(t, Plane):
                cs = gp_Ax3(t.origin.toPnt(), t.zDir.toDir(), t.xDir.toDir())
                T.SetTransformation(cs)
                T.Invert()
            elif isinstance(t, TopLoc_Location):
                self.wrapped = t
                return
            elif isinstance(t, gp_Trsf):
                T = t
            elif isinstance(t, (tuple, list)):
                raise TypeError(
                    "A tuple or list is not a valid parameter, use a Vector instead."
                )
            else:
                raise TypeError("Unexpected parameters")
        elif len(args) == 2:
            t, v = args
            cs = gp_Ax3(v.toPnt(), t.zDir.toDir(), t.xDir.toDir())
            T.SetTransformation(cs)
            T.Invert()
        else:
            t, ax, angle = args
            T.SetRotation(gp_Ax1(Vector().toPnt(), ax.toDir()),
                          angle * math.pi / 180.0)
            T.SetTranslationPart(t.wrapped)

        self.wrapped = TopLoc_Location(T)
Beispiel #7
0
class Location(object):
    """Location in 3D space. Depending on usage can be absolute or relative.

    This class wraps the TopLoc_Location class from OCCT. It can be used to move Shape
    objects in both relative and absolute manner. It is the preferred type to locate objects
    in CQ.
    """

    wrapped: TopLoc_Location

    @overload
    def __init__(self) -> None:
        """Empty location with not rotation or translation with respect to the original location."""
        ...

    @overload
    def __init__(self, t: Vector) -> None:
        """Location with translation t with respect to the orignal location."""
        ...

    @overload
    def __init__(self, t: Plane) -> None:
        """Location corresponding to the location of the Plane t."""
        ...

    @overload
    def __init__(self, t: Plane, v: Vector) -> None:
        """Location corresponding to the angular location of the Plane t with translation v."""
        ...

    @overload
    def __init__(self, t: TopLoc_Location) -> None:
        """Location wrapping the low-level TopLoc_Location object t"""
        ...

    @overload
    def __init__(self, t: gp_Trsf) -> None:
        """Location wrapping the low-level gp_Trsf object t"""
        ...

    @overload
    def __init__(self, t: Vector, ax: Vector, angle: float) -> None:
        """Location with translation t and rotation around ax by angle
        with respect to the original location."""
        ...

    def __init__(self, *args):

        T = gp_Trsf()

        if len(args) == 0:
            pass
        elif len(args) == 1:
            t = args[0]

            if isinstance(t, Vector):
                T.SetTranslationPart(t.wrapped)
            elif isinstance(t, Plane):
                cs = gp_Ax3(t.origin.toPnt(), t.zDir.toDir(), t.xDir.toDir())
                T.SetTransformation(cs)
                T.Invert()
            elif isinstance(t, TopLoc_Location):
                self.wrapped = t
                return
            elif isinstance(t, gp_Trsf):
                T = t
        elif len(args) == 2:
            t, v = args
            cs = gp_Ax3(v.toPnt(), t.zDir.toDir(), t.xDir.toDir())
            T.SetTransformation(cs)
            T.Invert()
        else:
            t, ax, angle = args
            T.SetRotation(gp_Ax1(Vector().toPnt(), ax.toDir()),
                          angle * math.pi / 180.0)
            T.SetTranslationPart(t.wrapped)

        self.wrapped = TopLoc_Location(T)

    @property
    def inverse(self) -> "Location":

        return Location(self.wrapped.Inverted())

    def __mul__(self, other: "Location") -> "Location":

        return Location(self.wrapped * other.wrapped)
Beispiel #8
0
    def tessellate(self):
        self.vertices = array("f")
        self.triangles = array("f")
        self.normals = array("f")

        # global buffers
        p_buf = gp_Pnt()
        n_buf = gp_Vec()
        loc_buf = TopLoc_Location()

        offset = -1

        # every line below is selected for performance. Do not introduce functions to "beautify" the code

        for face in get_faces(self.shape):
            if face.Orientation() == TopAbs_Orientation.TopAbs_REVERSED:
                i1, i2 = 2, 1
            else:
                i1, i2 = 1, 2

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

            poly = BRep_Tool.Triangulation_s(face, loc_buf)
            if poly is not None:
                Trsf = loc_buf.Transformation()

                # add vertices
                # [node.Transformed(Trsf).Coord() for node in poly.Nodes()] is 5-8 times slower!
                items = poly.Nodes()
                coords = [items.Value(i).Transformed(Trsf).Coord() for i in range(items.Lower(), items.Upper() + 1)]
                flat = []
                for coord in coords:
                    flat += coord
                self.vertices.extend(flat)

                # add triangles
                items = poly.Triangles()
                coords = [items.Value(i).Get() for i in range(items.Lower(), items.Upper() + 1)]
                flat = []
                for coord in coords:
                    flat += (coord[0] + offset, coord[i1] + offset, coord[i2] + offset)
                self.triangles.extend(flat)

                # add normals
                if poly.HasUVNodes():

                    def extract(uv0, uv1):
                        prop.Normal(uv0, uv1, p_buf, n_buf)
                        if n_buf.SquareMagnitude() > 0:
                            n_buf.Normalize()
                        return n_buf.Reverse().Coord() if internal else n_buf.Coord()

                    prop = BRepGProp_Face(face)
                    items = poly.UVNodes()

                    uvs = [items.Value(i).Coord() for i in range(items.Lower(), items.Upper() + 1)]
                    flat = []
                    for uv1, uv2 in uvs:
                        flat += extract(uv1, uv2)
                    self.normals.extend(flat)

                offset += poly.NbNodes()
Beispiel #9
0
def tq_to_loc(t, q):
    T = gp_Trsf()
    Q = gp_Quaternion(*q)
    V = gp_Vec(*t)
    T.SetTransformation(Q, V)
    return TopLoc_Location(T)
Beispiel #10
0
class Location(object):
    """Location in 3D space. Depending on usage can be absolute or relative.

    This class wraps the TopLoc_Location class from OCCT. It can be used to move Shape
    objects in both relative and absolute manner. It is the preferred type to locate objects
    in CQ.
    """

    wrapped: TopLoc_Location

    @overload
    def __init__(self) -> None:
        """Empty location with not rotation or translation with respect to the original location."""
        ...

    @overload
    def __init__(self, t: Vector) -> None:
        """Location with translation t with respect to the original location."""
        ...

    @overload
    def __init__(self, t: Plane) -> None:
        """Location corresponding to the location of the Plane t."""
        ...

    @overload
    def __init__(self, t: Plane, v: Vector) -> None:
        """Location corresponding to the angular location of the Plane t with translation v."""
        ...

    @overload
    def __init__(self, t: TopLoc_Location) -> None:
        """Location wrapping the low-level TopLoc_Location object t"""
        ...

    @overload
    def __init__(self, t: gp_Trsf) -> None:
        """Location wrapping the low-level gp_Trsf object t"""
        ...

    @overload
    def __init__(self, t: Vector, ax: Vector, angle: float) -> None:
        """Location with translation t and rotation around ax by angle
        with respect to the original location."""
        ...

    def __init__(self, *args):

        T = gp_Trsf()

        if len(args) == 0:
            pass
        elif len(args) == 1:
            t = args[0]

            if isinstance(t, Vector):
                T.SetTranslationPart(t.wrapped)
            elif isinstance(t, Plane):
                cs = gp_Ax3(t.origin.toPnt(), t.zDir.toDir(), t.xDir.toDir())
                T.SetTransformation(cs)
                T.Invert()
            elif isinstance(t, TopLoc_Location):
                self.wrapped = t
                return
            elif isinstance(t, gp_Trsf):
                T = t
            elif isinstance(t, (tuple, list)):
                raise TypeError(
                    "A tuple or list is not a valid parameter, use a Vector instead."
                )
            else:
                raise TypeError("Unexpected parameters")
        elif len(args) == 2:
            t, v = args
            cs = gp_Ax3(v.toPnt(), t.zDir.toDir(), t.xDir.toDir())
            T.SetTransformation(cs)
            T.Invert()
        else:
            t, ax, angle = args
            T.SetRotation(gp_Ax1(Vector().toPnt(), ax.toDir()),
                          angle * math.pi / 180.0)
            T.SetTranslationPart(t.wrapped)

        self.wrapped = TopLoc_Location(T)

    @property
    def inverse(self) -> "Location":

        return Location(self.wrapped.Inverted())

    def __mul__(self, other: "Location") -> "Location":

        return Location(self.wrapped * other.wrapped)

    def toTuple(
            self
    ) -> Tuple[Tuple[float, float, float], Tuple[float, float, float]]:
        """Convert the location to a translation, rotation tuple."""

        T = self.wrapped.Transformation()
        trans = T.TranslationPart()
        rot = T.GetRotation()

        rv_trans = (trans.X(), trans.Y(), trans.Z())
        rv_rot = rot.GetEulerAngles(gp_EulerSequence.gp_Extrinsic_XYZ)

        return rv_trans, rv_rot
Beispiel #11
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),
    )