Move tangent to general constraint mode framework

This commit is contained in:
AjinkyaDahale 2017-02-02 23:49:19 +05:30 committed by wmayer
parent df658ae889
commit adc13eda06

View File

@ -997,6 +997,46 @@ protected:
} }
}; };
/* XPM */
static const char *cursor_genericconstraint[]={
"32 32 3 1",
" c None",
". c #FFFFFF",
"+ c #FF0000",
" . ",
" . ",
" . ",
" . ",
" . ",
" ",
"..... ..... ",
" ",
" . ",
" . ",
" . ",
" . ",
" . ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",};
void CmdSketcherConstraint::activated(int /*iMsg*/) void CmdSketcherConstraint::activated(int /*iMsg*/)
{ {
ActivateHandler(getActiveGuiDocument(), ActivateHandler(getActiveGuiDocument(),
@ -2867,7 +2907,7 @@ CmdSketcherConstrainPerpendicular::CmdSketcherConstrainPerpendicular()
{SelVertexOrRoot, SelEdge, SelEdgeOrAxis}, {SelVertexOrRoot, SelEdge, SelEdgeOrAxis},
{SelVertexOrRoot, SelEdgeOrAxis, SelEdge}, {SelVertexOrRoot, SelEdgeOrAxis, SelEdge},
{SelEdge, SelVertexOrRoot, SelEdgeOrAxis}, {SelEdge, SelVertexOrRoot, SelEdgeOrAxis},
{SelEdgeOrAxis, SelVertex, SelEdge}}; {SelEdgeOrAxis, SelVertexOrRoot, SelEdge}};
; ;
constraintCursor = cursor_createperpconstraint; constraintCursor = cursor_createperpconstraint;
} }
@ -3242,7 +3282,6 @@ void CmdSketcherConstrainPerpendicular::applyConstraint(std::vector<SelIdPair> &
{ {
SketcherGui::ViewProviderSketch* sketchgui = static_cast<SketcherGui::ViewProviderSketch*>(getActiveGuiDocument()->getInEdit()); SketcherGui::ViewProviderSketch* sketchgui = static_cast<SketcherGui::ViewProviderSketch*>(getActiveGuiDocument()->getInEdit());
Sketcher::SketchObject* Obj = sketchgui->getSketchObject(); Sketcher::SketchObject* Obj = sketchgui->getSketchObject();
QString strError;
int GeoId1 = Constraint::GeoUndef, GeoId2 = Constraint::GeoUndef, GeoId3 = Constraint::GeoUndef; int GeoId1 = Constraint::GeoUndef, GeoId2 = Constraint::GeoUndef, GeoId3 = Constraint::GeoUndef;
Sketcher::PointPos PosId1 = Sketcher::none, PosId2 = Sketcher::none, PosId3 = Sketcher::none; Sketcher::PointPos PosId1 = Sketcher::none, PosId2 = Sketcher::none, PosId3 = Sketcher::none;
@ -3414,7 +3453,7 @@ void CmdSketcherConstrainPerpendicular::applyConstraint(std::vector<SelIdPair> &
break; break;
} }
case 4: // {SelEdge, SelVertexOrRoot, SelEdgeOrAxis} case 4: // {SelEdge, SelVertexOrRoot, SelEdgeOrAxis}
case 5: // {SelEdgeOrAxis, SelVertex, SelEdge} case 5: // {SelEdgeOrAxis, SelVertexOrRoot, SelEdge}
{ {
//let's sink the point to be GeoId3. //let's sink the point to be GeoId3.
GeoId1 = selSeq.at(0).GeoId; GeoId2 = selSeq.at(2).GeoId; GeoId3 = selSeq.at(1).GeoId; GeoId1 = selSeq.at(0).GeoId; GeoId2 = selSeq.at(2).GeoId; GeoId3 = selSeq.at(1).GeoId;
@ -3482,16 +3521,26 @@ void CmdSketcherConstrainPerpendicular::applyConstraint(std::vector<SelIdPair> &
return; return;
}; };
strError = QObject::tr("With 3 objects, there must be 2 curves and 1 point.", "tangent constraint");
} }
// ====================================================================================== // ======================================================================================
DEF_STD_CMD_A(CmdSketcherConstrainTangent); //DEF_STD_CMD_A(CmdSketcherConstrainTangent);
class CmdSketcherConstrainTangent : public CmdSketcherConstraint
{
public:
CmdSketcherConstrainTangent();
virtual ~CmdSketcherConstrainTangent(){}
virtual const char* className() const
{ return "CmdSketcherConstrainTangent"; }
protected:
virtual void activated(int iMsg);
virtual void applyConstraint(std::vector<SelIdPair> &selSeq, int seqIndex);
};
CmdSketcherConstrainTangent::CmdSketcherConstrainTangent() CmdSketcherConstrainTangent::CmdSketcherConstrainTangent()
:Command("Sketcher_ConstrainTangent") :CmdSketcherConstraint("Sketcher_ConstrainTangent")
{ {
sAppModule = "Sketcher"; sAppModule = "Sketcher";
sGroup = QT_TR_NOOP("Sketcher"); sGroup = QT_TR_NOOP("Sketcher");
@ -3502,6 +3551,14 @@ CmdSketcherConstrainTangent::CmdSketcherConstrainTangent()
sPixmap = "Constraint_Tangent"; sPixmap = "Constraint_Tangent";
sAccel = "T"; sAccel = "T";
eType = ForEdit; eType = ForEdit;
allowedSelSequences = {{SelEdge, SelEdgeOrAxis}, {SelEdgeOrAxis, SelEdge}, /* Two Curves */
{SelVertexOrRoot, SelEdge, SelEdgeOrAxis},
{SelVertexOrRoot, SelEdgeOrAxis, SelEdge},
{SelEdge, SelVertexOrRoot, SelEdgeOrAxis},
{SelEdgeOrAxis, SelVertexOrRoot, SelEdge}, /* Two Curves and a Point */
{SelVertexOrRoot, SelVertex} /*Two Endpoints*/ /*No Place One Endpoint and One Curve*/};
constraintCursor = cursor_genericconstraint;
} }
void CmdSketcherConstrainTangent::activated(int iMsg) void CmdSketcherConstrainTangent::activated(int iMsg)
@ -3509,7 +3566,7 @@ void CmdSketcherConstrainTangent::activated(int iMsg)
Q_UNUSED(iMsg); Q_UNUSED(iMsg);
QString strBasicHelp = QString strBasicHelp =
QObject::tr( QObject::tr(
"There is a number of ways this constraint can be applied.\n\n" "There are a number of ways this constraint can be applied.\n\n"
"Accepted combinations: two curves; an endpoint and a curve; two endpoints; two curves and a point.", "Accepted combinations: two curves; an endpoint and a curve; two endpoints; two curves and a point.",
/*disambig.:*/ "tangent constraint"); /*disambig.:*/ "tangent constraint");
@ -3519,12 +3576,16 @@ void CmdSketcherConstrainTangent::activated(int iMsg)
// only one sketch with its subelements are allowed to be selected // only one sketch with its subelements are allowed to be selected
if (selection.size() != 1) { if (selection.size() != 1) {
strError = QObject::tr("Select some geometry from the sketch.", "tangent constraint"); // strError = QObject::tr("Select some geometry from the sketch.", "tangent constraint");
if (!strError.isEmpty()) strError.append(QString::fromLatin1("\n\n")); // if (!strError.isEmpty()) strError.append(QString::fromLatin1("\n\n"));
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), // QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
strError+strBasicHelp); // strError+strBasicHelp);
return;
ActivateHandler(getActiveGuiDocument(),
new DrawSketchHandlerGenConstraint(constraintCursor, this));
getSelection().clearSelection();
return;
} }
// get the needed lists and objects // get the needed lists and objects
@ -3825,9 +3886,259 @@ void CmdSketcherConstrainTangent::activated(int iMsg)
return; return;
} }
bool CmdSketcherConstrainTangent::isActive(void) void CmdSketcherConstrainTangent::applyConstraint(std::vector<SelIdPair> &selSeq, int seqIndex)
{ {
return isCreateConstraintActive( getActiveGuiDocument() ); SketcherGui::ViewProviderSketch* sketchgui = static_cast<SketcherGui::ViewProviderSketch*>(getActiveGuiDocument()->getInEdit());
Sketcher::SketchObject* Obj = sketchgui->getSketchObject();
QString strError;
int GeoId1 = Constraint::GeoUndef, GeoId2 = Constraint::GeoUndef, GeoId3 = Constraint::GeoUndef;
Sketcher::PointPos PosId1 = Sketcher::none, PosId2 = Sketcher::none, PosId3 = Sketcher::none;
switch (seqIndex) {
case 0: // {SelEdge, SelEdgeOrAxis}
case 1: // {SelEdgeOrAxis, SelEdge}
{
GeoId1 = selSeq.at(0).GeoId; GeoId2 = selSeq.at(1).GeoId;
const Part::Geometry *geom1 = Obj->getGeometry(GeoId1);
const Part::Geometry *geom2 = Obj->getGeometry(GeoId2);
if( geom1 && geom2 &&
( geom1->getTypeId() == Part::GeomBSplineCurve::getClassTypeId() ||
geom2->getTypeId() == Part::GeomBSplineCurve::getClassTypeId() )){
// unsupported until tangent to BSpline at any point implemented.
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("Tangency to BSpline edge currently unsupported."));
return;
}
if( geom1 && geom2 &&
( geom1->getTypeId() == Part::GeomEllipse::getClassTypeId() ||
geom2->getTypeId() == Part::GeomEllipse::getClassTypeId() )){
if(geom1->getTypeId() != Part::GeomEllipse::getClassTypeId())
std::swap(GeoId1,GeoId2);
// GeoId1 is the ellipse
geom1 = Obj->getGeometry(GeoId1);
geom2 = Obj->getGeometry(GeoId2);
if( geom2->getTypeId() == Part::GeomEllipse::getClassTypeId() ||
geom2->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId() ||
geom2->getTypeId() == Part::GeomCircle::getClassTypeId() ||
geom2->getTypeId() == Part::GeomArcOfCircle::getClassTypeId() ) {
Gui::Command::openCommand("add tangent constraint point");
makeTangentToEllipseviaNewPoint(Obj,geom1,geom2,GeoId1,GeoId2);
getSelection().clearSelection();
return;
}
else if( geom2->getTypeId() == Part::GeomArcOfHyperbola::getClassTypeId() ) {
Gui::Command::openCommand("add tangent constraint point");
makeTangentToArcOfHyperbolaviaNewPoint(Obj,geom2,geom1,GeoId2,GeoId1);
getSelection().clearSelection();
return;
}
else if( geom2->getTypeId() == Part::GeomArcOfParabola::getClassTypeId() ) {
Gui::Command::openCommand("add tangent constraint point");
makeTangentToArcOfParabolaviaNewPoint(Obj,geom2,geom1,GeoId2,GeoId1);
getSelection().clearSelection();
return;
}
}
else if( geom1 && geom2 &&
( geom1->getTypeId() == Part::GeomArcOfHyperbola::getClassTypeId() ||
geom2->getTypeId() == Part::GeomArcOfHyperbola::getClassTypeId() )){
if(geom1->getTypeId() != Part::GeomArcOfHyperbola::getClassTypeId())
std::swap(GeoId1,GeoId2);
// GeoId1 is the arc of hyperbola
geom1 = Obj->getGeometry(GeoId1);
geom2 = Obj->getGeometry(GeoId2);
if( geom2->getTypeId() == Part::GeomArcOfHyperbola::getClassTypeId() ||
geom2->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId() ||
geom2->getTypeId() == Part::GeomCircle::getClassTypeId() ||
geom2->getTypeId() == Part::GeomArcOfCircle::getClassTypeId() ||
geom2->getTypeId() == Part::GeomLineSegment::getClassTypeId() ) {
Gui::Command::openCommand("add tangent constraint point");
makeTangentToArcOfHyperbolaviaNewPoint(Obj,geom1,geom2,GeoId1,GeoId2);
getSelection().clearSelection();
return;
}
else if( geom2->getTypeId() == Part::GeomArcOfParabola::getClassTypeId() ) {
Gui::Command::openCommand("add tangent constraint point");
makeTangentToArcOfParabolaviaNewPoint(Obj,geom2,geom1,GeoId2,GeoId1);
getSelection().clearSelection();
return;
}
}
else if( geom1 && geom2 &&
( geom1->getTypeId() == Part::GeomArcOfParabola::getClassTypeId() ||
geom2->getTypeId() == Part::GeomArcOfParabola::getClassTypeId() )){
if(geom1->getTypeId() != Part::GeomArcOfParabola::getClassTypeId())
std::swap(GeoId1,GeoId2);
// GeoId1 is the arc of hyperbola
geom1 = Obj->getGeometry(GeoId1);
geom2 = Obj->getGeometry(GeoId2);
if (geom2->getTypeId() == Part::GeomArcOfParabola::getClassTypeId() ||
geom2->getTypeId() == Part::GeomArcOfHyperbola::getClassTypeId() ||
geom2->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId() ||
geom2->getTypeId() == Part::GeomCircle::getClassTypeId() ||
geom2->getTypeId() == Part::GeomArcOfCircle::getClassTypeId() ||
geom2->getTypeId() == Part::GeomLineSegment::getClassTypeId() ) {
Gui::Command::openCommand("add tangent constraint point");
makeTangentToArcOfParabolaviaNewPoint(Obj,geom1,geom2,GeoId1,GeoId2);
getSelection().clearSelection();
return;
}
}
openCommand("add tangent constraint");
Gui::Command::doCommand(
Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Tangent',%d,%d)) ",
Obj->getNameInDocument(),GeoId1,GeoId2);
commitCommand();
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher");
bool autoRecompute = hGrp->GetBool("AutoRecompute",false);
if(autoRecompute)
Gui::Command::updateActive();
return;
}
case 2: // {SelVertexOrRoot, SelEdge, SelEdgeOrAxis}
case 3: // {SelVertexOrRoot, SelEdgeOrAxis, SelEdge}
{
//let's sink the point to be GeoId3.
GeoId1 = selSeq.at(1).GeoId; GeoId2 = selSeq.at(2).GeoId; GeoId3 = selSeq.at(0).GeoId;
PosId3 = selSeq.at(0).PosId;
break;
}
case 4: // {SelEdge, SelVertexOrRoot, SelEdgeOrAxis}
case 5: // {SelEdgeOrAxis, SelVertexOrRoot, SelEdge}
{
//let's sink the point to be GeoId3.
GeoId1 = selSeq.at(0).GeoId; GeoId2 = selSeq.at(2).GeoId; GeoId3 = selSeq.at(1).GeoId;
PosId3 = selSeq.at(1).PosId;
break;
}
case 6: // {SelVertexOrRoot, SelVertex}
{
// Different notation than the previous places
GeoId1 = selSeq.at(0).GeoId; GeoId2 = selSeq.at(1).GeoId;
PosId1 = selSeq.at(0).PosId; PosId2 = selSeq.at(1).PosId;
if (isSimpleVertex(Obj, GeoId1, PosId1) ||
isSimpleVertex(Obj, GeoId2, PosId2)) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("Cannot add a tangency constraint at an unconnected point!"));
return;
}
// This code supports simple bspline endpoint tangency to any other geometric curve
const Part::Geometry *geom1 = Obj->getGeometry(GeoId1);
const Part::Geometry *geom2 = Obj->getGeometry(GeoId2);
if( geom1 && geom2 &&
( geom1->getTypeId() == Part::GeomBSplineCurve::getClassTypeId() ||
geom2->getTypeId() == Part::GeomBSplineCurve::getClassTypeId() )){
if(geom1->getTypeId() != Part::GeomBSplineCurve::getClassTypeId()) {
std::swap(GeoId1,GeoId2);
std::swap(PosId1,PosId2);
}
// GeoId1 is the bspline now
} // end of code supports simple bspline endpoint tangency
openCommand("add tangent constraint");
Gui::Command::doCommand(
Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Tangent',%d,%d,%d,%d)) ",
Obj->getNameInDocument(),GeoId1,PosId1,GeoId2,PosId2);
commitCommand();
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher");
bool autoRecompute = hGrp->GetBool("AutoRecompute",false);
if(autoRecompute)
Gui::Command::updateActive();
getSelection().clearSelection();
return;
}
default:
return;
}
if (isEdge(GeoId1, PosId1) && isEdge(GeoId2, PosId2) && isVertex(GeoId3, PosId3)) {
openCommand("add tangent constraint");
try{
//add missing point-on-object constraints
if(! IsPointAlreadyOnCurve(GeoId1, GeoId3, PosId3, Obj)){
Gui::Command::doCommand(
Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('PointOnObject',%d,%d,%d)) ",
Obj->getNameInDocument(),GeoId3,PosId3,GeoId1);
};
if(! IsPointAlreadyOnCurve(GeoId2, GeoId3, PosId3, Obj)){
Gui::Command::doCommand(
Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('PointOnObject',%d,%d,%d)) ",
Obj->getNameInDocument(),GeoId3,PosId3,GeoId2);
};
if(! IsPointAlreadyOnCurve(GeoId1, GeoId3, PosId3, Obj)){//FIXME: it's a good idea to add a check if the sketch is solved
Gui::Command::doCommand(
Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('PointOnObject',%d,%d,%d)) ",
Obj->getNameInDocument(),GeoId3,PosId3,GeoId1);
};
Gui::Command::doCommand(
Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('TangentViaPoint',%d,%d,%d,%d)) ",
Obj->getNameInDocument(), GeoId1,GeoId2,GeoId3,PosId3);
} catch (const Base::Exception& e) {
Base::Console().Error("%s\n", e.what());
QMessageBox::warning(Gui::getMainWindow(),
QObject::tr("Error"),
QString::fromLatin1(e.what()));
Gui::Command::abortCommand();
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher");
bool autoRecompute = hGrp->GetBool("AutoRecompute",false);
if(autoRecompute) // toggling does not modify the DoF of the solver, however it may affect features depending on the sketch
Gui::Command::updateActive();
return;
}
commitCommand();
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher");
bool autoRecompute = hGrp->GetBool("AutoRecompute",false);
if(autoRecompute)
Gui::Command::updateActive();
getSelection().clearSelection();
return;
};
} }
// ====================================================================================== // ======================================================================================