Closed gumyr closed 1 year ago
Currently Mirror
uses transform_geometry
for which the comment says: "WARNING: transform_geometry will sometimes convert lines and circles to splines, ..."
A simple solution for mirror changing geom_type could be (similar to CQ):
def __init__(
self,
*objects: Union[Edge, Wire, Face, Compound],
about: Plane = Plane.XZ,
mode: Mode = Mode.ADD,
):
context: Builder = Builder._get_context(self)
context.validate_inputs(self, objects)
if not objects:
objects = [context._obj]
self.objects = objects
self.about = about
self.mode = mode
# scale_matrix = Matrix(
# [
# [1.0, 0.0, 00.0, 0.0],
# [0.0, 1.0, 00.0, 0.0],
# [0.0, 0.0, -1.0, 0.0],
# [0.0, 0.0, 00.0, 1.0],
# ]
# )
# localized = [about.to_local_coords(o) for o in objects]
# local_mirrored = [o.transform_geometry(scale_matrix) for o in localized]
# mirrored = [about.from_local_coords(o) for o in local_mirrored]
mirrored = [copy(o).mirror(about) for o in objects]
context._add_to_context(*mirrored, mode=mode)
super().__init__(Compound.make_compound(mirrored).wrapped)
But I guess you had a good reason for selecting a different approach.
The Shape.mirror()
method (as follows) also transforms the geometry:
def mirror(self, mirror_plane: Plane = None) -> Shape:
if not mirror_plane:
mirror_plane = Plane.XY
transformation = gp_Trsf()
transformation.SetMirror(
gp_Ax2(mirror_plane.origin.to_pnt(), mirror_plane.z_dir.to_dir())
)
return self._apply_transform(transformation)
I haven't tried it but I wouldn't expect there would be a difference in behaviour. Is there something I'm missing?
I gave it a try with the above change and the examples returns a shape where both the top and the bottom face are of geom_type "PLANE"
The docs for gp_Trsf (https://dev.opencascade.org/doc/refman/html/classgp___trsf.html) say:
This transformation never change the nature of the objects.
On the other side, if we look at transform_geometry
(which is currently used in class Mirror
), it uses BRepBuilderAPI_GTransform
The transformation to be applied is defined as a
gp_GTrsf
transformation
and gp_GTrsf says:
Be careful if you apply such a transformation to all points of a geometric object, as this can change the nature of the object and thus render it incoherent! Typically, a circle is transformed into an ellipse by an affinity transformation. To avoid modifying the nature of an object, use a gp_Trsf transformation instead, as objects of this class respect the nature of geometric objects.
And Shape.mirror
uses BRepBuilderAPI_Transform
which uses gp_Trsf
and as such my expectation is that it keeps planes as planes.
That is at least how I understand the OCCT docs. But maybe I miss something ...
Thanks @bernhard-42, I followed your advise and used:
mirrored = [copy.deepcopy(o).mirror(about) for o in objects]
(and hence avoided gp_GTrsf
) to do the mirror operation.
(Note that copy() is depreciated)
The
Mirror
operation changes thegeomtype
from PLANE to BSPLINE.Rectangle
on the construction_face isn't making a square.Extrude
isn't creating a new Solid.