Download src/Mod/Part/Gui/DlgPrimitives.cpp from AbdulElahGwaith/FreeCAD: direct link, hf CLI and curl.
- Browser
- Download file 93.5 kB
-
https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Mod/Part/Gui/DlgPrimitives.cpp
- Command line
-
hf download hf://AbdulElahGwaith/FreeCAD/src/Mod/Part/Gui/DlgPrimitives.cpp
-
curl -L -o DlgPrimitives.cpp https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Mod/Part/Gui/DlgPrimitives.cpp
93.5 kB
| // SPDX-License-Identifier: LGPL-2.1-or-later | |
| /*************************************************************************** | |
| * Copyright (c) 2007 Werner Mayer <wmayer[at]users.sourceforge.net> * | |
| * * | |
| * 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 * | |
| * * | |
| ***************************************************************************/ | |
| using namespace PartGui; | |
| namespace PartGui | |
| { | |
| QString getAutoGroupCommandStr(QString objectName) | |
| // Helper function to get the python code to add the newly created object to the active Part object | |
| // if present | |
| { | |
| App::Part* activePart = Gui::Application::Instance->activeView()->getActiveObject<App::Part*>( | |
| "part" | |
| ); | |
| if (activePart) { | |
| QString activeObjectName = QString::fromUtf8(activePart->getNameInDocument()); | |
| return QStringLiteral( | |
| "App.ActiveDocument.getObject('%1\')." | |
| "addObject(App.ActiveDocument.getObject('%2\'))\n" | |
| ) | |
| .arg(activeObjectName, objectName); | |
| } | |
| return QStringLiteral("# Object %1 created at document root").arg(objectName); | |
| } | |
| const char* gce_ErrorStatusText(gce_ErrorType et) | |
| { | |
| switch (et) { | |
| case gce_Done: | |
| return "Construction was successful"; | |
| case gce_ConfusedPoints: | |
| return "Two points are coincident"; | |
| case gce_NegativeRadius: | |
| return "Radius value is negative"; | |
| case gce_ColinearPoints: | |
| return "Three points are collinear"; | |
| case gce_IntersectionError: | |
| return "Intersection cannot be computed"; | |
| case gce_NullAxis: | |
| return "Axis is undefined"; | |
| case gce_NullAngle: | |
| return "Angle value is invalid (usually null)"; | |
| case gce_NullRadius: | |
| return "Radius is null"; | |
| case gce_InvertAxis: | |
| return "Axis value is invalid"; | |
| case gce_BadAngle: | |
| return "Angle value is invalid"; | |
| case gce_InvertRadius: | |
| return "Radius value is incorrect (usually with respect to another radius)"; | |
| case gce_NullFocusLength: | |
| return "Focal distance is null"; | |
| case gce_NullVector: | |
| return "Vector is null"; | |
| case gce_BadEquation: | |
| return "Coefficients are incorrect (applies to the equation of a geometric object)"; | |
| default: | |
| return "Creation of geometry failed"; | |
| } | |
| } | |
| static QString safeQuantityQString(Gui::QuantitySpinBox* qs) | |
| { | |
| return QString::fromStdString(qs->value().getSafeUserString()); | |
| } | |
| void Picker::createPrimitive(QWidget* widget, const QString& descr, Gui::Document* doc) | |
| { | |
| try { | |
| App::Document* app = doc->getDocument(); | |
| QString cmd = this->command(app); | |
| // Execute the Python block | |
| doc->openCommand(descr.toUtf8()); | |
| Gui::Command::runCommand(Gui::Command::Doc, cmd.toUtf8()); | |
| doc->commitCommand(); | |
| Gui::Command::runCommand(Gui::Command::Doc, "App.ActiveDocument.recompute()"); | |
| Gui::Command::runCommand(Gui::Command::Gui, "Gui.SendMsgToActiveView(\"ViewFit\")"); | |
| } | |
| catch (const Base::Exception& e) { | |
| QMessageBox::warning(widget, descr, QCoreApplication::translate("Exception", e.what())); | |
| } | |
| } | |
| QString Picker::toPlacement(const gp_Ax2& axis) const | |
| { | |
| gp_Dir dir = axis.Direction(); | |
| gp_Pnt pnt = gp_Pnt(0.0, 0.0, 0.0); | |
| gp_Ax3 ax3(pnt, dir, axis.XDirection()); | |
| gp_Trsf Trf; | |
| Trf.SetTransformation(ax3); | |
| Trf.Invert(); | |
| gp_XYZ theAxis(0, 0, 1); | |
| Standard_Real theAngle = 0.0; | |
| Trf.GetRotation(theAxis, theAngle); | |
| Base::Rotation rot(Base::convertTo<Base::Vector3d>(theAxis), theAngle); | |
| gp_Pnt loc = axis.Location(); | |
| return QStringLiteral("Base.Placement(Base.Vector(%1,%2,%3),Base.Rotation(%4,%5,%6,%7))") | |
| .arg(loc.X(), 0, 'g', Base::UnitsApi::getDecimals()) | |
| .arg(loc.Y(), 0, 'g', Base::UnitsApi::getDecimals()) | |
| .arg(loc.Z(), 0, 'g', Base::UnitsApi::getDecimals()) | |
| .arg(rot[0], 0, 'g', Base::UnitsApi::getDecimals()) | |
| .arg(rot[1], 0, 'g', Base::UnitsApi::getDecimals()) | |
| .arg(rot[2], 0, 'g', Base::UnitsApi::getDecimals()) | |
| .arg(rot[3], 0, 'g', Base::UnitsApi::getDecimals()); | |
| } | |
| class CircleFromThreePoints: public Picker | |
| { | |
| public: | |
| CircleFromThreePoints() | |
| : Picker() | |
| {} | |
| bool pickedPoint(const SoPickedPoint* point) override | |
| { | |
| SbVec3f pnt = point->getPoint(); | |
| points.emplace_back(pnt[0], pnt[1], pnt[2]); | |
| return points.size() == 3; | |
| } | |
| QString command(App::Document* doc) const override | |
| { | |
| GC_MakeArcOfCircle arc(points[0], points[1], points[2]); | |
| if (!arc.IsDone()) { | |
| throw Base::CADKernelError(gce_ErrorStatusText(arc.Status())); | |
| } | |
| Handle(Geom_TrimmedCurve) trim = arc.Value(); | |
| Handle(Geom_Circle) circle = Handle(Geom_Circle)::DownCast(trim->BasisCurve()); | |
| QString name = QString::fromUtf8(doc->getUniqueObjectName("Circle").c_str()); | |
| return QStringLiteral( | |
| "App.ActiveDocument.addObject(\"Part::Circle\",\"%1\")\n" | |
| "App.ActiveDocument.%1.Radius=%2\n" | |
| "App.ActiveDocument.%1.Angle1=%3\n" | |
| "App.ActiveDocument.%1.Angle2=%4\n" | |
| "App.ActiveDocument.%1.Placement=%5\n" | |
| ) | |
| .arg(name) | |
| .arg(circle->Radius(), 0, 'g', Base::UnitsApi::getDecimals()) | |
| .arg(Base::toDegrees(trim->FirstParameter()), 0, 'g', Base::UnitsApi::getDecimals()) | |
| .arg(Base::toDegrees(trim->LastParameter()), 0, 'g', Base::UnitsApi::getDecimals()) | |
| .arg(toPlacement(circle->Position())); | |
| } | |
| private: | |
| std::vector<gp_Pnt> points; | |
| }; | |
| } // namespace PartGui | |
| // ---------------------------------------------------------------------------- | |
| AbstractPrimitive::AbstractPrimitive(Part::Primitive* feature) | |
| : featurePtr(feature) | |
| {} | |
| bool AbstractPrimitive::hasValidPrimitive() const | |
| { | |
| return (!featurePtr.expired()); | |
| } | |
| void AbstractPrimitive::connectSignalMapper(QSignalMapper* mapper) | |
| { | |
| connect(mapper, &QSignalMapper::mappedObject, this, &AbstractPrimitive::changeValue); | |
| } | |
| namespace PartGui | |
| { | |
| void mapSignalMapper(QObject* sender, QSignalMapper* mapper) | |
| { | |
| mapper->setMapping(sender, sender); | |
| } | |
| template<typename Function> | |
| void connectMapSignalMapper( | |
| typename QtPrivate::FunctionPointer<Function>::Object* sender, | |
| Function func, | |
| QSignalMapper* mapper | |
| ) | |
| { | |
| QObject::connect(sender, func, mapper, qOverload<>(&QSignalMapper::map)); | |
| mapSignalMapper(sender, mapper); | |
| } | |
| } // namespace PartGui | |
| // ---------------------------------------------------------------------------- | |
| PlanePrimitive::PlanePrimitive(std::shared_ptr<Ui_DlgPrimitives> ui, Part::Plane* feature) | |
| : AbstractPrimitive(feature) | |
| , ui(ui) | |
| { | |
| ui->planeLength->setRange(0, std::numeric_limits<int>::max()); | |
| ui->planeWidth->setRange(0, std::numeric_limits<int>::max()); | |
| if (feature) { | |
| ui->planeLength->setValue(feature->Length.getQuantityValue()); | |
| ui->planeLength->bind(feature->Length); | |
| ui->planeWidth->setValue(feature->Width.getQuantityValue()); | |
| ui->planeWidth->bind(feature->Width); | |
| QSignalMapper* mapper = new QSignalMapper(this); | |
| connectSignalMapper(mapper); | |
| connectMapSignalMapper( | |
| ui->planeLength, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->planeWidth, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| } | |
| } | |
| const char* PlanePrimitive::getDefaultName() const | |
| { | |
| return "Plane"; | |
| } | |
| QString PlanePrimitive::create(const QString& objectName, const QString& placement) const | |
| { | |
| return QStringLiteral( | |
| "App.ActiveDocument.addObject(\"Part::Plane\",\"%1\")\n" | |
| "App.ActiveDocument.%1.Length='%2'\n" | |
| "App.ActiveDocument.%1.Width='%3'\n" | |
| "App.ActiveDocument.%1.Placement=%4\n" | |
| "App.ActiveDocument.%1.Label='%5'\n" | |
| ) | |
| .arg( | |
| objectName, | |
| safeQuantityQString(ui->planeLength), | |
| safeQuantityQString(ui->planeWidth), | |
| placement, | |
| DlgPrimitives::tr("Plane") | |
| ); | |
| } | |
| QString PlanePrimitive::change(const QString& objectName, const QString& placement) const | |
| { | |
| return QStringLiteral( | |
| "%1.Length='%2'\n" | |
| "%1.Width='%3'\n" | |
| "%1.Placement=%4\n" | |
| ) | |
| .arg( | |
| objectName, | |
| safeQuantityQString(ui->planeLength), | |
| safeQuantityQString(ui->planeWidth), | |
| placement | |
| ); | |
| } | |
| void PlanePrimitive::changeValue(QObject* widget) | |
| { | |
| if (featurePtr.expired()) { | |
| return; | |
| } | |
| Part::Plane* plane = featurePtr.get<Part::Plane>(); | |
| if (widget == ui->planeLength) { | |
| plane->Length.setValue(ui->planeLength->value().getValue()); | |
| } | |
| else if (widget == ui->planeWidth) { | |
| plane->Width.setValue(ui->planeWidth->value().getValue()); | |
| } | |
| plane->recomputeFeature(); | |
| } | |
| // ---------------------------------------------------------------------------- | |
| BoxPrimitive::BoxPrimitive(std::shared_ptr<Ui_DlgPrimitives> ui, Part::Box* feature) | |
| : AbstractPrimitive(feature) | |
| , ui(ui) | |
| { | |
| ui->boxLength->setRange(0, std::numeric_limits<int>::max()); | |
| ui->boxWidth->setRange(0, std::numeric_limits<int>::max()); | |
| ui->boxHeight->setRange(0, std::numeric_limits<int>::max()); | |
| if (feature) { | |
| ui->boxLength->setValue(feature->Length.getQuantityValue()); | |
| ui->boxLength->bind(feature->Length); | |
| ui->boxWidth->setValue(feature->Width.getQuantityValue()); | |
| ui->boxWidth->bind(feature->Width); | |
| ui->boxHeight->setValue(feature->Height.getQuantityValue()); | |
| ui->boxHeight->bind(feature->Height); | |
| QSignalMapper* mapper = new QSignalMapper(this); | |
| connectSignalMapper(mapper); | |
| connectMapSignalMapper( | |
| ui->boxLength, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->boxWidth, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->boxHeight, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| } | |
| } | |
| const char* BoxPrimitive::getDefaultName() const | |
| { | |
| return "Box"; | |
| } | |
| QString BoxPrimitive::create(const QString& objectName, const QString& placement) const | |
| { | |
| return QStringLiteral( | |
| "App.ActiveDocument.addObject(\"Part::Box\",\"%1\")\n" | |
| "App.ActiveDocument.%1.Length='%2'\n" | |
| "App.ActiveDocument.%1.Width='%3'\n" | |
| "App.ActiveDocument.%1.Height='%4'\n" | |
| "App.ActiveDocument.%1.Placement=%5\n" | |
| "App.ActiveDocument.%1.Label='%6'\n" | |
| ) | |
| .arg( | |
| objectName, | |
| safeQuantityQString(ui->boxLength), | |
| safeQuantityQString(ui->boxWidth), | |
| safeQuantityQString(ui->boxHeight), | |
| placement, | |
| DlgPrimitives::tr("Box") | |
| ); | |
| } | |
| QString BoxPrimitive::change(const QString& objectName, const QString& placement) const | |
| { | |
| return QStringLiteral( | |
| "%1.Length='%2'\n" | |
| "%1.Width='%3'\n" | |
| "%1.Height='%4'\n" | |
| "%1.Placement=%5\n" | |
| ) | |
| .arg( | |
| objectName, | |
| safeQuantityQString(ui->boxLength), | |
| safeQuantityQString(ui->boxWidth), | |
| safeQuantityQString(ui->boxHeight), | |
| placement | |
| ); | |
| } | |
| void BoxPrimitive::changeValue(QObject* widget) | |
| { | |
| if (featurePtr.expired()) { | |
| return; | |
| } | |
| Part::Box* box = featurePtr.get<Part::Box>(); | |
| if (widget == ui->boxLength) { | |
| box->Length.setValue(ui->boxLength->value().getValue()); | |
| } | |
| else if (widget == ui->boxWidth) { | |
| box->Width.setValue(ui->boxWidth->value().getValue()); | |
| } | |
| else if (widget == ui->boxHeight) { | |
| box->Height.setValue(ui->boxHeight->value().getValue()); | |
| } | |
| box->recomputeFeature(); | |
| } | |
| // ---------------------------------------------------------------------------- | |
| CylinderPrimitive::CylinderPrimitive(std::shared_ptr<Ui_DlgPrimitives> ui, Part::Cylinder* feature) | |
| : AbstractPrimitive(feature) | |
| , ui(ui) | |
| { | |
| ui->cylinderRadius->setRange(0, std::numeric_limits<int>::max()); | |
| ui->cylinderHeight->setRange(0, std::numeric_limits<int>::max()); | |
| ui->cylinderAngle->setRange(0, 360); | |
| if (feature) { | |
| ui->cylinderRadius->setValue(feature->Radius.getQuantityValue()); | |
| ui->cylinderRadius->bind(feature->Radius); | |
| ui->cylinderHeight->setValue(feature->Height.getQuantityValue()); | |
| ui->cylinderHeight->bind(feature->Height); | |
| ui->cylinderXSkew->setValue(feature->FirstAngle.getQuantityValue()); | |
| ui->cylinderXSkew->bind(feature->FirstAngle); | |
| ui->cylinderYSkew->setValue(feature->SecondAngle.getQuantityValue()); | |
| ui->cylinderYSkew->bind(feature->SecondAngle); | |
| ui->cylinderAngle->setValue(feature->Angle.getQuantityValue()); | |
| ui->cylinderAngle->bind(feature->Angle); | |
| QSignalMapper* mapper = new QSignalMapper(this); | |
| connectSignalMapper(mapper); | |
| connectMapSignalMapper( | |
| ui->cylinderRadius, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->cylinderHeight, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->cylinderXSkew, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->cylinderYSkew, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->cylinderAngle, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| } | |
| } | |
| const char* CylinderPrimitive::getDefaultName() const | |
| { | |
| return "Cylinder"; | |
| } | |
| QString CylinderPrimitive::create(const QString& objectName, const QString& placement) const | |
| { | |
| return QStringLiteral( | |
| "App.ActiveDocument.addObject(\"Part::Cylinder\",\"%1\")\n" | |
| "App.ActiveDocument.%1.Radius='%2'\n" | |
| "App.ActiveDocument.%1.Height='%3'\n" | |
| "App.ActiveDocument.%1.Angle='%4'\n" | |
| "App.ActiveDocument.%1.FirstAngle='%5'\n" | |
| "App.ActiveDocument.%1.SecondAngle='%6'\n" | |
| "App.ActiveDocument.%1.Placement=%7\n" | |
| "App.ActiveDocument.%1.Label='%8'\n" | |
| ) | |
| .arg( | |
| objectName, | |
| safeQuantityQString(ui->cylinderRadius), | |
| safeQuantityQString(ui->cylinderHeight), | |
| safeQuantityQString(ui->cylinderAngle), | |
| safeQuantityQString(ui->cylinderXSkew), | |
| safeQuantityQString(ui->cylinderYSkew), | |
| placement, | |
| DlgPrimitives::tr("Cylinder") | |
| ); | |
| } | |
| QString CylinderPrimitive::change(const QString& objectName, const QString& placement) const | |
| { | |
| return QStringLiteral( | |
| "%1.Radius='%2'\n" | |
| "%1.Height='%3'\n" | |
| "%1.Angle='%4'\n" | |
| "%1.FirstAngle='%5'\n" | |
| "%1.SecondAngle='%6'\n" | |
| "%1.Placement=%7\n" | |
| ) | |
| .arg( | |
| objectName, | |
| safeQuantityQString(ui->cylinderRadius), | |
| safeQuantityQString(ui->cylinderHeight), | |
| safeQuantityQString(ui->cylinderAngle), | |
| safeQuantityQString(ui->cylinderXSkew), | |
| safeQuantityQString(ui->cylinderYSkew), | |
| placement | |
| ); | |
| } | |
| void CylinderPrimitive::changeValue(QObject* widget) | |
| { | |
| if (featurePtr.expired()) { | |
| return; | |
| } | |
| Part::Cylinder* cyl = featurePtr.get<Part::Cylinder>(); | |
| if (widget == ui->cylinderRadius) { | |
| cyl->Radius.setValue(ui->cylinderRadius->value().getValue()); | |
| } | |
| else if (widget == ui->cylinderHeight) { | |
| cyl->Height.setValue(ui->cylinderHeight->value().getValue()); | |
| } | |
| else if (widget == ui->cylinderAngle) { | |
| cyl->Angle.setValue(ui->cylinderAngle->value().getValue()); | |
| } | |
| else if (widget == ui->cylinderXSkew) { | |
| cyl->FirstAngle.setValue(ui->cylinderXSkew->value().getValue()); | |
| } | |
| else if (widget == ui->cylinderYSkew) { | |
| cyl->SecondAngle.setValue(ui->cylinderYSkew->value().getValue()); | |
| } | |
| cyl->recomputeFeature(); | |
| } | |
| // ---------------------------------------------------------------------------- | |
| ConePrimitive::ConePrimitive(std::shared_ptr<Ui_DlgPrimitives> ui, Part::Cone* feature) | |
| : AbstractPrimitive(feature) | |
| , ui(ui) | |
| { | |
| ui->coneRadius1->setRange(0, std::numeric_limits<int>::max()); | |
| ui->coneRadius2->setRange(0, std::numeric_limits<int>::max()); | |
| ui->coneHeight->setRange(0, std::numeric_limits<int>::max()); | |
| ui->coneAngle->setRange(0, 360); | |
| if (feature) { | |
| ui->coneRadius1->setValue(feature->Radius1.getQuantityValue()); | |
| ui->coneRadius1->bind(feature->Radius1); | |
| ui->coneRadius2->setValue(feature->Radius2.getQuantityValue()); | |
| ui->coneRadius2->bind(feature->Radius2); | |
| ui->coneHeight->setValue(feature->Height.getQuantityValue()); | |
| ui->coneHeight->bind(feature->Height); | |
| ui->coneAngle->setValue(feature->Angle.getQuantityValue()); | |
| ui->coneAngle->bind(feature->Angle); | |
| QSignalMapper* mapper = new QSignalMapper(this); | |
| connectSignalMapper(mapper); | |
| connectMapSignalMapper( | |
| ui->coneRadius1, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->coneRadius2, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->coneHeight, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->coneAngle, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| } | |
| } | |
| const char* ConePrimitive::getDefaultName() const | |
| { | |
| return "Cone"; | |
| } | |
| QString ConePrimitive::create(const QString& objectName, const QString& placement) const | |
| { | |
| return QStringLiteral( | |
| "App.ActiveDocument.addObject(\"Part::Cone\",\"%1\")\n" | |
| "App.ActiveDocument.%1.Radius1='%2'\n" | |
| "App.ActiveDocument.%1.Radius2='%3'\n" | |
| "App.ActiveDocument.%1.Height='%4'\n" | |
| "App.ActiveDocument.%1.Angle='%5'\n" | |
| "App.ActiveDocument.%1.Placement=%6\n" | |
| "App.ActiveDocument.%1.Label='%7'\n" | |
| ) | |
| .arg( | |
| objectName, | |
| safeQuantityQString(ui->coneRadius1), | |
| safeQuantityQString(ui->coneRadius2), | |
| safeQuantityQString(ui->coneHeight), | |
| safeQuantityQString(ui->coneAngle), | |
| placement, | |
| DlgPrimitives::tr("Cone") | |
| ); | |
| } | |
| QString ConePrimitive::change(const QString& objectName, const QString& placement) const | |
| { | |
| return QStringLiteral( | |
| "%1.Radius1='%2'\n" | |
| "%1.Radius2='%3'\n" | |
| "%1.Height='%4'\n" | |
| "%1.Angle='%5'\n" | |
| "%1.Placement=%6\n" | |
| ) | |
| .arg( | |
| objectName, | |
| safeQuantityQString(ui->coneRadius1), | |
| safeQuantityQString(ui->coneRadius2), | |
| safeQuantityQString(ui->coneHeight), | |
| safeQuantityQString(ui->coneAngle), | |
| placement | |
| ); | |
| } | |
| void ConePrimitive::changeValue(QObject* widget) | |
| { | |
| if (featurePtr.expired()) { | |
| return; | |
| } | |
| Part::Cone* cone = featurePtr.get<Part::Cone>(); | |
| if (widget == ui->coneRadius1) { | |
| cone->Radius1.setValue(ui->coneRadius1->value().getValue()); | |
| } | |
| else if (widget == ui->coneRadius2) { | |
| cone->Radius2.setValue(ui->coneRadius2->value().getValue()); | |
| } | |
| else if (widget == ui->coneHeight) { | |
| cone->Height.setValue(ui->coneHeight->value().getValue()); | |
| } | |
| else if (widget == ui->coneAngle) { | |
| cone->Angle.setValue(ui->coneAngle->value().getValue()); | |
| } | |
| cone->recomputeFeature(); | |
| } | |
| // ---------------------------------------------------------------------------- | |
| SpherePrimitive::SpherePrimitive(std::shared_ptr<Ui_DlgPrimitives> ui, Part::Sphere* feature) | |
| : AbstractPrimitive(feature) | |
| , ui(ui) | |
| { | |
| ui->sphereRadius->setRange(0, std::numeric_limits<int>::max()); | |
| ui->sphereAngle1->setRange(-90, 90); | |
| ui->sphereAngle2->setRange(-90, 90); | |
| ui->sphereAngle3->setRange(0, 360); | |
| if (feature) { | |
| ui->sphereRadius->setValue(feature->Radius.getQuantityValue()); | |
| ui->sphereRadius->bind(feature->Radius); | |
| ui->sphereAngle1->setValue(feature->Angle1.getQuantityValue()); | |
| ui->sphereAngle1->bind(feature->Angle1); | |
| ui->sphereAngle2->setValue(feature->Angle2.getQuantityValue()); | |
| ui->sphereAngle2->bind(feature->Angle2); | |
| ui->sphereAngle3->setValue(feature->Angle3.getQuantityValue()); | |
| ui->sphereAngle3->bind(feature->Angle3); | |
| QSignalMapper* mapper = new QSignalMapper(this); | |
| connectSignalMapper(mapper); | |
| connectMapSignalMapper( | |
| ui->sphereRadius, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->sphereAngle1, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->sphereAngle2, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->sphereAngle3, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| } | |
| } | |
| const char* SpherePrimitive::getDefaultName() const | |
| { | |
| return "Sphere"; | |
| } | |
| QString SpherePrimitive::create(const QString& objectName, const QString& placement) const | |
| { | |
| return QStringLiteral( | |
| "App.ActiveDocument.addObject(\"Part::Sphere\",\"%1\")\n" | |
| "App.ActiveDocument.%1.Radius='%2'\n" | |
| "App.ActiveDocument.%1.Angle1='%3'\n" | |
| "App.ActiveDocument.%1.Angle2='%4'\n" | |
| "App.ActiveDocument.%1.Angle3='%5'\n" | |
| "App.ActiveDocument.%1.Placement=%6\n" | |
| "App.ActiveDocument.%1.Label='%7'\n" | |
| ) | |
| .arg( | |
| objectName, | |
| safeQuantityQString(ui->sphereRadius), | |
| safeQuantityQString(ui->sphereAngle1), | |
| safeQuantityQString(ui->sphereAngle2), | |
| safeQuantityQString(ui->sphereAngle3), | |
| placement, | |
| DlgPrimitives::tr("Sphere") | |
| ); | |
| } | |
| QString SpherePrimitive::change(const QString& objectName, const QString& placement) const | |
| { | |
| return QStringLiteral( | |
| "%1.Radius='%2'\n" | |
| "%1.Angle1='%3'\n" | |
| "%1.Angle2='%4'\n" | |
| "%1.Angle3='%5'\n" | |
| "%1.Placement=%6\n" | |
| ) | |
| .arg( | |
| objectName, | |
| safeQuantityQString(ui->sphereRadius), | |
| safeQuantityQString(ui->sphereAngle1), | |
| safeQuantityQString(ui->sphereAngle2), | |
| safeQuantityQString(ui->sphereAngle3), | |
| placement | |
| ); | |
| } | |
| void SpherePrimitive::changeValue(QObject* widget) | |
| { | |
| if (featurePtr.expired()) { | |
| return; | |
| } | |
| Part::Sphere* sphere = featurePtr.get<Part::Sphere>(); | |
| if (widget == ui->sphereRadius) { | |
| sphere->Radius.setValue(ui->sphereRadius->value().getValue()); | |
| } | |
| else if (widget == ui->sphereAngle1) { | |
| sphere->Angle1.setValue(ui->sphereAngle1->value().getValue()); | |
| } | |
| else if (widget == ui->sphereAngle2) { | |
| sphere->Angle2.setValue(ui->sphereAngle2->value().getValue()); | |
| } | |
| else if (widget == ui->sphereAngle3) { | |
| sphere->Angle3.setValue(ui->sphereAngle3->value().getValue()); | |
| } | |
| sphere->recomputeFeature(); | |
| } | |
| // ---------------------------------------------------------------------------- | |
| EllipsoidPrimitive::EllipsoidPrimitive(std::shared_ptr<Ui_DlgPrimitives> ui, Part::Ellipsoid* feature) | |
| : AbstractPrimitive(feature) | |
| , ui(ui) | |
| { | |
| ui->ellipsoidRadius1->setRange(0, std::numeric_limits<int>::max()); | |
| ui->ellipsoidRadius2->setRange(0, std::numeric_limits<int>::max()); | |
| ui->ellipsoidRadius3->setRange(0, std::numeric_limits<int>::max()); | |
| ui->ellipsoidAngle1->setRange(-90, 90); | |
| ui->ellipsoidAngle2->setRange(-90, 90); | |
| ui->ellipsoidAngle3->setRange(0, 360); | |
| if (feature) { | |
| ui->ellipsoidRadius1->setValue(feature->Radius1.getQuantityValue()); | |
| ui->ellipsoidRadius1->bind(feature->Radius1); | |
| ui->ellipsoidRadius2->setValue(feature->Radius2.getQuantityValue()); | |
| ui->ellipsoidRadius2->bind(feature->Radius2); | |
| ui->ellipsoidRadius3->setValue(feature->Radius3.getQuantityValue()); | |
| ui->ellipsoidRadius3->bind(feature->Radius3); | |
| ui->ellipsoidAngle1->setValue(feature->Angle1.getQuantityValue()); | |
| ui->ellipsoidAngle1->bind(feature->Angle1); | |
| ui->ellipsoidAngle2->setValue(feature->Angle2.getQuantityValue()); | |
| ui->ellipsoidAngle2->bind(feature->Angle2); | |
| ui->ellipsoidAngle3->setValue(feature->Angle3.getQuantityValue()); | |
| ui->ellipsoidAngle3->bind(feature->Angle3); | |
| QSignalMapper* mapper = new QSignalMapper(this); | |
| connectSignalMapper(mapper); | |
| connectMapSignalMapper( | |
| ui->ellipsoidRadius1, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->ellipsoidRadius2, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->ellipsoidRadius3, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->ellipsoidAngle1, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->ellipsoidAngle2, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->ellipsoidAngle3, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| } | |
| } | |
| const char* EllipsoidPrimitive::getDefaultName() const | |
| { | |
| return "Ellipsoid"; | |
| } | |
| QString EllipsoidPrimitive::create(const QString& objectName, const QString& placement) const | |
| { | |
| return QStringLiteral( | |
| "App.ActiveDocument.addObject(\"Part::Ellipsoid\",\"%1\")\n" | |
| "App.ActiveDocument.%1.Radius1='%2'\n" | |
| "App.ActiveDocument.%1.Radius2='%3'\n" | |
| "App.ActiveDocument.%1.Radius3='%4'\n" | |
| "App.ActiveDocument.%1.Angle1='%5'\n" | |
| "App.ActiveDocument.%1.Angle2='%6'\n" | |
| "App.ActiveDocument.%1.Angle3='%7'\n" | |
| "App.ActiveDocument.%1.Placement=%8\n" | |
| "App.ActiveDocument.%1.Label='%9'\n" | |
| ) | |
| .arg( | |
| objectName, | |
| safeQuantityQString(ui->ellipsoidRadius1), | |
| safeQuantityQString(ui->ellipsoidRadius2), | |
| safeQuantityQString(ui->ellipsoidRadius3), | |
| safeQuantityQString(ui->ellipsoidAngle1), | |
| safeQuantityQString(ui->ellipsoidAngle2), | |
| safeQuantityQString(ui->ellipsoidAngle3), | |
| placement, | |
| DlgPrimitives::tr("Ellipsoid") | |
| ); | |
| } | |
| QString EllipsoidPrimitive::change(const QString& objectName, const QString& placement) const | |
| { | |
| return QStringLiteral( | |
| "%1.Radius1='%2'\n" | |
| "%1.Radius2='%3'\n" | |
| "%1.Radius3='%4'\n" | |
| "%1.Angle1='%5'\n" | |
| "%1.Angle2='%6'\n" | |
| "%1.Angle3='%7'\n" | |
| "%1.Placement=%8\n" | |
| ) | |
| .arg( | |
| objectName, | |
| safeQuantityQString(ui->ellipsoidRadius1), | |
| safeQuantityQString(ui->ellipsoidRadius2), | |
| safeQuantityQString(ui->ellipsoidRadius3), | |
| safeQuantityQString(ui->ellipsoidAngle1), | |
| safeQuantityQString(ui->ellipsoidAngle2), | |
| safeQuantityQString(ui->ellipsoidAngle3), | |
| placement | |
| ); | |
| } | |
| void EllipsoidPrimitive::changeValue(QObject* widget) | |
| { | |
| if (featurePtr.expired()) { | |
| return; | |
| } | |
| Part::Ellipsoid* ell = featurePtr.get<Part::Ellipsoid>(); | |
| if (widget == ui->ellipsoidRadius1) { | |
| ell->Radius1.setValue(ui->ellipsoidRadius1->value().getValue()); | |
| } | |
| else if (widget == ui->ellipsoidRadius2) { | |
| ell->Radius2.setValue(ui->ellipsoidRadius2->value().getValue()); | |
| } | |
| else if (widget == ui->ellipsoidRadius3) { | |
| ell->Radius3.setValue(ui->ellipsoidRadius3->value().getValue()); | |
| } | |
| else if (widget == ui->ellipsoidAngle1) { | |
| ell->Angle1.setValue(ui->ellipsoidAngle1->value().getValue()); | |
| } | |
| else if (widget == ui->ellipsoidAngle2) { | |
| ell->Angle2.setValue(ui->ellipsoidAngle2->value().getValue()); | |
| } | |
| else if (widget == ui->ellipsoidAngle3) { | |
| ell->Angle3.setValue(ui->ellipsoidAngle3->value().getValue()); | |
| } | |
| ell->recomputeFeature(); | |
| } | |
| // ---------------------------------------------------------------------------- | |
| TorusPrimitive::TorusPrimitive(std::shared_ptr<Ui_DlgPrimitives> ui, Part::Torus* feature) | |
| : AbstractPrimitive(feature) | |
| , ui(ui) | |
| { | |
| ui->torusRadius1->setRange(0, std::numeric_limits<int>::max()); | |
| ui->torusRadius2->setRange(0, std::numeric_limits<int>::max()); | |
| ui->torusAngle1->setRange(-180, 180); | |
| ui->torusAngle2->setRange(-180, 180); | |
| ui->torusAngle3->setRange(0, 360); | |
| if (feature) { | |
| ui->torusRadius1->setValue(feature->Radius1.getQuantityValue()); | |
| ui->torusRadius1->bind(feature->Radius1); | |
| ui->torusRadius2->setValue(feature->Radius2.getQuantityValue()); | |
| ui->torusRadius2->bind(feature->Radius2); | |
| ui->torusAngle1->setValue(feature->Angle1.getQuantityValue()); | |
| ui->torusAngle1->bind(feature->Angle1); | |
| ui->torusAngle2->setValue(feature->Angle2.getQuantityValue()); | |
| ui->torusAngle2->bind(feature->Angle2); | |
| ui->torusAngle3->setValue(feature->Angle3.getQuantityValue()); | |
| ui->torusAngle3->bind(feature->Angle3); | |
| QSignalMapper* mapper = new QSignalMapper(this); | |
| connectSignalMapper(mapper); | |
| connectMapSignalMapper( | |
| ui->torusRadius1, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->torusRadius2, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->torusAngle1, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->torusAngle2, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->torusAngle3, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| } | |
| } | |
| const char* TorusPrimitive::getDefaultName() const | |
| { | |
| return "Torus"; | |
| } | |
| QString TorusPrimitive::create(const QString& objectName, const QString& placement) const | |
| { | |
| return QStringLiteral( | |
| "App.ActiveDocument.addObject(\"Part::Torus\",\"%1\")\n" | |
| "App.ActiveDocument.%1.Radius1='%2'\n" | |
| "App.ActiveDocument.%1.Radius2='%3'\n" | |
| "App.ActiveDocument.%1.Angle1='%4'\n" | |
| "App.ActiveDocument.%1.Angle2='%5'\n" | |
| "App.ActiveDocument.%1.Angle3='%6'\n" | |
| "App.ActiveDocument.%1.Placement=%7\n" | |
| "App.ActiveDocument.%1.Label='%8'\n" | |
| ) | |
| .arg( | |
| objectName, | |
| safeQuantityQString(ui->torusRadius1), | |
| safeQuantityQString(ui->torusRadius2), | |
| safeQuantityQString(ui->torusAngle1), | |
| safeQuantityQString(ui->torusAngle2), | |
| safeQuantityQString(ui->torusAngle3), | |
| placement, | |
| DlgPrimitives::tr("Torus") | |
| ); | |
| } | |
| QString TorusPrimitive::change(const QString& objectName, const QString& placement) const | |
| { | |
| return QStringLiteral( | |
| "%1.Radius1='%2'\n" | |
| "%1.Radius2='%3'\n" | |
| "%1.Angle1='%4'\n" | |
| "%1.Angle2='%5'\n" | |
| "%1.Angle3='%6'\n" | |
| "%1.Placement=%7\n" | |
| ) | |
| .arg( | |
| objectName, | |
| safeQuantityQString(ui->torusRadius1), | |
| safeQuantityQString(ui->torusRadius2), | |
| safeQuantityQString(ui->torusAngle1), | |
| safeQuantityQString(ui->torusAngle2), | |
| safeQuantityQString(ui->torusAngle3), | |
| placement | |
| ); | |
| } | |
| void TorusPrimitive::changeValue(QObject* widget) | |
| { | |
| if (featurePtr.expired()) { | |
| return; | |
| } | |
| Part::Torus* torus = featurePtr.get<Part::Torus>(); | |
| if (widget == ui->torusRadius1) { | |
| torus->Radius1.setValue(ui->torusRadius1->value().getValue()); | |
| } | |
| else if (widget == ui->torusRadius2) { | |
| torus->Radius2.setValue(ui->torusRadius2->value().getValue()); | |
| } | |
| else if (widget == ui->torusAngle1) { | |
| torus->Angle1.setValue(ui->torusAngle1->value().getValue()); | |
| } | |
| else if (widget == ui->torusAngle2) { | |
| torus->Angle2.setValue(ui->torusAngle2->value().getValue()); | |
| } | |
| else if (widget == ui->torusAngle3) { | |
| torus->Angle3.setValue(ui->torusAngle3->value().getValue()); | |
| } | |
| torus->recomputeFeature(); | |
| } | |
| // ---------------------------------------------------------------------------- | |
| PrismPrimitive::PrismPrimitive(std::shared_ptr<Ui_DlgPrimitives> ui, Part::Prism* feature) | |
| : AbstractPrimitive(feature) | |
| , ui(ui) | |
| { | |
| ui->prismCircumradius->setRange(0, std::numeric_limits<int>::max()); | |
| ui->prismHeight->setRange(0, std::numeric_limits<int>::max()); | |
| if (feature) { | |
| ui->prismPolygon->setValue(feature->Polygon.getValue()); | |
| ui->prismCircumradius->setValue(feature->Circumradius.getQuantityValue()); | |
| ui->prismCircumradius->bind(feature->Circumradius); | |
| ui->prismHeight->setValue(feature->Height.getQuantityValue()); | |
| ui->prismHeight->bind(feature->Height); | |
| ui->prismXSkew->setValue(feature->FirstAngle.getQuantityValue()); | |
| ui->prismXSkew->bind(feature->FirstAngle); | |
| ui->prismYSkew->setValue(feature->SecondAngle.getQuantityValue()); | |
| ui->prismYSkew->bind(feature->SecondAngle); | |
| QSignalMapper* mapper = new QSignalMapper(this); | |
| connectSignalMapper(mapper); | |
| connectMapSignalMapper(ui->prismPolygon, qOverload<int>(&QSpinBox::valueChanged), mapper); | |
| connectMapSignalMapper( | |
| ui->prismCircumradius, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->prismHeight, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->prismXSkew, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->prismYSkew, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| } | |
| } | |
| const char* PrismPrimitive::getDefaultName() const | |
| { | |
| return "Prism"; | |
| } | |
| QString PrismPrimitive::create(const QString& objectName, const QString& placement) const | |
| { | |
| return QStringLiteral( | |
| "App.ActiveDocument.addObject(\"Part::Prism\",\"%1\")\n" | |
| "App.ActiveDocument.%1.Polygon=%2\n" | |
| "App.ActiveDocument.%1.Circumradius='%3'\n" | |
| "App.ActiveDocument.%1.Height='%4'\n" | |
| "App.ActiveDocument.%1.FirstAngle='%5'\n" | |
| "App.ActiveDocument.%1.SecondAngle='%6'\n" | |
| "App.ActiveDocument.%1.Placement=%7\n" | |
| "App.ActiveDocument.%1.Label='%8'\n" | |
| ) | |
| .arg( | |
| objectName, | |
| QString::number(ui->prismPolygon->value()), | |
| safeQuantityQString(ui->prismCircumradius), | |
| safeQuantityQString(ui->prismHeight), | |
| safeQuantityQString(ui->prismXSkew), | |
| safeQuantityQString(ui->prismYSkew), | |
| placement, | |
| DlgPrimitives::tr("Prism") | |
| ); | |
| } | |
| QString PrismPrimitive::change(const QString& objectName, const QString& placement) const | |
| { | |
| return QStringLiteral( | |
| "%1.Polygon=%2\n" | |
| "%1.Circumradius='%3'\n" | |
| "%1.Height='%4'\n" | |
| "%1.FirstAngle='%5'\n" | |
| "%1.SecondAngle='%6'\n" | |
| "%1.Placement=%7\n" | |
| ) | |
| .arg( | |
| objectName, | |
| QString::number(ui->prismPolygon->value()), | |
| safeQuantityQString(ui->prismCircumradius), | |
| safeQuantityQString(ui->prismHeight), | |
| safeQuantityQString(ui->prismXSkew), | |
| safeQuantityQString(ui->prismYSkew), | |
| placement | |
| ); | |
| } | |
| void PrismPrimitive::changeValue(QObject* widget) | |
| { | |
| if (featurePtr.expired()) { | |
| return; | |
| } | |
| Part::Prism* prism = featurePtr.get<Part::Prism>(); | |
| if (widget == ui->prismPolygon) { | |
| prism->Polygon.setValue(ui->prismPolygon->value()); | |
| } | |
| else if (widget == ui->prismCircumradius) { | |
| prism->Circumradius.setValue(ui->prismCircumradius->value().getValue()); | |
| } | |
| else if (widget == ui->prismHeight) { | |
| prism->Height.setValue(ui->prismHeight->value().getValue()); | |
| } | |
| else if (widget == ui->prismXSkew) { | |
| prism->FirstAngle.setValue(ui->prismXSkew->value().getValue()); | |
| } | |
| else if (widget == ui->prismYSkew) { | |
| prism->SecondAngle.setValue(ui->prismYSkew->value().getValue()); | |
| } | |
| prism->recomputeFeature(); | |
| } | |
| // ---------------------------------------------------------------------------- | |
| WedgePrimitive::WedgePrimitive(std::shared_ptr<Ui_DlgPrimitives> ui, Part::Wedge* feature) | |
| : AbstractPrimitive(feature) | |
| , ui(ui) | |
| { | |
| constexpr int min = std::numeric_limits<int>::min(); | |
| constexpr int max = std::numeric_limits<int>::max(); | |
| ui->wedgeXmin->setMinimum(min); | |
| ui->wedgeXmin->setMaximum(max); | |
| ui->wedgeYmin->setMinimum(min); | |
| ui->wedgeYmin->setMaximum(max); | |
| ui->wedgeZmin->setMinimum(min); | |
| ui->wedgeZmin->setMaximum(max); | |
| ui->wedgeX2min->setMinimum(min); | |
| ui->wedgeX2min->setMaximum(max); | |
| ui->wedgeZ2min->setMinimum(min); | |
| ui->wedgeZ2min->setMaximum(max); | |
| ui->wedgeXmax->setMinimum(min); | |
| ui->wedgeXmax->setMaximum(max); | |
| ui->wedgeYmax->setMinimum(min); | |
| ui->wedgeYmax->setMaximum(max); | |
| ui->wedgeZmax->setMinimum(min); | |
| ui->wedgeZmax->setMaximum(max); | |
| ui->wedgeX2max->setMinimum(min); | |
| ui->wedgeX2max->setMaximum(max); | |
| ui->wedgeZ2max->setMinimum(min); | |
| ui->wedgeZ2max->setMaximum(max); | |
| if (feature) { | |
| ui->wedgeXmin->setValue(feature->Xmin.getQuantityValue()); | |
| ui->wedgeXmin->bind(feature->Xmin); | |
| ui->wedgeYmin->setValue(feature->Ymin.getQuantityValue()); | |
| ui->wedgeYmin->bind(feature->Ymin); | |
| ui->wedgeZmin->setValue(feature->Zmin.getQuantityValue()); | |
| ui->wedgeZmin->bind(feature->Zmin); | |
| ui->wedgeX2min->setValue(feature->X2min.getQuantityValue()); | |
| ui->wedgeX2min->bind(feature->X2min); | |
| ui->wedgeZ2min->setValue(feature->Z2min.getQuantityValue()); | |
| ui->wedgeZ2min->bind(feature->Z2min); | |
| ui->wedgeXmax->setValue(feature->Xmax.getQuantityValue()); | |
| ui->wedgeXmax->bind(feature->Xmax); | |
| ui->wedgeYmax->setValue(feature->Ymax.getQuantityValue()); | |
| ui->wedgeYmax->bind(feature->Ymax); | |
| ui->wedgeZmax->setValue(feature->Zmax.getQuantityValue()); | |
| ui->wedgeZmax->bind(feature->Zmax); | |
| ui->wedgeX2max->setValue(feature->X2max.getQuantityValue()); | |
| ui->wedgeX2max->bind(feature->X2max); | |
| ui->wedgeZ2max->setValue(feature->Z2max.getQuantityValue()); | |
| ui->wedgeZ2max->bind(feature->Z2max); | |
| QSignalMapper* mapper = new QSignalMapper(this); | |
| connectSignalMapper(mapper); | |
| connectMapSignalMapper( | |
| ui->wedgeXmin, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->wedgeYmin, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->wedgeZmin, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->wedgeX2min, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->wedgeZ2min, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->wedgeXmax, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->wedgeYmax, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->wedgeZmax, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->wedgeX2max, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->wedgeZ2max, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| } | |
| } | |
| const char* WedgePrimitive::getDefaultName() const | |
| { | |
| return "Wedge"; | |
| } | |
| QString WedgePrimitive::create(const QString& objectName, const QString& placement) const | |
| { | |
| return QStringLiteral( | |
| "App.ActiveDocument.addObject(\"Part::Wedge\",\"%1\")\n" | |
| "App.ActiveDocument.%1.Xmin='%2'\n" | |
| "App.ActiveDocument.%1.Ymin='%3'\n" | |
| "App.ActiveDocument.%1.Zmin='%4'\n" | |
| "App.ActiveDocument.%1.X2min='%5'\n" | |
| "App.ActiveDocument.%1.Z2min='%6'\n" | |
| "App.ActiveDocument.%1.Xmax='%7'\n" | |
| "App.ActiveDocument.%1.Ymax='%8'\n" | |
| "App.ActiveDocument.%1.Zmax='%9'\n" | |
| "App.ActiveDocument.%1.X2max='%10'\n" | |
| "App.ActiveDocument.%1.Z2max='%11'\n" | |
| "App.ActiveDocument.%1.Placement=%12\n" | |
| "App.ActiveDocument.%1.Label='%13'\n" | |
| ) | |
| .arg( | |
| objectName, | |
| safeQuantityQString(ui->wedgeXmin), | |
| safeQuantityQString(ui->wedgeYmin), | |
| safeQuantityQString(ui->wedgeZmin), | |
| safeQuantityQString(ui->wedgeX2min), | |
| safeQuantityQString(ui->wedgeZ2min), | |
| safeQuantityQString(ui->wedgeXmax), | |
| safeQuantityQString(ui->wedgeYmax) | |
| ) | |
| .arg( | |
| safeQuantityQString(ui->wedgeZmax), | |
| safeQuantityQString(ui->wedgeX2max), | |
| safeQuantityQString(ui->wedgeZ2max), | |
| placement, | |
| DlgPrimitives::tr("Wedge") | |
| ); | |
| } | |
| QString WedgePrimitive::change(const QString& objectName, const QString& placement) const | |
| { | |
| return QStringLiteral( | |
| "%1.Xmin='%2'\n" | |
| "%1.Ymin='%3'\n" | |
| "%1.Zmin='%4'\n" | |
| "%1.X2min='%5'\n" | |
| "%1.Z2min='%6'\n" | |
| "%1.Xmax='%7'\n" | |
| "%1.Ymax='%8'\n" | |
| "%1.Zmax='%9'\n" | |
| "%1.X2max='%10'\n" | |
| "%1.Z2max='%11'\n" | |
| "%1.Placement=%12\n" | |
| ) | |
| .arg( | |
| objectName, | |
| safeQuantityQString(ui->wedgeXmin), | |
| safeQuantityQString(ui->wedgeYmin), | |
| safeQuantityQString(ui->wedgeZmin), | |
| safeQuantityQString(ui->wedgeX2min), | |
| safeQuantityQString(ui->wedgeZ2min), | |
| safeQuantityQString(ui->wedgeXmax), | |
| safeQuantityQString(ui->wedgeYmax), | |
| safeQuantityQString(ui->wedgeZmax) | |
| ) | |
| .arg(safeQuantityQString(ui->wedgeX2max), safeQuantityQString(ui->wedgeZ2max), placement); | |
| } | |
| void WedgePrimitive::changeValue(QObject* widget) | |
| { | |
| if (featurePtr.expired()) { | |
| return; | |
| } | |
| Part::Wedge* wedge = featurePtr.get<Part::Wedge>(); | |
| if (widget == ui->wedgeXmin) { | |
| wedge->Xmin.setValue(ui->wedgeXmin->value().getValue()); | |
| } | |
| else if (widget == ui->wedgeYmin) { | |
| wedge->Ymin.setValue(ui->wedgeYmin->value().getValue()); | |
| } | |
| else if (widget == ui->wedgeZmin) { | |
| wedge->Zmin.setValue(ui->wedgeZmin->value().getValue()); | |
| } | |
| else if (widget == ui->wedgeX2min) { | |
| wedge->X2min.setValue(ui->wedgeX2min->value().getValue()); | |
| } | |
| else if (widget == ui->wedgeZ2min) { | |
| wedge->Z2min.setValue(ui->wedgeZ2min->value().getValue()); | |
| } | |
| else if (widget == ui->wedgeXmax) { | |
| wedge->Xmax.setValue(ui->wedgeXmax->value().getValue()); | |
| } | |
| else if (widget == ui->wedgeYmax) { | |
| wedge->Ymax.setValue(ui->wedgeYmax->value().getValue()); | |
| } | |
| else if (widget == ui->wedgeZmax) { | |
| wedge->Zmax.setValue(ui->wedgeZmax->value().getValue()); | |
| } | |
| else if (widget == ui->wedgeX2max) { | |
| wedge->X2max.setValue(ui->wedgeX2max->value().getValue()); | |
| } | |
| else if (widget == ui->wedgeZ2max) { | |
| wedge->Z2max.setValue(ui->wedgeZ2max->value().getValue()); | |
| } | |
| wedge->recomputeFeature(); | |
| } | |
| // ---------------------------------------------------------------------------- | |
| HelixPrimitive::HelixPrimitive(std::shared_ptr<Ui_DlgPrimitives> ui, Part::Helix* feature) | |
| : AbstractPrimitive(feature) | |
| , ui(ui) | |
| { | |
| ui->helixPitch->setRange(0, std::numeric_limits<int>::max()); | |
| ui->helixHeight->setRange(0, std::numeric_limits<int>::max()); | |
| ui->helixRadius->setRange(0, std::numeric_limits<int>::max()); | |
| ui->helixAngle->setRange(-89.9, 89.9); | |
| if (feature) { | |
| ui->helixPitch->setValue(feature->Pitch.getQuantityValue()); | |
| ui->helixPitch->bind(feature->Pitch); | |
| ui->helixHeight->setValue(feature->Height.getQuantityValue()); | |
| ui->helixHeight->bind(feature->Height); | |
| ui->helixRadius->setValue(feature->Radius.getQuantityValue()); | |
| ui->helixRadius->bind(feature->Radius); | |
| ui->helixAngle->setValue(feature->Angle.getQuantityValue()); | |
| ui->helixAngle->bind(feature->Angle); | |
| ui->helixLocalCS->setCurrentIndex(feature->LocalCoord.getValue()); | |
| QSignalMapper* mapper = new QSignalMapper(this); | |
| connectSignalMapper(mapper); | |
| connectMapSignalMapper( | |
| ui->helixPitch, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->helixHeight, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->helixRadius, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->helixAngle, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper(ui->helixLocalCS, qOverload<int>(&QComboBox::currentIndexChanged), mapper); | |
| } | |
| } | |
| const char* HelixPrimitive::getDefaultName() const | |
| { | |
| return "Helix"; | |
| } | |
| QString HelixPrimitive::create(const QString& objectName, const QString& placement) const | |
| { | |
| return QStringLiteral( | |
| "App.ActiveDocument.addObject(\"Part::Helix\",\"%1\")\n" | |
| "App.ActiveDocument.%1.Pitch='%2'\n" | |
| "App.ActiveDocument.%1.Height='%3'\n" | |
| "App.ActiveDocument.%1.Radius='%4'\n" | |
| "App.ActiveDocument.%1.Angle='%5'\n" | |
| "App.ActiveDocument.%1.LocalCoord=%6\n" | |
| "App.ActiveDocument.%1.Style=1\n" | |
| "App.ActiveDocument.%1.Placement=%7\n" | |
| "App.ActiveDocument.%1.Label='%8'\n" | |
| ) | |
| .arg( | |
| objectName, | |
| safeQuantityQString(ui->helixPitch), | |
| safeQuantityQString(ui->helixHeight), | |
| safeQuantityQString(ui->helixRadius), | |
| safeQuantityQString(ui->helixAngle), | |
| QString::number(ui->helixLocalCS->currentIndex()), | |
| placement, | |
| DlgPrimitives::tr("Helix") | |
| ); | |
| } | |
| QString HelixPrimitive::change(const QString& objectName, const QString& placement) const | |
| { | |
| return QStringLiteral( | |
| "%1.Pitch='%2'\n" | |
| "%1.Height='%3'\n" | |
| "%1.Radius='%4'\n" | |
| "%1.Angle='%5'\n" | |
| "%1.LocalCoord=%6\n" | |
| "%1.Placement=%7\n" | |
| ) | |
| .arg( | |
| objectName, | |
| safeQuantityQString(ui->helixPitch), | |
| safeQuantityQString(ui->helixHeight), | |
| safeQuantityQString(ui->helixRadius), | |
| safeQuantityQString(ui->helixAngle), | |
| QString::number(ui->helixLocalCS->currentIndex()), | |
| placement | |
| ); | |
| } | |
| void HelixPrimitive::changeValue(QObject* widget) | |
| { | |
| if (featurePtr.expired()) { | |
| return; | |
| } | |
| Part::Helix* helix = featurePtr.get<Part::Helix>(); | |
| if (widget == ui->helixPitch) { | |
| helix->Pitch.setValue(ui->helixPitch->value().getValue()); | |
| } | |
| else if (widget == ui->helixHeight) { | |
| helix->Height.setValue(ui->helixHeight->value().getValue()); | |
| } | |
| else if (widget == ui->helixRadius) { | |
| helix->Radius.setValue(ui->helixRadius->value().getValue()); | |
| } | |
| else if (widget == ui->helixAngle) { | |
| helix->Angle.setValue(ui->helixAngle->value().getValue()); | |
| } | |
| else if (widget == ui->helixLocalCS) { | |
| helix->LocalCoord.setValue(ui->helixLocalCS->currentIndex()); | |
| } | |
| helix->recomputeFeature(); | |
| } | |
| // ---------------------------------------------------------------------------- | |
| SpiralPrimitive::SpiralPrimitive(std::shared_ptr<Ui_DlgPrimitives> ui, Part::Spiral* feature) | |
| : AbstractPrimitive(feature) | |
| , ui(ui) | |
| { | |
| ui->spiralGrowth->setRange(0, std::numeric_limits<int>::max()); | |
| ui->spiralRotation->setRange(0, std::numeric_limits<int>::max()); | |
| ui->spiralRadius->setRange(0, std::numeric_limits<int>::max()); | |
| if (feature) { | |
| ui->spiralGrowth->setValue(feature->Growth.getQuantityValue()); | |
| ui->spiralGrowth->bind(feature->Growth); | |
| ui->spiralRotation->setValue(feature->Rotations.getQuantityValue().getValue()); | |
| ui->spiralRadius->setValue(feature->Radius.getQuantityValue()); | |
| ui->spiralRadius->bind(feature->Radius); | |
| QSignalMapper* mapper = new QSignalMapper(this); | |
| connectSignalMapper(mapper); | |
| connectMapSignalMapper( | |
| ui->spiralGrowth, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->spiralRotation, | |
| qOverload<double>(&QDoubleSpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->spiralRadius, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| } | |
| } | |
| const char* SpiralPrimitive::getDefaultName() const | |
| { | |
| return "Spiral"; | |
| } | |
| QString SpiralPrimitive::create(const QString& objectName, const QString& placement) const | |
| { | |
| return QStringLiteral( | |
| "App.ActiveDocument.addObject(\"Part::Spiral\",\"%1\")\n" | |
| "App.ActiveDocument.%1.Growth='%2'\n" | |
| "App.ActiveDocument.%1.Rotations=%3\n" | |
| "App.ActiveDocument.%1.Radius='%4'\n" | |
| "App.ActiveDocument.%1.Placement=%5\n" | |
| "App.ActiveDocument.%1.Label='%6'\n" | |
| ) | |
| .arg( | |
| objectName, | |
| safeQuantityQString(ui->spiralGrowth), | |
| QString::number(ui->spiralRotation->value()), | |
| safeQuantityQString(ui->spiralRadius), | |
| placement, | |
| DlgPrimitives::tr("Spiral") | |
| ); | |
| } | |
| QString SpiralPrimitive::change(const QString& objectName, const QString& placement) const | |
| { | |
| return QStringLiteral( | |
| "%1.Growth='%2'\n" | |
| "%1.Rotations=%3\n" | |
| "%1.Radius='%4'\n" | |
| "%1.Placement=%5\n" | |
| ) | |
| .arg( | |
| objectName, | |
| safeQuantityQString(ui->spiralGrowth), | |
| QString::number(ui->spiralRotation->value()), | |
| safeQuantityQString(ui->spiralRadius), | |
| placement | |
| ); | |
| } | |
| void SpiralPrimitive::changeValue(QObject* widget) | |
| { | |
| if (featurePtr.expired()) { | |
| return; | |
| } | |
| Part::Spiral* spiral = featurePtr.get<Part::Spiral>(); | |
| if (widget == ui->spiralGrowth) { | |
| spiral->Growth.setValue(ui->spiralGrowth->value().getValue()); | |
| } | |
| else if (widget == ui->spiralRotation) { | |
| spiral->Rotations.setValue(ui->spiralRotation->value()); | |
| } | |
| else if (widget == ui->spiralRadius) { | |
| spiral->Radius.setValue(ui->spiralRadius->value().getValue()); | |
| } | |
| spiral->recomputeFeature(); | |
| } | |
| // ---------------------------------------------------------------------------- | |
| CirclePrimitive::CirclePrimitive(std::shared_ptr<Ui_DlgPrimitives> ui, Part::Circle* feature) | |
| : AbstractPrimitive(feature) | |
| , ui(ui) | |
| { | |
| ui->circleRadius->setRange(0, std::numeric_limits<int>::max()); | |
| ui->circleAngle1->setRange(0, 360); | |
| ui->circleAngle2->setRange(0, 360); | |
| if (feature) { | |
| ui->circleRadius->setValue(feature->Radius.getQuantityValue()); | |
| ui->circleRadius->bind(feature->Radius); | |
| ui->circleAngle1->setValue(feature->Angle1.getQuantityValue()); | |
| ui->circleAngle1->bind(feature->Angle1); | |
| ui->circleAngle2->setValue(feature->Angle2.getQuantityValue()); | |
| ui->circleAngle2->bind(feature->Angle2); | |
| QSignalMapper* mapper = new QSignalMapper(this); | |
| connectSignalMapper(mapper); | |
| connectMapSignalMapper( | |
| ui->circleRadius, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->circleAngle1, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->circleAngle2, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| } | |
| } | |
| const char* CirclePrimitive::getDefaultName() const | |
| { | |
| return "Circle"; | |
| } | |
| QString CirclePrimitive::create(const QString& objectName, const QString& placement) const | |
| { | |
| return QStringLiteral( | |
| "App.ActiveDocument.addObject(\"Part::Circle\",\"%1\")\n" | |
| "App.ActiveDocument.%1.Radius='%2'\n" | |
| "App.ActiveDocument.%1.Angle1='%3'\n" | |
| "App.ActiveDocument.%1.Angle2='%4'\n" | |
| "App.ActiveDocument.%1.Placement=%5\n" | |
| "App.ActiveDocument.%1.Label='%6'\n" | |
| ) | |
| .arg( | |
| objectName, | |
| safeQuantityQString(ui->circleRadius), | |
| safeQuantityQString(ui->circleAngle1), | |
| safeQuantityQString(ui->circleAngle2), | |
| placement, | |
| DlgPrimitives::tr("Circle") | |
| ); | |
| } | |
| QString CirclePrimitive::change(const QString& objectName, const QString& placement) const | |
| { | |
| return QStringLiteral( | |
| "%1.Radius='%2'\n" | |
| "%1.Angle1='%3'\n" | |
| "%1.Angle2='%4'\n" | |
| "%1.Placement=%5\n" | |
| ) | |
| .arg( | |
| objectName, | |
| safeQuantityQString(ui->circleRadius), | |
| safeQuantityQString(ui->circleAngle1), | |
| safeQuantityQString(ui->circleAngle2), | |
| placement | |
| ); | |
| } | |
| void CirclePrimitive::changeValue(QObject* widget) | |
| { | |
| if (featurePtr.expired()) { | |
| return; | |
| } | |
| Part::Circle* circle = featurePtr.get<Part::Circle>(); | |
| if (widget == ui->circleRadius) { | |
| circle->Radius.setValue(ui->circleRadius->value().getValue()); | |
| } | |
| else if (widget == ui->circleAngle1) { | |
| circle->Angle1.setValue(ui->circleAngle1->value().getValue()); | |
| } | |
| else if (widget == ui->circleAngle2) { | |
| circle->Angle2.setValue(ui->circleAngle2->value().getValue()); | |
| } | |
| circle->recomputeFeature(); | |
| } | |
| // ---------------------------------------------------------------------------- | |
| EllipsePrimitive::EllipsePrimitive(std::shared_ptr<Ui_DlgPrimitives> ui, Part::Ellipse* feature) | |
| : AbstractPrimitive(feature) | |
| , ui(ui) | |
| { | |
| ui->ellipseMajorRadius->setRange(0, std::numeric_limits<int>::max()); | |
| ui->ellipseMinorRadius->setRange(0, std::numeric_limits<int>::max()); | |
| ui->ellipseAngle1->setRange(0, 360); | |
| ui->ellipseAngle2->setRange(0, 360); | |
| if (feature) { | |
| ui->ellipseMajorRadius->setValue(feature->MajorRadius.getQuantityValue()); | |
| ui->ellipseMajorRadius->bind(feature->MajorRadius); | |
| ui->ellipseMinorRadius->setValue(feature->MinorRadius.getQuantityValue()); | |
| ui->ellipseMinorRadius->bind(feature->MinorRadius); | |
| ui->ellipseAngle1->setValue(feature->Angle1.getQuantityValue()); | |
| ui->ellipseAngle1->bind(feature->Angle1); | |
| ui->ellipseAngle2->setValue(feature->Angle2.getQuantityValue()); | |
| ui->ellipseAngle2->bind(feature->Angle2); | |
| QSignalMapper* mapper = new QSignalMapper(this); | |
| connectSignalMapper(mapper); | |
| connectMapSignalMapper( | |
| ui->ellipseMajorRadius, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->ellipseMinorRadius, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->ellipseAngle1, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->ellipseAngle2, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| } | |
| } | |
| const char* EllipsePrimitive::getDefaultName() const | |
| { | |
| return "Ellipse"; | |
| } | |
| QString EllipsePrimitive::create(const QString& objectName, const QString& placement) const | |
| { | |
| return QStringLiteral( | |
| "App.ActiveDocument.addObject(\"Part::Ellipse\",\"%1\")\n" | |
| "App.ActiveDocument.%1.MajorRadius='%2'\n" | |
| "App.ActiveDocument.%1.MinorRadius='%3'\n" | |
| "App.ActiveDocument.%1.Angle1='%4'\n" | |
| "App.ActiveDocument.%1.Angle2='%5'\n" | |
| "App.ActiveDocument.%1.Placement=%6\n" | |
| "App.ActiveDocument.%1.Label='%7'\n" | |
| ) | |
| .arg( | |
| objectName, | |
| safeQuantityQString(ui->ellipseMajorRadius), | |
| safeQuantityQString(ui->ellipseMinorRadius), | |
| safeQuantityQString(ui->ellipseAngle1), | |
| safeQuantityQString(ui->ellipseAngle2), | |
| placement, | |
| DlgPrimitives::tr("Ellipse") | |
| ); | |
| } | |
| QString EllipsePrimitive::change(const QString& objectName, const QString& placement) const | |
| { | |
| return QStringLiteral( | |
| "%1.MajorRadius='%2'\n" | |
| "%1.MinorRadius='%3'\n" | |
| "%1.Angle1='%4'\n" | |
| "%1.Angle2='%5'\n" | |
| "%1.Placement=%6\n" | |
| ) | |
| .arg( | |
| objectName, | |
| safeQuantityQString(ui->ellipseMajorRadius), | |
| safeQuantityQString(ui->ellipseMinorRadius), | |
| safeQuantityQString(ui->ellipseAngle1), | |
| safeQuantityQString(ui->ellipseAngle2), | |
| placement | |
| ); | |
| } | |
| void EllipsePrimitive::changeValue(QObject* widget) | |
| { | |
| if (featurePtr.expired()) { | |
| return; | |
| } | |
| Part::Ellipse* ell = featurePtr.get<Part::Ellipse>(); | |
| if (widget == ui->ellipseMajorRadius) { | |
| ell->MajorRadius.setValue(ui->ellipseMajorRadius->value().getValue()); | |
| } | |
| else if (widget == ui->ellipseMinorRadius) { | |
| ell->MinorRadius.setValue(ui->ellipseMinorRadius->value().getValue()); | |
| } | |
| else if (widget == ui->ellipseAngle1) { | |
| ell->Angle1.setValue(ui->ellipseAngle1->value().getValue()); | |
| } | |
| else if (widget == ui->ellipseAngle2) { | |
| ell->Angle2.setValue(ui->ellipseAngle2->value().getValue()); | |
| } | |
| ell->recomputeFeature(); | |
| } | |
| // ---------------------------------------------------------------------------- | |
| PolygonPrimitive::PolygonPrimitive(std::shared_ptr<Ui_DlgPrimitives> ui, Part::RegularPolygon* feature) | |
| : AbstractPrimitive(feature) | |
| , ui(ui) | |
| { | |
| ui->regularPolygonCircumradius->setRange(0, std::numeric_limits<int>::max()); | |
| if (feature) { | |
| ui->regularPolygonPolygon->setValue(feature->Polygon.getValue()); | |
| ui->regularPolygonCircumradius->setValue(feature->Circumradius.getQuantityValue()); | |
| ui->regularPolygonCircumradius->bind(feature->Circumradius); | |
| QSignalMapper* mapper = new QSignalMapper(this); | |
| connectSignalMapper(mapper); | |
| connectMapSignalMapper(ui->regularPolygonPolygon, qOverload<int>(&QSpinBox::valueChanged), mapper); | |
| connectMapSignalMapper( | |
| ui->regularPolygonCircumradius, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| } | |
| } | |
| const char* PolygonPrimitive::getDefaultName() const | |
| { | |
| return "RegularPolygon"; | |
| } | |
| QString PolygonPrimitive::create(const QString& objectName, const QString& placement) const | |
| { | |
| return QStringLiteral( | |
| "App.ActiveDocument.addObject(\"Part::RegularPolygon\",\"%1\")\n" | |
| "App.ActiveDocument.%1.Polygon=%2\n" | |
| "App.ActiveDocument.%1.Circumradius='%3'\n" | |
| "App.ActiveDocument.%1.Placement=%4\n" | |
| "App.ActiveDocument.%1.Label='%5'\n" | |
| ) | |
| .arg( | |
| objectName, | |
| QString::number(ui->regularPolygonPolygon->value()), | |
| safeQuantityQString(ui->regularPolygonCircumradius), | |
| placement, | |
| DlgPrimitives::tr("Regular polygon") | |
| ); | |
| } | |
| QString PolygonPrimitive::change(const QString& objectName, const QString& placement) const | |
| { | |
| return QStringLiteral( | |
| "%1.Polygon=%2\n" | |
| "%1.Circumradius='%3'\n" | |
| "%1.Placement=%4\n" | |
| ) | |
| .arg( | |
| objectName, | |
| QString::number(ui->regularPolygonPolygon->value()), | |
| safeQuantityQString(ui->regularPolygonCircumradius), | |
| placement | |
| ); | |
| } | |
| void PolygonPrimitive::changeValue(QObject* widget) | |
| { | |
| if (featurePtr.expired()) { | |
| return; | |
| } | |
| Part::RegularPolygon* poly = featurePtr.get<Part::RegularPolygon>(); | |
| if (widget == ui->regularPolygonPolygon) { | |
| poly->Polygon.setValue(ui->regularPolygonPolygon->value()); | |
| } | |
| else if (widget == ui->regularPolygonCircumradius) { | |
| poly->Circumradius.setValue(ui->regularPolygonCircumradius->value().getValue()); | |
| } | |
| poly->recomputeFeature(); | |
| } | |
| // ---------------------------------------------------------------------------- | |
| LinePrimitive::LinePrimitive(std::shared_ptr<Ui_DlgPrimitives> ui, Part::Line* feature) | |
| : AbstractPrimitive(feature) | |
| , ui(ui) | |
| { | |
| constexpr int min = std::numeric_limits<int>::min(); | |
| constexpr int max = std::numeric_limits<int>::max(); | |
| ui->edgeX1->setMaximum(max); | |
| ui->edgeX1->setMinimum(min); | |
| ui->edgeY1->setMaximum(max); | |
| ui->edgeY1->setMinimum(min); | |
| ui->edgeZ1->setMaximum(max); | |
| ui->edgeZ1->setMinimum(min); | |
| ui->edgeX2->setMaximum(max); | |
| ui->edgeX2->setMinimum(min); | |
| ui->edgeY2->setMaximum(max); | |
| ui->edgeY2->setMinimum(min); | |
| ui->edgeZ2->setMaximum(max); | |
| ui->edgeZ2->setMinimum(min); | |
| if (feature) { | |
| ui->edgeX1->setValue(feature->X1.getQuantityValue()); | |
| ui->edgeX1->bind(feature->X1); | |
| ui->edgeY1->setValue(feature->Y1.getQuantityValue()); | |
| ui->edgeY1->bind(feature->Y1); | |
| ui->edgeZ1->setValue(feature->Z1.getQuantityValue()); | |
| ui->edgeZ1->bind(feature->Z1); | |
| ui->edgeX2->setValue(feature->X2.getQuantityValue()); | |
| ui->edgeX2->bind(feature->X2); | |
| ui->edgeY2->setValue(feature->Y2.getQuantityValue()); | |
| ui->edgeY2->bind(feature->Y2); | |
| ui->edgeZ2->setValue(feature->Z2.getQuantityValue()); | |
| ui->edgeZ2->bind(feature->Z2); | |
| QSignalMapper* mapper = new QSignalMapper(this); | |
| connectSignalMapper(mapper); | |
| connectMapSignalMapper(ui->edgeX1, qOverload<double>(&Gui::QuantitySpinBox::valueChanged), mapper); | |
| connectMapSignalMapper(ui->edgeY1, qOverload<double>(&Gui::QuantitySpinBox::valueChanged), mapper); | |
| connectMapSignalMapper(ui->edgeZ1, qOverload<double>(&Gui::QuantitySpinBox::valueChanged), mapper); | |
| connectMapSignalMapper(ui->edgeX2, qOverload<double>(&Gui::QuantitySpinBox::valueChanged), mapper); | |
| connectMapSignalMapper(ui->edgeY2, qOverload<double>(&Gui::QuantitySpinBox::valueChanged), mapper); | |
| connectMapSignalMapper(ui->edgeZ2, qOverload<double>(&Gui::QuantitySpinBox::valueChanged), mapper); | |
| } | |
| } | |
| const char* LinePrimitive::getDefaultName() const | |
| { | |
| return "Line"; | |
| } | |
| QString LinePrimitive::create(const QString& objectName, const QString& placement) const | |
| { | |
| return QStringLiteral( | |
| "App.ActiveDocument.addObject(\"Part::Line\",\"%1\")\n" | |
| "App.ActiveDocument.%1.X1='%2'\n" | |
| "App.ActiveDocument.%1.Y1='%3'\n" | |
| "App.ActiveDocument.%1.Z1='%4'\n" | |
| "App.ActiveDocument.%1.X2='%5'\n" | |
| "App.ActiveDocument.%1.Y2='%6'\n" | |
| "App.ActiveDocument.%1.Z2='%7'\n" | |
| "App.ActiveDocument.%1.Placement=%8\n" | |
| "App.ActiveDocument.%1.Label='%9'\n" | |
| ) | |
| .arg( | |
| objectName, | |
| safeQuantityQString(ui->edgeX1), | |
| safeQuantityQString(ui->edgeY1), | |
| safeQuantityQString(ui->edgeZ1), | |
| safeQuantityQString(ui->edgeX2), | |
| safeQuantityQString(ui->edgeY2), | |
| safeQuantityQString(ui->edgeZ2), | |
| placement, | |
| DlgPrimitives::tr("Line") | |
| ); | |
| } | |
| QString LinePrimitive::change(const QString& objectName, const QString& placement) const | |
| { | |
| return QStringLiteral( | |
| "%1.X1='%2'\n" | |
| "%1.Y1='%3'\n" | |
| "%1.Z1='%4'\n" | |
| "%1.X2='%5'\n" | |
| "%1.Y2='%6'\n" | |
| "%1.Z2='%7'\n" | |
| "%1.Placement=%8\n" | |
| ) | |
| .arg( | |
| objectName, | |
| safeQuantityQString(ui->edgeX1), | |
| safeQuantityQString(ui->edgeY1), | |
| safeQuantityQString(ui->edgeZ1), | |
| safeQuantityQString(ui->edgeX2), | |
| safeQuantityQString(ui->edgeY2), | |
| safeQuantityQString(ui->edgeZ2), | |
| placement | |
| ); | |
| } | |
| void LinePrimitive::changeValue(QObject* widget) | |
| { | |
| if (featurePtr.expired()) { | |
| return; | |
| } | |
| Part::Line* line = featurePtr.get<Part::Line>(); | |
| if (widget == ui->edgeX1) { | |
| line->X1.setValue(ui->edgeX1->value().getValue()); | |
| } | |
| else if (widget == ui->edgeY1) { | |
| line->Y1.setValue(ui->edgeY1->value().getValue()); | |
| } | |
| else if (widget == ui->edgeZ1) { | |
| line->Z1.setValue(ui->edgeZ1->value().getValue()); | |
| } | |
| else if (widget == ui->edgeX2) { | |
| line->X2.setValue(ui->edgeX2->value().getValue()); | |
| } | |
| else if (widget == ui->edgeY2) { | |
| line->Y2.setValue(ui->edgeY2->value().getValue()); | |
| } | |
| else if (widget == ui->edgeZ2) { | |
| line->Z2.setValue(ui->edgeZ2->value().getValue()); | |
| } | |
| line->recomputeFeature(); | |
| } | |
| // ---------------------------------------------------------------------------- | |
| VertexPrimitive::VertexPrimitive(std::shared_ptr<Ui_DlgPrimitives> ui, Part::Vertex* feature) | |
| : AbstractPrimitive(feature) | |
| , ui(ui) | |
| { | |
| constexpr int min = std::numeric_limits<int>::min(); | |
| constexpr int max = std::numeric_limits<int>::max(); | |
| ui->vertexX->setMaximum(max); | |
| ui->vertexY->setMaximum(max); | |
| ui->vertexZ->setMaximum(max); | |
| ui->vertexX->setMinimum(min); | |
| ui->vertexY->setMinimum(min); | |
| ui->vertexZ->setMinimum(min); | |
| if (feature) { | |
| ui->vertexX->setValue(feature->X.getQuantityValue()); | |
| ui->vertexX->bind(feature->X); | |
| ui->vertexY->setValue(feature->Y.getQuantityValue()); | |
| ui->vertexY->bind(feature->Y); | |
| ui->vertexZ->setValue(feature->Z.getQuantityValue()); | |
| ui->vertexZ->bind(feature->Z); | |
| QSignalMapper* mapper = new QSignalMapper(this); | |
| connectSignalMapper(mapper); | |
| connectMapSignalMapper( | |
| ui->vertexX, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->vertexY, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| connectMapSignalMapper( | |
| ui->vertexZ, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| mapper | |
| ); | |
| } | |
| } | |
| const char* VertexPrimitive::getDefaultName() const | |
| { | |
| return "Vertex"; | |
| } | |
| QString VertexPrimitive::create(const QString& objectName, const QString& placement) const | |
| { | |
| return QStringLiteral( | |
| "App.ActiveDocument.addObject(\"Part::Vertex\",\"%1\")\n" | |
| "App.ActiveDocument.%1.X='%2'\n" | |
| "App.ActiveDocument.%1.Y='%3'\n" | |
| "App.ActiveDocument.%1.Z='%4'\n" | |
| "App.ActiveDocument.%1.Placement=%5\n" | |
| "App.ActiveDocument.%1.Label='%6'\n" | |
| ) | |
| .arg( | |
| objectName, | |
| safeQuantityQString(ui->vertexX), | |
| safeQuantityQString(ui->vertexY), | |
| safeQuantityQString(ui->vertexZ), | |
| placement, | |
| DlgPrimitives::tr("Vertex") | |
| ); | |
| } | |
| QString VertexPrimitive::change(const QString& objectName, const QString& placement) const | |
| { | |
| return QStringLiteral( | |
| "%1.X='%2'\n" | |
| "%1.Y='%3'\n" | |
| "%1.Z='%4'\n" | |
| "%1.Placement=%5\n" | |
| ) | |
| .arg( | |
| objectName, | |
| safeQuantityQString(ui->vertexX), | |
| safeQuantityQString(ui->vertexY), | |
| safeQuantityQString(ui->vertexZ), | |
| placement | |
| ); | |
| } | |
| void VertexPrimitive::changeValue(QObject* widget) | |
| { | |
| if (featurePtr.expired()) { | |
| return; | |
| } | |
| Part::Vertex* v = featurePtr.get<Part::Vertex>(); | |
| if (widget == ui->vertexX) { | |
| v->X.setValue(ui->vertexX->value().getValue()); | |
| } | |
| else if (widget == ui->vertexY) { | |
| v->Y.setValue(ui->vertexY->value().getValue()); | |
| } | |
| else if (widget == ui->vertexZ) { | |
| v->Z.setValue(ui->vertexZ->value().getValue()); | |
| } | |
| v->recomputeFeature(); | |
| } | |
| // ---------------------------------------------------------------------------- | |
| /* TRANSLATOR PartGui::DlgPrimitives */ | |
| DlgPrimitives::DlgPrimitives(QWidget* parent, Part::Primitive* feature) | |
| : QWidget(parent) | |
| , ui(new Ui_DlgPrimitives) | |
| , featurePtr(feature) | |
| { | |
| ui->setupUi(this); | |
| connect( | |
| ui->buttonCircleFromThreePoints, | |
| &QPushButton::clicked, | |
| this, | |
| &DlgPrimitives::buttonCircleFromThreePoints | |
| ); | |
| Gui::Command::doCommand(Gui::Command::Doc, "from FreeCAD import Base"); | |
| Gui::Command::doCommand(Gui::Command::Doc, "import Part,PartGui"); | |
| // must be in the same order as of the stacked widget | |
| addPrimitive(std::make_shared<PlanePrimitive>(ui, dynamic_cast<Part::Plane*>(feature))); | |
| addPrimitive(std::make_shared<BoxPrimitive>(ui, dynamic_cast<Part::Box*>(feature))); | |
| addPrimitive(std::make_shared<CylinderPrimitive>(ui, dynamic_cast<Part::Cylinder*>(feature))); | |
| addPrimitive(std::make_shared<ConePrimitive>(ui, dynamic_cast<Part::Cone*>(feature))); | |
| addPrimitive(std::make_shared<SpherePrimitive>(ui, dynamic_cast<Part::Sphere*>(feature))); | |
| addPrimitive(std::make_shared<EllipsoidPrimitive>(ui, dynamic_cast<Part::Ellipsoid*>(feature))); | |
| addPrimitive(std::make_shared<TorusPrimitive>(ui, dynamic_cast<Part::Torus*>(feature))); | |
| addPrimitive(std::make_shared<PrismPrimitive>(ui, dynamic_cast<Part::Prism*>(feature))); | |
| addPrimitive(std::make_shared<WedgePrimitive>(ui, dynamic_cast<Part::Wedge*>(feature))); | |
| addPrimitive(std::make_shared<HelixPrimitive>(ui, dynamic_cast<Part::Helix*>(feature))); | |
| addPrimitive(std::make_shared<SpiralPrimitive>(ui, dynamic_cast<Part::Spiral*>(feature))); | |
| addPrimitive(std::make_shared<CirclePrimitive>(ui, dynamic_cast<Part::Circle*>(feature))); | |
| addPrimitive(std::make_shared<EllipsePrimitive>(ui, dynamic_cast<Part::Ellipse*>(feature))); | |
| addPrimitive(std::make_shared<VertexPrimitive>(ui, dynamic_cast<Part::Vertex*>(feature))); | |
| addPrimitive(std::make_shared<LinePrimitive>(ui, dynamic_cast<Part::Line*>(feature))); | |
| addPrimitive(std::make_shared<PolygonPrimitive>(ui, dynamic_cast<Part::RegularPolygon*>(feature))); | |
| if (feature) { | |
| activatePage(); | |
| } | |
| } | |
| /* | |
| * Destroys the object and frees any allocated resources | |
| */ | |
| DlgPrimitives::~DlgPrimitives() = default; | |
| void DlgPrimitives::activatePage() | |
| { | |
| int index = findIndexOfValidPrimitive(); | |
| ui->PrimitiveTypeCB->setCurrentIndex(index); | |
| ui->widgetStack2->setCurrentIndex(index); | |
| ui->PrimitiveTypeCB->setDisabled(true); | |
| } | |
| void DlgPrimitives::addPrimitive(std::shared_ptr<AbstractPrimitive> prim) | |
| { | |
| primitive.push_back(prim); | |
| } | |
| std::shared_ptr<AbstractPrimitive> DlgPrimitives::getPrimitive(int index) const | |
| { | |
| return primitive.at(index); | |
| } | |
| int DlgPrimitives::findIndexOfValidPrimitive() const | |
| { | |
| return std::distance( | |
| primitive.begin(), | |
| std::find_if(primitive.begin(), primitive.end(), [](std::shared_ptr<AbstractPrimitive> prim) { | |
| return prim->hasValidPrimitive(); | |
| }) | |
| ); | |
| } | |
| void DlgPrimitives::pickCallback(void* ud, SoEventCallback* n) | |
| { | |
| const SoMouseButtonEvent* mbe = static_cast<const SoMouseButtonEvent*>(n->getEvent()); | |
| Picker* pick = static_cast<Picker*>(ud); | |
| if (pick->exitCode >= 0) { | |
| pick->loop.exit(pick->exitCode); | |
| } | |
| // Mark all incoming mouse button events as handled, especially, to deactivate the selection node | |
| n->setHandled(); | |
| if (mbe->getButton() == SoMouseButtonEvent::BUTTON1) { | |
| if (mbe->getState() == SoButtonEvent::DOWN) { | |
| const SoPickedPoint* point = n->getPickedPoint(); | |
| if (point) { | |
| if (pick->pickedPoint(point)) { | |
| pick->exitCode = 0; | |
| } | |
| } | |
| } | |
| } | |
| else if (mbe->getButton() == SoMouseButtonEvent::BUTTON2) { | |
| if (mbe->getState() == SoButtonEvent::UP) { | |
| pick->loop.exit(1); | |
| } | |
| } | |
| } | |
| void DlgPrimitives::executeCallback(Picker* p) | |
| { | |
| Gui::Document* doc = Gui::Application::Instance->activeDocument(); | |
| if (!doc) { | |
| return; | |
| } | |
| Gui::View3DInventor* view = static_cast<Gui::View3DInventor*>(doc->getActiveView()); | |
| if (view) { | |
| Gui::View3DInventorViewer* viewer = view->getViewer(); | |
| if (!viewer->isEditing()) { | |
| viewer->setEditing(true); | |
| viewer->setRedirectToSceneGraph(true); | |
| SoNode* root = viewer->getSceneGraph(); | |
| int mode = 0; | |
| if (root && root->getTypeId().isDerivedFrom(Gui::SoFCUnifiedSelection::getClassTypeId())) { | |
| mode = static_cast<Gui::SoFCUnifiedSelection*>(root)->selectionMode.getValue(); | |
| static_cast<Gui::SoFCUnifiedSelection*>(root)->selectionMode.setValue( | |
| Gui::SoFCUnifiedSelection::OFF | |
| ); | |
| } | |
| viewer->addEventCallback(SoMouseButtonEvent::getClassTypeId(), pickCallback, p); | |
| this->setDisabled(true); | |
| int ret = p->loop.exec(); | |
| if (root && root->getTypeId().isDerivedFrom(Gui::SoFCUnifiedSelection::getClassTypeId())) { | |
| static_cast<Gui::SoFCUnifiedSelection*>(root)->selectionMode.setValue(mode); | |
| } | |
| this->setEnabled(true); | |
| viewer->setEditing(false); | |
| viewer->setRedirectToSceneGraph(false); | |
| viewer->removeEventCallback(SoMouseButtonEvent::getClassTypeId(), pickCallback, p); | |
| if (ret == 0) { | |
| p->createPrimitive(this, ui->PrimitiveTypeCB->currentText(), doc); | |
| } | |
| } | |
| } | |
| } | |
| void DlgPrimitives::buttonCircleFromThreePoints() | |
| { | |
| CircleFromThreePoints pp; | |
| executeCallback(&pp); | |
| } | |
| void DlgPrimitives::tryCreatePrimitive(const QString& placement) | |
| { | |
| QString cmd; | |
| QString name; | |
| App::Document* doc = App::GetApplication().getActiveDocument(); | |
| if (!doc) { | |
| QMessageBox::warning( | |
| this, | |
| tr("Create %1").arg(ui->PrimitiveTypeCB->currentText()), | |
| tr("No active document") | |
| ); | |
| return; | |
| } | |
| std::shared_ptr<AbstractPrimitive> primitive = getPrimitive(ui->PrimitiveTypeCB->currentIndex()); | |
| name = QString::fromUtf8(doc->getUniqueObjectName(primitive->getDefaultName()).c_str()); | |
| cmd = primitive->create(name, placement); | |
| // Execute the Python block | |
| QString prim = tr("Create %1").arg(ui->PrimitiveTypeCB->currentText()); | |
| Gui::Application::Instance->activeDocument()->openCommand(prim.toUtf8()); | |
| Gui::Command::runCommand(Gui::Command::Doc, cmd.toUtf8()); | |
| Gui::Command::runCommand(Gui::Command::Doc, getAutoGroupCommandStr(name).toUtf8()); | |
| Gui::Application::Instance->activeDocument()->commitCommand(); | |
| Gui::Command::runCommand(Gui::Command::Doc, "App.ActiveDocument.recompute()"); | |
| Gui::Command::runCommand(Gui::Command::Gui, "Gui.SendMsgToActiveView(\"ViewFit\")"); | |
| } | |
| void DlgPrimitives::createPrimitive(const QString& placement) | |
| { | |
| try { | |
| tryCreatePrimitive(placement); | |
| } | |
| catch (const std::exception& e) { | |
| QMessageBox::warning( | |
| this, | |
| tr("Create %1").arg(ui->PrimitiveTypeCB->currentText()), | |
| QCoreApplication::translate("Exception", e.what()) | |
| ); | |
| } | |
| catch (const Base::PyException& e) { | |
| QMessageBox::warning( | |
| this, | |
| tr("Create %1").arg(ui->PrimitiveTypeCB->currentText()), | |
| QCoreApplication::translate("Exception", e.what()) | |
| ); | |
| } | |
| } | |
| void DlgPrimitives::acceptChanges(const QString& placement) | |
| { | |
| App::Document* doc = featurePtr->getDocument(); | |
| QString objectName = QStringLiteral("App.getDocument(\"%1\").%2") | |
| .arg( | |
| QString::fromUtf8(doc->getName()), | |
| QString::fromUtf8(featurePtr->getNameInDocument()) | |
| ); | |
| // read values from the properties | |
| std::shared_ptr<AbstractPrimitive> primitive = getPrimitive(ui->PrimitiveTypeCB->currentIndex()); | |
| QString command = primitive->change(objectName, placement); | |
| // execute command, a transaction is already opened | |
| Gui::Command::runCommand(Gui::Command::App, command.toUtf8()); | |
| } | |
| void DlgPrimitives::accept(const QString& placement) | |
| { | |
| if (featurePtr.expired()) { | |
| return; | |
| } | |
| App::Document* doc = featurePtr->getDocument(); | |
| acceptChanges(placement); | |
| doc->recompute(); | |
| // commit undo command | |
| doc->commitTransaction(); | |
| } | |
| void DlgPrimitives::reject() | |
| { | |
| if (featurePtr.expired()) { | |
| return; | |
| } | |
| App::Document* doc = featurePtr->getDocument(); | |
| doc->abortTransaction(); | |
| } | |
| // ---------------------------------------------- | |
| /* TRANSLATOR PartGui::Location */ | |
| Location::Location(QWidget* parent, Part::Feature* feature) | |
| : QWidget(parent) | |
| , ui(new Ui_Location) | |
| , featurePtr(feature) | |
| { | |
| mode = 0; | |
| ui->setupUi(this); | |
| connect(ui->viewPositionButton, &QPushButton::clicked, this, &Location::onViewPositionButton); | |
| ui->XPositionQSB->setUnit(Base::Unit::Length); | |
| ui->YPositionQSB->setUnit(Base::Unit::Length); | |
| ui->ZPositionQSB->setUnit(Base::Unit::Length); | |
| ui->AngleQSB->setUnit(Base::Unit::Angle); | |
| // fill location widget if object already exists | |
| if (feature) { | |
| setPlacement(feature); | |
| bindExpressions(feature); | |
| connectSignals(); | |
| } | |
| } | |
| Location::~Location() | |
| { | |
| // no need to delete child widgets, Qt does it all for us | |
| if (!this->activeView.isNull()) { | |
| Gui::View3DInventorViewer* viewer | |
| = static_cast<Gui::View3DInventor*>(this->activeView.data())->getViewer(); | |
| viewer->setEditing(false); | |
| viewer->setRedirectToSceneGraph(false); | |
| viewer->removeEventCallback(SoMouseButtonEvent::getClassTypeId(), pickCallback, this); | |
| SoNode* root = viewer->getSceneGraph(); | |
| if (root && root->getTypeId().isDerivedFrom(Gui::SoFCUnifiedSelection::getClassTypeId())) { | |
| static_cast<Gui::SoFCUnifiedSelection*>(root)->selectionMode.setValue(this->mode); | |
| } | |
| } | |
| } | |
| void Location::setPlacement(Part::Feature* feature) | |
| { | |
| // get the placement values | |
| auto placement = feature->Placement.getValue(); | |
| auto position = placement.getPosition(); | |
| ui->XPositionQSB->setValue(position.x); | |
| ui->YPositionQSB->setValue(position.y); | |
| ui->ZPositionQSB->setValue(position.z); | |
| double rotationAngle; | |
| Base::Vector3d rotationAxes; | |
| auto rotation = placement.getRotation(); | |
| rotation.getRawValue(rotationAxes, rotationAngle); | |
| ui->XDirectionEdit->setValue(rotationAxes.x); | |
| ui->YDirectionEdit->setValue(rotationAxes.y); | |
| ui->ZDirectionEdit->setValue(rotationAxes.z); | |
| // the angle is rad, transform it for display to degrees | |
| ui->AngleQSB->setValue(Base::toDegrees<double>(rotationAngle)); | |
| } | |
| void Location::bindExpressions(Part::Feature* feature) | |
| { | |
| ui->XPositionQSB->bind(App::ObjectIdentifier::parse(feature, std::string("Placement.Base.x"))); | |
| ui->YPositionQSB->bind(App::ObjectIdentifier::parse(feature, std::string("Placement.Base.y"))); | |
| ui->ZPositionQSB->bind(App::ObjectIdentifier::parse(feature, std::string("Placement.Base.z"))); | |
| ui->XDirectionEdit->bind( | |
| App::ObjectIdentifier::parse(feature, std::string("Placement.Rotation.Axis.x")) | |
| ); | |
| ui->YDirectionEdit->bind( | |
| App::ObjectIdentifier::parse(feature, std::string("Placement.Rotation.Axis.y")) | |
| ); | |
| ui->ZDirectionEdit->bind( | |
| App::ObjectIdentifier::parse(feature, std::string("Placement.Rotation.Axis.z")) | |
| ); | |
| ui->AngleQSB->bind(App::ObjectIdentifier::parse(feature, std::string("Placement.Rotation.Angle"))); | |
| } | |
| void Location::connectSignals() | |
| { | |
| connect( | |
| ui->XPositionQSB, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| this, | |
| &Location::onPlacementChanged | |
| ); | |
| connect( | |
| ui->YPositionQSB, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| this, | |
| &Location::onPlacementChanged | |
| ); | |
| connect( | |
| ui->ZPositionQSB, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| this, | |
| &Location::onPlacementChanged | |
| ); | |
| connect( | |
| ui->AngleQSB, | |
| qOverload<double>(&Gui::QuantitySpinBox::valueChanged), | |
| this, | |
| &Location::onPlacementChanged | |
| ); | |
| connect( | |
| ui->XDirectionEdit, | |
| qOverload<double>(&Gui::DoubleSpinBox::valueChanged), | |
| this, | |
| &Location::onPlacementChanged | |
| ); | |
| connect( | |
| ui->YDirectionEdit, | |
| qOverload<double>(&Gui::DoubleSpinBox::valueChanged), | |
| this, | |
| &Location::onPlacementChanged | |
| ); | |
| connect( | |
| ui->ZDirectionEdit, | |
| qOverload<double>(&Gui::DoubleSpinBox::valueChanged), | |
| this, | |
| &Location::onPlacementChanged | |
| ); | |
| } | |
| void Location::onPlacementChanged() | |
| { | |
| App::GeoFeature* geom = featurePtr.get<App::GeoFeature>(); | |
| if (!geom) { | |
| return; | |
| } | |
| // read dialog values | |
| Base::Vector3d loc; | |
| loc.x = ui->XPositionQSB->rawValue(); | |
| loc.y = ui->YPositionQSB->rawValue(); | |
| loc.z = ui->ZPositionQSB->rawValue(); | |
| double angle = ui->AngleQSB->rawValue(); | |
| // the angle is displayed in degrees, transform it to rad | |
| angle = Base::toRadians<double>(angle); | |
| Base::Vector3d rot; | |
| rot.x = ui->XDirectionEdit->value(); | |
| rot.y = ui->YDirectionEdit->value(); | |
| rot.z = ui->ZDirectionEdit->value(); | |
| // set placement and rotation | |
| Base::Placement placement; | |
| Base::Rotation rotation(rot, angle); | |
| placement.setPosition(loc); | |
| placement.setRotation(rotation); | |
| // apply new placement to the feature | |
| geom->Placement.setValue(placement); | |
| geom->recomputeFeature(); | |
| } | |
| void Location::onViewPositionButton() | |
| { | |
| Gui::Document* doc = Gui::Application::Instance->activeDocument(); | |
| if (!doc) { | |
| return; | |
| } | |
| Gui::View3DInventor* view = static_cast<Gui::View3DInventor*>(doc->getActiveView()); | |
| if (view && !this->activeView) { | |
| Gui::View3DInventorViewer* viewer = view->getViewer(); | |
| if (!viewer->isEditing()) { | |
| this->activeView = view; | |
| viewer->setEditing(true); | |
| viewer->setRedirectToSceneGraph(true); | |
| viewer->addEventCallback(SoMouseButtonEvent::getClassTypeId(), pickCallback, this); | |
| SoNode* root = viewer->getSceneGraph(); | |
| if (root && root->getTypeId().isDerivedFrom(Gui::SoFCUnifiedSelection::getClassTypeId())) { | |
| this->mode = static_cast<Gui::SoFCUnifiedSelection*>(root)->selectionMode.getValue(); | |
| static_cast<Gui::SoFCUnifiedSelection*>(root)->selectionMode.setValue( | |
| Gui::SoFCUnifiedSelection::OFF | |
| ); | |
| } | |
| } | |
| } | |
| } | |
| void Location::pickCallback(void* ud, SoEventCallback* n) | |
| { | |
| const SoMouseButtonEvent* mbe = static_cast<const SoMouseButtonEvent*>(n->getEvent()); | |
| Gui::View3DInventorViewer* view = static_cast<Gui::View3DInventorViewer*>(n->getUserData()); | |
| // Mark all incoming mouse button events as handled, especially, to deactivate the selection node | |
| n->getAction()->setHandled(); | |
| if (mbe->getButton() == SoMouseButtonEvent::BUTTON1) { | |
| if (mbe->getState() == SoButtonEvent::DOWN) { | |
| const SoPickedPoint* point = n->getPickedPoint(); | |
| if (point) { | |
| SbVec3f pnt = point->getPoint(); | |
| SbVec3f nor = point->getNormal(); | |
| Location* dlg = static_cast<Location*>(ud); | |
| dlg->ui->XPositionQSB->setValue(pnt[0]); | |
| dlg->ui->YPositionQSB->setValue(pnt[1]); | |
| dlg->ui->ZPositionQSB->setValue(pnt[2]); | |
| dlg->ui->XDirectionEdit->setValue(nor[0]); | |
| dlg->ui->YDirectionEdit->setValue(nor[1]); | |
| dlg->ui->ZDirectionEdit->setValue(nor[2]); | |
| n->setHandled(); | |
| } | |
| } | |
| } | |
| else if (mbe->getButton() == SoMouseButtonEvent::BUTTON2) { | |
| if (mbe->getState() == SoButtonEvent::UP) { | |
| n->setHandled(); | |
| view->setEditing(false); | |
| view->setRedirectToSceneGraph(false); | |
| Location* dlg = static_cast<Location*>(ud); | |
| dlg->activeView = nullptr; | |
| view->removeEventCallback(SoMouseButtonEvent::getClassTypeId(), pickCallback, ud); | |
| SoNode* root = view->getSceneGraph(); | |
| if (root && root->getTypeId().isDerivedFrom(Gui::SoFCUnifiedSelection::getClassTypeId())) { | |
| static_cast<Gui::SoFCUnifiedSelection*>(root)->selectionMode.setValue( | |
| static_cast<Location*>(ud)->mode | |
| ); | |
| } | |
| } | |
| } | |
| } | |
| QString Location::toPlacement() const | |
| { | |
| // create a command to set the position and angle of the primitive object | |
| Base::Vector3d rot; | |
| rot.x = ui->XDirectionEdit->value(); | |
| rot.y = ui->YDirectionEdit->value(); | |
| rot.z = ui->ZDirectionEdit->value(); | |
| double angle = ui->AngleQSB->rawValue(); | |
| Base::Vector3d loc; | |
| loc.x = ui->XPositionQSB->rawValue(); | |
| loc.y = ui->YPositionQSB->rawValue(); | |
| loc.z = ui->ZPositionQSB->rawValue(); | |
| return QStringLiteral("App.Placement(App.Vector(%1,%2,%3),App.Rotation(App.Vector(%4,%5,%6),%7))") | |
| .arg(loc.x, 0, 'f', Base::UnitsApi::getDecimals()) | |
| .arg(loc.y, 0, 'f', Base::UnitsApi::getDecimals()) | |
| .arg(loc.z, 0, 'f', Base::UnitsApi::getDecimals()) | |
| .arg(rot.x, 0, 'f', Base::UnitsApi::getDecimals()) | |
| .arg(rot.y, 0, 'f', Base::UnitsApi::getDecimals()) | |
| .arg(rot.z, 0, 'f', Base::UnitsApi::getDecimals()) | |
| .arg(angle, 0, 'f', Base::UnitsApi::getDecimals()); | |
| } | |
| // ---------------------------------------------- | |
| /* TRANSLATOR PartGui::TaskPrimitives */ | |
| TaskPrimitives::TaskPrimitives() | |
| { | |
| widget = new DlgPrimitives(); | |
| addTaskBox(widget); | |
| location = new Location(); | |
| addTaskBox(location); | |
| } | |
| QDialogButtonBox::StandardButtons TaskPrimitives::getStandardButtons() const | |
| { | |
| return QDialogButtonBox::Close | QDialogButtonBox::Ok; | |
| } | |
| void TaskPrimitives::modifyStandardButtons(QDialogButtonBox* box) | |
| { | |
| QPushButton* btn = box->button(QDialogButtonBox::Ok); | |
| btn->setText(QApplication::translate("PartGui::DlgPrimitives", "&Create")); | |
| } | |
| bool TaskPrimitives::accept() | |
| { | |
| widget->createPrimitive(location->toPlacement()); | |
| return false; | |
| } | |
| bool TaskPrimitives::reject() | |
| { | |
| return true; | |
| } | |
| // ---------------------------------------------- | |
| /* TRANSLATOR PartGui::TaskPrimitivesEdit */ | |
| TaskPrimitivesEdit::TaskPrimitivesEdit(Part::Primitive* feature) | |
| { | |
| // create and show dialog for the primitives | |
| widget = new DlgPrimitives(nullptr, feature); | |
| addTaskBox(widget); | |
| // create and show dialog for the location | |
| location = new Location(nullptr, feature); | |
| addTaskBox(location); | |
| } | |
| QDialogButtonBox::StandardButtons TaskPrimitivesEdit::getStandardButtons() const | |
| { | |
| return QDialogButtonBox::Cancel | QDialogButtonBox::Ok; | |
| } | |
| bool TaskPrimitivesEdit::accept() | |
| { | |
| widget->accept(location->toPlacement()); | |
| std::string document = getDocumentName(); // needed because resetEdit() deletes this instance | |
| Gui::Command::doCommand(Gui::Command::Gui, "Gui.getDocument('%s').resetEdit()", document.c_str()); | |
| return true; | |
| } | |
| bool TaskPrimitivesEdit::reject() | |
| { | |
| widget->reject(); | |
| std::string document = getDocumentName(); // needed because resetEdit() deletes this instance | |
| Gui::Command::doCommand(Gui::Command::Gui, "Gui.getDocument('%s').resetEdit()", document.c_str()); | |
| return true; | |
| } | |