This commit addresses two regressions in the MultiCommon feature:
1. Computation Logic: Fixed an issue where the common operation was
calculated as the intersection of the first shape with the union of
the rest (the default behavior of makeElementBoolean). It now
correctly computes the intersection of all shapes sequentially.
2. Compound Handling: Added logic to expand a single compound input
into its constituent shapes. Previously, a compound was treated
as a single entity, leading to incorrect intersection results.
To maintain backward compatibility, a hidden 'Behavior' property is
introduced. This ensures that documents created in FreeCAD 1.0, which
rely on the previous behavior, continue to render as originally
intended while new objects use the corrected logic.
* Part: Fix mirror() regression with non-identity Placement
The makeElementMirror() function incorrectly extracted and pre-multiplied
the shape's Location with the mirror transform. Since BRepBuilderAPI_Transform
already handles shapes with Location correctly, this resulted in the placement
being applied twice, producing incorrect results for shapes with non-identity
Placement.
Fixes#20834
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Part: Add regression test for mirror() with Placement
Adds testTopoShapeMirrorWithPlacement to verify that mirror() produces
identical results regardless of whether the shape is positioned via
direct coordinates or via Placement.
This test would have caught the bug fixed in the previous commit where
shapes with non-identity Placement produced incorrect mirror results.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix regression test for mirror with Placement
The test was incorrectly trying to create equivalent boxes using
different methods that don't actually produce the same geometry.
Part.makeBox with a direction vector is not equivalent to setting
a Placement with rotation.
Fixed to use the correct approach that demonstrates the actual bug:
- Method 1: Box with geometry at (0,30,0), identity Placement
- Method 2: Box with geometry at origin, moved via Placement
Both should produce identical mirror results, which they now do
with the makeElementMirror() fix.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Timothy Miller <theosib@zeromark.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* PartDesign: Add interactive gizmo for draft operation
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
---------
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
* Added support for cylindrical surfaces
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Removed unnessecary sign
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Reverted change
---------
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit registers last rendered shape within the ViewProvider for
Part objects and short-circuits the visuals recomputed if shape did not
change.
Co-Authored-By: Kacper Donat <kadet1090@gmail.com>
* Part: Fix Part_Extrude taper angle regression for internal faces
The taper angle for holes (inner wires) in `Part_Extrude` was not being
negated after the toponaming refactor, causing internal faces to taper
in the wrong direction compared to v0.21.2.
The original makeDraft function correctly handled inner wires by:
- Negating taper for all inner wires in Part_Extrude
- Negating taper only for multi-edge inner wires in PartDesign
This logic was controlled via an isPartDesign function parameter.
When makeElementDraft was introduced for toponaming support, it was
designed to use innerTaperAngleFwd/innerTaperAngleRev fields that were
never ported from realthunder's branch. The cleanup (commit c31ebeeee6)
removed references to these non-existent fields, leaving makeElementDraft
with no inner wire taper handling at all.
So, this fix ports the makeDraft inner wire logic to makeElementDraft by
adding the flag, and counting wires and then triggering proper angle
flip depending on the flag/wire situation.
---------
Co-authored-by: Chris Hennes <chennes@pioneerlibrarysystem.org>
This commit introduces PreviewUpdateScheduler class that is responsible
to schedule the true recompute of the preview. View Providers (or other
components) can use this service to ask for the preview recompute to
happend at a time that is convinent for a program and that won't impact
performance.
The provided implementation uses Queued Connections in Qt to calculate
preview essentially on next run of the event loop. It allows business
logic in FreeCAD (like property propagation) to execute fully and then
recompute preview once. This greately reduces number of recompute calls
for previews.
* Part: Fix orientation of internal shells of a solid
If a solid consists of multiple shells then it can happen that the
internal shells have incorrect orientation that leads to a broken solid.
This fixes issue https://github.com/FreeCAD/FreeCAD/issues/24994
* Part: Add method Feature::fixSolids
This method explicitly checks for solids with the error
'BRepCheck_EnclosedRegion' that means that internal shells of a solid
are wrong.
Using ShapeFix_Solid fixes the solid.
---------
Co-authored-by: wwmayer <wmayer@freecad.org>
* [Surf]provide geometry to Measure
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
---------
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
* PD: fix gizmo direction when the calculated point lies outside the face
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
---------
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
* Part: Toposhape: fix regressions due to changes in getElementTypeAndIndex
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update TopoShape.cpp
* Update TopoShape.cpp
* Update TopoShape.cpp
* Update TopoShape.h
---------
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
* Gui: Prevent whole-object highlight when picked list is enabled
Removed the logic that forced `onTop=1` when `needPickedList()` is true
in View3DInventorSelection. This was causing the entire object to be
highlighted instead of just the selected sub-element when the "Picked
object list" option was enabled.
* Part: Remove `needPickedList` mat override to prevent rendering artifact
The `needPickedList` check in `SoBrepFaceSet` was triggering
unnecessary material override processing that caused face clipping
artifacts when the "Picked object list" option was enabled in Selection
View. This check has been removed as the picked list functionality works
independently of the rendering path.
The `needPickedList` check in `SoBrepFaceSet` was triggering
unnecessary material override processing that caused face clipping
artifacts when the "Picked object list" option was enabled in Selection
View. This check has been removed as the picked list functionality works
independently of the rendering path.
* Part: Preserve child visibility when deleting compound copies
Currently, if we have a FC document two compounds, when one of them is a
copy of the other containing same children and we delete the copy
compound to keep the children, their visibility state changes.
The cause of that was a part of code in `onDelete()` method, which was
unconditionally calling `showViewProvider()` on every child object,
without checking if other compounds still claim those children or what
the current visibility should be.
So this patch adds parent-checking logic before changing visibility. The
visibility is only updated if the child is truly orphaned. So in the
scenario where we have the children referenced STILL by some compounds,
the visibility remains unchanged. It only changes when child has truly
no parents.
* Part: Use std::ranges::find for finding parent
* Fix rotation expression handling
- Make added rotation angle unit the same as the original expression unit
- Keep rotated angle expressions within the accepted [-180, +180] range
Calling BRepMesh_IncrementalMesh repeatedly would accumulate BRep_CurveRepresentation instances attached to the BRep_TEdges of the shape. We now clean added triangulations before adding a new one, which improves performance in the long run.
Co-authored-by: Kacper Donat <kadet1090@gmail.com>
* Part: fix Part_EditAttachment nesting handling
Fixes#26264.
The previous 'fix' (#25887) did not consider that the object to-be-attached may not be in the global space.
The code in this PR has been tested on the forum:
https://forum.freecad.org/viewtopic.php?p=862968#p862968
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
---------
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This introduces much faster CenterOfMassProvider#supports method that
can be used as cheap pre-check to see if the object supplied could have
the center of mass and so delay the domputation to a moment where it is
actually needed.
* Part: TopoShape make getElementTypeAndIndex more robust
* Part: Add unit tests for new regex
---------
Co-authored-by: Chris Hennes <chennes@gmail.com>
This method can be used to bake in transform directly into geometry.
Normally the setTransform or setPlacement methods only store additional
positional data within the shape without changing the actual geometry.
So if we have some geometry placed at 0,0,0 and we want to have few
copies of that shape the goemetry stays intact but additional transform
is stored. This method can be used to alter the gometry and reset the
transform to identity. It helps with model stability, as not every
method correctly handles that additional transform metadata.