[Sketcher] Support splitting b-splines

This commit is contained in:
Ajinkya Dahale
2022-03-02 04:22:06 -05:00
committed by abdullahtahiriyo
parent b937ca35d4
commit 062450be1b
2 changed files with 79 additions and 3 deletions

View File

@@ -3116,14 +3116,88 @@ int SketchObject::split(int GeoId, const Base::Vector3d &point)
}
}
}
else if (geo->getTypeId() == Part::GeomBSplineCurve::getClassTypeId()) {
const Part::GeomBSplineCurve *bsp = static_cast<const Part::GeomBSplineCurve *>(geo);
// find split point
double splitParam;
bsp->closestParameter(point, splitParam);
// what to do for periodic b-splines?
if (bsp->isPeriodic()) {
Part::GeomBSplineCurve* newBsp;
int newId(GeoEnum::GeoUndef);
newBsp = static_cast<Part::GeomBSplineCurve *>(bsp->clone());
newGeometries.push_back(newBsp);
newBsp->Trim(splitParam, splitParam);
newId = addGeometry(newBsp);
if (newId >= 0) {
newIds.push_back(newId);
setConstruction(newId, GeometryFacade::getConstruction(geo));
exposeInternalGeometry(newId);
// no constraints to transfer here, and we assume the split is to "break" the b-spline
ok = true;
}
}
else {
// create new b-splines
Part::GeomBSplineCurve* newBsp;
int newId(GeoEnum::GeoUndef);
newBsp = static_cast<Part::GeomBSplineCurve *>(bsp->clone());
newGeometries.push_back(newBsp);
newBsp->Trim(newBsp->getFirstParameter(), splitParam);
newId = addGeometry(newBsp);
if (newId >= 0) {
newIds.push_back(newId);
setConstruction(newId, GeometryFacade::getConstruction(geo));
exposeInternalGeometry(newId);
// the "second" half
newBsp = static_cast<Part::GeomBSplineCurve *>(bsp->clone());
newGeometries.push_back(newBsp);
newBsp->Trim(splitParam, newBsp->getLastParameter());
newId = addGeometry(newBsp);
if (newId >= 0) {
newIds.push_back(newId);
setConstruction(newId, GeometryFacade::getConstruction(geo));
exposeInternalGeometry(newId);
// apply appropriate constraints on the new points at split point
Constraint* joint = new Constraint();
joint->Type = Coincident;
joint->First = newIds[0];
joint->FirstPos = PointPos::end;
joint->Second = newIds[1];
joint->SecondPos = PointPos::start;
newConstraints.push_back(joint);
// transfer constraints from start and end of original spline
transferConstraints(GeoId, PointPos::start, newIds[0], PointPos::start, true);
transferConstraints(GeoId, PointPos::end, newIds[1], PointPos::end, true);
ok = true;
}
}
}
}
if (ok) {
std::vector<int> oldConstraints;
getConstraintIndices(GeoId, oldConstraints);
const auto& allConstraints = this->Constraints.getValues();
// keep constraints on internal geometries so they are deleted
// when the old curve is deleted
oldConstraints.erase(
std::remove_if(
oldConstraints.begin(), oldConstraints.end(),
[=](const auto& i){return allConstraints[i]->Type == InternalAlignment;}),
oldConstraints.end());
for (unsigned int i = 0; i < oldConstraints.size(); ++i) {
Constraint *con = this->Constraints.getValues()[oldConstraints[i]];
Constraint *con = allConstraints[oldConstraints[i]];
int conId = con->First;
PointPos conPos = con->FirstPos;
if (conId == GeoId) {

View File

@@ -52,7 +52,8 @@ public:
const Part::Geometry *geom = Sketch->getGeometry(GeoId);
if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId()
|| geom->getTypeId() == Part::GeomCircle::getClassTypeId()
|| geom->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) {
|| geom->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()
|| geom->getTypeId() == Part::GeomBSplineCurve::getClassTypeId()) {
return true;
}
}
@@ -88,7 +89,8 @@ public:
const Part::Geometry *geom = sketchgui->getSketchObject()->getGeometry(GeoId);
if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId()
|| geom->getTypeId() == Part::GeomCircle::getClassTypeId()
|| geom->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) {
|| geom->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()
|| geom->getTypeId() == Part::GeomBSplineCurve::getClassTypeId()) {
try {
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Split edge"));
Gui::cmdAppObjectArgs(sketchgui->getObject(), "split(%d,App.Vector(%f,%f,0))",