Sketcher: fix polyline closing when coincident points are involved

This commit is contained in:
logari81 2014-02-12 22:23:43 +01:00
parent 9c8df98c9f
commit 4d918d1f8f
3 changed files with 42 additions and 19 deletions

View File

@ -1460,6 +1460,25 @@ void SketchObject::getCoincidentPoints(int VertexId, std::vector<int> &GeoIdList
getCoincidentPoints(GeoId, PosId, GeoIdList, PosIdList); getCoincidentPoints(GeoId, PosId, GeoIdList, PosIdList);
} }
bool SketchObject::arePointsCoincident(int GeoId1, PointPos PosId1,
int GeoId2, PointPos PosId2)
{
if (GeoId1 == GeoId2 && PosId1 == PosId2)
return true;
const std::vector<Constraint *> &constraints = this->Constraints.getValues();
for (std::vector<Constraint *>::const_iterator it=constraints.begin();
it != constraints.end(); ++it) {
if ((*it)->Type == Sketcher::Coincident)
if (((*it)->First == GeoId1 && (*it)->FirstPos == PosId1 &&
(*it)->Second == GeoId2 && (*it)->SecondPos == PosId2) ||
((*it)->First == GeoId2 && (*it)->FirstPos == PosId2 &&
(*it)->Second == GeoId1 && (*it)->SecondPos == PosId1))
return true;
}
return false;
}
void SketchObject::appendConflictMsg(const std::vector<int> &conflicting, std::string &msg) void SketchObject::appendConflictMsg(const std::vector<int> &conflicting, std::string &msg)
{ {
std::stringstream ss; std::stringstream ss;

View File

@ -136,6 +136,7 @@ public:
void getCoincidentPoints(int GeoId, PointPos PosId, std::vector<int> &GeoIdList, void getCoincidentPoints(int GeoId, PointPos PosId, std::vector<int> &GeoIdList,
std::vector<PointPos> &PosIdList); std::vector<PointPos> &PosIdList);
void getCoincidentPoints(int VertexId, std::vector<int> &GeoIdList, std::vector<PointPos> &PosIdList); void getCoincidentPoints(int VertexId, std::vector<int> &GeoIdList, std::vector<PointPos> &PosIdList);
bool arePointsCoincident(int GeoId1, PointPos PosId1, int GeoId2, PointPos PosId2);
/// generates a warning message about constraint conflicts and appends it to the given message /// generates a warning message about constraint conflicts and appends it to the given message
static void appendConflictMsg(const std::vector<int> &conflicting, std::string &msg); static void appendConflictMsg(const std::vector<int> &conflicting, std::string &msg);

View File

@ -502,7 +502,8 @@ public:
DrawSketchHandlerLineSet() DrawSketchHandlerLineSet()
: Mode(STATUS_SEEK_First),SegmentMode(SEGMENT_MODE_Line), : Mode(STATUS_SEEK_First),SegmentMode(SEGMENT_MODE_Line),
TransitionMode(TRANSITION_MODE_Free),suppressTransition(false),EditCurve(2), TransitionMode(TRANSITION_MODE_Free),suppressTransition(false),EditCurve(2),
firstVertex(-1),firstCurve(-1),previousCurve(-1),previousPosId(Sketcher::none) {} firstCurve(-1),previousCurve(-1),
firstPosId(Sketcher::none),previousPosId(Sketcher::none) {}
virtual ~DrawSketchHandlerLineSet() {} virtual ~DrawSketchHandlerLineSet() {}
/// mode table /// mode table
enum SELECT_MODE { enum SELECT_MODE {
@ -748,13 +749,9 @@ public:
} }
} }
// in case a transition is set up, firstCurve and firstVertex should // remember our first point (even if we are doing a transition from a previous curve)
// remain set to -1 in order to disable closing the wire
if (previousCurve == -1) {
// remember our first point
firstVertex = getHighestVertexIndex() + 1;
firstCurve = getHighestCurveIndex() + 1; firstCurve = getHighestCurveIndex() + 1;
} firstPosId = Sketcher::start;
if (SegmentMode == SEGMENT_MODE_Line) if (SegmentMode == SEGMENT_MODE_Line)
EditCurve.resize(TransitionMode == TRANSITION_MODE_Free ? 2 : 3); EditCurve.resize(TransitionMode == TRANSITION_MODE_Free ? 2 : 3);
@ -771,10 +768,20 @@ public:
sketchgui->drawEdit(EditCurve); sketchgui->drawEdit(EditCurve);
sketchgui->purgeHandler(); // no code after this line, Handler get deleted in ViewProvider sketchgui->purgeHandler(); // no code after this line, Handler get deleted in ViewProvider
} }
if (sketchgui->getPreselectPoint() == firstVertex && firstVertex != -1)
Mode = STATUS_Close;
else
Mode = STATUS_Do; Mode = STATUS_Do;
if (sketchgui->getPreselectPoint() != -1 && firstPosId != Sketcher::none) {
int GeoId;
Sketcher::PointPos PosId;
sketchgui->getSketchObject()->getGeoVertexIndex(sketchgui->getPreselectPoint(),GeoId,PosId);
if (sketchgui->getSketchObject()->arePointsCoincident(GeoId,PosId,firstCurve,firstPosId))
Mode = STATUS_Close;
}
else if (sketchgui->getPreselectCross() == 0 && firstPosId != Sketcher::none) {
// close line started at root point
if (sketchgui->getSketchObject()->arePointsCoincident(-1,Sketcher::start,firstCurve,firstPosId))
Mode = STATUS_Close;
}
} }
return true; return true;
} }
@ -806,7 +813,7 @@ public:
std::min(startAngle,endAngle), std::max(startAngle,endAngle)); std::min(startAngle,endAngle), std::max(startAngle,endAngle));
} }
// issue the constraint // issue the constraint
if (previousCurve != -1) { if (previousPosId != Sketcher::none) {
int lastCurve = getHighestCurveIndex(); int lastCurve = getHighestCurveIndex();
Sketcher::PointPos lastStartPosId = (SegmentMode == SEGMENT_MODE_Arc && startAngle > endAngle) ? Sketcher::PointPos lastStartPosId = (SegmentMode == SEGMENT_MODE_Arc && startAngle > endAngle) ?
Sketcher::end : Sketcher::start; Sketcher::end : Sketcher::start;
@ -814,7 +821,7 @@ public:
Sketcher::start : Sketcher::end; Sketcher::start : Sketcher::end;
// in case of a tangency constraint, the coincident constraint is redundant // in case of a tangency constraint, the coincident constraint is redundant
std::string constrType = "Coincident"; std::string constrType = "Coincident";
if (!suppressTransition) { if (!suppressTransition && previousCurve != -1) {
if (TransitionMode == TRANSITION_MODE_Tangent) if (TransitionMode == TRANSITION_MODE_Tangent)
constrType = "Tangent"; constrType = "Tangent";
else if (TransitionMode == TRANSITION_MODE_Perpendicular_L || else if (TransitionMode == TRANSITION_MODE_Perpendicular_L ||
@ -826,10 +833,6 @@ public:
sketchgui->getObject()->getNameInDocument(), constrType.c_str(), sketchgui->getObject()->getNameInDocument(), constrType.c_str(),
previousCurve, previousPosId, lastCurve, lastStartPosId); previousCurve, previousPosId, lastCurve, lastStartPosId);
if (Mode == STATUS_Close) { if (Mode == STATUS_Close) {
int firstGeoId;
Sketcher::PointPos firstPosId;
sketchgui->getSketchObject()->getGeoVertexIndex(firstVertex, firstGeoId, firstPosId);
//assert(firstCurve == firstGeoId);
// close the loop by constrain to the first curve point // close the loop by constrain to the first curve point
Gui::Command::doCommand(Gui::Command::Doc, Gui::Command::doCommand(Gui::Command::Doc,
"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Coincident',%i,%i,%i,%i)) ", "App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Coincident',%i,%i,%i,%i)) ",
@ -907,9 +910,9 @@ protected:
bool suppressTransition; bool suppressTransition;
std::vector<Base::Vector2D> EditCurve; std::vector<Base::Vector2D> EditCurve;
int firstVertex;
int firstCurve; int firstCurve;
int previousCurve; int previousCurve;
Sketcher::PointPos firstPosId;
Sketcher::PointPos previousPosId; Sketcher::PointPos previousPosId;
std::vector<AutoConstraint> sugConstr1, sugConstr2; std::vector<AutoConstraint> sugConstr1, sugConstr2;