Fixes#16333.
Follow-up of #19487.
* The functions have been made nesting-aware. New objects are put in the same container (Group, Part) as the original objects. As a consequence for some operations the original objects must be in the same container as well.
* New objects receive the visual properties of the original objects. This is not always perfect. For example when upgrading to multiple wires there is currently no check to see which edge came from which orginal object. The fact that the `format_object` function is called from the Draft `make*` functions is problematic here. If construction mode is active `make_wire` puts new objects in the construction group and we don't always want that. This has been solved with a workaround (see 'cludge' in the code).
* The 'de-parametrize' downgrade option has also been enabled for features of PartDesign Bodies that have the `Profile` property.
* Before deleting objects there is a check to see if they are in use elsewhere (`InList` check). Base objects of arrays are not deleted if they are visible. If a PartDesign Body, or an object inside a Body is selected, the whole Body is deleted.
* The force options did not work for functions that take a single object.
* The `getShapeFromMesh` function in ArchCommands.py could return a solid that was not closed. A check for that has been added.
* Draft: gui_utils.py fix error in select function
PR #18795 changed the select function to also handle tuples. This PR adds a check to ensure the referenced objects in the tuple still exist before calling `Gui.Selection.addSelection()`.
* Draft: make move, rotate and scale commands link-aware
Fixes#12836.
Fixes#15681.
These changes are presented as a single ('big') PR because the mentioned commands have several similarities. Working on them seperately would have made less sense.
The commands have been made 'link-aware' meaning they can now handle Links and objects in linked containers.
This required several changes in the following main files. For each command all options are handled by a single function now (the `move`, `rotate` and `scale` functions). This was the only reasonable solution to correctly handle nested placements. As a result there is no longer a need to build very complex 'cmd' strings in the gui_*.py files (which is a good thing IMO).
Main files:
* move.py
* rotate.py
* scale.py
* gui_move.py
* gui_rotate.py
* gui_scale.py
* gui_trackers.py
The following files have also been updated:
* Draft.py: Imports updated.
* DraftGui.py: If `CopyMode` is changed the ghosts have to be updated. The move and rotate commands now also show previews of movable children. But since those are not copied they should be removed from the ghosts if `CopyMode` is changed to `True`.
* utils.py: Some helper functions have been added. An existing helper function (only used internally) has been renamed.
* gui_utils.py: The `select` function has been updated to accept a list of tuples to allow the reselection of nested objects.
* clone.py: A new property `ForceCompound`, necessary for non-uniform scaling, has been added.
* join.py: The `join_wires` function now returns the resultant wire objects.
* task_scale.py: Updated to allow negative scale factors. Support for `SubelementMode` preference added.
* dimension.py: `transform` methods added.
* layer.py: `get_layer` function added.
* svg.py: Updated to use `get_layer`.
* view_text.py: Instead of two added `coin.SoTransform()` nodes the main transform node is used instead. This was done so that ghosts of Draft Texts can be handled properly without requiring dedicated code in gui_trackers.py.
Notes:
* Support for "App::Annotation" is limited. Only their `Position` is handled (by the move and rotate commands).
* Support for "Image::ImagePlane" has been removed from the scale command. The object has its own calibrate feature (see https://wiki.freecad.org/Std_Import).
* Copies and clones are always created in the global space.
* Fix several unit test issues.
* Reset value that was changed while testing
* Rebase and update test_modification.py
* Reintroduce scaling of image planes
Uses new material system for appearance
Each feature object now has a property called ShapeMaterial that
describes its physical properties. If it has a shape, it has a
material.
The ShapeColor attribute is replaced by a ShapeAppearance attribute.
This is a material list that describes all appearance properties, not
just diffuse color. As a list in can be used for all elements of a
shape, such as edges and faces.
A new widget is provided to allow the user to select materials in a
consistent fashion. It can also launch the material editor with its
more advanced capabilities.
These messages were perhaps originally intended as a debuggin aid but now add clutter to the output panes. Remaining messges are mostly the result of methods to display attributes of an object (which one could call from the Python console) or actually provide some information which would not be obvious from the circumstances
The command now applies all style properties from `utils.get_default_annotation_style()` and `utils.get_default_shape_style()`.
Additionally: minor improvements to gui_setstyle.py.
* Added handling of DefaultShapeVertexColor, DefaultShapePointSize, DefaultAnnoLineColor and DefaultAnnoLineWidth preferences.
* Rearranged the task panel.
Additionally the DefaultDrawStyle and DefaultDisplayMode preferences are now applied by format_object in gui_utils.py.
* DisplayMode controlled by new pref DefaultAnnoDisplayMode. This replaces the old dimstyle pref.
* LineSpacing pref is now used when creating annotations. Will be added to prefs ui later.
* format_object no longer changes FontSize as this conflicted with the height parameter in the make_text function.
* make_text function updated.
This PR replaces the showSnapBar and hideSnapBar preferences with a single new preference: SnapBarShowOnlyDuringCommands.
Additonally:
Improved some param observer callbacks.
Additionally:
* Added the DimShowLine preference. Layout of the tab will be updated later.
* Improved handling of DraftAnnotationScale preference: catch division by zero and use it for the default anno style.
The tolerance function now derives its value from the precision preference.
Additonally:
Removed the epsilon() function. It did not make sense and was not used.
As suggested by @Vanuan. and already implemented in new experimental BIM Wall: 1084a4b0a9
Draft: updated Draft Edit
thanks to the suggestions by @Vanuan
Draft: further bugfixing and improvements in Draft_Edit
Draft: moved Draft_Edit preview code into respective GuiTools
This includes `gui_utils`, `init_draft_statusbar`, `init_tools`,
`messages`, `todo`, `translate`, `utils`.
These are added to the `draftutils` Doxygen group
so that the functions contained in each module are listed
appropriately in the automatically generated documentation.
These functions were previously in `draftutils.utils`,
and are related to grouping objects and finding objects
inside groups. These include `get_group_names`, `ungroup`,
`get_windows`, `get_group_contents`, `get_movable_children`.
These are imported in the main `Draft.py` module, so compatibility
is retained.
Modules which use these functions are updated; these include
Gui Commands like `Move`, `Rotate`, `Scale`, `AddToGroup`,
as well as objects like `DrawingView` and `Shape2DView`,
and `ViewProviderClone`.
The code inside the `importDXF` module is also updated.
The Arch Workbench uses many of these functions
but it does so from the `Draft` namespace, so these edits
don't change the situation for these commands.
The old `convertDraftTexts` function was moved from the `Draft.py`
module to the `draftutils.utils` module; however, here it is
not possible to use because the `makeText` function
is not accessible. Therefore, the function is moved to
`draftmake.make_text`.
These style properties are used by `ViewProviderDraftAnnotation`
and by the Gui Command `Draft_AnnotationStyleEditor`.
Therefore, they are moved from `draftguitools.gui_annotationstyleeditor`
module to the `draftutils.utils` module, so that they
are in a central location where they won't cause circular
dependencies.
Also add `find_doc` to be able to test the existence of an
active document before searching for the object.
These can be used in the make functions of most modifier commands.