Mirroring an assembly

18 views
Skip to first unread message

Zbyněk Winkler

unread,
Mar 1, 2024, 9:38:34 AMMar 1
to cadq...@googlegroups.com
Hello,

Is there a way to mirror an assembly? I am looking for something akin to assy.toCompound().mirror(), but without converting to compound.
Thanks.

Zbyněk

Lorenz

unread,
Mar 2, 2024, 1:39:44 PMMar 2
to CadQuery
I'm experimenting with the following (limited testing).  Does it work for you?

def mirrorassy(
    assy: cq.Assembly,
    plane: Union[Literal["XY", "YX", "XZ", "ZX", "YZ", "ZY"], VectorLike] = "XY",
    point: VectorLike = (0, 0, 0),
    loc: Optional[cq.Location] = None,
):
    loc = assy.loc * loc if loc else assy.loc

    if assy.obj:
        if isinstance(assy.obj, cq.Shape):
            obj = assy.obj
        else:
            obj = cq.Compound.makeCompound(
                s for s in assy.obj.vals() if isinstance(s, cq.Shape)
            )
        obj = obj.moved(loc)
        obj = obj.mirror(plane, point)
        assy.obj = obj

    assy.loc = cq.Location()

    for ch in assy.children:
        mirrorassy(ch, plane, point, loc)


# create assy
# ...

mirrorassy(assy, "XZ")

Zbyněk Winkler

unread,
Mar 2, 2024, 5:00:28 PMMar 2
to Lorenz, CadQuery
Thanks. It worked. Kind of. It looks perfect in the visualization. An interesting idea using moved to merge loc into the obj and then just use mirror and let opencascade do all the work. But then we lose the locations. I am going to need them separate from the shapes for later CAM. Any ideas on how to do that? I have the feeling that it should be possible to instead transform the mirroring info through the locations in the assembly down to the individual shape, do the mirror, and transform back.

In my current specific case I`ll most likely be able to hack it using OBB since the parts are going to be board cuts using a router so in the end they are the same parts which can only be flipped upside down since not all cuts are all the way through. But it would be super-cool to keep the locations separate from the shapes in the general case.

Zbyněk

--
cadquery home: https://github.com/CadQuery/cadquery
post issues at https://github.com/CadQuery/cadquery/issues
run it at home at : https://github.com/CadQuery/CQ-editor
---
You received this message because you are subscribed to the Google Groups "CadQuery" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cadquery+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/cadquery/0c1fb2cb-2d91-42f0-90e6-d2e354f3c1a2n%40googlegroups.com.

Lorenz

unread,
Mar 3, 2024, 9:50:37 AMMar 3
to CadQuery
Hi Zbyněk,

Here is a version that does not modify the Assembly.obj - only the locations.

import cadquery as cq
from typing import Union, Literal, Optional
from cadquery.occ_impl.geom import VectorLike


def mirrorassy(
    assy: cq.Assembly,
    plane: Union[Literal["XY", "YX", "XZ", "ZX", "YZ", "ZY"], VectorLike] = "XY",
    point: VectorLike = (0, 0, 0),
    loc: Optional[cq.Location] = None,
):
    loc = assy.loc * loc if loc else assy.loc

    if assy.obj:
        if isinstance(assy.obj, cq.Shape):
            obj = assy.obj
        else:
            obj = cq.Compound.makeCompound(
                s for s in assy.obj.vals() if isinstance(s, cq.Shape)
            )
        c0 = obj.Center()

        obj = obj.moved(loc)
        obj = obj.mirror(plane, point)
        assy.loc = cq.Location(obj.Center() - c0)
    else:

        assy.loc = cq.Location()

    for ch in assy.children:
        mirrorassy(ch, plane, point, loc)



Note that it is not optimal. Better to cache compounds as in the toCAF method.  Another idea is to cache compounds on the Assembly itself. Then if exported to say both STEP and glTF (or mirrored then exported) the compounds can be reused.
Reply all
Reply to author
Forward
0 new messages