diff --git a/src/Mod/Sketcher/App/SketchObject.cpp b/src/Mod/Sketcher/App/SketchObject.cpp index 9e52eceb30..8a25fcce54 100644 --- a/src/Mod/Sketcher/App/SketchObject.cpp +++ b/src/Mod/Sketcher/App/SketchObject.cpp @@ -2976,6 +2976,7 @@ int SketchObject::split(int GeoId, const Base::Vector3d &point) Base::Vector3d startPoint, endPoint, splitPoint; double radius, startAngle, endAngle, splitAngle=0.0; + double startParam, endParam, splitParam=0.0; unsigned int longestPart = 0; @@ -3116,11 +3117,65 @@ int SketchObject::split(int GeoId, const Base::Vector3d &point) } } } + else if (geo->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()) { + const Part::GeomArcOfEllipse *arc = static_cast(geo); + + startPoint = arc->getStartPoint(); + endPoint = arc->getEndPoint(); + + // find split point + arc->closestParameter(point, splitParam); + startParam = arc->getFirstParameter(); + endParam = arc->getLastParameter(); + // TODO: Using parameter difference as a poor substitute of length. + // Computing length of an arc of an ellipse would be expensive. + if (endParam - splitParam > splitParam - startParam) { + longestPart = 1; + } + + // create new arcs + auto newArc = static_cast(arc->clone()); + int newId(GeoEnum::GeoUndef); + newGeometries.push_back(newArc); + newArc->setRange(startParam, splitParam, /*emulateCCW=*/true); + newId = addGeometry(newArc); + if (newId >= 0) { + newIds.push_back(newId); + setConstruction(newId, GeometryFacade::getConstruction(geo)); + exposeInternalGeometry(newId); + + // the "second" half + auto newArc2 = static_cast(arc->clone()); + int newId2(GeoEnum::GeoUndef); + newArc2->setRange(splitParam, endParam, /*emulateCCW=*/true); + newId2 = addGeometry(newArc2); + if (newId2 >= 0) { + newIds.push_back(newId2); + setConstruction(newId2, GeometryFacade::getConstruction(geo)); + exposeInternalGeometry(newId2); + + // 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); + + // TODO: Do we apply constraints on center etc of the conics? + + // 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; + } + } + } else if (geo->getTypeId() == Part::GeomBSplineCurve::getClassTypeId()) { const Part::GeomBSplineCurve *bsp = static_cast(geo); // find split point - double splitParam; bsp->closestParameter(point, splitParam); // what to do for periodic b-splines? @@ -3218,7 +3273,7 @@ int SketchObject::split(int GeoId, const Base::Vector3d &point) unsigned int initial = 0; unsigned int limit = newIds.size(); - if (geo->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) { + if (geo->isDerivedFrom(Part::GeomArcOfConic::getClassTypeId())) { const Part::Geometry *conGeo = getGeometry(conId); if (conGeo && conGeo->isDerivedFrom(Part::GeomCurve::getClassTypeId())) { std::vector> intersections; @@ -3282,6 +3337,12 @@ int SketchObject::split(int GeoId, const Base::Vector3d &point) targetId = newIds[1]; } } + else if (geo->isDerivedFrom(Part::GeomArcOfConic::getClassTypeId())) { + double conParam; + static_cast(geo)->closestParameter(conPoint, conParam); + if (conParam > splitParam) + targetId = newIds[1]; + } trans->Second = targetId; newConstraints.push_back(trans); diff --git a/src/Mod/Sketcher/Gui/DrawSketchHandlerSplitting.h b/src/Mod/Sketcher/Gui/DrawSketchHandlerSplitting.h index f1edddba01..90f3e60b0d 100644 --- a/src/Mod/Sketcher/Gui/DrawSketchHandlerSplitting.h +++ b/src/Mod/Sketcher/Gui/DrawSketchHandlerSplitting.h @@ -53,6 +53,7 @@ public: if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId() || geom->getTypeId() == Part::GeomCircle::getClassTypeId() || geom->getTypeId() == Part::GeomArcOfCircle::getClassTypeId() + || geom->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId() || geom->getTypeId() == Part::GeomBSplineCurve::getClassTypeId()) { return true; } @@ -90,6 +91,7 @@ public: if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId() || geom->getTypeId() == Part::GeomCircle::getClassTypeId() || geom->getTypeId() == Part::GeomArcOfCircle::getClassTypeId() + || geom->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId() || geom->getTypeId() == Part::GeomBSplineCurve::getClassTypeId()) { try { Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Split edge"));