[Sketcher] Fix some coincidence issues in B-spline drawing

See https://github.com/FreeCAD/FreeCAD/pull/8530#issuecomment-1474824366.

When there are already existing points and coincidence auto-constraints are
added in the process of making a B-spline (either by control points or
interpolation), unintended behaviour can happen.

Additionally, when creating B-spline by interpolation, if consecutive points are
coincident (or very close to each other), the OCCT algorithm fails. This is also
prevented in this commit.
This commit is contained in:
Ajinkya Dahale
2023-03-21 21:26:40 +05:30
committed by abdullahtahiriyo
parent 60e79a14e4
commit fc3086a96e
2 changed files with 33 additions and 9 deletions

View File

@@ -141,8 +141,18 @@ public:
// check if coincident with first pole
for(auto & ac : sugConstr.back()) {
if( ac.Type == Sketcher::Coincident && ac.GeoId == poleGeoIds[0] && ac.PosId == Sketcher::PointPos::mid ) {
IsClosed = true;
if (ac.Type == Sketcher::Coincident) {
if (ac.GeoId == poleGeoIds[0] && ac.PosId == Sketcher::PointPos::mid)
IsClosed = true;
else {
// The coincidence with first point may be indirect
const auto coincidents =
static_cast<Sketcher::SketchObject*>(sketchgui->getObject())
->getAllCoincidentPoints(ac.GeoId, ac.PosId);
if (coincidents.find(poleGeoIds[0]) != coincidents.end() &&
coincidents.at(poleGeoIds[0]) == Sketcher::PointPos::mid)
IsClosed = true;
}
}
}

View File

@@ -136,17 +136,31 @@ public:
addSugConstraint();
}
else if (Mode == STATUS_SEEK_ADDITIONAL_POINTS) {
BSplineKnots.push_back(onSketchPos);
BSplineMults.push_back(1);// NOTE: not strictly true for end-points
// check if coincident with first knot
// check if coincidence issues with first or last added knot
for (auto& ac : sugConstr.back()) {
if (ac.Type == Sketcher::Coincident && ac.GeoId == knotGeoIds[0]
&& ac.PosId == Sketcher::PointPos::start) {
IsClosed = true;
if (ac.Type == Sketcher::Coincident) {
if (ac.GeoId == knotGeoIds[0] && ac.PosId == Sketcher::PointPos::start)
IsClosed = true;
else {
// The coincidence with first point may be indirect
const auto coincidents =
static_cast<Sketcher::SketchObject*>(sketchgui->getObject())
->getAllCoincidentPoints(ac.GeoId, ac.PosId);
if (coincidents.find(knotGeoIds[0]) != coincidents.end() &&
coincidents.at(knotGeoIds[0]) == Sketcher::PointPos::start)
IsClosed = true;
else if (coincidents.find(knotGeoIds.back()) != coincidents.end() &&
coincidents.at(knotGeoIds.back()) == Sketcher::PointPos::start) {
return true;// OCCT doesn't allow consecutive points being coincident
}
}
}
}
BSplineKnots.push_back(onSketchPos);
BSplineMults.push_back(1);// NOTE: not strictly true for end-points
if (IsClosed) {
Mode = STATUS_CLOSE;