Some instances of TimeInfo serve the sole purpose of measuring time
duration. Using system time is unfortunate as it returns wall clock,
which is not guaranteed to be monotonic. Replace such a usage with
the new TimeElapsed class based on steady clock.
The following commits were squashed into this
[Sketcher] Handle some corner cases in AngleViaPoint
[Sketcher] Avoid redundant constraints with B-splines...
When involving tangent, perpendicular and angle constraints.
[Sketcher] Add pre-commit changes
[Sketcher] Do not allow 2-selection tangent with B-spline
Also...
[Sketcher] Report error when using direct tangency with B-splines
[Sketcher] Fix malformed constraint when B-spline is selected second
To clarify, this means the second curve selected. The position of the point in
selection order does not matter in angle-via-point.
[Sketcher] Fix wrong number for B-Spline tangent on redundancy
[Sketcher] Remove existing point-on-object in some redundant cases
Particularly when point constrained on a B-spline is being used for
tangent, perpendicular or angle via point with the same B-spline.
[Sketcher] Fix direction issue with B-spline tangents.
Without these changes the solver might try to "twist" the B-spline to make the
angle between curves be 0 instead of PI (which may be closer to the initial shape).
The latter is intended for a specific solver constraint.
[Sketcher] Make further changes for tangent-at-knot separation
1. Remove code for tangent-at-knot from `addAngleAtPointConstraint`.
2. Use correct order of input.
3. Separate internal C0 knot vs end knots. The latter can still be constrained
but the user must use endpoints of the spline instead of knots.
Also squashes:
[Sketcher] Make tangent-at-knot with just knot and line
[Sketcher] Disallow tangent at C0 knot
If passed on to planegcs can cause segmentation fault.
[Sketcher] (Re-)Support tangent at B-spline end-knots
New code had introduced problems for non-periodic spline end-points, and
periodic spline "end-points" were not supported anyway.
(here end-points mean star/end points)
Also squashes:
[Sketcher] Create center of gravity constraint in planegcs
[Sketcher] typo
[Sketcher] Use accurate "weights" for knots
By weights we mean the linear combination factor B_i(x) such that
spline(x) = sum(pole_i * B_i(x)) for _non-rational_ splines.
[Sketcher] Use more appropriate weights for knots
These are relevant for knots _away_ from any ends (and possibly other high
multiplicity knots).
[Sketcher] Make COG constraint weights user-definable
[Sketcher] Make `flattenedknots` for periodic B-Splines
[Sketcher] Fix incorrect setup of `flattenedknots`
Without ensuring enough space, iterators become invalid. These iterators are
needed because for periodic B-splines we need to pad flattenedknots with offset
values within flattenedknots.
Apparently there is still some iterator issues even after the reserve. Just use
fresh vectors instead.
[Sketcher] Apply knot constraints by parameter
Hopefully this will allow directly applying constraints on knots.
[Sketcher] Disable some knot updating
[Sketcher] Use center of gravity constraint on knots
[Sketcher] Fix knot COG constraint for periodic splines
[Sketcher] Add start/end point of periodic spline to solver
This removes the trouble of transferring constraints to the underlying knot.
[Sketcher] Support knot constraints on rational B-splines
[Sketcher] Remove virtual from overridden methods in planegcs
Follow 0penbrain's comments
[Sketcher][planegcs] Use `unsigned int` in signatures
Also `size_t` at places
Suggestions by @abdullahtahiriyo
================================================================
Master has a problem in that internal alignment constraints are suggested to the user for removal.
This is fundamentally wrong, as an internal alignment constraint are an inherent part of the geometry. They cannot be the ones suggested for removal.
The popularity contest algorithm is an heuristic algorithm that determines which redundant/conflicting constraints should be proposed for removal.
Basically, the algorithm works on groups of redundant/conflicting constraints detected via the QR decomposition. A constraint may belong to more than one group.
The algorithm runs some heuristics, each constraint scoring a value, the one constraint from each group scoring the highest is proposed (is more popular and wins the contest).
This PR documents the algorithm, and adds a further condition, that internal alignment constraints are never proposed.
As the solver works with solver constraints as opposed to the sketcher, which works with sketcher constraints, information about whether a solver constraint originated from a
sketcher constraint that is internal alignment is necessary. So the solver constraint is extended to accomodate this piece of information.
As a bonus, it fixes a bug. Solver constraints carry information of the ID of the corresponding sketcher constraint in their tag. Knots are not currently implemented as constraints.
However, the tag index was not being update. This caused the popularity contest to provide wrong suggestions despite good detection.
Here, "small" means that the number of poles of the spline is so low that moving
any piece of the curve without changing shape would require moving all the
poles. In that case the rest of the algorithm in `initBSplinePieceMove()` only
complicates the matter.
===============================================================================
* SolverGeometryExtension is extended to:
- Enable to determine whether the x or the y of a point is a dependent or independent parameter
- Extend SolverExtension to provide information on individual edge parameters
- Convenience access to DoF status
* Sketch (solver interface) is extended to store geometry parameter dependency state, for these reasons:
Geometry and Constraint solver information is generated when performing a full solve() [QR decomposition + minimization(e.g. DogLeg)].
Constraint information remains in the sketch object (not SketchObject, but sketch), which is then retrieved by SketchObject.
Geometry information is incorporated to the deep copy of Geometry that the sketch object comprises. However, this information is only
available outside the sketch object, if the Geometry property of SketchObject is assigned. This is always the situation after a successful
full solve. However, it is not the case in a successful temporary minimal diagnosis (here succesful relates to conflicting/redundant constraints and
convergence).
The lightweight solution is to keep a (shallow) copy of the SolverGeometryExtensions (shared pointer) to be retrieved by GeoId, which is what is provided.
=================================================================================
Apart from simplifying code, the allocated memory is not managed by the lifetime of the unique pointer owned by the GeometryFacade, preventing memory leaks.
===================================================
This commit is an independent refactor of the identifications used at Sketcher level.
It introduces a new type "GeoElementId" as a combination of GeoId and PointPos.
It moves the Undefined GeoId, previous Constraint::GeoUndef to GeoEnum, together with all
other fixed values of GeoIds.
========================================================
Users chennes and hyarion made me aware of this covereity issue:
Fixes Coverity: geoit can be end() when dereferenced
https://github.com/FreeCAD/FreeCAD/pull/4429/files#
When analysing the block where the dereferrencing appears, it
appears that it is a left-over that no longer makes sense:
- The algorithm classifies block constraints into those that are
not affected by any other driving constraint and those that are
affected by other driving constraints.
- The offending block deals with internal aligned geometry, thus
per definition has a driving internal alignment constraint, for which
the previous block already set the need of post-analysis.
- No matter what, the geometries, the complex one and the internal one
will have at least the driving internal alignment constraint, so they
cannot become "not affected by any other driving constraint".
- If the geometry had a block constraint on it, it was already added for
post-analysis in the previous block. If it did not have one block constraint,
the fact that it is internal aligned geometry is an irrelevant consideration.
Probably there was a point during development when this made sense, but with
the current post-analysis, it does not appear to make sense anymore. So the
block was removed.
This commit adds a unit test for blocked geometry (new block constraint).
=================================================
Knot position is not calculated by the solver, but by OCCT when updating the
b-spline to conform to given pole positions, as mandated by the solver. Before
this commit, all constraints driving and non-driving operating on the knots required
and extra solve (from advanced solver dialog, or from the Python console), or a recompute
to be recomputed.
This commit introduces transparently re-solving at Sketch.cpp level if B-Splines are present,
so that when the Sketcher mandated solve returns, the geometry is fully solved.