diff --git a/src/Mod/PartDesign/App/FeatureGroove.cpp b/src/Mod/PartDesign/App/FeatureGroove.cpp index ede3a980e..8f7bbd874 100644 --- a/src/Mod/PartDesign/App/FeatureGroove.cpp +++ b/src/Mod/PartDesign/App/FeatureGroove.cpp @@ -34,8 +34,6 @@ # include # include # include -# include -# include #endif #include @@ -181,72 +179,21 @@ App::DocumentObjectExecReturn *Groove::execute(void) bool Groove::suggestReversed(void) { - try { - updateAxis(); - - Part::Part2DObject* sketch = getVerifiedSketch(); - std::vector wires = getSketchWires(); - TopoDS_Shape sketchshape = makeFace(wires); - - Base::Vector3d b = Base.getValue(); - Base::Vector3d v = Axis.getValue(); - - // get centre of gravity of the sketch face - GProp_GProps props; - BRepGProp::SurfaceProperties(sketchshape, props); - gp_Pnt cog = props.CentreOfMass(); - Base::Vector3d p_cog(cog.X(), cog.Y(), cog.Z()); - // get direction to cog from its projection on the revolve axis - Base::Vector3d perp_dir = p_cog - p_cog.Perpendicular(b, v); - // get cross product of projection direction with revolve axis direction - Base::Vector3d cross = v % perp_dir; - // get sketch vector pointing away from support material - Base::Placement SketchPos = sketch->Placement.getValue(); - Base::Rotation SketchOrientation = SketchPos.getRotation(); - Base::Vector3d SketchNormal(0,0,1); - SketchOrientation.multVec(SketchNormal,SketchNormal); - - // return true if the angle between norm and cross is acute - return SketchNormal * cross > 0.f; - } - catch (...) { - return Reversed.getValue(); - } + updateAxis(); + return SketchBased::getReversedAngle(Base.getValue(), Axis.getValue()) > 0.0; } void Groove::updateAxis(void) { - Part::Part2DObject* sketch = getVerifiedSketch(); - Base::Placement SketchPlm = sketch->Placement.getValue(); - - // get reference axis App::DocumentObject *pcReferenceAxis = ReferenceAxis.getValue(); const std::vector &subReferenceAxis = ReferenceAxis.getSubValues(); - if (pcReferenceAxis && pcReferenceAxis == sketch) { - bool hasValidAxis=false; - Base::Axis axis; - if (subReferenceAxis[0] == "V_Axis") { - hasValidAxis = true; - axis = sketch->getAxis(Part::Part2DObject::V_Axis); - } - else if (subReferenceAxis[0] == "H_Axis") { - hasValidAxis = true; - axis = sketch->getAxis(Part::Part2DObject::H_Axis); - } - else if (subReferenceAxis[0].size() > 4 && subReferenceAxis[0].substr(0,4) == "Axis") { - int AxId = std::atoi(subReferenceAxis[0].substr(4,4000).c_str()); - if (AxId >= 0 && AxId < sketch->getAxisCount()) { - hasValidAxis = true; - axis = sketch->getAxis(AxId); - } - } - if (hasValidAxis) { - axis *= SketchPlm; - Base::Vector3d base=axis.getBase(); - Base::Vector3d dir=axis.getDirection(); - Base.setValue(base.x,base.y,base.z); - Axis.setValue(dir.x,dir.y,dir.z); - } + Base::Vector3d base; + Base::Vector3d dir; + getAxis(pcReferenceAxis, subReferenceAxis, base, dir); + + if (dir.Length() > Precision::Confusion()) { + Base.setValue(base.x,base.y,base.z); + Axis.setValue(dir.x,dir.y,dir.z); } } diff --git a/src/Mod/PartDesign/App/FeatureRevolution.cpp b/src/Mod/PartDesign/App/FeatureRevolution.cpp index 83b9f69f2..35d56c930 100644 --- a/src/Mod/PartDesign/App/FeatureRevolution.cpp +++ b/src/Mod/PartDesign/App/FeatureRevolution.cpp @@ -34,8 +34,6 @@ # include # include # include -# include -# include #endif #include @@ -181,75 +179,20 @@ App::DocumentObjectExecReturn *Revolution::execute(void) bool Revolution::suggestReversed(void) { - try { - updateAxis(); - - Part::Part2DObject* sketch = getVerifiedSketch(); - std::vector wires = getSketchWires(); - TopoDS_Shape sketchshape = makeFace(wires); - - Base::Vector3d b = Base.getValue(); - Base::Vector3d v = Axis.getValue(); - - // get centre of gravity of the sketch face - GProp_GProps props; - BRepGProp::SurfaceProperties(sketchshape, props); - gp_Pnt cog = props.CentreOfMass(); - Base::Vector3d p_cog(cog.X(), cog.Y(), cog.Z()); - // get direction to cog from its projection on the revolve axis - Base::Vector3d perp_dir = p_cog - p_cog.Perpendicular(b, v); - // get cross product of projection direction with revolve axis direction - Base::Vector3d cross = v % perp_dir; - // get sketch vector pointing away from support material - Base::Placement SketchPos = sketch->Placement.getValue(); - Base::Rotation SketchOrientation = SketchPos.getRotation(); - Base::Vector3d SketchNormal(0,0,1); - SketchOrientation.multVec(SketchNormal,SketchNormal); - // simply convert double to float - Base::Vector3d norm(SketchNormal.x, SketchNormal.y, SketchNormal.z); - - // return true if the angle between norm and cross is obtuse - return norm * cross < 0.f; - } - catch (...) { - return Reversed.getValue(); - } + updateAxis(); + return SketchBased::getReversedAngle(Base.getValue(), Axis.getValue()) < 0.0; } void Revolution::updateAxis(void) { - Part::Part2DObject* sketch = getVerifiedSketch(); - Base::Placement SketchPlm = sketch->Placement.getValue(); - - // get reference axis App::DocumentObject *pcReferenceAxis = ReferenceAxis.getValue(); const std::vector &subReferenceAxis = ReferenceAxis.getSubValues(); - if (pcReferenceAxis && pcReferenceAxis == sketch) { - bool hasValidAxis=false; - Base::Axis axis; - if (subReferenceAxis[0] == "V_Axis") { - hasValidAxis = true; - axis = sketch->getAxis(Part::Part2DObject::V_Axis); - } - else if (subReferenceAxis[0] == "H_Axis") { - hasValidAxis = true; - axis = sketch->getAxis(Part::Part2DObject::H_Axis); - } - else if (subReferenceAxis[0].size() > 4 && subReferenceAxis[0].substr(0,4) == "Axis") { - int AxId = std::atoi(subReferenceAxis[0].substr(4,4000).c_str()); - if (AxId >= 0 && AxId < sketch->getAxisCount()) { - hasValidAxis = true; - axis = sketch->getAxis(AxId); - } - } - if (hasValidAxis) { - axis *= SketchPlm; - Base::Vector3d base=axis.getBase(); - Base::Vector3d dir=axis.getDirection(); - Base.setValue(float(base.x),float(base.y),float(base.z)); - Axis.setValue(float(dir.x),float(dir.y),float(dir.z)); - } - } + Base::Vector3d base; + Base::Vector3d dir; + getAxis(pcReferenceAxis, subReferenceAxis, base, dir); + + Base.setValue(base.x,base.y,base.z); + Axis.setValue(dir.x,dir.y,dir.z); } } diff --git a/src/Mod/PartDesign/App/FeatureSketchBased.cpp b/src/Mod/PartDesign/App/FeatureSketchBased.cpp index 7c81b5661..a4fabb94c 100644 --- a/src/Mod/PartDesign/App/FeatureSketchBased.cpp +++ b/src/Mod/PartDesign/App/FeatureSketchBased.cpp @@ -59,6 +59,8 @@ # include # include # include +# include +# include #endif #include @@ -72,6 +74,7 @@ #include #include "FeatureSketchBased.h" #include "DatumPlane.h" +#include "DatumLine.h" using namespace PartDesign; @@ -971,6 +974,95 @@ bool SketchBased::isSupportDatum() const return isDatum(SupportObject); } +const double SketchBased::getReversedAngle(const Base::Vector3d &b, const Base::Vector3d &v) +{ + try { + Part::Part2DObject* sketch = getVerifiedSketch(); + std::vector wires = getSketchWires(); + TopoDS_Shape sketchshape = makeFace(wires); + + // get centre of gravity of the sketch face + GProp_GProps props; + BRepGProp::SurfaceProperties(sketchshape, props); + gp_Pnt cog = props.CentreOfMass(); + Base::Vector3d p_cog(cog.X(), cog.Y(), cog.Z()); + // get direction to cog from its projection on the revolve axis + Base::Vector3d perp_dir = p_cog - p_cog.Perpendicular(b, v); + // get cross product of projection direction with revolve axis direction + Base::Vector3d cross = v % perp_dir; + // get sketch vector pointing away from support material + Base::Placement SketchPos = sketch->Placement.getValue(); + Base::Rotation SketchOrientation = SketchPos.getRotation(); + Base::Vector3d SketchNormal(0,0,1); + SketchOrientation.multVec(SketchNormal,SketchNormal); + + return SketchNormal * cross; + } + catch (...) { + return Reversed.getValue(); + } +} + +void SketchBased::getAxis(const App::DocumentObject *pcReferenceAxis, const std::vector &subReferenceAxis, + Base::Vector3d& base, Base::Vector3d& dir) +{ + dir = Base::Vector3d(0,0,0); // If unchanged signals that no valid axis was found + Part::Part2DObject* sketch = getVerifiedSketch(); + Base::Placement SketchPlm = sketch->Placement.getValue(); + + // get reference axis + if (pcReferenceAxis->getTypeId().isDerivedFrom(PartDesign::Line::getClassTypeId())) { + const PartDesign::Line* line = static_cast(pcReferenceAxis); + base = line->getBasePoint(); + dir = line->getDirection(); + } else if (pcReferenceAxis->getTypeId().isDerivedFrom(PartDesign::Feature::getClassTypeId())) { + if (subReferenceAxis[0].empty()) + throw Base::Exception("No rotation axis reference specified"); + const Part::Feature* refFeature = static_cast(pcReferenceAxis); + Part::TopoShape refShape = refFeature->Shape.getShape(); + TopoDS_Shape ref = refShape.getSubShape(subReferenceAxis[0].c_str()); + + if (ref.ShapeType() == TopAbs_EDGE) { + TopoDS_Edge refEdge = TopoDS::Edge(ref); + if (refEdge.IsNull()) + throw Base::Exception("Failed to extract rotation edge"); + BRepAdaptor_Curve adapt(refEdge); + if (adapt.GetType() != GeomAbs_Line) + throw Base::Exception("Rotation edge must be a straight line"); + + gp_Pnt b = adapt.Line().Location(); + base = Base::Vector3d(b.X(), b.Y(), b.Z()); + gp_Dir d = adapt.Line().Direction(); + dir = Base::Vector3d(d.X(), d.Y(), d.Z()); + } else { + throw Base::Exception("Rotation reference must be an edge"); + } + } else if (pcReferenceAxis && pcReferenceAxis == sketch) { + bool hasValidAxis=false; + Base::Axis axis; + if (subReferenceAxis[0] == "V_Axis") { + hasValidAxis = true; + axis = sketch->getAxis(Part::Part2DObject::V_Axis); + } + else if (subReferenceAxis[0] == "H_Axis") { + hasValidAxis = true; + axis = sketch->getAxis(Part::Part2DObject::H_Axis); + } + else if (subReferenceAxis[0].size() > 4 && subReferenceAxis[0].substr(0,4) == "Axis") { + int AxId = std::atoi(subReferenceAxis[0].substr(4,4000).c_str()); + if (AxId >= 0 && AxId < sketch->getAxisCount()) { + hasValidAxis = true; + axis = sketch->getAxis(AxId); + } + } + if (hasValidAxis) { + axis *= SketchPlm; + base=axis.getBase(); + dir=axis.getDirection(); + } + } +} + TopoDS_Shape SketchBased::refineShapeIfActive(const TopoDS_Shape& oldShape) const { Base::Reference hGrp = App::GetApplication().GetUserParameter() diff --git a/src/Mod/PartDesign/App/FeatureSketchBased.h b/src/Mod/PartDesign/App/FeatureSketchBased.h index b28f18cc2..5336b218c 100644 --- a/src/Mod/PartDesign/App/FeatureSketchBased.h +++ b/src/Mod/PartDesign/App/FeatureSketchBased.h @@ -124,6 +124,12 @@ protected: static const bool checkLineCrossesFace(const gp_Lin& line, const TopoDS_Face& face); class Wire_Compare; + + /// Used to suggest a value for Reversed flag so that material is always removed (Groove) or added (Revolution) from the support + const double getReversedAngle(const Base::Vector3d& b, const Base::Vector3d& v); + /// get Axis from ReferenceAxis + void getAxis(const App::DocumentObject* pcReferenceAxis, const std::vector& subReferenceAxis, + Base::Vector3d& base, Base::Vector3d& dir); }; } //namespace PartDesign diff --git a/src/Mod/PartDesign/Gui/TaskGrooveParameters.cpp b/src/Mod/PartDesign/Gui/TaskGrooveParameters.cpp index 2a84a9b3d..27011e7ad 100644 --- a/src/Mod/PartDesign/Gui/TaskGrooveParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskGrooveParameters.cpp @@ -39,10 +39,13 @@ #include #include #include +#include #include #include #include #include "Workbench.h" +#include "ReferenceSelection.h" +#include "TaskSketchBasedParameters.h" using namespace PartDesignGui; using namespace Gui; @@ -85,33 +88,8 @@ TaskGrooveParameters::TaskGrooveParameters(ViewProviderGroove *GrooveView,QWidge ui->grooveAngle->setValue(l); ui->grooveAngle->bind(pcGroove->Angle); - int count=pcGroove->getSketchAxisCount(); - - for (int i=ui->axis->count()-1; i >= count+2; i--) - ui->axis->removeItem(i); - for (int i=ui->axis->count(); i < count+2; i++) - ui->axis->addItem(QString::fromLatin1("Sketch axis %1").arg(i-2)); - - int pos=-1; - - App::DocumentObject *pcReferenceAxis = pcGroove->ReferenceAxis.getValue(); - const std::vector &subReferenceAxis = pcGroove->ReferenceAxis.getSubValues(); - if (pcReferenceAxis && pcReferenceAxis == pcGroove->Sketch.getValue()) { - assert(subReferenceAxis.size()==1); - if (subReferenceAxis[0] == "V_Axis") - pos = 0; - else if (subReferenceAxis[0] == "H_Axis") - pos = 1; - else if (subReferenceAxis[0].size() > 4 && subReferenceAxis[0].substr(0,4) == "Axis") - pos = 2 + std::atoi(subReferenceAxis[0].substr(4,4000).c_str()); - } - - if (pos < 0 || pos >= ui->axis->count()) { - ui->axis->addItem(QString::fromLatin1("Undefined")); - pos = ui->axis->count()-1; - } - - ui->axis->setCurrentIndex(pos); + blockUpdate = false; + updateUI(); ui->checkBoxMidplane->setChecked(mirrored); ui->checkBoxReversed->setChecked(reversed); @@ -124,15 +102,99 @@ TaskGrooveParameters::TaskGrooveParameters(ViewProviderGroove *GrooveView,QWidge setFocus (); } +void TaskGrooveParameters::updateUI() +{ + if (blockUpdate) + return; + blockUpdate = true; + + PartDesign::Groove* pcGroove = static_cast(vp->getObject()); + + App::DocumentObject* pcReferenceAxis = pcGroove->ReferenceAxis.getValue(); + std::vector sub = pcGroove->ReferenceAxis.getSubValues(); + + // Add user-defined sketch axes to the reference selection combo box + Sketcher::SketchObject *pcSketch = static_cast(pcGroove->Sketch.getValue()); + int maxcount=2; + if (pcSketch) + maxcount += pcSketch->getAxisCount(); + + for (int i=ui->axis->count()-1; i >= 2; i--) + ui->axis->removeItem(i); + for (int i=ui->axis->count(); i < maxcount; i++) + ui->axis->addItem(QString::fromAscii("Sketch axis %1").arg(i-5)); + + bool undefined = false; + if (pcReferenceAxis != NULL && !sub.empty()) { + if (sub.front() == "H_Axis") + ui->axis->setCurrentIndex(0); + else if (sub.front() == "V_Axis") + ui->axis->setCurrentIndex(1); + else if (sub.front().size() > 4 && sub.front().substr(0,4) == "Axis") { + int pos = 2 + std::atoi(sub.front().substr(4,4000).c_str()); + if (pos <= maxcount) + ui->axis->setCurrentIndex(pos); + else + undefined = true; + } else { + ui->axis->addItem(getRefStr(pcReferenceAxis, sub)); + ui->axis->setCurrentIndex(maxcount); + } + } else { + undefined = true; + } + + ui->axis->addItem(tr("Select reference...")); + + blockUpdate = false; +} + +void TaskGrooveParameters::onSelectionChanged(const Gui::SelectionChanges& msg) +{ + if (msg.Type == Gui::SelectionChanges::AddSelection) { + PartDesign::Groove* pcGroove = static_cast(vp->getObject()); + + exitSelectionMode(); + if (!blockUpdate) { + std::vector axis; + App::DocumentObject* selObj; + getReferencedSelection(pcGroove, msg, selObj, axis); + pcGroove->ReferenceAxis.setValue(selObj, axis); + + + recomputeFeature(); + updateUI(); + } + else { + Sketcher::SketchObject *pcSketch = static_cast(pcGroove->Sketch.getValue()); + int maxcount=2; + if (pcSketch) + maxcount += pcSketch->getAxisCount(); + for (int i=ui->axis->count()-1; i >= maxcount; i--) + ui->axis->removeItem(i); + + std::vector sub; + App::DocumentObject* selObj; + getReferencedSelection(pcGroove, msg, selObj, sub); + ui->axis->addItem(getRefStr(selObj, sub)); + ui->axis->setCurrentIndex(maxcount); + ui->axis->addItem(tr("Select reference...")); + } + } +} + void TaskGrooveParameters::onAngleChanged(double len) { PartDesign::Groove* pcGroove = static_cast(vp->getObject()); pcGroove->Angle.setValue(len); + exitSelectionMode(); recomputeFeature(); } void TaskGrooveParameters::onAxisChanged(int num) { + if (blockUpdate) + return; PartDesign::Groove* pcGroove = static_cast(vp->getObject()); Sketcher::SketchObject *pcSketch = static_cast(pcGroove->Sketch.getValue()); if (pcSketch) { @@ -140,20 +202,26 @@ void TaskGrooveParameters::onAxisChanged(int num) std::vector oldSubRefAxis = pcGroove->ReferenceAxis.getSubValues(); int maxcount = pcSketch->getAxisCount()+2; - if (num == 0) - pcGroove->ReferenceAxis.setValue(pcSketch, std::vector(1,"V_Axis")); - else if (num == 1) + if (num == 0) { pcGroove->ReferenceAxis.setValue(pcSketch, std::vector(1,"H_Axis")); - else if (num >= 2 && num < maxcount) { + exitSelectionMode(); + } else if (num == 1) { + pcGroove->ReferenceAxis.setValue(pcSketch, std::vector(1,"V_Axis")); + exitSelectionMode(); + } else if (num >= 2 && num < maxcount) { QString buf = QString::fromUtf8("Axis%1").arg(num-2); std::string str = buf.toStdString(); pcGroove->ReferenceAxis.setValue(pcSketch, std::vector(1,str)); - } - if (num < maxcount && ui->axis->count() > maxcount) - ui->axis->setMaxCount(maxcount); + exitSelectionMode(); + } else if (num == ui->axis->count() - 1) { + // enter reference selection mode + TaskSketchBasedParameters::onSelectReference(true, true, false, true); + } else if (num == maxcount) + exitSelectionMode(); + App::DocumentObject *newRefAxis = pcGroove->ReferenceAxis.getValue(); const std::vector &newSubRefAxis = pcGroove->ReferenceAxis.getSubValues(); - if (oldRefAxis != pcSketch || + if (oldRefAxis != newRefAxis || oldSubRefAxis.size() != newSubRefAxis.size() || oldSubRefAxis[0] != newSubRefAxis[0]) { bool reversed = pcGroove->suggestReversed(); @@ -165,6 +233,8 @@ void TaskGrooveParameters::onAxisChanged(int num) } } } + + updateUI(); recomputeFeature(); } @@ -187,29 +257,36 @@ double TaskGrooveParameters::getAngle(void) const return ui->grooveAngle->value().getValue(); } -QString TaskGrooveParameters::getReferenceAxis(void) const +void TaskGrooveParameters::getReferenceAxis(App::DocumentObject*& obj, std::vector& sub) const { // get the support and Sketch PartDesign::Groove* pcGroove = static_cast(vp->getObject()); - Sketcher::SketchObject *pcSketch = static_cast(pcGroove->Sketch.getValue()); + obj = static_cast(pcGroove->Sketch.getValue()); + sub = std::vector(1,""); + int maxcount=2; + if (obj) + maxcount += static_cast(obj)->getAxisCount(); - QString buf; - if (pcSketch) { - buf = QString::fromUtf8("(App.ActiveDocument.%1,[%2])"); - buf = buf.arg(QString::fromUtf8(pcSketch->getNameInDocument())); - if (ui->axis->currentIndex() == 0) - buf = buf.arg(QString::fromUtf8("'V_Axis'")); - else if (ui->axis->currentIndex() == 1) - buf = buf.arg(QString::fromUtf8("'H_Axis'")); - else if (ui->axis->currentIndex() >= 2) { - buf = buf.arg(QString::fromUtf8("'Axis%1'")); - buf = buf.arg(ui->axis->currentIndex()-2); + if (obj) { + int num = ui->axis->currentIndex(); + if (num == 0) + sub[0] = "H_Axis"; + else if (num == 1) + sub[0] = "V_Axis"; + else if (num >= 2 && num < maxcount) { + QString buf = QString::fromUtf8("Axis%1").arg(num-2); + sub[0] = buf.toStdString(); + } else if (num == maxcount && ui->axis->count() == maxcount + 2) { + QStringList parts = ui->axis->currentText().split(QChar::fromAscii(':')); + obj = vp->getObject()->getDocument()->getObject(parts[0].toStdString().c_str()); + if (parts.size() > 1) + sub[0] = parts[1].toStdString(); + } else { + obj = NULL; } } else - buf = QString::fromUtf8("''"); - - return buf; + obj = NULL; } bool TaskGrooveParameters::getMidplane(void) const @@ -252,7 +329,10 @@ void TaskGrooveParameters::apply() //Gui::Command::openCommand("Groove changed"); ui->grooveAngle->apply(); - std::string axis = getReferenceAxis().toStdString(); + std::vector sub; + App::DocumentObject* obj; + parameter->getReferenceAxis(obj, sub); + std::string axis = getPythonStr(obj, sub); Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.ReferenceAxis = %s",name.c_str(),axis.c_str()); Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Midplane = %i",name.c_str(), getMidplane() ? 1 : 0); Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Reversed = %i",name.c_str(), getReversed() ? 1 : 0); diff --git a/src/Mod/PartDesign/Gui/TaskGrooveParameters.cpp.orig b/src/Mod/PartDesign/Gui/TaskGrooveParameters.cpp.orig new file mode 100644 index 000000000..e365cc7b2 --- /dev/null +++ b/src/Mod/PartDesign/Gui/TaskGrooveParameters.cpp.orig @@ -0,0 +1,458 @@ +/****************************************************************************** + * Copyright (c)2012 Jan Rheinlaender * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ******************************************************************************/ + + +#include "PreCompiled.h" + +#ifndef _PreComp_ +#endif + +#include "ui_TaskGrooveParameters.h" +#include "TaskGrooveParameters.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Workbench.h" +#include "ReferenceSelection.h" +#include "TaskSketchBasedParameters.h" + +using namespace PartDesignGui; +using namespace Gui; + +/* TRANSLATOR PartDesignGui::TaskGrooveParameters */ + +TaskGrooveParameters::TaskGrooveParameters(ViewProviderGroove *GrooveView,QWidget *parent) + : TaskSketchBasedParameters(GrooveView, parent, "PartDesign_Groove",tr("Groove parameters")) +{ + // we need a separate container widget to add all controls to + proxy = new QWidget(this); + ui = new Ui_TaskGrooveParameters(); + ui->setupUi(proxy); + QMetaObject::connectSlotsByName(this); + + connect(ui->grooveAngle, SIGNAL(valueChanged(double)), + this, SLOT(onAngleChanged(double))); + connect(ui->axis, SIGNAL(activated(int)), + this, SLOT(onAxisChanged(int))); + connect(ui->checkBoxMidplane, SIGNAL(toggled(bool)), + this, SLOT(onMidplane(bool))); + connect(ui->checkBoxReversed, SIGNAL(toggled(bool)), + this, SLOT(onReversed(bool))); + connect(ui->checkBoxUpdateView, SIGNAL(toggled(bool)), + this, SLOT(onUpdateView(bool))); + + this->groupLayout()->addWidget(proxy); + + // Temporarily prevent unnecessary feature updates + ui->grooveAngle->blockSignals(true); + ui->axis->blockSignals(true); + ui->checkBoxMidplane->blockSignals(true); + ui->checkBoxReversed->blockSignals(true); + + PartDesign::Groove* pcGroove = static_cast(vp->getObject()); + double l = pcGroove->Angle.getValue(); + bool mirrored = pcGroove->Midplane.getValue(); + bool reversed = pcGroove->Reversed.getValue(); + + ui->grooveAngle->setValue(l); + ui->grooveAngle->bind(pcGroove->Angle); + +<<<<<<< f0798a82fe8f03db57aca4f634d2123486daaea0 + int count=pcGroove->getSketchAxisCount(); + + for (int i=ui->axis->count()-1; i >= count+2; i--) + ui->axis->removeItem(i); + for (int i=ui->axis->count(); i < count+2; i++) + ui->axis->addItem(QString::fromLatin1("Sketch axis %1").arg(i-2)); + + int pos=-1; + + App::DocumentObject *pcReferenceAxis = pcGroove->ReferenceAxis.getValue(); + const std::vector &subReferenceAxis = pcGroove->ReferenceAxis.getSubValues(); + if (pcReferenceAxis && pcReferenceAxis == pcGroove->Sketch.getValue()) { + assert(subReferenceAxis.size()==1); + if (subReferenceAxis[0] == "V_Axis") + pos = 0; + else if (subReferenceAxis[0] == "H_Axis") + pos = 1; + else if (subReferenceAxis[0].size() > 4 && subReferenceAxis[0].substr(0,4) == "Axis") + pos = 2 + std::atoi(subReferenceAxis[0].substr(4,4000).c_str()); + } + + if (pos < 0 || pos >= ui->axis->count()) { + ui->axis->addItem(QString::fromLatin1("Undefined")); + pos = ui->axis->count()-1; + } + + ui->axis->setCurrentIndex(pos); +======= + blockUpdate = false; + updateUI(); +>>>>>>> Enable edges and datum lines as rotation axis for Groove and Revolution features + + ui->checkBoxMidplane->setChecked(mirrored); + ui->checkBoxReversed->setChecked(reversed); + + ui->grooveAngle->blockSignals(false); + ui->axis->blockSignals(false); + ui->checkBoxMidplane->blockSignals(false); + ui->checkBoxReversed->blockSignals(false); + + setFocus (); +} + +void TaskGrooveParameters::updateUI() +{ + if (blockUpdate) + return; + blockUpdate = true; + + PartDesign::Groove* pcGroove = static_cast(vp->getObject()); + + App::DocumentObject* pcReferenceAxis = pcGroove->ReferenceAxis.getValue(); + std::vector sub = pcGroove->ReferenceAxis.getSubValues(); + + // Add user-defined sketch axes to the reference selection combo box + Sketcher::SketchObject *pcSketch = static_cast(pcGroove->Sketch.getValue()); + int maxcount=2; + if (pcSketch) + maxcount += pcSketch->getAxisCount(); + + for (int i=ui->axis->count()-1; i >= 2; i--) + ui->axis->removeItem(i); + for (int i=ui->axis->count(); i < maxcount; i++) + ui->axis->addItem(QString::fromAscii("Sketch axis %1").arg(i-5)); + + bool undefined = false; + if (pcReferenceAxis != NULL && !sub.empty()) { + if (sub.front() == "H_Axis") + ui->axis->setCurrentIndex(0); + else if (sub.front() == "V_Axis") + ui->axis->setCurrentIndex(1); + else if (sub.front().size() > 4 && sub.front().substr(0,4) == "Axis") { + int pos = 2 + std::atoi(sub.front().substr(4,4000).c_str()); + if (pos <= maxcount) + ui->axis->setCurrentIndex(pos); + else + undefined = true; + } else { + ui->axis->addItem(getRefStr(pcReferenceAxis, sub)); + ui->axis->setCurrentIndex(maxcount); + } + } else { + undefined = true; + } + + ui->axis->addItem(tr("Select reference...")); + + blockUpdate = false; +} + +void TaskGrooveParameters::onSelectionChanged(const Gui::SelectionChanges& msg) +{ + if (msg.Type == Gui::SelectionChanges::AddSelection) { + PartDesign::Groove* pcGroove = static_cast(vp->getObject()); + + exitSelectionMode(); + if (!blockUpdate) { + std::vector axis; + App::DocumentObject* selObj; + getReferencedSelection(pcGroove, msg, selObj, axis); + pcGroove->ReferenceAxis.setValue(selObj, axis); + + + recomputeFeature(); + updateUI(); + } + else { + Sketcher::SketchObject *pcSketch = static_cast(pcGroove->Sketch.getValue()); + int maxcount=2; + if (pcSketch) + maxcount += pcSketch->getAxisCount(); + for (int i=ui->axis->count()-1; i >= maxcount; i--) + ui->axis->removeItem(i); + + std::vector sub; + App::DocumentObject* selObj; + getReferencedSelection(pcGroove, msg, selObj, sub); + ui->axis->addItem(getRefStr(selObj, sub)); + ui->axis->setCurrentIndex(maxcount); + ui->axis->addItem(tr("Select reference...")); + } + } +} + +void TaskGrooveParameters::onAngleChanged(double len) +{ + PartDesign::Groove* pcGroove = static_cast(vp->getObject()); + pcGroove->Angle.setValue(len); + exitSelectionMode(); + recomputeFeature(); +} + +void TaskGrooveParameters::onAxisChanged(int num) +{ + if (blockUpdate) + return; + PartDesign::Groove* pcGroove = static_cast(vp->getObject()); + Sketcher::SketchObject *pcSketch = static_cast(pcGroove->Sketch.getValue()); + if (pcSketch) { + App::DocumentObject *oldRefAxis = pcGroove->ReferenceAxis.getValue(); + std::vector oldSubRefAxis = pcGroove->ReferenceAxis.getSubValues(); + + int maxcount = pcSketch->getAxisCount()+2; + if (num == 0) { + pcGroove->ReferenceAxis.setValue(pcSketch, std::vector(1,"H_Axis")); + exitSelectionMode(); + } else if (num == 1) { + pcGroove->ReferenceAxis.setValue(pcSketch, std::vector(1,"V_Axis")); + exitSelectionMode(); + } else if (num >= 2 && num < maxcount) { + QString buf = QString::fromUtf8("Axis%1").arg(num-2); + std::string str = buf.toStdString(); + pcGroove->ReferenceAxis.setValue(pcSketch, std::vector(1,str)); + exitSelectionMode(); + } else if (num == ui->axis->count() - 1) { + // enter reference selection mode + TaskSketchBasedParameters::onSelectReference(true, true, false, true); + } else if (num == maxcount) + exitSelectionMode(); + + App::DocumentObject *newRefAxis = pcGroove->ReferenceAxis.getValue(); + const std::vector &newSubRefAxis = pcGroove->ReferenceAxis.getSubValues(); + if (oldRefAxis != newRefAxis || + oldSubRefAxis.size() != newSubRefAxis.size() || + oldSubRefAxis[0] != newSubRefAxis[0]) { + bool reversed = pcGroove->suggestReversed(); + if (reversed != pcGroove->Reversed.getValue()) { + pcGroove->Reversed.setValue(reversed); + ui->checkBoxReversed->blockSignals(true); + ui->checkBoxReversed->setChecked(reversed); + ui->checkBoxReversed->blockSignals(false); + } + } + } + + updateUI(); + recomputeFeature(); +} + +void TaskGrooveParameters::onMidplane(bool on) +{ + PartDesign::Groove* pcGroove = static_cast(vp->getObject()); + pcGroove->Midplane.setValue(on); + recomputeFeature(); +} + +void TaskGrooveParameters::onReversed(bool on) +{ + PartDesign::Groove* pcGroove = static_cast(vp->getObject()); + pcGroove->Reversed.setValue(on); + recomputeFeature(); +} + +double TaskGrooveParameters::getAngle(void) const +{ + return ui->grooveAngle->value().getValue(); +} + +void TaskGrooveParameters::getReferenceAxis(App::DocumentObject*& obj, std::vector& sub) const +{ + // get the support and Sketch + PartDesign::Groove* pcGroove = static_cast(vp->getObject()); + obj = static_cast(pcGroove->Sketch.getValue()); + sub = std::vector(1,""); + int maxcount=2; + if (obj) + maxcount += static_cast(obj)->getAxisCount(); + + if (obj) { + int num = ui->axis->currentIndex(); + if (num == 0) + sub[0] = "H_Axis"; + else if (num == 1) + sub[0] = "V_Axis"; + else if (num >= 2 && num < maxcount) { + QString buf = QString::fromUtf8("Axis%1").arg(num-2); + sub[0] = buf.toStdString(); + } else if (num == maxcount && ui->axis->count() == maxcount + 2) { + QStringList parts = ui->axis->currentText().split(QChar::fromAscii(':')); + obj = vp->getObject()->getDocument()->getObject(parts[0].toStdString().c_str()); + if (parts.size() > 1) + sub[0] = parts[1].toStdString(); + } else { + obj = NULL; + } + } + else + obj = NULL; +} + +bool TaskGrooveParameters::getMidplane(void) const +{ + return ui->checkBoxMidplane->isChecked(); +} + +bool TaskGrooveParameters::getReversed(void) const +{ + return ui->checkBoxReversed->isChecked(); +} + +TaskGrooveParameters::~TaskGrooveParameters() +{ + delete ui; +} + +void TaskGrooveParameters::changeEvent(QEvent *e) +{ + TaskBox::changeEvent(e); + if (e->type() == QEvent::LanguageChange) { + ui->retranslateUi(proxy); + } +} + +void TaskGrooveParameters::apply() +{ + App::DocumentObject* groove = vp->getObject(); + std::string name = groove->getNameInDocument(); + + // retrieve sketch and its support object + App::DocumentObject* sketch = 0; + App::DocumentObject* support = 0; + if (groove->getTypeId().isDerivedFrom(PartDesign::Groove::getClassTypeId())) { + sketch = static_cast(groove)->Sketch.getValue(); + if (sketch) { + support = static_cast(sketch)->Support.getValue(); + } + } + + //Gui::Command::openCommand("Groove changed"); + ui->grooveAngle->apply(); + std::vector sub; + App::DocumentObject* obj; + parameter->getReferenceAxis(obj, sub); + std::string axis = getPythonStr(obj, sub); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.ReferenceAxis = %s",name.c_str(),axis.c_str()); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Midplane = %i",name.c_str(), getMidplane() ? 1 : 0); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Reversed = %i",name.c_str(), getReversed() ? 1 : 0); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()"); + if (groove->isValid()) { + if (sketch) + Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().hide(\"%s\")",sketch->getNameInDocument()); + if (support) + Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().hide(\"%s\")",support->getNameInDocument()); + } + Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()"); + Gui::Command::commitCommand(); + } + +//************************************************************************** +//************************************************************************** +// TaskDialog +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +TaskDlgGrooveParameters::TaskDlgGrooveParameters(ViewProviderGroove *GrooveView) + : TaskDlgSketchBasedParameters(GrooveView) +{ + assert(vp); + parameter = new TaskGrooveParameters(static_cast(vp)); + + Content.push_back(parameter); +} + +TaskDlgGrooveParameters::~TaskDlgGrooveParameters() +{ + +} + +//==== calls from the TaskView =============================================================== + + +void TaskDlgGrooveParameters::open() +{ + // a transaction is already open at creation time of the groove + if (!Gui::Command::hasPendingCommand()) { + QString msg = QObject::tr("Edit groove"); + Gui::Command::openCommand((const char*)msg.toUtf8()); + } +} + +void TaskDlgGrooveParameters::clicked(int) +{ + +} + +bool TaskDlgGrooveParameters::accept() +{ + parameter->apply(); + return true; +} + +bool TaskDlgGrooveParameters::reject() +{ + // get the support and Sketch + PartDesign::Groove* pcGroove = static_cast(vp->getObject()); + Sketcher::SketchObject *pcSketch = 0; + if (pcGroove->Sketch.getValue()) { + pcSketch = static_cast(pcGroove->Sketch.getValue()); + } + + // role back the done things + Gui::Command::abortCommand(); + Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()"); + + // if abort command deleted the object the support is visible again + if (!Gui::Application::Instance->getViewProvider(pcGroove)) { + if (pcSketch && Gui::Application::Instance->getViewProvider(pcSketch)) + Gui::Application::Instance->getViewProvider(pcSketch)->show(); + } + + // Body housekeeping + if (ActivePartObject != NULL) { + // Make the new Tip and the previous solid feature visible again + App::DocumentObject* tip = ActivePartObject->Tip.getValue(); + App::DocumentObject* prev = ActivePartObject->getPrevSolidFeature(); + if (tip != NULL) { + Gui::Application::Instance->getViewProvider(tip)->show(); + if ((tip != prev) && (prev != NULL)) + Gui::Application::Instance->getViewProvider(prev)->show(); + } + } + + return true; +} + + + +#include "moc_TaskGrooveParameters.cpp" diff --git a/src/Mod/PartDesign/Gui/TaskGrooveParameters.h b/src/Mod/PartDesign/Gui/TaskGrooveParameters.h index d98aaddd3..e4511475c 100644 --- a/src/Mod/PartDesign/Gui/TaskGrooveParameters.h +++ b/src/Mod/PartDesign/Gui/TaskGrooveParameters.h @@ -62,15 +62,16 @@ private Q_SLOTS: void onReversed(bool); protected: - void onSelectionChanged(const Gui::SelectionChanges& msg) {} + void onSelectionChanged(const Gui::SelectionChanges& msg); void changeEvent(QEvent *e); - QString getReferenceAxis(void) const; + void getReferenceAxis(App::DocumentObject *&obj, std::vector &sub) const; double getAngle(void) const; bool getMidplane(void) const; bool getReversed(void) const; const bool updateView() const; private: + void updateUI(); private: QWidget* proxy; diff --git a/src/Mod/PartDesign/Gui/TaskGrooveParameters.ui b/src/Mod/PartDesign/Gui/TaskGrooveParameters.ui index 43f540cd4..07f78e043 100644 --- a/src/Mod/PartDesign/Gui/TaskGrooveParameters.ui +++ b/src/Mod/PartDesign/Gui/TaskGrooveParameters.ui @@ -25,6 +25,11 @@ + + + Horizontal sketch axis + + Vertical sketch axis @@ -32,7 +37,7 @@ - Horizontal sketch axis + Select reference... diff --git a/src/Mod/PartDesign/Gui/TaskRevolutionParameters.cpp b/src/Mod/PartDesign/Gui/TaskRevolutionParameters.cpp index 268c5cb8a..740311c50 100644 --- a/src/Mod/PartDesign/Gui/TaskRevolutionParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskRevolutionParameters.cpp @@ -39,9 +39,12 @@ #include #include #include +#include #include #include #include +#include "ReferenceSelection.h" +#include "TaskSketchBasedParameters.h" #include "Workbench.h" @@ -84,40 +87,14 @@ TaskRevolutionParameters::TaskRevolutionParameters(ViewProviderRevolution *Revol bool reversed = pcRevolution->Reversed.getValue(); ui->revolveAngle->setValue(l); - - int count=pcRevolution->getSketchAxisCount(); - - for (int i=ui->axis->count()-1; i >= count+2; i--) - ui->axis->removeItem(i); - for (int i=ui->axis->count(); i < count+2; i++) - ui->axis->addItem(QString::fromLatin1("Sketch axis %1").arg(i-2)); - - int pos=-1; - - App::DocumentObject *pcReferenceAxis = pcRevolution->ReferenceAxis.getValue(); - const std::vector &subReferenceAxis = pcRevolution->ReferenceAxis.getSubValues(); - if (pcReferenceAxis && pcReferenceAxis == pcRevolution->Sketch.getValue()) { - assert(subReferenceAxis.size()==1); - if (subReferenceAxis[0] == "V_Axis") - pos = 0; - else if (subReferenceAxis[0] == "H_Axis") - pos = 1; - else if (subReferenceAxis[0].size() > 4 && subReferenceAxis[0].substr(0,4) == "Axis") - pos = 2 + std::atoi(subReferenceAxis[0].substr(4,4000).c_str()); - } - - if (pos < 0 || pos >= ui->axis->count()) { - ui->axis->addItem(tr("Undefined")); - pos = ui->axis->count()-1; - } - - ui->axis->setCurrentIndex(pos); + blockUpdate = false; + updateUI(); ui->checkBoxMidplane->setChecked(mirrored); ui->checkBoxReversed->setChecked(reversed); ui->revolveAngle->bind(pcRevolution->Angle); - ui->revolveAngle->blockSignals(false); + ui->doubleSpinBox->blockSignals(false); ui->axis->blockSignals(false); ui->checkBoxMidplane->blockSignals(false); ui->checkBoxReversed->blockSignals(false); @@ -125,16 +102,100 @@ TaskRevolutionParameters::TaskRevolutionParameters(ViewProviderRevolution *Revol setFocus (); } +void TaskRevolutionParameters::updateUI() +{ + if (blockUpdate) + return; + blockUpdate = true; + + PartDesign::Revolution* pcRevolution = static_cast(vp->getObject()); + + App::DocumentObject* pcReferenceAxis = pcRevolution->ReferenceAxis.getValue(); + std::vector sub = pcRevolution->ReferenceAxis.getSubValues(); + + // Add user-defined sketch axes to the reference selection combo box + Sketcher::SketchObject *pcSketch = static_cast(pcRevolution->Sketch.getValue()); + int maxcount=2; + if (pcSketch) + maxcount += pcSketch->getAxisCount(); + + for (int i=ui->axis->count()-1; i >= 2; i--) + ui->axis->removeItem(i); + for (int i=ui->axis->count(); i < maxcount; i++) + ui->axis->addItem(QString::fromAscii("Sketch axis %1").arg(i-5)); + + bool undefined = false; + if (pcReferenceAxis != NULL && !sub.empty()) { + if (sub.front() == "H_Axis") + ui->axis->setCurrentIndex(0); + else if (sub.front() == "V_Axis") + ui->axis->setCurrentIndex(1); + else if (sub.front().size() > 4 && sub.front().substr(0,4) == "Axis") { + int pos = 2 + std::atoi(sub.front().substr(4,4000).c_str()); + if (pos <= maxcount) + ui->axis->setCurrentIndex(pos); + else + undefined = true; + } else { + ui->axis->addItem(getRefStr(pcReferenceAxis, sub)); + ui->axis->setCurrentIndex(maxcount); + } + } else { + undefined = true; + } + + ui->axis->addItem(tr("Select reference...")); + + blockUpdate = false; +} + +void TaskRevolutionParameters::onSelectionChanged(const Gui::SelectionChanges& msg) +{ + if (msg.Type == Gui::SelectionChanges::AddSelection) { + PartDesign::Revolution* pcRevolution = static_cast(vp->getObject()); + + exitSelectionMode(); + if (!blockUpdate) { + std::vector axis; + App::DocumentObject* selObj; + getReferencedSelection(pcRevolution, msg, selObj, axis); + pcRevolution->ReferenceAxis.setValue(selObj, axis); + + + recomputeFeature(); + updateUI(); + } + else { + Sketcher::SketchObject *pcSketch = static_cast(pcRevolution->Sketch.getValue()); + int maxcount=2; + if (pcSketch) + maxcount += pcSketch->getAxisCount(); + for (int i=ui->axis->count()-1; i >= maxcount; i--) + ui->axis->removeItem(i); + + std::vector sub; + App::DocumentObject* selObj; + getReferencedSelection(pcRevolution, msg, selObj, sub); + ui->axis->addItem(getRefStr(selObj, sub)); + ui->axis->setCurrentIndex(maxcount); + ui->axis->addItem(tr("Select reference...")); + } + } +} + + void TaskRevolutionParameters::onAngleChanged(double len) { PartDesign::Revolution* pcRevolution = static_cast(vp->getObject()); pcRevolution->Angle.setValue(len); - if (updateView()) - pcRevolution->getDocument()->recomputeFeature(pcRevolution); + exitSelectionMode(); + recomputeFeature(); } void TaskRevolutionParameters::onAxisChanged(int num) { + if (blockUpdate) + return; PartDesign::Revolution* pcRevolution = static_cast(vp->getObject()); Sketcher::SketchObject *pcSketch = static_cast(pcRevolution->Sketch.getValue()); if (pcSketch) { @@ -142,20 +203,26 @@ void TaskRevolutionParameters::onAxisChanged(int num) std::vector oldSubRefAxis = pcRevolution->ReferenceAxis.getSubValues(); int maxcount = pcSketch->getAxisCount()+2; - if (num == 0) - pcRevolution->ReferenceAxis.setValue(pcSketch, std::vector(1,"V_Axis")); - else if (num == 1) + if (num == 0) { pcRevolution->ReferenceAxis.setValue(pcSketch, std::vector(1,"H_Axis")); - else if (num >= 2 && num < maxcount) { + exitSelectionMode(); + } else if (num == 1) { + pcRevolution->ReferenceAxis.setValue(pcSketch, std::vector(1,"V_Axis")); + exitSelectionMode(); + } else if (num >= 2 && num < maxcount) { QString buf = QString::fromUtf8("Axis%1").arg(num-2); std::string str = buf.toStdString(); pcRevolution->ReferenceAxis.setValue(pcSketch, std::vector(1,str)); - } - if (num < maxcount && ui->axis->count() > maxcount) - ui->axis->setMaxCount(maxcount); + exitSelectionMode(); + } else if (num == ui->axis->count() - 1) { + // enter reference selection mode + TaskSketchBasedParameters::onSelectReference(true, true, false, true); + } else if (num == maxcount) + exitSelectionMode(); + App::DocumentObject *newRefAxis = pcRevolution->ReferenceAxis.getValue(); const std::vector &newSubRefAxis = pcRevolution->ReferenceAxis.getSubValues(); - if (oldRefAxis != pcSketch || + if (oldRefAxis != newRefAxis || oldSubRefAxis.size() != newSubRefAxis.size() || oldSubRefAxis[0] != newSubRefAxis[0]) { bool reversed = pcRevolution->suggestReversed(); @@ -167,24 +234,23 @@ void TaskRevolutionParameters::onAxisChanged(int num) } } } - if (updateView()) - pcRevolution->getDocument()->recomputeFeature(pcRevolution); + + updateUI(); + recomputeFeature(); } void TaskRevolutionParameters::onMidplane(bool on) { PartDesign::Revolution* pcRevolution = static_cast(vp->getObject()); pcRevolution->Midplane.setValue(on); - if (updateView()) - pcRevolution->getDocument()->recomputeFeature(pcRevolution); + recomputeFeature(); } void TaskRevolutionParameters::onReversed(bool on) { PartDesign::Revolution* pcRevolution = static_cast(vp->getObject()); pcRevolution->Reversed.setValue(on); - if (updateView()) - pcRevolution->getDocument()->recomputeFeature(pcRevolution); + recomputeFeature(); } double TaskRevolutionParameters::getAngle(void) const @@ -192,29 +258,36 @@ double TaskRevolutionParameters::getAngle(void) const return ui->revolveAngle->value().getValue(); } -QString TaskRevolutionParameters::getReferenceAxis(void) const +void TaskRevolutionParameters::getReferenceAxis(App::DocumentObject*& obj, std::vector& sub) const { // get the support and Sketch PartDesign::Revolution* pcRevolution = static_cast(vp->getObject()); - Sketcher::SketchObject *pcSketch = static_cast(pcRevolution->Sketch.getValue()); + obj = static_cast(pcRevolution->Sketch.getValue()); + sub = std::vector(1,""); + int maxcount=2; + if (obj) + maxcount += static_cast(obj)->getAxisCount(); - QString buf; - if (pcSketch) { - buf = QString::fromUtf8("(App.ActiveDocument.%1,[%2])"); - buf = buf.arg(QString::fromUtf8(pcSketch->getNameInDocument())); - if (ui->axis->currentIndex() == 0) - buf = buf.arg(QString::fromUtf8("'V_Axis'")); - else if (ui->axis->currentIndex() == 1) - buf = buf.arg(QString::fromUtf8("'H_Axis'")); - else if (ui->axis->currentIndex() >= 2) { - buf = buf.arg(QString::fromUtf8("'Axis%1'")); - buf = buf.arg(ui->axis->currentIndex()-2); + if (obj) { + int num = ui->axis->currentIndex(); + if (num == 0) + sub[0] = "H_Axis"; + else if (num == 1) + sub[0] = "V_Axis"; + else if (num >= 2 && num < maxcount) { + QString buf = QString::fromUtf8("Axis%1").arg(num-2); + sub[0] = buf.toStdString(); + } else if (num == maxcount && ui->axis->count() == maxcount + 2) { + QStringList parts = ui->axis->currentText().split(QChar::fromAscii(':')); + obj = vp->getObject()->getDocument()->getObject(parts[0].toStdString().c_str()); + if (parts.size() > 1) + sub[0] = parts[1].toStdString(); + } else { + obj = NULL; } } else - buf = QString::fromUtf8("''"); - - return buf; + obj = NULL; } bool TaskRevolutionParameters::getMidplane(void) const @@ -227,11 +300,6 @@ bool TaskRevolutionParameters::getReversed(void) const return ui->checkBoxReversed->isChecked(); } -const bool TaskRevolutionParameters::updateView() const -{ - return ui->checkBoxUpdateView->isChecked(); -} - TaskRevolutionParameters::~TaskRevolutionParameters() { delete ui; @@ -262,7 +330,10 @@ void TaskRevolutionParameters::apply() //Gui::Command::openCommand("Revolution changed"); ui->revolveAngle->apply(); - std::string axis = getReferenceAxis().toStdString(); + std::vector sub; + App::DocumentObject* obj; + parameter->getReferenceAxis(obj, sub); + std::string axis = getPythonStr(obj, sub); Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.ReferenceAxis = %s",name.c_str(),axis.c_str()); Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Midplane = %i",name.c_str(), getMidplane() ? 1 : 0); Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Reversed = %i",name.c_str(), getReversed() ? 1 : 0); diff --git a/src/Mod/PartDesign/Gui/TaskRevolutionParameters.cpp.orig b/src/Mod/PartDesign/Gui/TaskRevolutionParameters.cpp.orig new file mode 100644 index 000000000..3d058d31d --- /dev/null +++ b/src/Mod/PartDesign/Gui/TaskRevolutionParameters.cpp.orig @@ -0,0 +1,410 @@ +/*************************************************************************** + * Copyright (c) 2011 Juergen Riegel * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#include "PreCompiled.h" + +#ifndef _PreComp_ +#endif + +#include "ui_TaskRevolutionParameters.h" +#include "TaskRevolutionParameters.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ReferenceSelection.h" +#include "TaskSketchBasedParameters.h" +#include "Workbench.h" + + +using namespace PartDesignGui; +using namespace Gui; + +/* TRANSLATOR PartDesignGui::TaskRevolutionParameters */ + +TaskRevolutionParameters::TaskRevolutionParameters(ViewProviderRevolution *RevolutionView,QWidget *parent) + : TaskSketchBasedParameters(RevolutionView, parent, "PartDesign_Revolution",tr("Revolution parameters")) +{ + // we need a separate container widget to add all controls to + proxy = new QWidget(this); + ui = new Ui_TaskRevolutionParameters(); + ui->setupUi(proxy); + QMetaObject::connectSlotsByName(this); + + connect(ui->revolveAngle, SIGNAL(valueChanged(double)), + this, SLOT(onAngleChanged(double))); + connect(ui->axis, SIGNAL(activated(int)), + this, SLOT(onAxisChanged(int))); + connect(ui->checkBoxMidplane, SIGNAL(toggled(bool)), + this, SLOT(onMidplane(bool))); + connect(ui->checkBoxReversed, SIGNAL(toggled(bool)), + this, SLOT(onReversed(bool))); + connect(ui->checkBoxUpdateView, SIGNAL(toggled(bool)), + this, SLOT(onUpdateView(bool))); + + this->groupLayout()->addWidget(proxy); + + // Temporarily prevent unnecessary feature recomputes + ui->revolveAngle->blockSignals(true); + ui->axis->blockSignals(true); + ui->checkBoxMidplane->blockSignals(true); + ui->checkBoxReversed->blockSignals(true); + + PartDesign::Revolution* pcRevolution = static_cast(vp->getObject()); + double l = pcRevolution->Angle.getValue(); + bool mirrored = pcRevolution->Midplane.getValue(); + bool reversed = pcRevolution->Reversed.getValue(); + + ui->revolveAngle->setValue(l); +<<<<<<< f0798a82fe8f03db57aca4f634d2123486daaea0 + + int count=pcRevolution->getSketchAxisCount(); + + for (int i=ui->axis->count()-1; i >= count+2; i--) + ui->axis->removeItem(i); + for (int i=ui->axis->count(); i < count+2; i++) + ui->axis->addItem(QString::fromLatin1("Sketch axis %1").arg(i-2)); + + int pos=-1; + + App::DocumentObject *pcReferenceAxis = pcRevolution->ReferenceAxis.getValue(); + const std::vector &subReferenceAxis = pcRevolution->ReferenceAxis.getSubValues(); + if (pcReferenceAxis && pcReferenceAxis == pcRevolution->Sketch.getValue()) { + assert(subReferenceAxis.size()==1); + if (subReferenceAxis[0] == "V_Axis") + pos = 0; + else if (subReferenceAxis[0] == "H_Axis") + pos = 1; + else if (subReferenceAxis[0].size() > 4 && subReferenceAxis[0].substr(0,4) == "Axis") + pos = 2 + std::atoi(subReferenceAxis[0].substr(4,4000).c_str()); + } + + if (pos < 0 || pos >= ui->axis->count()) { + ui->axis->addItem(tr("Undefined")); + pos = ui->axis->count()-1; + } + + ui->axis->setCurrentIndex(pos); +======= + blockUpdate = false; + updateUI(); +>>>>>>> Enable edges and datum lines as rotation axis for Groove and Revolution features + + ui->checkBoxMidplane->setChecked(mirrored); + ui->checkBoxReversed->setChecked(reversed); + ui->revolveAngle->bind(pcRevolution->Angle); + + ui->doubleSpinBox->blockSignals(false); + ui->axis->blockSignals(false); + ui->checkBoxMidplane->blockSignals(false); + ui->checkBoxReversed->blockSignals(false); + + setFocus (); +} + +void TaskRevolutionParameters::updateUI() +{ + if (blockUpdate) + return; + blockUpdate = true; + + PartDesign::Revolution* pcRevolution = static_cast(vp->getObject()); + + App::DocumentObject* pcReferenceAxis = pcRevolution->ReferenceAxis.getValue(); + std::vector sub = pcRevolution->ReferenceAxis.getSubValues(); + + // Add user-defined sketch axes to the reference selection combo box + Sketcher::SketchObject *pcSketch = static_cast(pcRevolution->Sketch.getValue()); + int maxcount=2; + if (pcSketch) + maxcount += pcSketch->getAxisCount(); + + for (int i=ui->axis->count()-1; i >= 2; i--) + ui->axis->removeItem(i); + for (int i=ui->axis->count(); i < maxcount; i++) + ui->axis->addItem(QString::fromAscii("Sketch axis %1").arg(i-5)); + + bool undefined = false; + if (pcReferenceAxis != NULL && !sub.empty()) { + if (sub.front() == "H_Axis") + ui->axis->setCurrentIndex(0); + else if (sub.front() == "V_Axis") + ui->axis->setCurrentIndex(1); + else if (sub.front().size() > 4 && sub.front().substr(0,4) == "Axis") { + int pos = 2 + std::atoi(sub.front().substr(4,4000).c_str()); + if (pos <= maxcount) + ui->axis->setCurrentIndex(pos); + else + undefined = true; + } else { + ui->axis->addItem(getRefStr(pcReferenceAxis, sub)); + ui->axis->setCurrentIndex(maxcount); + } + } else { + undefined = true; + } + + ui->axis->addItem(tr("Select reference...")); + + blockUpdate = false; +} + +void TaskRevolutionParameters::onSelectionChanged(const Gui::SelectionChanges& msg) +{ + if (msg.Type == Gui::SelectionChanges::AddSelection) { + PartDesign::Revolution* pcRevolution = static_cast(vp->getObject()); + + exitSelectionMode(); + if (!blockUpdate) { + std::vector axis; + App::DocumentObject* selObj; + getReferencedSelection(pcRevolution, msg, selObj, axis); + pcRevolution->ReferenceAxis.setValue(selObj, axis); + + + recomputeFeature(); + updateUI(); + } + else { + Sketcher::SketchObject *pcSketch = static_cast(pcRevolution->Sketch.getValue()); + int maxcount=2; + if (pcSketch) + maxcount += pcSketch->getAxisCount(); + for (int i=ui->axis->count()-1; i >= maxcount; i--) + ui->axis->removeItem(i); + + std::vector sub; + App::DocumentObject* selObj; + getReferencedSelection(pcRevolution, msg, selObj, sub); + ui->axis->addItem(getRefStr(selObj, sub)); + ui->axis->setCurrentIndex(maxcount); + ui->axis->addItem(tr("Select reference...")); + } + } +} + + +void TaskRevolutionParameters::onAngleChanged(double len) +{ + PartDesign::Revolution* pcRevolution = static_cast(vp->getObject()); + pcRevolution->Angle.setValue(len); + exitSelectionMode(); + recomputeFeature(); +} + +void TaskRevolutionParameters::onAxisChanged(int num) +{ + if (blockUpdate) + return; + PartDesign::Revolution* pcRevolution = static_cast(vp->getObject()); + Sketcher::SketchObject *pcSketch = static_cast(pcRevolution->Sketch.getValue()); + if (pcSketch) { + App::DocumentObject *oldRefAxis = pcRevolution->ReferenceAxis.getValue(); + std::vector oldSubRefAxis = pcRevolution->ReferenceAxis.getSubValues(); + + int maxcount = pcSketch->getAxisCount()+2; + if (num == 0) { + pcRevolution->ReferenceAxis.setValue(pcSketch, std::vector(1,"H_Axis")); + exitSelectionMode(); + } else if (num == 1) { + pcRevolution->ReferenceAxis.setValue(pcSketch, std::vector(1,"V_Axis")); + exitSelectionMode(); + } else if (num >= 2 && num < maxcount) { + QString buf = QString::fromUtf8("Axis%1").arg(num-2); + std::string str = buf.toStdString(); + pcRevolution->ReferenceAxis.setValue(pcSketch, std::vector(1,str)); + exitSelectionMode(); + } else if (num == ui->axis->count() - 1) { + // enter reference selection mode + TaskSketchBasedParameters::onSelectReference(true, true, false, true); + } else if (num == maxcount) + exitSelectionMode(); + + App::DocumentObject *newRefAxis = pcRevolution->ReferenceAxis.getValue(); + const std::vector &newSubRefAxis = pcRevolution->ReferenceAxis.getSubValues(); + if (oldRefAxis != newRefAxis || + oldSubRefAxis.size() != newSubRefAxis.size() || + oldSubRefAxis[0] != newSubRefAxis[0]) { + bool reversed = pcRevolution->suggestReversed(); + if (reversed != pcRevolution->Reversed.getValue()) { + pcRevolution->Reversed.setValue(reversed); + ui->checkBoxReversed->blockSignals(true); + ui->checkBoxReversed->setChecked(reversed); + ui->checkBoxReversed->blockSignals(false); + } + } + } + + updateUI(); + recomputeFeature(); +} + +void TaskRevolutionParameters::onMidplane(bool on) +{ + PartDesign::Revolution* pcRevolution = static_cast(vp->getObject()); + pcRevolution->Midplane.setValue(on); + recomputeFeature(); +} + +void TaskRevolutionParameters::onReversed(bool on) +{ + PartDesign::Revolution* pcRevolution = static_cast(vp->getObject()); + pcRevolution->Reversed.setValue(on); + recomputeFeature(); +} + +double TaskRevolutionParameters::getAngle(void) const +{ + return ui->revolveAngle->value().getValue(); +} + +void TaskRevolutionParameters::getReferenceAxis(App::DocumentObject*& obj, std::vector& sub) const +{ + // get the support and Sketch + PartDesign::Revolution* pcRevolution = static_cast(vp->getObject()); + obj = static_cast(pcRevolution->Sketch.getValue()); + sub = std::vector(1,""); + int maxcount=2; + if (obj) + maxcount += static_cast(obj)->getAxisCount(); + + if (obj) { + int num = ui->axis->currentIndex(); + if (num == 0) + sub[0] = "H_Axis"; + else if (num == 1) + sub[0] = "V_Axis"; + else if (num >= 2 && num < maxcount) { + QString buf = QString::fromUtf8("Axis%1").arg(num-2); + sub[0] = buf.toStdString(); + } else if (num == maxcount && ui->axis->count() == maxcount + 2) { + QStringList parts = ui->axis->currentText().split(QChar::fromAscii(':')); + obj = vp->getObject()->getDocument()->getObject(parts[0].toStdString().c_str()); + if (parts.size() > 1) + sub[0] = parts[1].toStdString(); + } else { + obj = NULL; + } + } + else + obj = NULL; +} + +bool TaskRevolutionParameters::getMidplane(void) const +{ + return ui->checkBoxMidplane->isChecked(); +} + +bool TaskRevolutionParameters::getReversed(void) const +{ + return ui->checkBoxReversed->isChecked(); +} + +TaskRevolutionParameters::~TaskRevolutionParameters() +{ + delete ui; +} + +void TaskRevolutionParameters::changeEvent(QEvent *e) +{ + TaskBox::changeEvent(e); + if (e->type() == QEvent::LanguageChange) { + ui->retranslateUi(proxy); + } +} + +void TaskRevolutionParameters::apply() +{ + App::DocumentObject* revolve = vp->getObject(); + std::string name = revolve->getNameInDocument(); + + // retrieve sketch and its support object + App::DocumentObject* sketch = 0; + App::DocumentObject* support = 0; + if (revolve->getTypeId().isDerivedFrom(PartDesign::Revolution::getClassTypeId())) { + sketch = static_cast(revolve)->Sketch.getValue(); + if (sketch) { + support = static_cast(sketch)->Support.getValue(); + } + } + + //Gui::Command::openCommand("Revolution changed"); + ui->revolveAngle->apply(); + std::vector sub; + App::DocumentObject* obj; + parameter->getReferenceAxis(obj, sub); + std::string axis = getPythonStr(obj, sub); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.ReferenceAxis = %s",name.c_str(),axis.c_str()); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Midplane = %i",name.c_str(), getMidplane() ? 1 : 0); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Reversed = %i",name.c_str(), getReversed() ? 1 : 0); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()"); + if (revolve->isValid()) { + if (sketch) + Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().hide(\"%s\")",sketch->getNameInDocument()); + if (support) + Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().hide(\"%s\")",support->getNameInDocument()); + } + Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()"); + Gui::Command::commitCommand(); +} + +//************************************************************************** +//************************************************************************** +// TaskDialog +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +TaskDlgRevolutionParameters::TaskDlgRevolutionParameters(ViewProviderRevolution *RevolutionView) + : TaskDlgSketchBasedParameters(RevolutionView) +{ + assert(RevolutionView); + parameter = new TaskRevolutionParameters(RevolutionView); + + Content.push_back(parameter); +} + +TaskDlgRevolutionParameters::~TaskDlgRevolutionParameters() +{ + +} + +//==== calls from the TaskView =============================================================== + +bool TaskDlgRevolutionParameters::accept() +{ + parameter->apply(); + return true; +} + + +#include "moc_TaskRevolutionParameters.cpp" diff --git a/src/Mod/PartDesign/Gui/TaskRevolutionParameters.h b/src/Mod/PartDesign/Gui/TaskRevolutionParameters.h index 1f224447f..c38ff7342 100644 --- a/src/Mod/PartDesign/Gui/TaskRevolutionParameters.h +++ b/src/Mod/PartDesign/Gui/TaskRevolutionParameters.h @@ -62,17 +62,20 @@ private Q_SLOTS: void onReversed(bool); protected: - void onSelectionChanged(const Gui::SelectionChanges& msg) {} + void onSelectionChanged(const Gui::SelectionChanges& msg); void changeEvent(QEvent *e); const bool updateView() const; - QString getReferenceAxis(void) const; + void getReferenceAxis(App::DocumentObject *&obj, std::vector &sub) const; double getAngle(void) const; bool getMidplane(void) const; bool getReversed(void) const; +private: + void updateUI(); + private: QWidget* proxy; - Ui_TaskRevolutionParameters* ui; + Ui_TaskRevolutionParameters* ui; }; /// simulation dialog for the TaskView diff --git a/src/Mod/PartDesign/Gui/TaskRevolutionParameters.ui b/src/Mod/PartDesign/Gui/TaskRevolutionParameters.ui index 989786f40..23a640d2c 100644 --- a/src/Mod/PartDesign/Gui/TaskRevolutionParameters.ui +++ b/src/Mod/PartDesign/Gui/TaskRevolutionParameters.ui @@ -25,6 +25,11 @@ + + + Horizontal sketch axis + + Vertical sketch axis @@ -32,7 +37,7 @@ - Horizontal sketch axis + Select reference... diff --git a/src/Mod/PartDesign/Gui/TaskSketchBasedParameters.cpp b/src/Mod/PartDesign/Gui/TaskSketchBasedParameters.cpp index 669f440e1..d239a5cb6 100644 --- a/src/Mod/PartDesign/Gui/TaskSketchBasedParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskSketchBasedParameters.cpp @@ -113,6 +113,11 @@ void TaskSketchBasedParameters::onSelectReference(const bool pressed, const bool } } +void TaskSketchBasedParameters::exitSelectionMode() +{ + onSelectReference(false, false, false, false); +} + const QByteArray TaskSketchBasedParameters::onFaceName(const QString& text) { if (text.length() == 0) diff --git a/src/Mod/PartDesign/Gui/TaskSketchBasedParameters.h b/src/Mod/PartDesign/Gui/TaskSketchBasedParameters.h index f72fe4cf2..9724fb713 100644 --- a/src/Mod/PartDesign/Gui/TaskSketchBasedParameters.h +++ b/src/Mod/PartDesign/Gui/TaskSketchBasedParameters.h @@ -50,6 +50,7 @@ protected: void onSelectionChanged(const Gui::SelectionChanges& msg)=0; const QString onAddSelection(const Gui::SelectionChanges& msg); void onSelectReference(const bool pressed, const bool edge, const bool face, const bool planar); + void exitSelectionMode(); const QByteArray onFaceName(const QString& text); QString getFaceReference(const QString& obj, const QString& sub) const; void recomputeFeature();