[Sketcher] Only move one piece of B-spline when dragging
This commit is contained in:
committed by
abdullahtahiriyo
parent
e899c221cc
commit
4db7da7314
@@ -4021,6 +4021,66 @@ void Sketch::resetInitMove()
|
||||
isInitMove = false;
|
||||
}
|
||||
|
||||
int Sketch::initBSplinePieceMove(int geoId, PointPos pos, const Base::Vector3d& firstPoint, bool fine)
|
||||
{
|
||||
isFine = fine;
|
||||
|
||||
geoId = checkGeoId(geoId);
|
||||
|
||||
clearTemporaryConstraints();
|
||||
|
||||
// don't try to move sketches that contain conflicting constraints
|
||||
if (hasConflicts()) {
|
||||
isInitMove = false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// this is only meant for B-Splines
|
||||
if (Geoms[geoId].type != BSpline || pos == PointPos::start || pos == PointPos::end) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Find the closest knot
|
||||
auto partBsp = static_cast<GeomBSplineCurve*>(Geoms[geoId].geo);
|
||||
double uNear;
|
||||
partBsp->closestParameter(firstPoint, uNear);
|
||||
GCS::BSpline &bsp = BSplines[Geoms[geoId].index];
|
||||
auto& knots = bsp.knots;
|
||||
auto upperknot = std::upper_bound(
|
||||
knots.begin(), knots.end(), uNear,
|
||||
[](double u, double* element) {
|
||||
return u < *element;
|
||||
});
|
||||
|
||||
size_t idx = 0;
|
||||
// skipping the first knot for adjustment
|
||||
// TODO: ensure this works for periodic as well
|
||||
for (size_t i=1; i<bsp.mult.size() && knots[i]!=*upperknot; ++i)
|
||||
idx += bsp.mult[i];
|
||||
|
||||
MoveParameters.resize(2*(bsp.degree+1)); // x[idx],y[idx],x[idx+1],y[idx+1],...
|
||||
|
||||
size_t mvindex = 0;
|
||||
auto lastIt = (idx + bsp.degree + 1) % bsp.poles.size();
|
||||
for (size_t i = idx; i != lastIt; i=(i+1)%bsp.poles.size(), ++mvindex) {
|
||||
GCS::Point p1;
|
||||
p1.x = &MoveParameters[mvindex];
|
||||
++mvindex;
|
||||
p1.y = &MoveParameters[mvindex];
|
||||
|
||||
*p1.x = *bsp.poles[i].x;
|
||||
*p1.y = *bsp.poles[i].y;
|
||||
|
||||
GCSsys.addConstraintP2PCoincident(p1,bsp.poles[i],GCS::DefaultTemporaryConstraint);
|
||||
}
|
||||
|
||||
InitParameters = MoveParameters;
|
||||
|
||||
GCSsys.initSolution();
|
||||
isInitMove = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Sketch::movePoint(int geoId, PointPos pos, Base::Vector3d toPoint, bool relative)
|
||||
{
|
||||
geoId = checkGeoId(geoId);
|
||||
|
||||
@@ -133,10 +133,19 @@ public:
|
||||
*/
|
||||
int initMove(int geoId, PointPos pos, bool fine=true);
|
||||
|
||||
/** Initializes a B-spline piece drag by setting the current
|
||||
* sketch status as a reference. Only moves piece around `firstPoint`.
|
||||
*/
|
||||
int initBSplinePieceMove(int geoId, PointPos pos, const Base::Vector3d& firstPoint, bool fine=true);
|
||||
|
||||
/** Resets the initialization of a point or curve drag
|
||||
*/
|
||||
void resetInitMove();
|
||||
|
||||
/** Limits a b-spline drag to the segment around `firstPoint`.
|
||||
*/
|
||||
int limitBSplineMove(int geoId, PointPos pos, const Base::Vector3d& firstPoint);
|
||||
|
||||
/** move this point (or curve) to a new location and solve.
|
||||
* This will introduce some additional weak constraints expressing
|
||||
* a condition for satisfying the new point location!
|
||||
|
||||
@@ -450,6 +450,8 @@ public: /* Solver exposed interface */
|
||||
{solvedSketch.setRecalculateInitialSolutionWhileMovingPoint(recalculateInitialSolutionWhileMovingPoint);}
|
||||
/// Forwards a request for a temporary initMove to the solver using the current sketch state as a reference (enables dragging)
|
||||
inline int initTemporaryMove(int geoId, PointPos pos, bool fine=true);
|
||||
/// Forwards a request for a temporary initBSplinePieceMove to the solver using the current sketch state as a reference (enables dragging)
|
||||
inline int initTemporaryBSplinePieceMove(int geoId, PointPos pos, const Base::Vector3d& firstPoint, bool fine=true);
|
||||
/** Forwards a request for point or curve temporary movement to the solver using the current state as a reference (enables dragging).
|
||||
* NOTE: A temporary move operation must always be preceded by a initTemporaryMove() operation.
|
||||
*/
|
||||
@@ -692,6 +694,17 @@ inline int SketchObject::initTemporaryMove(int geoId, PointPos pos, bool fine/*=
|
||||
return solvedSketch.initMove(geoId,pos,fine);
|
||||
}
|
||||
|
||||
inline int SketchObject::initTemporaryBSplinePieceMove(int geoId, PointPos pos, const Base::Vector3d& firstPoint, bool fine)
|
||||
{
|
||||
// if a previous operation did not update the geometry (including geometry extensions)
|
||||
// or constraints (including any deleted pointer, as in renameConstraint) of the solver,
|
||||
// here we update them before starting a temporary operation.
|
||||
if(solverNeedsUpdate)
|
||||
solve();
|
||||
|
||||
return solvedSketch.initBSplinePieceMove(geoId,pos,firstPoint,fine);
|
||||
}
|
||||
|
||||
inline int SketchObject::moveTemporaryPoint(int geoId, PointPos pos, Base::Vector3d toPoint, bool relative/*=false*/)
|
||||
{
|
||||
return solvedSketch.movePoint(geoId, pos, toPoint, relative);
|
||||
|
||||
@@ -1234,8 +1234,13 @@ bool ViewProviderSketch::mouseMove(const SbVec2s &cursorPos, Gui::View3DInventor
|
||||
drag.resetVector();
|
||||
}
|
||||
|
||||
getSketchObject()->initTemporaryMove(drag.DragCurve, Sketcher::PointPos::none, false);
|
||||
|
||||
if (geo->getTypeId() == Part::GeomBSplineCurve::getClassTypeId()) {
|
||||
getSketchObject()->initTemporaryBSplinePieceMove(
|
||||
drag.DragCurve, Sketcher::PointPos::none,
|
||||
Base::Vector3d(drag.xInit, drag.yInit, 0.0), false);
|
||||
} else {
|
||||
getSketchObject()->initTemporaryMove(drag.DragCurve, Sketcher::PointPos::none, false);
|
||||
}
|
||||
} else {
|
||||
Mode = STATUS_NONE;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user