Sketcher: Driving/reference creation improvements and some other fixes

======================================================================

- Changing from Driving to reference does not include unnecessary solvings.
- Added some checks to avoid making Driving constraints when calling directly from python and involving only external geometry (would give redundant constraints).
- New python command toggleDriving to just change the status from reference to Driving
- New UI toolbar Command to toggle constraints
- Fix to allow switching from/to construction mode during continuous mode creation.
- Enable/Disable for constraints in constraints widget has changed to operate on multiselection and now effects "toggle" instead of enable/disable.
- Disable the option to directly create a SnellsLaw non-driving constraint (this constraint does not support direct creation, it can be toggled to non-driving after creation though).
This commit is contained in:
Abdullah Tahiri 2015-05-26 14:37:22 +02:00 committed by wmayer
parent 4dfc96e102
commit a1c3b942aa
9 changed files with 180 additions and 52 deletions

View File

@ -234,7 +234,10 @@ int SketchObject::setDriving(int ConstrId, bool isdriving)
type != Radius && type != Radius &&
type != Angle && type != Angle &&
type != SnellsLaw) type != SnellsLaw)
return -1; return -2;
if (!(vals[ConstrId]->First>=0 || vals[ConstrId]->Second>=0 || vals[ConstrId]->Third>=0) && isdriving==true)
return -3; // a constraint that does not have at least one element as not-external-geometry can never be driving.
// copy the list // copy the list
std::vector<Constraint *> newVals(vals); std::vector<Constraint *> newVals(vals);
@ -245,11 +248,7 @@ int SketchObject::setDriving(int ConstrId, bool isdriving)
this->Constraints.setValues(newVals); this->Constraints.setValues(newVals);
delete constNew; delete constNew;
int err = solve(); return 0;
if (err)
this->Constraints.setValues(vals);
return err;
} }
int SketchObject::getDriving(int ConstrId, bool &isdriving) int SketchObject::getDriving(int ConstrId, bool &isdriving)
@ -273,6 +272,38 @@ int SketchObject::getDriving(int ConstrId, bool &isdriving)
return 0; return 0;
} }
int SketchObject::toggleDriving(int ConstrId)
{
const std::vector<Constraint *> &vals = this->Constraints.getValues();
if (ConstrId < 0 || ConstrId >= int(vals.size()))
return -1;
ConstraintType type = vals[ConstrId]->Type;
if (type != Distance &&
type != DistanceX &&
type != DistanceY &&
type != Radius &&
type != Angle &&
type != SnellsLaw)
return -2;
if (!(vals[ConstrId]->First>=0 || vals[ConstrId]->Second>=0 || vals[ConstrId]->Third>=0) && vals[ConstrId]->isDriving==false)
return -3; // a constraint that does not have at least one element as not-external-geometry can never be driving.
// copy the list
std::vector<Constraint *> newVals(vals);
// clone the changed Constraint
Constraint *constNew = vals[ConstrId]->clone();
constNew->isDriving = !constNew->isDriving;
newVals[ConstrId] = constNew;
this->Constraints.setValues(newVals);
delete constNew;
return 0;
}
int SketchObject::movePoint(int GeoId, PointPos PosId, const Base::Vector3d& toPoint, bool relative) int SketchObject::movePoint(int GeoId, PointPos PosId, const Base::Vector3d& toPoint, bool relative)
{ {
Sketch sketch; Sketch sketch;
@ -489,7 +520,7 @@ int SketchObject::setConstruction(int GeoId, bool on)
newVals[GeoId]=geoNew; newVals[GeoId]=geoNew;
this->Geometry.setValues(newVals); this->Geometry.setValues(newVals);
this->Constraints.acceptGeometry(getCompleteGeometry()); //this->Constraints.acceptGeometry(getCompleteGeometry()); <= This is not necessary for a toggle. Reducing redundant solving. Abdullah
return 0; return 0;
} }

View File

@ -114,6 +114,8 @@ public:
int setDriving(int ConstrId, bool isdriving); int setDriving(int ConstrId, bool isdriving);
/// get the driving status of this constraint /// get the driving status of this constraint
int getDriving(int ConstrId, bool &isdriving); int getDriving(int ConstrId, bool &isdriving);
/// toggle the driving status of this constraint
int toggleDriving(int ConstrId);
/// move this point to a new location and solve /// move this point to a new location and solve
int movePoint(int GeoId, PointPos PosId, const Base::Vector3d& toPoint, bool relative=false); int movePoint(int GeoId, PointPos PosId, const Base::Vector3d& toPoint, bool relative=false);
/// retrieves the coordinates of a point /// retrieves the coordinates of a point

View File

@ -87,6 +87,11 @@
<Documentation> <Documentation>
<UserDocu>Get the Driving status of a datum constraint</UserDocu> <UserDocu>Get the Driving status of a datum constraint</UserDocu>
</Documentation> </Documentation>
</Methode>
<Methode Name="toggleDriving">
<Documentation>
<UserDocu>toggle the Driving status of a datum constraint</UserDocu>
</Documentation>
</Methode> </Methode>
<Methode Name="movePoint"> <Methode Name="movePoint">
<Documentation> <Documentation>

View File

@ -49,7 +49,7 @@ using namespace Sketcher;
// returns a string which represents the object e.g. when printed in python // returns a string which represents the object e.g. when printed in python
std::string SketchObjectPy::representation(void) const std::string SketchObjectPy::representation(void) const
{ {
return "<Sketcher::SketchObject>"; return "<Sketcher::SketchObject>";
} }
@ -578,7 +578,7 @@ PyObject* SketchObjectPy::setDriving(PyObject *args)
if (this->getSketchObjectPtr()->setDriving(constrid, PyObject_IsTrue(driving) ? true : false)) { if (this->getSketchObjectPtr()->setDriving(constrid, PyObject_IsTrue(driving) ? true : false)) {
std::stringstream str; std::stringstream str;
str << "Not able set Driving for constraint with the given index: " << constrid; str << "Not able set Driving/reference for constraint with the given index: " << constrid;
PyErr_SetString(PyExc_ValueError, str.str().c_str()); PyErr_SetString(PyExc_ValueError, str.str().c_str());
return 0; return 0;
} }
@ -603,6 +603,23 @@ PyObject* SketchObjectPy::getDriving(PyObject *args)
return Py::new_reference_to(Py::Boolean(driving)); return Py::new_reference_to(Py::Boolean(driving));
} }
PyObject* SketchObjectPy::toggleDriving(PyObject *args)
{
int constrid;
if (!PyArg_ParseTuple(args, "i", &constrid))
return 0;
if (this->getSketchObjectPtr()->toggleDriving(constrid)) {
std::stringstream str;
str << "Not able toggle Driving for constraint with the given index: " << constrid;
PyErr_SetString(PyExc_ValueError, str.str().c_str());
return 0;
}
Py_Return;
}
PyObject* SketchObjectPy::movePoint(PyObject *args) PyObject* SketchObjectPy::movePoint(PyObject *args)
{ {

View File

@ -2869,10 +2869,10 @@ void CmdSketcherConstrainSnellsLaw::activated(int iMsg)
std::swap(PosId2,PosId3); std::swap(PosId2,PosId3);
} }
bool allexternal=false;
//a bunch of validity checks //a bunch of validity checks
if ((GeoId1 < 0 && GeoId2 < 0 && GeoId3 < 0)) { if ((GeoId1 < 0 && GeoId2 < 0 && GeoId3 < 0)) {
allexternal=true; strError = QObject::tr("Can not create constraint with external geometry only!!", dmbg);
throw(Base::Exception(""));
} }
if (!(isVertex(GeoId1,PosId1) && !isSimpleVertex(Obj, GeoId1, PosId1) && if (!(isVertex(GeoId1,PosId1) && !isSimpleVertex(Obj, GeoId1, PosId1) &&
@ -2884,29 +2884,27 @@ void CmdSketcherConstrainSnellsLaw::activated(int iMsg)
double n2divn1=0; double n2divn1=0;
if(!allexternal){ //the essence.
//the essence. //Unlike other constraints, we'll ask for a value immediately.
//Unlike other constraints, we'll ask for a value immediately. QDialog dlg(Gui::getMainWindow());
QDialog dlg(Gui::getMainWindow()); Ui::InsertDatum ui_Datum;
Ui::InsertDatum ui_Datum; ui_Datum.setupUi(&dlg);
ui_Datum.setupUi(&dlg); dlg.setWindowTitle(EditDatumDialog::tr("Refractive index ratio", dmbg));
dlg.setWindowTitle(EditDatumDialog::tr("Refractive index ratio", dmbg)); ui_Datum.label->setText(EditDatumDialog::tr("Ratio n2/n1:", dmbg));
ui_Datum.label->setText(EditDatumDialog::tr("Ratio n2/n1:", dmbg)); Base::Quantity init_val;
Base::Quantity init_val; init_val.setUnit(Base::Unit());
init_val.setUnit(Base::Unit()); init_val.setValue(0.0);
init_val.setValue(0.0);
ui_Datum.labelEdit->setValue(init_val); ui_Datum.labelEdit->setValue(init_val);
ui_Datum.labelEdit->setParamGrpPath(QByteArray("User parameter:BaseApp/History/SketcherRefrIndexRatio")); ui_Datum.labelEdit->setParamGrpPath(QByteArray("User parameter:BaseApp/History/SketcherRefrIndexRatio"));
ui_Datum.labelEdit->setToLastUsedValue(); ui_Datum.labelEdit->setToLastUsedValue();
ui_Datum.labelEdit->selectNumber(); ui_Datum.labelEdit->selectNumber();
if (dlg.exec() != QDialog::Accepted) return; if (dlg.exec() != QDialog::Accepted) return;
ui_Datum.labelEdit->pushToHistory(); ui_Datum.labelEdit->pushToHistory();
Base::Quantity newQuant = ui_Datum.labelEdit->value(); Base::Quantity newQuant = ui_Datum.labelEdit->value();
n2divn1 = newQuant.getValue(); n2divn1 = newQuant.getValue();
}
//add constraint //add constraint
openCommand("add Snell's law constraint"); openCommand("add Snell's law constraint");
@ -2925,12 +2923,12 @@ void CmdSketcherConstrainSnellsLaw::activated(int iMsg)
Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('SnellsLaw',%d,%d,%d,%d,%d,%.12f)) ", Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('SnellsLaw',%d,%d,%d,%d,%d,%.12f)) ",
selection[0].getFeatName(),GeoId1,PosId1,GeoId2,PosId2,GeoId3,n2divn1); selection[0].getFeatName(),GeoId1,PosId1,GeoId2,PosId2,GeoId3,n2divn1);
if (allexternal || constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving /*if (allexternal || constraintCreationMode==Reference) { // it is a constraint on a external line, make it non-driving
const std::vector<Sketcher::Constraint *> &ConStr = Obj->Constraints.getValues(); const std::vector<Sketcher::Constraint *> &ConStr = Obj->Constraints.getValues();
Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.setDriving(%i,%s)", Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.setDriving(%i,%s)",
selection[0].getFeatName(),ConStr.size()-1,"False"); selection[0].getFeatName(),ConStr.size()-1,"False");
} }*/
commitCommand(); commitCommand();
updateActive(); updateActive();
@ -3437,6 +3435,83 @@ bool CmdSketcherConstraintCreationMode::isActive(void)
return false; return false;
} }
/* Constrain commands =======================================================*/
DEF_STD_CMD_A(CmdSketcherToggleDrivingConstraint);
CmdSketcherToggleDrivingConstraint::CmdSketcherToggleDrivingConstraint()
:Command("Sketcher_ToggleDrivingConstraint")
{
sAppModule = "Sketcher";
sGroup = QT_TR_NOOP("Sketcher");
sMenuText = QT_TR_NOOP("Toggle reference/driving constraint");
sToolTipText = QT_TR_NOOP("Toggles the currently selected constraint to/from reference mode");
sWhatsThis = "Sketcher_ToggleDrivingConstraint";
sStatusTip = sToolTipText;
sPixmap = "Sketcher_ToggleDrivingConstraint";
sAccel = "";
eType = ForEdit;
}
void CmdSketcherToggleDrivingConstraint::activated(int iMsg)
{
// get the selection
std::vector<Gui::SelectionObject> selection = getSelection().getSelectionEx();
// only one sketch with its subelements are allowed to be selected
if (selection.size() != 1) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("Select constraint(s) from the sketch."));
return;
}
// get the needed lists and objects
const std::vector<std::string> &SubNames = selection[0].getSubNames();
if (SubNames.empty()) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("Select constraint(s) from the sketch."));
return;
}
// make sure the selected object is the sketch in edit mode
const App::DocumentObject* obj = selection[0].getObject();
ViewProviderSketch* sketchView = static_cast<ViewProviderSketch*>
(Gui::Application::Instance->getViewProvider(obj));
// undo command open
openCommand("Toggle driving from/to non-driving");
int succesful=SubNames.size();
// go through the selected subelements
for (std::vector<std::string>::const_iterator it=SubNames.begin();it!=SubNames.end();++it){
// only handle constraints
if (it->size() > 10 && it->substr(0,10) == "Constraint") {
int ConstrId = std::atoi(it->substr(10,4000).c_str()) - 1;
try {
// issue the actual commands to toggle
doCommand(Doc,"App.ActiveDocument.%s.toggleDriving(%d) ",selection[0].getFeatName(),ConstrId);
}
catch(const Base::Exception& e) {
succesful--;
}
}
}
if(succesful>0)
commitCommand();
else
abortCommand();
updateActive();
// clear the selection (convenience)
getSelection().clearSelection();
}
bool CmdSketcherToggleDrivingConstraint::isActive(void)
{
return isCreateConstraintActive( getActiveGuiDocument() );
}
void CreateSketcherCommandsConstraints(void) void CreateSketcherCommandsConstraints(void)
{ {
Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager(); Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager();
@ -3459,5 +3534,5 @@ void CreateSketcherCommandsConstraints(void)
rcCmdMgr.addCommand(new CmdSketcherConstrainSnellsLaw()); rcCmdMgr.addCommand(new CmdSketcherConstrainSnellsLaw());
rcCmdMgr.addCommand(new CmdSketcherConstrainInternalAlignment()); rcCmdMgr.addCommand(new CmdSketcherConstrainInternalAlignment());
rcCmdMgr.addCommand(new CmdSketcherConstraintCreationMode()); rcCmdMgr.addCommand(new CmdSketcherConstraintCreationMode());
rcCmdMgr.addCommand(new CmdSketcherToggleDrivingConstraint());
} }

View File

@ -5350,7 +5350,16 @@ void CmdSketcherGeometryCreationMode::activated(int iMsg)
bool CmdSketcherGeometryCreationMode::isActive(void) bool CmdSketcherGeometryCreationMode::isActive(void)
{ {
return isCreateGeoActive(getActiveGuiDocument()); Gui::Document * doc=getActiveGuiDocument();
if (doc) {
// checks if a Sketch Viewprovider is in Edit and is in no special mode
if (doc->getInEdit() && doc->getInEdit()->isDerivedFrom
(SketcherGui::ViewProviderSketch::getClassTypeId())) {
return true;
}
}
return false;
} }
void CreateSketcherCommandsCreateGeo(void) void CreateSketcherCommandsCreateGeo(void)

View File

@ -136,7 +136,7 @@ void ConstraintView::contextMenuEvent (QContextMenuEvent* event)
{ {
ConstraintItem *it = dynamic_cast<ConstraintItem*>(item); ConstraintItem *it = dynamic_cast<ConstraintItem*>(item);
QAction* driven = menu.addAction(it->isDriving?tr("Change to reference"):tr("Change to driving"), this, SLOT(updateDrivingStatus())); QAction* driven = menu.addAction(tr("Toggle to/from reference"), this, SLOT(updateDrivingStatus()));
// if its the right constraint // if its the right constraint
if ((it->Type == Sketcher::Distance || if ((it->Type == Sketcher::Distance ||
it->Type == Sketcher::DistanceX || it->Type == Sketcher::DistanceX ||
@ -349,21 +349,8 @@ void TaskSketcherConstrains::on_listWidgetConstraints_updateDrivingStatus(QListW
ConstraintItem *it = dynamic_cast<ConstraintItem*>(item); ConstraintItem *it = dynamic_cast<ConstraintItem*>(item);
if (!item) return; if (!item) return;
const std::vector< Sketcher::Constraint * > &vals = sketchView->getSketchObject()->Constraints.getValues(); Gui::Application::Instance->commandManager().runCommandByName("Sketcher_ToggleDrivingConstraint");
try {
Gui::Command::openCommand("Modify driving status of constraint");
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.setDriving(%i,%s)",
this->sketchView->getSketchObject()->getNameInDocument(),
it->ConstraintNbr,
status?"True":"False");
Gui::Command::commitCommand();
Gui::Command::updateActive();
}
catch (const Base::Exception& e) {
Gui::Command::abortCommand();
}
slotConstraintsChanged(); slotConstraintsChanged();
} }

View File

@ -50,7 +50,7 @@
</item> </item>
<item> <item>
<property name="text"> <property name="text">
<string>Non-Driving</string> <string>Reference</string>
</property> </property>
</item> </item>
</widget> </widget>

View File

@ -206,6 +206,7 @@ inline void SketcherAddWorkbenchConstraints<Gui::MenuItem>(Gui::MenuItem& cons){
<< "Sketcher_ConstrainSnellsLaw" << "Sketcher_ConstrainSnellsLaw"
<< "Sketcher_ConstrainInternalAlignment" << "Sketcher_ConstrainInternalAlignment"
<< "Separator" << "Separator"
<< "Sketcher_ToggleDrivingConstraint"
<< "Sketcher_ConstraintCreationMode"; << "Sketcher_ConstraintCreationMode";
} }
@ -229,6 +230,7 @@ inline void SketcherAddWorkbenchConstraints<Gui::ToolBarItem>(Gui::ToolBarItem&
<< "Sketcher_ConstrainAngle" << "Sketcher_ConstrainAngle"
<< "Sketcher_ConstrainSnellsLaw" << "Sketcher_ConstrainSnellsLaw"
<< "Separator" << "Separator"
<< "Sketcher_ToggleDrivingConstraint"
<< "Sketcher_ConstraintCreationMode"; << "Sketcher_ConstraintCreationMode";
} }