[Sketcher] Constrain B-spline knots as linear combination of poles
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
This commit is contained in:
committed by
abdullahtahiriyo
parent
bad4406387
commit
ba4f2bf128
@@ -617,12 +617,7 @@ int Sketch::addGeometry(const Part::Geometry *geo, bool fixed)
|
||||
const GeomPoint *point = static_cast<const GeomPoint*>(geo);
|
||||
auto pointf = GeometryFacade::getFacade(point);
|
||||
// create the definition struct for that geom
|
||||
if( pointf->getInternalType() == InternalType::BSplineKnotPoint ) {
|
||||
return addPoint(*point, true);
|
||||
}
|
||||
else {
|
||||
return addPoint(*point, fixed);
|
||||
}
|
||||
return addPoint(*point, fixed);
|
||||
}
|
||||
else if (geo->getTypeId() == GeomLineSegment::getClassTypeId()) { // add a line
|
||||
const GeomLineSegment *lineSeg = static_cast<const GeomLineSegment*>(geo);
|
||||
@@ -1257,12 +1252,10 @@ int Sketch::addBSpline(const Part::GeomBSplineCurve &bspline, bool fixed)
|
||||
double * p1x = new double(startPnt.x);
|
||||
double * p1y = new double(startPnt.y);
|
||||
|
||||
// if periodic, startpoint and endpoint do not play a role in the solver, this removes unnecessary DoF of determining where in the curve
|
||||
// the start and the stop should be
|
||||
if(!periodic) {
|
||||
params.push_back(p1x);
|
||||
params.push_back(p1y);
|
||||
}
|
||||
// If periodic, startpoint and endpoint do not play a role in the solver, this can remove unnecessary DoF of determining where in the curve
|
||||
// the start and the stop should be. However, since start and end points are placed above knots, removing them leads to that knot being unusable.
|
||||
params.push_back(p1x);
|
||||
params.push_back(p1y);
|
||||
|
||||
p1.x = p1x;
|
||||
p1.y = p1y;
|
||||
@@ -1270,12 +1263,11 @@ int Sketch::addBSpline(const Part::GeomBSplineCurve &bspline, bool fixed)
|
||||
double * p2x = new double(endPnt.x);
|
||||
double * p2y = new double(endPnt.y);
|
||||
|
||||
// if periodic, startpoint and endpoint do not play a role in the solver, this removes unnecessary DoF of determining where in the curve
|
||||
// the start and the stop should be
|
||||
if(!periodic) {
|
||||
params.push_back(p2x);
|
||||
params.push_back(p2y);
|
||||
}
|
||||
// If periodic, startpoint and endpoint do not play a role in the solver, this can remove unnecessary DoF of determining where in the curve
|
||||
// the start and the stop should be. However, since start and end points are placed above knots, removing them leads to that knot being unusable.
|
||||
params.push_back(p2x);
|
||||
params.push_back(p2y);
|
||||
|
||||
p2.x = p2x;
|
||||
p2.y = p2y;
|
||||
|
||||
@@ -3311,16 +3303,14 @@ int Sketch::addInternalAlignmentKnotPoint(int geoId1, int geoId2, int knotindex)
|
||||
int pointId1 = getPointId(geoId2, PointPos::start);
|
||||
|
||||
if (pointId1 >= 0 && pointId1 < int(Points.size())) {
|
||||
// GCS::Point &p = Points[pointId1];
|
||||
|
||||
GCS::Point &p = Points[pointId1];
|
||||
GCS::BSpline &b = BSplines[Geoms[geoId1].index];
|
||||
|
||||
// no constraint is actually added, as knots are fixed geometry in this implementation
|
||||
// indexing is added here.
|
||||
// However, we need to advance the tag, so that the index after a knot constraint is accurate
|
||||
ConstraintsCounter++;
|
||||
assert(knotindex < static_cast<int>(b.knots.size()) && knotindex >= 0);
|
||||
|
||||
b.knotpointGeoids[knotindex] = geoId2;
|
||||
int tag = ++ConstraintsCounter;
|
||||
GCSsys.addConstraintInternalAlignmentKnotPoint(b, p, knotindex, tag);
|
||||
|
||||
return ConstraintsCounter;
|
||||
}
|
||||
@@ -3374,12 +3364,9 @@ bool Sketch::updateGeometry()
|
||||
GeomPoint *point = static_cast<GeomPoint*>(it->geo);
|
||||
auto pointf = GeometryFacade::getFacade(point);
|
||||
|
||||
if(!(pointf->getInternalType() == InternalType::BSplineKnotPoint)) {
|
||||
point->setPoint(Vector3d(*Points[it->startPointId].x,
|
||||
point->setPoint(Vector3d(*Points[it->startPointId].x,
|
||||
*Points[it->startPointId].y,
|
||||
0.0)
|
||||
);
|
||||
}
|
||||
0.0));
|
||||
}
|
||||
else if (it->type == Line) {
|
||||
GeomLineSegment *lineSeg = static_cast<GeomLineSegment*>(it->geo);
|
||||
@@ -3527,38 +3514,6 @@ bool Sketch::updateGeometry()
|
||||
}
|
||||
|
||||
bsp->setKnots(knots,mult);*/
|
||||
|
||||
// This is the code that needs to be here to take advantage of the current OCCT reliant implementation
|
||||
// The current B-Spline implementation relies on OCCT for pole calculation, so the knots are set by the OCCT calculated values
|
||||
auto occtknots = bsp->getKnots();
|
||||
|
||||
for(auto it3 = occtknots.begin() ; it3 != occtknots.end(); ++it3)
|
||||
knots.push_back(*it3);
|
||||
|
||||
int index = 0;
|
||||
for(std::vector<int>::const_iterator it5 = mybsp.knotpointGeoids.begin(); it5 != mybsp.knotpointGeoids.end(); ++it5, index++) {
|
||||
if( *it5 != GeoEnum::GeoUndef) {
|
||||
if (Geoms[*it5].type == Point) {
|
||||
GeomPoint *point = static_cast<GeomPoint*>(Geoms[*it5].geo);
|
||||
|
||||
auto pointf = GeometryFacade::getFacade(point);
|
||||
|
||||
if(pointf->getInternalType() == InternalType::BSplineKnotPoint) {
|
||||
auto pointcoords = bsp->pointAtParameter(knots[index]);
|
||||
point->setPoint(pointcoords); // update the geompoint of the knot (geometry update)
|
||||
// Now we update the position of the points in the solver, so that any call to solve()
|
||||
// calculates constraints and positions based on the actual position of the knots.
|
||||
auto pointindex = getPointId(*it5, PointPos::start);
|
||||
|
||||
if(pointindex >= 0) {
|
||||
auto solverpoint = Points[pointindex];
|
||||
*(solverpoint.x) = pointcoords.x;
|
||||
*(solverpoint.y) = pointcoords.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Base::Exception &e) {
|
||||
Base::Console().Error("Updating geometry: Error build geometry(%d): %s\n",
|
||||
|
||||
Reference in New Issue
Block a user