Constraints issues with the polyline Arc

It seems that I’ve isolated issue that’s been causing me the pain in my question for the polyline arc.

The issue that I’ve been having relates to arcs which appear to be drawn clockwise but are rendered clockwise by reversing the start and end points.    When I disabled the code, for applying the coincident point constraint my pictures seemed to be coming out better, but unfortunately the points are not connected.

Interestingly enough, when things went weird, it appears to be related to an autoconstraint kicking in.   It seems like these are occurring further upstream or possible some residual code I haven’t figured out yet.
Anyway as I said when I disabled my attempt at a applying a coincident point constraint things looked better:

The 4’th from the left on the top row actually drew out correctly but when I moved them it came appart because the coincident point constraint was applied.

On the bottom row, things got weird by themselves.  It seems to be intermittent a coincident point constraint snuck in there somehow.

 

 

My pain for the moment seems to be centered here:

//                if (coincidentPoint != 0)
//                {
//                    Gui::Command::doCommand(Gui::Command::Doc,”App.ActiveDocument.%s.addConstraint(Sketcher.Constraint(‘Coincident’,%i,%i,%i,1)) ”
//                          ,sketchgui->getObject()->getNameInDocument()
//                          ,previousCurve-1,coincidentPoint,previousCurve
//                          );
//

Because this is a python call, my IDE wont single step into it which makes it difficult to see whats going on.

For those interested this is what my release button code looks like at the moment:

virtual bool releaseButton(Base::Vector2D onSketchPos){

if (Mode==STATUS_LINE_Do || Mode==STATUS_LINE_Close||Mode==STATUS_ARC_Do || Mode==STATUS_ARC_Close )
{

if (Mode==STATUS_LINE_Do || Mode==STATUS_LINE_Close)
{
// open the transaction
Gui::Command::openCommand(“add sketch wire”);
// issue the geometry
Gui::Command::doCommand(Gui::Command::Doc,”App.ActiveDocument.%s.addGeometry(Part.Line(App.Vector(%f,%f,0),App.Vector(%f,%f,0)))”,
sketchgui->getObject()->getNameInDocument(),
EditCurve[0].fX,EditCurve[0].fY,EditCurve[1].fX,EditCurve[1].fY);
}
else
{//We’re dealing with an Arc
Gui::Command::openCommand(“Add sketch arc”);
Gui::Command::doCommand(Gui::Command::Doc,
“App.ActiveDocument.%s.addGeometry(Part.ArcOfCircle”
“(Part.Circle(App.Vector(%f,%f,0),App.Vector(0,0,1),%f),”
“%f,%f))”,
sketchgui->getObject()->getNameInDocument(),
CenterPoint.fX, CenterPoint.fY, radiusLength,
startAngleDraw, endAngleDraw); //arcAngle > 0 ? 0 : 1);
}
// issue the constraint

if (previousCurve != -1){
//we need to figure which point on the previous curve we’re connecting to
//if the we have a ccw arc we should be connecting to the second point
//if we’re going cw the start/ends are reversed since the arc is rendered ccw
//A line in theory should be the second point, but if we’re restarting the polyline is could
//todo need to check the previous curve(once this is all working
//if we don’t have a match on the previous curve need to keep going back till find one to make it coincident
int coincidentPoint=0;

const Part::Geometry *geom = sketchgui->getSketchObject()->getGeometry(previousCurve);
if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
const Part::GeomLineSegment *lineSeg = dynamic_cast<const Part::GeomLineSegment *>(geom);
//if (EditCurve[0] == Base::Vector2D(lineSeg->getStartPoint().x, lineSeg->getStartPoint().y))
//    coincidentPoint=1;
//else if (EditCurve[0] == Base::Vector2D(lineSeg->getEndPoint().x, lineSeg->getEndPoint().y));
coincidentPoint=2;
}
else if(geom->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()){
//The previous element is an arc.
const Part::GeomArcOfCircle *arcSeg = dynamic_cast<const Part::GeomArcOfCircle *>(geom);
if (previousArcDirection==1.0)
//if (EditCurve[0] == Base::Vector2D(arcSeg->getStartPoint().x, arcSeg->getStartPoint().y))
coincidentPoint=1;
else// if  (EditCurve[0] == Base::Vector2D(arcSeg->getEndPoint().x, arcSeg->getEndPoint().y))
coincidentPoint=2;
}

//                if (coincidentPoint != 0)
//                {
//                    Gui::Command::doCommand(Gui::Command::Doc,”App.ActiveDocument.%s.addConstraint(Sketcher.Constraint(‘Coincident’,%i,%i,%i,1)) ”
//                          ,sketchgui->getObject()->getNameInDocument()
//                          ,previousCurve-1,coincidentPoint,previousCurve
//                          );
//                }
}
if (Mode==STATUS_LINE_Close|| Mode==STATUS_ARC_Close)
{
// close the loop by constrain to the first curve pointConstraint

Gui::Command::doCommand(Gui::Command::Doc,”App.ActiveDocument.%s.addConstraint(Sketcher.Constraint(‘Coincident’,%i,%2,%i,1)) ”
,sketchgui->getObject()->getNameInDocument()
,previousCurve,firstCurve
);

Gui::Command::commitCommand();
Gui::Command::updateActive();

if (sugConstr2.size() > 0) {
// exclude any coincidence constraints
std::vector<AutoConstraint> sugConstr;
for (int i=0; i < sugConstr2.size(); i++) {
if (sugConstr2[i].Type != Sketcher::Coincident)
sugConstr.push_back(sugConstr2[i]);
}
createAutoConstraints(sugConstr, getHighestCurveIndex(), Sketcher::end);
sugConstr2.clear();
}

unsetCursor();
EditCurve.clear();
resetPositionText();
sketchgui->drawEdit(EditCurve);
sketchgui->purgeHandler(); // no code after this line, Handler get deleted in ViewProvider

}

else{

Gui::Command::commitCommand();
Gui::Command::updateActive();

// Add auto constraints
if (sugConstr1.size() > 0)
{
createAutoConstraints(sugConstr1, getHighestCurveIndex(), Sketcher::start);
sugConstr1.clear();
}

if (sugConstr2.size() > 0)
{
createAutoConstraints(sugConstr2, getHighestCurveIndex(), Sketcher::end);
sugConstr2.clear();
}

//remember the vertex for the next rounds constraint..
previousCurve = getHighestCurveIndex() + 1;

// setup for the next line segment
// Use updated endPoint as autoconstraints can modify the position
const Part::Geometry *geom = sketchgui->getSketchObject()->getGeometry(getHighestCurveIndex());
if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
const Part::GeomLineSegment *lineSeg = dynamic_cast<const Part::GeomLineSegment *>(geom);
previousArcDirection=0.0;
EditCurve[0] = Base::Vector2D(lineSeg->getEndPoint().x, lineSeg->getEndPoint().y);
}
else if (geom->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()){
const Part::GeomArcOfCircle *arcSeg = dynamic_cast<const Part::GeomArcOfCircle *>(geom);
previousArcDirection=kVec.z;
if (kVec.z ==1.0)//cw arc
EditCurve[0] = Base::Vector2D(arcSeg->getStartPoint().x,arcSeg->getStartPoint().y);
else //cw arc are rendered in reverse
EditCurve[0] = Base::Vector2D(arcSeg->getEndPoint().x,arcSeg->getEndPoint().y);

}

EditCurve.resize(2);

applyCursor();

Mode = STATUS_LINE_SEEK_Second;//LineMode is checked in mousemove and will reset mode to arc
//And will resize Edit Curve to and Arc if required.

}

}
return true;
}

[5-1]

Some notes from the IRC…

tangency constraint has 3 modes, edge to edge, edge to point, and point to point
if you select two end points and apply the tangency constraint, it also enforces the coincidence of the points
in general it is more robust to use a point to point tangency constraint than a point to point coincidence + an edge to edge tangency constraints
however it should work if you just put some breakpoints in the python *Impl.cpp files

File containing routine causing me pain:
you can catch the execution of this command in PyObject* SketchPy::addConstraint(PyObject *args) inside SketchPyImp.cpp

Sketcher.Constraint(‘Coinicident…. where is that implemented?
in ConstraintPyImp.cpp

Sketch components and command line can be view by:
print App.ActiveDocument.Sketch.Geometry
1 the same for print App.ActiveDocument.Sketch.Constraints

This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *