==================================================================================
Why?
if lastDoF<0, then an over-constrained situation has ensued and geometry is not to be updated, as geometry can not follow the constraints.
However, solver information needs to be updated.
Solution:
Just trigger a constraint change so that signaling is sent to ViewProviderSketch via boost and the solver information updated, using
Constraints.touch().
==================================================
This fix enables usage of the Eigen SparseQR starting in Eigen-3.3. It optimizes the code enabling it
to work with the new assignation interface of Eigen-3.3, which is more strict than that of Eigen-3.2.
It provides the same optimization for DenseQR code, and omits the extraction of the Q matrix in DenseQR
as this is not used anywhere else.
[NOTE: This is only to be merged after Debian has updated the Eigen-3.3-alpha1 package]
See:
http://forum.freecadweb.org/viewtopic.php?f=10&t=12769&start=30#p104740https://forum.kde.org/viewtopic.php?f=74&t=129115
- basic infrastructure for handling of expressions
- port the unit properties editor to support expressions
- port placement editor to support expressions
- expressions for double spinbox
- expressions in sketch constraints
=========================================
The problem:
Mirror stopped working.
How to reproduce:
Select a sketch, and apply "Mirror Sketch" from the menu.
Why?
With the introduction of expressions, mirror sketch stopped working. The reason is that mirror functionality did use the "clone" function to make copies of constraints
and then modify their values. After expessions introduction, which introduces a unique tag per constraint, this copy was regarded as a "rename" of the original constraint
as they shared the unique tag.
Fix?
New function "copy()" for a constraint, that copies all the content but the tag.
========================================================
This is an advanced setting just for allowing increased choices to power users that have problems with a given sketch and want to
test different flavours of DogLeg algorithm.
This commit does not change the default behaviour of FreeCAD. It is only intended to give more options to power users.
The advanced solver configuration is extended to support three different Gauss-newton steps for DogLeg:
FullPivLU => h_gn = Jx.fullPivLu().solve(-fx);
LeastNormFullPivLU => h_gn = Jx.adjoint()*(Jx*Jx.adjoint()).fullPivLu().solve(-fx);
LeastNormLdlt => h_gn = Jx.adjoint()*(Jx*Jx.adjoint()).ldlt().solve(-fx);
This setting is applied only to DogLeg. It is applied to DogLeg as normal or redundant solver, if DogLeg is the selected solver.
Selecting a solver different from DogLeg for both normal and redundant disables the setting.
We have been told:
https://forum.kde.org/viewtopic.php?f=74&t=129439#p346104
that our default Gauss-Newton step in DogLeg may not be adequate in general (we generally deal with underconstraint systems
unless we have a fully constraint sketch, and even then it is many times overconstraint at least for redundant solving).
We have been told that maybe these LeastNorm options are more suitable for us (performance set aside). This enables you as power
user to test if it works fine with FreeCAD.
===================================================
This commit sets the sketch size multiplier OFF by default (so the number of iterations DogLeg/BGFS/LM is not sketch size dependent).
In complicated sketches having a high number of parameters, with sketch multiplier on, the number of iterations is extremely high (100 parameters*100 iterations => 10000 iterations).
The idea of disabling this comes from tests performed by DeepSOIC and from my own experience using the Sketcher. In general
sketch multiplier makes FreeCAD unresposive (very high amount of iterations, not a real freeze) in big sketches so that users
end up killing the application. This is preventing the users from taking appropriate action, Developers from getting the information of the failure and
users angry.
The idea is that even for complicated sketchs N iterations (100 by default) should be enough to converge, if it is ever going to converge. Experience will tell us
if we have to increase this number in the range [100-300]. 100 iterations in complicated dossiers is in my experience generally under 30 seconds.
N.B.: This commit does not change the defaults stored in your computer, so if you have the sketcher multiplier on, the advanced solver dialog will still enforce this local setting. You
may disable it or click the "defaults" button to disable the sketcher multiplier.
===================================================================
It allows to export the c++ code to create a subsystem with the same information as the one solved using LM/DL/BGFS.
In this commit the functionality is disabled (for production).
To enable the functionality uncomment this line in planegcs/Constraints.h:
//#define _GCS_EXTRACT_SOLVER_SUBSYSTEM_
When enabled, upon solving with LM/DL/BGFS, the c++ code to generate the subsystem is added to a subsystem.txt that is created in the FreeCAD
execution directory.
Note that the file is created in append mode, so it will append all normal/redundant solvings until the file is deleted.
The resulting code can be directly pasted into a project similar to:
https://github.com/abdullahtahiriyo/Eigen_LUPiv_Convergence
Such a project only has libeigen as external dependency.
=========================================================================
This fixes issue:
http://www.freecadweb.org/tracker/view.php?id=2281
Discussed in:
http://forum.freecadweb.org/viewtopic.php?p=101910#p101910
How to reproduce?
With Auto-Update mode unchecked, execute the sequence in the bug tracker. You will reach to a geometry assembly successfully solved that can not be moved.
Why?
The coincident constraint is partially redundant within the meaning of redundancy of the solver.
The solve within "addconstraint" in SketchObjectPy.cpp causes the geometry to move to meet the coincident constraint.
At the end of the solve, the initial solution used in diagnostics is no longer valid (the geometry moved). This causes a subsequente move not to be executed.
The Solution:
Recalculate just the initial solution after the addition.
=====================================
When the solver converged (but did not succeed) or when the solver succeded but the solution is not OCC-valid, no error message was shown in the solver messages dialog.
=====================================================================
Issue:
http://freecadweb.org/tracker/view.php?id=2292
Constraints dissapear after a sketch loses support
Steps To Reproduce:
1. Make a sketch on a face.
2. Constrain it
3. Select "reorient sketch"
4. Do you want to lose support? Yes
5. Click cancel on the reorientation dialog.
6. Enter edit mode: No constraints...
Why?
GeoUndef not checked when deleting all external geometry (on dettaching from the support).
Solution:
Check for GeoUndef.
===================================================
The bug was introduced by myself here:
47c0859c1b
[code]
void SketchObject::onDocumentRestored()
{
try {
- rebuildExternalGeometry();
+ if(Support.getValue()) {
+ validateExternalLinks();
+ rebuildExternalGeometry();
+ }
Constraints.acceptGeometry(getCompleteGeometry());
}
[/code]
The issue is that "rebuildExternalGeometry" calls "rebuildVertexIndex". So for any sketch not having external geometry, if you open it, select everything and hit del, you will have a crash because
I effectively removed the creation of the index in this dossier. You won't have one if you do anything rebuilding the index before hitting del, like creating geometry, though.
================================================
Issue reported inter alia here:
http://forum.freecadweb.org/viewtopic.php?f=10&t=12380#p99456
How to reproduce:
1. Make an external geometry hexagon (make a hexagon, pad it, make a sketch on a hexagonal face and make all the lines external geometry)
2. Box select the external lines and press "del"
On the first pressing of "del" 3 lines were deleted and 3 remained, select again, on the second press 1 remains, select again, on the last press all are deleted.
Why?
Internal and External geometry were handled together in a single set. Group deletion of geometry is effected starting from the highest index,
so that upon deleting an element, the index of the remaining elements does not change. Handling both groups together caused that the external geometry
was actually deleted on the inversed order (as they are (decreasing) negative values for representation, but increasing positive indexes in the external geometry array).
Solution:
Internal and External geometries are handled separatedly
+ fix SoAutoZoomTranslation and SoZoomTranslation to get correct scaling factor
(do not rely on active view because this can be the wrong one and thus delivers wrong results)
=================================================================
First bug: Inability to create links to external geometry as described here:
http://forum.freecadweb.org/download/file.php?id=16668
Second bug: FC crashes on changing the support after having imported external geometry as described here:
http://forum.freecadweb.org/viewtopic.php?f=10&t=12380
and solving this ticket:
http://www.freecadweb.org/tracker/view.php?id=2225
Solution to first bug:
If for some reason a sketch ends up having a list of external geometries (property) that can not be recreated (rebuilt),
they remain latent, do not show the external elements in the elements widget or in the screen and prevent adding the
elements again.
In cases where the saved file contains invalid external geometry links (which will give raise to a handled exception that would prevent external geometry creation),
this condition gets detected during restore and the invalid links are deleted before external geometry creation, so as to allow the rest of external links to be recreated.
Solution to second bug:
It is also related to invalid external links (the link was existing, but upon change on the support, it is possible that an external edge is no longer valid, reduction of edges in support).
This situation is detected upon entering into edit mode, and the invalid ones are deleted.
Note that there is still the possibility for the user to remap an invalid sketch BEFORE editing, if the remapping is successful, it may not be necessary to delete links (all depends on the
specific case).
==============================================================================
What is this?
method
getCoincidentPoints
actually only included (as indicated in the documentation comment) those points coincident by a single constraint.
That is not "all the coincident points".
However some methods currently using it are expecting exactly that (coincident points linked by a single constraint).
A new method is introduced:
const std::map<int, Sketcher::PointPos> getAllCoincidentPoints(int GeoId, PointPos PosId);
that provides all the points coincident with the given one, directly (via a single constraint) or indirectly (via multiple coincident constraints).
The old method is renamed to:
getDirectlyCoincidentPoints
So as to have a more meaningful name to differentiate between both methods.
======================================================================
1. SketchObject::arePointsCoincident upgraded to check for indirect coincidence.
2. Coincidence constraint creation now checks for indirect coincidences and avoids
creating redundant coincidence constraints (for example during box selection).
=====================================================================================
This fixes a bug related to:
http://www.freecadweb.org/tracker/view.php?id=2093
that during creation of a geometric element if a vertical/horiz autoconstraint is to be enforced, it is not enforced if the endpoints of the geometric element under creation are
coincident with external geometry.
According to the discussion here:
http://forum.freecadweb.org/viewtopic.php?f=10&t=12254&sid=eacf5bdee068cb71cc54dc5a62a6849d&start=20#p99359
this fixes the bug.
It does not fulfil the request on the ticket as it was decided to still allow an explicit addition of a vertical/horizontal constraint, as
it may be needed in some cases and the user expects to be able to add them, even if it will lead to an overconstrained sketch.
How to reproduce?
1. Create a rectange
2. Pad it
3. Create a new sketch on a face
4. link two corners as "external geometry" (but not the ones of a diagonal)
5. Create a line coincident with the first and second corners, so that the line is horizontal or vertical
In master it will force horiz or vert leading to a overconstrained sketch.
With this patch, the horiz/vert will not be enforced in this case.
==================================================================
A recent improvement was to allow to create an object (several geometric elements) as construction lines
by providing an additional parameter as true (that defaults to false).
This introduced a bug, that when a list of geometries mixing construction and normal lines was added (with the parameter as false),
construction lines would be converted to normal lines.
This fixes the bug.
===============================================
Support for mirroring a full sketch.
A dialog appears allowing to select X, Y axis mirroring or mirroring about the origin of the sketch.
=========================================================
This commit provides with a single toolbar button to select between a copy and clone.
Copy just copies the constraints.
Clone modifies the dimensional constraints to geometric constraints, so that the constrained geometry follows the changes in the original object.
=============================================================
This commit allows the user to select in advance whether he wants a simple copy or a clone.
This involves substitution of dimensional constraints in the copies by equality and parallel constraints.
Terminology change for Arrays, now it is Rectangular array
==========================================================
- Support for copying geometric elements in the sketcher with Ctrl+C (or using the still missing icon). It will show you the vector of displacement from the
"reference point". The reference point can be chosen by the user (although it is not necessary to do it so) by making the point the user wish to be the reference point
the last selected element. It conveniently incorporates "autoconstraints", so that you can make this point (the one of the copy) directly coincident with any other point in the sketch.
- Python 2D array command modified to lock elements position using construction lines and constraints.
- Support for different spacing between u and v directions (the direction of the cols and the direction of the rows).
- Support to avoid copying DistanceX and DistanceY constraints when used for locking a point. This means that if the geometry that you copy(array) is
fully constraint, the resulting 2D array is also fully constraint.
- UI support for creating 2D linear arrays in the sketcher.
- Bug fix in python addArray, wrong line copy startingpoint calculation fixed.
How to create a 2D array in the sketcher:
1. Select your geometric elements.
2. Click the button
3. Fill in the rows/cols and preferences on spacing and constraining each element of the array
4. Click Ok
5. Define the direction of the cols of the array and click
========================================================
For a while End-to-endpoint tangency is implemented via AngleViaPoint constraint. The code was not recalculating the "value" of the constraint in this case.
This also forces to set the geometry first and constraints afterwards, as the AutoLockTangencyAndPerpty function requires a valid GeoId to operate (not a big deal anyway).
Correction of the condition to allow the symmetry when a single line is mirrored about a point pertaining to a geometric element.
======================================================
Two new python commands (no UI yet).
Copy: Copies the geoids in a list by a displacement given by a Vector3d:
App.ActiveDocument.Sketch001.addCopy([0,1,2,3,4,5],App.Vector(150,150,0))
Array: Copies the geoids in a list cols times in the displacement vector
direction and rows times in the perpendicular to the displacement vector:
App.ActiveDocument.Sketch001.addArray([0,1,2,3,4,5], App.Vector(150,150,0),3,4)
N.B.: You need to recompute or solve to update the view
App.ActiveDocument.recompute()
or
App.ActiveDocument.Sketch001.solve()
=====================================
Creates geometry symmetric to the selected one with respect to the last selected point or line.
It does not support the following constraints:
- Angle
- Horiz/vertical distance
- SnellLaw
Horizontal and Vertical (directional) dimensions removed from the the copying process when created
on a single edge (by picking one edge instead of two points), i.e. Constraint involving only one GeoId at "First".
=============================================================
http://forum.freecadweb.org/viewtopic.php?f=10&t=11341&start=80#p92820
...I already have a minor bug, if you insert a conflicting dimensional constraint,
the solver information is not updated, the work-around is to hit "Manual Update".
=========================================================================
What?
Sometimes this widgets where out of sync
Why?
Under the update only when it is redrawn policy, sometimes only one of them, i.e. the one associated with the property
triggering the updateData was updated.
Solution:
Both are updated after every redraw.
It also complements the previous bug fix related to crash on deleting, by updating the widgets to account for the deleted geometry.
==========================================================
Fixes the one reported by JMG here (Thanks!!):
http://forum.freecadweb.org/viewtopic.php?f=3&t=11508#p92693
Why?
- The newly introduced redrawing policy requires that the solver geometry matches in number the sketchobject geometry.
- Most (all) problems with updateColor or getGeometry returning a null pointer are related to an out of sync between UI geometry and SketchObject geometry.
General solution:
- In other bugs, a missing "solve()" is the problem, once the solver and sketchobject geometries have the same number, an SketchObject::OnChanged triggers
a VPSketch::draw (via VPSketch::updateData) which updates the UI geometry to match SketchObject geometry and then the problem does not arise.
Particular solution:
- In this bug, the problem is not a missing solve, but the fact that the solving was not succesful and did not synchronize the geometries, however triggering a
draw() on unsuccessful solving, syncronizes the UI geometry with the SketchObject geometry and the crash is gone.
=======================================
The SparseQR is set as default method. However, in accordance with the previous commit, only if a new enough Eigen library is present will SparseQR be executed.
If the library is old and SparseQR can not be reliably used, FC will automatically fall back to use DenseQR.
This ensures that users that have a new enough library > 3.2.2 will benefit from the performance increase, while the users that use older library will still have
the same performance as in legacy FC.
==========================================
For Eigen>=3.2.2 SparseQR is compiled in
For older versions SparseQR is not compiled in and if the option is selected FC gives a warning in the console and falls back to DenseQR.
This ensures that a user can get a sketch solved and work normally even if SparseQR is selected and the Eigen version is too old to support SparseQR.
================================================================
A new parameter added to the form in order to control how low a value should be
to be considered zero (how high a value shall be to be accounted for in rank calculation)
Debug for QR pivot threshold is also added.
===================================
Eigen currently only provides multithread for matrix products. It has been reported that it is even slightly slower than single-thread.
Therefore, temporarely the code is commented out. If Eigen ever implements multithread for QR decomposition, then it will make a lot of
sense to enable this.
==================================================================
It allows the view sketch perpendicular button to be active during continuous mode creation (and if activated does not exit the continuous mode).
Feature requested:
http://forum.freecadweb.org/viewtopic.php?f=10&t=11051&start=30#p92256
=============================================
EigenQR branch 3.2 with debug code fails an assertion. The result is generally ok if we disable the assertions, however it
eventually leads to memory leakage.
This commit reenables Eigen's assertions when in debug mode, and sets dense QR as default QR algoritm until Eigen's issue is solved.
==================================================
- ternary operator usage was making BFGS not to iterate
- Amount of debug information for BFGS increased
============================================================
This enables to exit the sketch by clicking the corresponding toolbar icon, even when in creation mode, i.e.
with a drawHandler active.
Requested here:
http://forum.freecadweb.org/viewtopic.php?f=10&t=11051&start=30#p92181
===============================================
- Increased solver debug
- Changing default values from float to string, as float has "only" a precision of 12 decimals.
- Default values as macros
===========================================
- Improvement Debug added to redundant solving in Iteration Mode, to show when just one iteration solved the system
- Fix wrong QR information on empty sketch
===================================================
I makes the advanced solver taskbox by default disabled (not shown) and provides
a setting in Preferences->Display->Sketcher to enable it.
==================================================================================
The solver has been adapted to use Eigen's SparseQR QR decomposition algorithm. The original
Dense QR implementation is maintained and can be selected using the Advanced Control TaskBox (see below).
The use of SparseQR provides over an order of magnitude improvement in solving time in complex sketches due to
the Sparse nature of the Jacobian matrix of the system of equations.
The solver advanced control is a new TaskBox in the Sketcher that allows to select which algorithms are to be used for
the different solving operations and tweak its parameters. It is not intended to be a user control, but means to debug
solving problems and improve the algorithms and their configuration.
This commit also introduces multithread support for Eigen. Currently it is only limited to products and does not provide
a substantial speed improvement. It is expected to have more multithreaded operations in Eigen in the future.
As a bonus, the TaskBoxes in the Taskbar of the Sketcher remember the last state (collapsed or deployed).
===============================================================
The sketcher crashed for example during effecting a fillet operation.
Cause:
The ElementsWidget/ConstraintWidget was being updated as a consequence of adding/removing geometry/constraints, and it was effecting
a selection after the update, in cases where the geometry in the screen was not being redraw (because the sketchobject was still unsolved), therefore
trying to select an element that according to ViewProvider did not exist (as it is created during redraw).
Solution:
Widgets update when their properties changes, provided that a redraw is effected (which actually also saves some (negligible) time, as they are only updated when they should).
======================
In no update mode, the last constraint was not enforced. The DoF was not properly shown.
The trim operation it is always solved at the end now if in no recompute mode.
============================================================
- Crashing on deleting line on fully constraint box
As a bonus:
- Fully constrained sketch not shown in green on opening the sketch
================================================================
A last moment change to regulate redrawing introduced this issue (reducing the redrawing to the cases where the solver geometry and the sketchObject geometry are equal).
This change also solved other issues.
The case of adding external geometry is special because the DoF is the same after insertion, yet there is an insertion (as opposed to the toggle case, where there is a change but no insertion).
SketchObject has been adapted to require a solver update before moving (which also caused a non-yet-reported crash, a separate bug), and CommandCreateGeo has been adapted to trigger a solve with
auto update mode disabled. This solve is a very low cost one as the geometry is already in place.
===============================================================================================
Group creation:
- complex geometries (consisting of several geometry elements and constraints) have been rewritten to use python list (one command call for all geometries and constraints)
- Ellipse ExposeInternalGeo as group creation of geometries and constraints
To construction mode creation:
- addGeometry python and SketchObject functions modified to take an additional optional parameter "construction" to create the geometry/geometries directly as construction.
In addition to the shorter form, this helps generate less amount of onChange propagation and Redraws.
- all the geometry creation commands in CommandCreateGeo.cpp have been rewritten to use the new construction argument. This includes modifying the regular polygon script to
take a new optional parameter to create geometry as construction in addGeometry.
- special care is taken in group creation not make construction points
- Show/hide internal geometry implemented with this option.
To solving:
- the solve previously included after every geometry addition (when in no Update, e.i. no Recompute mode) has been removed and each Gui::Command calls either an UpdateActive
for recompute or a Solve in no Update mode. This is behaviour is less intrusive and uniform with group creation.
Bug fixes and redrawing reduction:
- Fixes the CheckId exception problem. The solution also helps further remove redraws during creation of complex geometry (e.g. Slot)
- Fixes touching the sketch by only opening it.
- Code clean up.
===============================================
The help button next to the close button in the Task dialog is now removed.
It was requested that this button is removed as it is inconsistent with other help sources and it is not implemented.
================================================
Fixes a bug in master that the dependent 3D geometry would not update on Undo (in Auto update mode enabled).
Undo and redo signals are handled by ViewProvider in order to introduce an recompute or solve() of the sketchObject
as determined by the Auto Update Mode in order to update DoF and dependent geometry if necessary.
=================================================================
The new solving architecture focus all the solving on the SketchObject.
Actions that change the DoF can call execute() (i.e. recompute) or Solve() depending on whether a full recompute of dependent features is required or not.
In both calls the geometry of the solver is updated with the geometry of the SketchObject.
The only additional call that calls the solver is MovePoint. This function may or may not update the geometry of the SketchObject
(as now it is intended for UI related solving, like dragging, rubberbands, ...).
In operations that do not involve a change of DoF and therefore do not require a sketch solving, it may happen that as a side effect of moving a point, the
geometry changes to old behaviour. In order to avoid that, those SketchObject operations, as for example setConstruction or ToggleConstruction,
must set a flag "bool solverNeedsUpdate" to true. In case a movePoint is executed before any other solver execution, the geometry is first updated and then
the moving is performed.
So to keep in mind when programming sketcher operations:
-> Need recompute (UpdateActive)
-> Need solving because DoF changed (solve())
-> The operation does not change DoF (set solverNeedsUpdate to true)
=======================================
- Fixing toggle AutoUpdate Mode
- Fix Auto-Update Sketcher tools
- Fix missing createGeo recomputes
- Missing constraints recomputes fixed
Various fixes for non-Update mode:
- Fixes lack of update upon entering a conflicting datum constraint.
- Fixes lack of update upon setting the reference/driving status of a constraint
- Added tooltips to buttons
=========================================================
Upon deletion of a constraint, the constraint was still enforced for UI operations (dragging of a point) and DoF was not updated.
======================================================================================
There is a checkbox, default disabled, that makes the commands NOT to generate a recompute after each.
This means that if you are editing a sketch that is used to generate a pad or pocket, if the checkbox is
disabled, the dependent objects do not get recomputed.
There is a button next to it to force a manual recompute, in case it is needed.
If the user wants the previous behavior, he only needs to activate the checkbox. The previous status of the box
is restored upon entering a sketch in edit mode.
It is remarkable the case of the Fillet and Trim
On changing ActSketch (solvedSketch) to SketchObject and making movePoint not systematically update the geometry, the solving in MovePoint was confronted with solving for "the last solved geometry",
which is the default behaviour, in some situations (Fillet and Trim) where geometry had changed at SketchObject level, and was the subject of the moving actions.
MovePoint has been updated to take an extra optional parameter, to force the change in solved geometry in those situations.
Some other minor bug also fixed in Fillet creation in CommandCreateGeo.cpp
This commit also introduces conditional recompute on some operations of:
- constraints
- geometry creation (reubication of update active to comprise the autoconstraints within a single UpdateActive)
=======================================================================================
ActSketch in ViewProvider dissapears. The temporal sketch (sketch.cpp) for solving is now a data member of SketchObject.cpp (hereinafter solvedSketch). All the solving is concentrated in SketchObject.cpp.
SketchObject provides an interface to expose its solver, as it is still currently needed for some UI operations from ViewProviderSketch, like dragging points (solving rubber bands).
ViewProviderSketch still can select whether to draw the solvedSketch geometry (previously ActSketch) geometry (UI staff) or the SketchObject geometry. Performancewise, it makes sense to separate this two
geometries, as the SketchObject one involves modifying the Geometry and Constraint Properties (including all the undo related functionality), which would mess the undo functinality and incur in a big
peformance penalisation while dragging. One characteristic of solvedSketch is that its geometry is solved, whereas the geometry of SketchObject may not have been solved yet.
These geometries may differ at for the following reasons:
1. The geometry corresponds to an ongoing dragging operation, so solvedSketch has the last calculated dragging geometry, while SketchObject has the one corresponding to initial position.
2. Geometry/constraints were added to the sketch, but no solve/execute was triggered yet (envisioned situation is the future group creation functionality not in this commit).
What do I gain?
- Inserting a (simple) geometry element now costs 1 solver execution.
- Inserting a constraint now costs 1 solver executions.
For reference, in previous versions inserting a constraint involved 5 solver executions.
The following information provide a historical review of the coding of this commit (formed of 10 squashed commits):
This is a general sketch solve call reduction, not only during geometry creation (this commit does not include until here any specific measure to reduce calls on geometry creation, that is another branch)
After a lot of profiling, it seems that the "cause"(tm) that creates so many solver calls is that every update generates a solving in ViewProviderSketch, regardless of the need for that update,
many times with the only aim of providing the DoF for the message dialog and keeping ActSketch in sync with SketchObject in case it is needed (currently UI moving points, constraints,...).
Sketch solver is now a data member of SketchObject instead of a temporal object that gets initilized and destroyed.
This allows:
1. Potentially more synergy reducing calls to setUpSketch (still to be seen, still to be optimized)
2. Allowing SketchObject to access the latest geometry that has been solved => In future, allow objects that use SketchObject to obtain the latest
solved geometry instead the geometry of SketchObject that may still be unsolved. This is relevant for drawing the geometry
No more solving in ViewProviderSketch. Solving a Sketch is now an exclusive competence of SketchObject.
There is however a lot of cleaning to do in ViewProviderSketch
(I mean, not that these commits are making a mess in VPSketch,
but that as a consequence of the changes, it should be possible to
optimize VPSketch, specially moving and drawing methods)
Very useful comment for future developers that may wonder why a solve per constraint just upon addition is necessary.
Added a new function to get the size of the geometry of the instance of the solver object (Sketch.cpp).
The previous way was to extract the geometry, which is costly and error prone, as you have to delete it afterwards.
Inserted comment about the necessity of triggering a Part2D update during edit mode
==============================================================================
Now you can switch from one tool to the next just by clicking on the next tool
==================================================================================
Geometry button:
- if no object selected, the legacy toggle icon has a new functionality, switch to/from creating in construction mode
- if object selected, it has the legacy functionality
- the button can be clicked during "continuos creation mode" to switch from creating to/from creating in construction mode
Constraint button:
- The button is not selectable if nothing is selected (it would be impossible to determine the effect)
- When constraints are selected, the button toggles the constraints to/from Driving.
- When geometry is selected, the button switches from/to reference mode, the change is apparent from the color of the constraint icons.
Continuous creation mode:
- Default changed so that it is active unless you change it in settings
Updated terminology
======================================================================
- Changing from Driving to reference does not include unnecessary solvings.
- Added some checks to avoid making Driving constraints when calling directly from python and involving only external geometry (would give redundant constraints).
- New python command toggleDriving to just change the status from reference to Driving
- New UI toolbar Command to toggle constraints
- Fix to allow switching from/to construction mode during continuous mode creation.
- Enable/Disable for constraints in constraints widget has changed to operate on multiselection and now effects "toggle" instead of enable/disable.
- Disable the option to directly create a SnellsLaw non-driving constraint (this constraint does not support direct creation, it can be toggled to non-driving after creation though).
==============================================
The fillet applied to construction lines generates normal (not construction) geometry.
How to replicate?
1.Make a square and make all lines construction lines.
2.Apply fillet tool, there result will be a white line fillet connecting two blue constructions lines.
===================================================================
It allows to create constraints directly into Reference or Driving mode.
It does not include icons
===============================================
It allows to select whether the geometry will be created as construction geometry or normal geometry.
This commit includes an important bug fix to reduce the number of times the sketcher solver is called when toggling
geometry. It makes an important difference in the creation during construction mode and InternalAligment geometry like the ellipse.
This commit does not include icons.
You have a button next to toggle that after having been clicked, switches from Normal to Construction geometry and vice versa
============================================================
It lifts the need of clicking on the external geometry icon upon importing each external geometry element.
All the elements on which the user clicks are imported until the user right clicks with the mouse or presses ESC, like the Trim or Fillet tools.
===============================================
When creating a type of geometric element, the user can create as many elements of that type he wishes without having to click the button before each insertion.
The insertion of that type of elements ends by pressing ESC or clicking the right button of the mouse.
This mode is by default disabled and can be enabled in Preferences->Display->Sketch->Geometry Creation "Continue Mode".
===================================================================================================
This fixes a bug in the original implementation, that a non-driving constraint value could be
edited by double clicking on it in the 3D view.
It also includes minimal documentation on some functions.
It also includes:
- Color setting for non-driving constraints was not working.
- Settle UI terminology dispute:
* Driving Constraint (normal red constraint)
* Reference Constraint (non-driving constraint)
====================================================================================
It allows to enable and disable a constraint in the constraint list.
When disabled, the constraints current value is shown, but its value is not enforced (it is driven by the other constraints and user interaction).
A disabled constraint can be enabled (as far as it is enforceable, see non-driving constraints to external geometry below).
The sketcher functionality has been extended to support non-driving constraints to external geometry elements. This were previously excluded from
the possibility of creating a constraint on them (as their values depend on other sketches and would be redundant with the unchanged value or conflicting when value is changed).
Now these constraints are created as non-driving, but as they are not enforceable, the UI does not allow you to make them driving.
The constraint filter has been extended to include a Non-Driving constraints category.
Thanks again to Werner for his continuous support, and specially in this case to DeepSOIC, as he pointed towards a much better implementation solution than my original idea.
=========================================
The autoconstraints on creation of an hexagon were not working.
How to reproduce?
1. In a sketch make a couple of lines
2. Create an hexagon (or other polygon of your choice) with center in one end of a line and with side coincident with the end point of the other line
Result:
Neither the center nor the side autoconstraints are properly created.
Fix:
Straightforward. Just correct the indexes. Last is always the circle. Last but one is always a side.
========================================================================================
How to replicate:
1. Go to Preferences->Display->Sketch and disable that checkbox.
2. Create a distance constraint (radius, distance, ...)
It will ask for the value regardless of whether the checkbox is clicked or not.
Why?
In SketcherSettings.ui the prefpath is "Mod/Sketcher"
The code refered to ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher/General");
=============================================================
This function is like this from 2011 according to git blame.
The original code makes no sense. I assume that what is intended in this
function (in accordance with SketchPy.xml) is call the method clear in
Sketch.cpp.
Added buttons to port sketches to CCW-emulation Sketcher.
Bonus =) : Added constraint orientation lock/unlock buttons (affects
point-wise modes of tangent and perpendicular constraints so far)
Fixes a bug where an arc, ellipse, or arc-of-ellipse, being reversed in
XY plane, behaved badly in sketcher (see forum thread "Sketch: how to
handle reversed external arcs?"
http://forum.freecadweb.org/viewtopic.php?f=10&t=9130 ).
Also fixes a problem with rotated arcs (see forum thread "Rotating Arc
in Sketcher"
http://forum.freecadweb.org/viewtopic.php?f=22&t=9145#p74262 ).
This is done by adding an emulation flag to a few methods in
Part::GeomXXX, which makes the shape to pretend being non-reversed
(CCW). This causes endpoints of reversed arcs of circles lineked as
external geometry to swap, causing broken sketches sometimes.
This commit solves the problem that a ellipse appears rotated when added as external geometry, if the face having the
elliptical shape has a direction vector in the -z axis.
This solves the problem. However, the issue with CW and CCW shapes in the sketcher shall be further investigated in order
to arrive to a general acceptable solution.
Sketcher Ellipse: porting tangent-line to DeriVector2
Replacing a ton of unreadable, sage generated math code with
easy-to-manage C++ code.
Sketcher Ellipse: porting internal align-t to DeriVector2
Sketcher Ellipse: small math refactor; const members
Moving the repeating code computing deriv+value of major radius to a
method of GCS::Ellipse.
Marking several methods of DeriVector2 as const member functions.
Sketcher Ellipse: porting arc angle rules to DeriVector2
Just porting.
Probably a complete remake of the concept is worth... Angles can be
calculated explicitly, there's no need to load the solver. I see no
benefits whatsoever on using the solver to keep track of angle values.
Sketcher Ellipse: porting equality to DeriVector2
Fix AngleViaPoint to support new derivative calculation technique.
OpticConstraints: Adding Snell's law. Fix AngleViaPoint to support new derivative calculation technique.
Snell's law constraint added to GCS, but not yet exposed and cannot be
tested.
Since the way CalculateNormal() returns derivatives had changed,
AngleViaPoint constraint needed modifications. Nothing serious.
OpticConstraints: SnellsLaw progress
Addable through python. Fix math. Some quick-and-dirty visual stuff to
get rid of hangs and to see the constraint in action.
OpticConstraints: SnellsLaw: flipping logic fix
OpticConstraints: SnellsLaw progress
Added toolbar button. Allowed editing a datum by doubleclick. New error
message approach during constraint creation.
OpticConstraints: SnellsLaw
OpticConstraints: SnellsLaw: list label improvement
OpticConstraints: SnellsLaw: fix after rebase
OpticConstraints: SnellsLaw: expose helper constraints
Snell's law internally is made of three constraints: point-on-object,
coincident and the Snell's sin/sin. They were all buried under one UI
constraint. Exposing them allows to construct reflection and
birefringence on the point (attempting to do so used to result in
redundant constraints and was often not functional at all).
This commit breaks compatibility with older files.
OpticConstraints: SnellsLaw: small refactor of math
Placing the duplicated code of error and gradient calculation into a
private method.
OpticConstraints: SnellsLaw: fix datum edit unit
OpticConstraints: SnellsLaw: fix datum edit bug
After previous fix, the dimensionless value was not accepted (the
constraint's value did not change, the changes were ignored).
GCS::Vector2D was morphed into a DeriVector2, a derivative-aware vector.
A bunch of vector math methods were added that implicitly calculate
respective derivatives. Now, there is no need to calculate the partials
- most is done implicitly.
AngleViaPoint: fixes in UI routines + new messages
Goofed undo message in tangency via point is fixed.
Forgotten updateActive, clearSelection have been added.
New more informative error messages for tangent constraint.
AngleViaPoint: using it instead of via line tangency
* replaced the helper construction line for ellipse-to-ellipse and
similar tangency with a point. Using tangent-via-point there
* deleted tangency via line for point-to-point on
(cherry picked from commit 9e3fa8c8de0f49c0ef3c978e015eb905358dbdd9)
AngleViaPoint: internal/external tangency locking
*Added automatic tangency type lockdown for all new constraints (only
for point-wise tangency).
Tangency type is stored in the constraint datum field, as an angle value
shifted by Pi/2 (to be able to treat 0.0 as undefined type).
Added ability to switch the tangency by setting datum value from python
(can be abused by passing arbitrary angle).
Further simplified the tangency related code in Sketch.cpp.
AngleViaPoint: added license to Geo.cpp
AngleViaPoint: renames in Constraints.cpp/.h
Changed some names to increase self-explanatoryness:
bool "remapped" renamed to "pvecChangedFlag"
"ReconstructEverything()" renamed to "ReconstructGeomPointers()"
AngleViaPoint: renames in Constraints.cpp/.h
Changed some names to increase self-explanatoryness:
bool "remapped" renamed to "pvecChangedFlag"
"ReconstructEverything()" renamed to "ReconstructGeomPointers()"
AngleViaPoint: using for endpoint perpendicularity
+ direction lockdown, just as with tangency.
+ quite a lot of old code is gone because of that
AngleViaPoint: perp-ty UI routine made similar to tangent
(Git has made a very messy diff.)
The changes are:
* Perpendicularity-via-point (3-element selection) support added.
* Endpoint-to-curve and endpoint-to-endpoint supports all shape
combinations.
* a bit of code cleanup and clarifications.
AngleViaPoint: placement of perpendicular icon in 3d view
AngleViaPoint: fix: allow setDatum of perpendicular constraint
AngleViaPoint: fix: centers of ellipses are not endpoints
isSimpleVertex used to return false for centers of ellipses and arcs of
ellipses, which made them being accepted for point-to-point tangency.
Should be fixed forever, mo more changes are expected to be necessary
for new types of geometry.
AngleViaPoint: precalc with OCC (work in progress)
Work in progress (not yet working).
Using OCC's tangent to replace implementation of
SketchObject::calculateAngleViaPoint.
AngleViaPoint: fix math: normal now points inwards, where it was intended initially and goofed up.
AngleViaPoint: adding comments to the code
AngleViaPoint: using GeomCurve::closestParameterToBasicCurve for angle precalculation
AngleViaPoint: Py method: changeConstraintsLocking
changeConstraintsLocking(True) - locks/re-locks all lockable
tangency/perpendicularity constraints of the sketch (applicable to
existing sketches).
changeConstraintsLocking(False) - removes locking information from
lockable constraints
AngleViaPoint: final SketchObject::calculateAngleViaPoint
Now, finally, using OCC functionality (thanks Abdullah!), without
composing temporary Sketch object.
Solver iteration limit independent of system size (reduces hangs when
solver fails to converge).
Repaint() instead of update() to force render for every movePoint.
Sketcher: New Constraint AngleViaPoint
* Adding generic CalculateNormal() method
* Reconfiguration of GCS geometry classes: adding a base class "Curve",
that has a pure virtual function CalculateNormal().
* Initial inplementation of the new function.
* adding Vector2D class (I wanted to reuse the existing, but got wierd
compile errors, so implemented a new one... TODO.)
* Adding redirection support into GCS shapes. Adding a Copy method to
GCS::Curve.
* Automatic point-on-object
* Angle precalculation: when AngleViaPoint is added, angle is properly calculated based on
existing geometry.
* Added tangency-via-point using one.
* Implemented placement of tangency-via-point icon in 3d view. Also
affected is the placement of point-on-object icon (since it is very
similar code, it is now shared with tangency-via-point)
* Placement and moving of angle datum
Functions: calculateAngleViaPoint, isPointOnCurve,
calculateConstraintError exposed to python
* Endpoint tangency: All endpoint-to-endpoint and endpoint-to-curve tangency now works
through AngleViaPoint constraint and obsolete code clean up (most procedures
addConstraintTangentXXX2YYY)
Part: Extension of Geometry::Curve to wrap more functions of OCC
Apart from:
bool tangent(double u, gp_Dir&) const;
that was already implemented, now it also implements:
Base::Vector3d pointAtParameter(double u) const;
Base::Vector3d firstDerivativeAtParameter(double u) const;
Base::Vector3d secondDerivativeAtParameter(double u) const;
bool normal(double u, gp_Dir& dir) const;
bool closestParameter(Base::Vector3d point, double &u);
i.e. apart from giving the tangent vector for a given curve at parameter value u,
it also gives:
- The point cartesian coordinates of the curve point at parameter value u
- The vector of the first derivative at parameter value u
- The vector of the second derivative at parameter value u
- The normal vector to the curve at parameter value u
- The parameter value of a curve closest ot a given point
Code cleanup: Changing Trim functionality of Ellipse to use OCC calculations
Part Curve functions extension: closestParameterToBasicCurve
It provides the parameter of the curve closest to a given point. If the curve is a Trimmed curve, the parameter of the basic underlaying curve closest to the point is provided.
- ArcOfEllipse enhancement: Tangency ArcOfEllipse to ArcOfEllipse or ArcOfCircle by selecting end/starting points...
- Minor bug corrections (Thanks DeepSOIC)
- ExposeInternalGeometry python command
- DeleteUnusedInternalGeometry python command
- On deletion of an Ellipse/ArcOfEllipse all further unconstrained internal geometry is also deleted.
- This cleans up the code by eliminating code repetition in the creation methods.
- Major bug fix for autoconstraints for ellipse and arc of ellipse creation (for both creation methods)
- Major bug fix Start and Endpoint constraints of an arc of ellipse where not taking into account that Sketcher arcs are always CCW, so they have to be exchanged if we convert a CW arc into a CCW arc.
Sketcher: General bug fix: Tangency wrongly suggested
What?
=====
- On creation of a shape autoconstraints are suggested.
- Tangent autoconstraint was suggested even with lines perpendicular to the tangency direction
Reproduce
=========
- Make a circle on the origin and move the mouse along the X axis, it will suggest a tangency that is impossible
- Click on the axis and no circle will be created
Solution
========
- The SeekConstraint now can use the parameter dir to give a direction that is substantially perpendicular to the expected tangency, so that
if an object having a direction (a line) is hit, a tangency will not be suggested if within around 6 degrees of being parallel.
- Additionally, if such a line is an X,Y axis of the sketch, tangency will only be suggested if the direction is within 6 degrees of being perpendicular (i.e. it is almost tangent already while sketching).
- This difference is due to the fact that an X or Y axis can not "move" to meet the object under creation, whereas a line can.
I. Fix minor bug where wrong b was used to create ellipse internal geometry.
Tweak the internal geometry code a bit and reformat it so it isn't so wide.
Also begin debugging constraint conflicts on small circular ellipses.
There seem to be two issues currently in major/minor internal geometry lines:
1) Sometimes minorLength > majorLength due to round-tripping doubles, and
2) Constraint conflicts when majorLength > minorLength by an epsilon on the order of 1e-6
(cherry picked from commit 5c3e20af1a95c860112289dcdda54ea99778bc3a)
II. When testing for a valid ellipse, also ensure that the mangled major axis length > the mangled axis length.
This additional condition ensures that major and minor axis constraints don't conflict in the case of small
(nearly) circular ellipses.
The is still a potential bug in the solver when the major length is just slightly larger than the minor, but this fix
makes it nigh impossible to reproduce.
(cherry picked from commit 7e274bc32d9aa1a12ab52bfa33ed80353540b062)
III. Code clean up
Remove redundant 3d vectors.
(cherry picked from commit c656d5165c8bae8f101a2b46af6b12348d06cefe)
--Center, major radius, minor radius
--Periapsis, apoapsis, minor radius
Artist: We need an icon for periapsis, apoapsis, minor radius method.
(cherry picked from commit f0a4339621b0bf901754af14c3cd36c95ca55966)
Elements that have internal geometry are created with the internal geometry on creation.
It has been under discussion for a long time. Ulrich was in favour (asked for it several times).
DeepSOIC implemented the focus because he hated the poor dragging of the ellipse when empty.
- Visual representation of equality constraint: Separate circle and arcofcircle implementation from ellipse and arcofellipse implementation
- Fix for Alignment constraint: Now it allows to assign a second element, one by one
- Box selection for ArcOfEllipses
Fixes the bug that vertex far away got selected due to lack of sync between the selection and draw loops.
- Minor changes to alignment constraint selection to avoid to create objects just for simple calculations
- Equality constraint of Ellipse, ArcOfEllipse and combinations of those elements
- Bugfix for internalalignment creation of major and minor of ellipse and extension to arcofellipse
- Trim support for ellipses
- Solver threshold for rank calculation set at 1e-13.
- Trim support for arc of ellipse
- Ellipses and ArcOfEllipses as external geometry
- Validate Sketch now supports arcs of ellipse
- Tangents of Ellipse or ArcOfEllipse to any of ArcOfcircle, circle and Ellipse (using construction elements)
- Perpendicularity constraint
- Bug fix: Show/hide internal geometry not working for external geometry
- Visualization of Internal alignment constraints when selecting in the constraint widget
- Equality for ellipses and arc of ellipses
- Fix of internal geometry creation
- Fix swapped negative and positive ends of major radius line on creation
- Removing the fudge factor (no longer needed)
- Fix to restore internal alignment - autodecide on constraint creation which point of the line is closer to the position
- Change mode so that focus1 is not a point, but two doubles so that visual model and solver model match in number of points.
- Solver fix to deal with reduced constraint partials accuracy (threshold for matrix rank calculation tweak)
- Changes suggested by logari81
- Ellipse introduction button via (center,majaxis extreme, a point in edge), ellipse is always CCW so that Z axis goes in the positive direction of the sketch
- Backwards compatibility with files of previous versions of ellipse not defining a phi angle
- Art by Jim (all the icons you see and the XPMs shown on creation of an ellipse)
- Element Widget support for ellipses
- Box selection for ellipses
- Point on Ellipse constraint based on the gardener's method based on Ulrich's function proposal (radcan simplified, i.e. with simplify_radical sage function)
- Tangent: Ellipse to Line based on DeepSOIC's geometric formulation (radcan simplified)
Sketcher New Feature: Internal Alignment Constraint
- The element to which internal alignment is applied has to be selected last.
- All other elements are added in the order of priority, taking into account existing elements
- Art by Jim (beautiful icons).
Sketcher New Feature: Tool to show/hide/restore the internal geometry of an element
- New functionality for show/hide internal geometry:
toggles between hiding all unused internal geometry elements and showing all internal geometry.
The restore function is implicit to the showing all internal geometry
Sketcher New Feature: Arc of Ellipse support
- Part::Geometry + Python implementation
- ArcOfEllipse creation method
- Art by Jim (all the icons you see and the XPMs shown on creation of arc of ellipse elements)
- Sketcher Element widget for ArcOfEllipse.
Bug fix: Select elements associated to constraints works now for foci internal alignment constraints