* Base: Add TimeTracker
This adds TimeTracker utility that can be used to orchestrate code
with time measurements in an easy way and detect performance issues.
* Update src/Base/TimeInfo.h
Co-authored-by: Chris Hennes <chennes@pioneerlibrarysystem.org>
---------
Co-authored-by: Chris Hennes <chennes@pioneerlibrarysystem.org>
When a child (e.g. a Wall) of an ArchBuildingPart (e.g. of a Level)
had both 'Move With Host' and 'Move Base' enabled, it failed to move
the base (e.g. Line) of the child, and only displaced the child
itself (effectively ignoring the 'Move Base' setting).
Example project structure:
Level
|
+- Wall ('Move With Host' = true, 'Move Base' = true)
|
+- (base of Wall) Line
Export mesh object names as 'name' attribute in 3MF files according to
the 3MF specification. This allows downstream tools to identify objects
by their original FreeCAD names.
Changes:
- Moved Exporter::xmlEscape() to Base XMLTools::escapeXml() for shared XML entity escaping
- Update Writer3MF::AddMesh() to accept and output object names with default "" where no attribute will be added
- Updated all codepaths leading to 3mf exports to include the object name
Since we are linking to boost anyway, use boost function for case
insensitive string compare. While there, make affected methods accept
std::string arguments, which simplifies code a bit.
It can happen that TransactionFactory::createTransaction() fails to create a transaction object because an unsuitable type is passed
(like BadType) and returns a null pointer.
The calling instances (Transaction::addObjectChange, Transaction::addObjectDel, Transaction::addObjectNew, Transaction::addOrRemoveProperty)
do not check for a null pointer and thus cause a segmentation fault by dereferencing it.
To fix the issue change the above methods to explicitly handle a null pointer.
This fixes issue 21095.
Note: In this case it's caused by the class ViewProviderFace which on purpose isn't added to the type system so that its type will be BadType.
If the property is added to a view provider then in debug mode this will
cause a crash while in release mode this will cause undefined behaviour
because of a static_cast.
To fix crashes remove the assert() and replace the static_cast with
freecad_cast.
Put the reading of each expression of an object into a try/catch block. This is to avoid that all expressions of an object may be lost.
This mitigates the issue 19866
- FileOptionsDialog is only used in the 'save screenshot / save image'
codepath, and currently it doesn't set a directory to it defaults to
process CWD, which is surely not what the user wants.
- The load image codepath uses a custom QFileDialog instead of the
helper code in FileDialog, there doesn't seem to be a great reason for
this, although the helper doesn't have support for mime types it seems.
- I haven't changed the dialogs to 'set/store' the working directory. I'm
not sure this is desired as this isn't a 'normal' save/load operation.
- It would be ideal to remove the FileOptionsDialog in future. The
extended functionality could be turned into a separate dialog which
opens before or after the file chooser. This would allow native dialogs
to be used and would unify the code paths for file selection.
- Further, it would be nice to just merge at least the load image into
the existing import/open option, and to put 'save image' next to
'export', but those changes may be much more time consuming.
For now I've kept it simple. Let's see what others think.
* Menu text "Align Horizontal/Vertical Chain Dimensions" to match "Align Oblique Chain Dimensions"
* Menu text "Centerline Between 2 Faces" is not correct.
* Update button text "Replace References With Current Selection" to title case
* Change task panel title from 'Add offset vertex' to 'Offset Vertex'
* Correct text casing for 'Pick points' button
* Correct text casing for 'Pick points' and 'Edit points'
* Fix capitalization of task panel section title
* Correct text case for 'Escape Picking' button
* Update texts for centerline buttons to match menu texts
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>