From f93b376cd57cdb51753cdf5e7ba7d04726866021 Mon Sep 17 00:00:00 2001 From: Abdullah Tahiri Date: Thu, 18 Feb 2021 17:24:56 +0100 Subject: [PATCH] Sketcher: Improved ViewProvider visualisation for non-rational Bsplines with non-unitary weight constraints =========================================================================================================== OCCT forces weights of non-rationa Bsplines to be 1.0 In the presence of non-unitary weight constraints, the weight representation (constraint) has a different radius than the circle. This commit fixes this behaviour, by forcing the circle to match the weight constraint. The information layer still reports OCCT weights being 1.0, but the visual artifact is fixed. --- src/Mod/Sketcher/Gui/ViewProviderSketch.cpp | 26 ++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp index 72a70c40d9..31a42a3d43 100644 --- a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp +++ b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp @@ -3985,8 +3985,32 @@ void ViewProviderSketch::draw(bool temp /*=false*/, bool rebuildinformationlayer // proportional to the length of the bspline // inversely proportional to the number of poles double scalefactor = bspline->length(bspline->getFirstParameter(), bspline->getLastParameter())/10.0/weights.size(); - //double scalefactor = getScaleFactor(); + double vradius = weight*scalefactor; + if(!bspline->isRational()) { + // OCCT sets the weights to 1.0 if a bspline is non-rational, but if the user has a weight constraint on any + // pole it would cause a visual artifact of having a constraint with a different radius and an unscaled circle + // so better scale the circles. + std::vector polegeoids; + polegeoids.reserve(weights.size()); + + for ( auto ic : getSketchObject()->Constraints.getValues()) { + if( ic->Type == InternalAlignment && ic->AlignmentType == BSplineControlPoint && ic->Second == c->Second) { + polegeoids.push_back(ic->First); + } + } + + for ( auto ic : getSketchObject()->Constraints.getValues()) { + if( ic->Type == Weight ) { + auto pos = std::find(polegeoids.begin(), polegeoids.end(), ic->First); + + if(pos != polegeoids.end()) { + vradius = ic->getValue() * scalefactor; + break; // one is enough, otherwise it would not be non-rational + } + } + } + } // virtual circle or radius vradius auto mcurve = [¢er, vradius](double param, double &x, double &y) {