/*************************************************************************** * Copyright (c) 2015 Stefan Tröger * * * * 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_ #include #endif #include #include #include #include #include #include #include #include #include #include #include #include "TaskPrimitiveParameters.h" #include "ui_TaskPrimitiveParameters.h" using namespace PartDesignGui; // clang-format off TaskBoxPrimitives::TaskBoxPrimitives(ViewProviderPrimitive* vp, QWidget* parent) : TaskBox(QPixmap(),tr("Primitive parameters"), true, parent) , ui(new Ui_DlgPrimitives) , vp(vp) { proxy = new QWidget(this); ui->setupUi(proxy); this->groupLayout()->addWidget(proxy); int index = 0; switch(getObject()->getPrimitiveType()) { case PartDesign::FeaturePrimitive::Box: index = 1; ui->boxLength->setValue(getObject()->Length.getValue()); ui->boxLength->bind(getObject()->Length); ui->boxHeight->setValue(getObject()->Height.getValue()); ui->boxHeight->bind(getObject()->Height); ui->boxWidth->setValue(getObject()->Width.getValue()); ui->boxWidth->bind(getObject()->Width); ui->boxLength->setMinimum(getObject()->Length.getMinimum()); ui->boxLength->setMaximum(getObject()->Length.getMaximum()); ui->boxWidth->setMinimum(getObject()->Width.getMinimum()); ui->boxWidth->setMaximum(getObject()->Width.getMaximum()); ui->boxHeight->setMinimum(getObject()->Height.getMinimum()); ui->boxHeight->setMaximum(getObject()->Height.getMaximum()); break; case PartDesign::FeaturePrimitive::Cylinder: index = 2; ui->cylinderAngle->setValue(getObject()->Angle.getValue()); ui->cylinderAngle->bind(getObject()->Angle); ui->cylinderHeight->setValue(getObject()->Height.getValue()); ui->cylinderHeight->bind(getObject()->Height); ui->cylinderRadius->setValue(getObject()->Radius.getValue()); ui->cylinderRadius->bind(getObject()->Radius); ui->cylinderXSkew->setValue(getObject()->FirstAngle.getValue()); ui->cylinderXSkew->bind(getObject()->FirstAngle); ui->cylinderYSkew->setValue(getObject()->SecondAngle.getValue()); ui->cylinderYSkew->bind(getObject()->SecondAngle); ui->cylinderAngle->setMaximum(getObject()->Angle.getMaximum()); ui->cylinderAngle->setMinimum(getObject()->Angle.getMinimum()); ui->cylinderHeight->setMaximum(getObject()->Height.getMaximum()); ui->cylinderHeight->setMinimum(getObject()->Height.getMinimum()); ui->cylinderRadius->setMaximum(getObject()->Radius.getMaximum()); ui->cylinderRadius->setMinimum(getObject()->Radius.getMinimum()); break; case PartDesign::FeaturePrimitive::Sphere: index = 4; ui->sphereAngle1->setValue(getObject()->Angle1.getValue()); ui->sphereAngle1->bind(getObject()->Angle1); ui->sphereAngle2->setValue(getObject()->Angle2.getValue()); ui->sphereAngle2->bind(getObject()->Angle2); ui->sphereAngle3->setValue(getObject()->Angle3.getValue()); ui->sphereAngle3->bind(getObject()->Angle3); ui->sphereRadius->setValue(getObject()->Radius.getValue()); ui->sphereRadius->bind(getObject()->Radius); ui->sphereAngle1->setMaximum(ui->sphereAngle2->rawValue()); // must geometrically be <= than sphereAngle2 ui->sphereAngle1->setMinimum(getObject()->Angle1.getMinimum()); ui->sphereAngle2->setMaximum(getObject()->Angle2.getMaximum()); ui->sphereAngle2->setMinimum(ui->sphereAngle1->rawValue()); ui->sphereAngle3->setMaximum(getObject()->Angle3.getMaximum()); ui->sphereAngle3->setMinimum(getObject()->Angle3.getMinimum()); ui->sphereRadius->setMaximum(getObject()->Radius.getMaximum()); ui->sphereRadius->setMinimum(getObject()->Radius.getMinimum()); break; case PartDesign::FeaturePrimitive::Cone: index = 3; ui->coneAngle->setValue(getObject()->Angle.getValue()); ui->coneAngle->bind(getObject()->Angle); ui->coneHeight->setValue(getObject()->Height.getValue()); ui->coneHeight->bind(getObject()->Height); ui->coneRadius1->setValue(getObject()->Radius1.getValue()); ui->coneRadius1->bind(getObject()->Radius1); ui->coneRadius2->setValue(getObject()->Radius2.getValue()); ui->coneRadius2->bind(getObject()->Radius2); ui->coneAngle->setMaximum(getObject()->Angle.getMaximum()); ui->coneAngle->setMinimum(getObject()->Angle.getMinimum()); ui->coneHeight->setMaximum(getObject()->Height.getMaximum()); ui->coneHeight->setMinimum(getObject()->Height.getMinimum()); ui->coneRadius1->setMaximum(getObject()->Radius1.getMaximum()); ui->coneRadius1->setMinimum(getObject()->Radius1.getMinimum()); ui->coneRadius2->setMaximum(getObject()->Radius2.getMaximum()); ui->coneRadius2->setMinimum(getObject()->Radius2.getMinimum()); break; case PartDesign::FeaturePrimitive::Ellipsoid: index = 5; ui->ellipsoidAngle1->setValue(getObject()->Angle1.getValue()); ui->ellipsoidAngle1->bind(getObject()->Angle1); ui->ellipsoidAngle2->setValue(getObject()->Angle2.getValue()); ui->ellipsoidAngle2->bind(getObject()->Angle2); ui->ellipsoidAngle3->setValue(getObject()->Angle3.getValue()); ui->ellipsoidAngle3->bind(getObject()->Angle3); ui->ellipsoidRadius1->setValue(getObject()->Radius1.getValue()); ui->ellipsoidRadius1->bind(getObject()->Radius1); ui->ellipsoidRadius2->setValue(getObject()->Radius2.getValue()); ui->ellipsoidRadius2->bind(getObject()->Radius2); ui->ellipsoidRadius3->setValue(getObject()->Radius3.getValue()); ui->ellipsoidRadius3->bind(getObject()->Radius3); ui->ellipsoidAngle1->setMaximum(ui->ellipsoidAngle2->rawValue()); // must geometrically be <= than sphereAngle2 ui->ellipsoidAngle1->setMinimum(getObject()->Angle1.getMinimum()); ui->ellipsoidAngle2->setMaximum(getObject()->Angle2.getMaximum()); ui->ellipsoidAngle2->setMinimum(ui->ellipsoidAngle1->rawValue()); ui->ellipsoidAngle3->setMaximum(getObject()->Angle3.getMaximum()); ui->ellipsoidAngle3->setMinimum(getObject()->Angle3.getMinimum()); ui->ellipsoidRadius1->setMinimum(getObject()->Radius1.getMinimum()); ui->ellipsoidRadius1->setMaximum(getObject()->Radius1.getMaximum()); ui->ellipsoidRadius2->setMinimum(getObject()->Radius2.getMinimum()); ui->ellipsoidRadius2->setMaximum(getObject()->Radius2.getMaximum()); ui->ellipsoidRadius3->setMinimum(getObject()->Radius3.getMinimum()); ui->ellipsoidRadius3->setMaximum(getObject()->Radius3.getMaximum()); break; case PartDesign::FeaturePrimitive::Torus: index = 6; ui->torusAngle1->setValue(getObject()->Angle1.getValue()); ui->torusAngle1->bind(getObject()->Angle1); ui->torusAngle2->setValue(getObject()->Angle2.getValue()); ui->torusAngle2->bind(getObject()->Angle2); ui->torusAngle3->setValue(getObject()->Angle3.getValue()); ui->torusAngle3->bind(getObject()->Angle3); ui->torusRadius1->setValue(getObject()->Radius1.getValue()); ui->torusRadius1->bind(getObject()->Radius1); ui->torusRadius2->setValue(getObject()->Radius2.getValue()); ui->torusRadius2->bind(getObject()->Radius2); ui->torusAngle1->setMaximum(ui->torusAngle2->rawValue()); // must geometrically be <= than sphereAngle2 ui->torusAngle1->setMinimum(getObject()->Angle1.getMinimum()); ui->torusAngle2->setMaximum(getObject()->Angle2.getMaximum()); ui->torusAngle2->setMinimum(ui->torusAngle1->rawValue()); ui->torusAngle3->setMaximum(getObject()->Angle3.getMaximum()); ui->torusAngle3->setMinimum(getObject()->Angle3.getMinimum()); // this is the outer radius that must not be smaller than the inner one // otherwise the geometry is impossible and we can even get a crash: // https://forum.freecad.org/viewtopic.php?f=3&t=44467 ui->torusRadius1->setMaximum(getObject()->Radius1.getMaximum()); ui->torusRadius1->setMinimum(ui->torusRadius2->rawValue()); ui->torusRadius2->setMaximum(ui->torusRadius1->rawValue()); ui->torusRadius2->setMinimum(getObject()->Radius2.getMinimum()); break; case PartDesign::FeaturePrimitive::Prism: index = 7; ui->prismPolygon->setValue(getObject()->Polygon.getValue()); ui->prismCircumradius->setValue(getObject()->Circumradius.getValue()); ui->prismCircumradius->bind(getObject()->Circumradius); ui->prismHeight->setValue(getObject()->Height.getValue()); ui->prismHeight->bind(getObject()->Height); ui->prismXSkew->setValue(getObject()->FirstAngle.getValue()); ui->prismXSkew->bind(getObject()->FirstAngle); ui->prismYSkew->setValue(getObject()->SecondAngle.getValue()); ui->prismYSkew->bind(getObject()->SecondAngle); ui->prismCircumradius->setMaximum(getObject()->Circumradius.getMaximum()); ui->prismCircumradius->setMinimum(getObject()->Circumradius.getMinimum()); ui->prismHeight->setMaximum(getObject()->Height.getMaximum()); ui->prismHeight->setMinimum(getObject()->Height.getMinimum()); break; case PartDesign::FeaturePrimitive::Wedge: index = 8; ui->wedgeXmax->setValue(getObject()->Xmax.getValue()); ui->wedgeXmax->bind(getObject()->Xmax); ui->wedgeXmin->setValue(getObject()->Xmin.getValue()); ui->wedgeXmin->bind(getObject()->Xmin); ui->wedgeX2max->setValue(getObject()->X2max.getValue()); ui->wedgeX2max->bind(getObject()->X2max); ui->wedgeX2min->setValue(getObject()->X2min.getValue()); ui->wedgeX2min->bind(getObject()->X2min); ui->wedgeYmax->setValue(getObject()->Ymax.getValue()); ui->wedgeYmax->bind(getObject()->Ymax); ui->wedgeYmin->setValue(getObject()->Ymin.getValue()); ui->wedgeYmin->bind(getObject()->Ymin); ui->wedgeZmax->setValue(getObject()->Zmax.getValue()); ui->wedgeZmax->bind(getObject()->Zmax); ui->wedgeZmin->setValue(getObject()->Zmin.getValue()); ui->wedgeZmin->bind(getObject()->Zmin); ui->wedgeZ2max->setValue(getObject()->Z2max.getValue()); ui->wedgeZ2max->bind(getObject()->Z2max); ui->wedgeZ2min->setValue(getObject()->Z2min.getValue()); ui->wedgeZ2min->bind(getObject()->Z2min); ui->wedgeXmin->setMinimum(INT_MIN); ui->wedgeXmin->setMaximum(ui->wedgeXmax->rawValue()); // must be < than wedgeXmax ui->wedgeYmin->setMinimum(INT_MIN); ui->wedgeYmin->setMaximum(ui->wedgeYmax->rawValue()); // must be < than wedgeYmax ui->wedgeZmin->setMinimum(INT_MIN); ui->wedgeZmin->setMaximum(ui->wedgeZmax->rawValue()); // must be < than wedgeZmax ui->wedgeX2min->setMinimum(INT_MIN); ui->wedgeX2min->setMaximum(ui->wedgeX2max->rawValue()); // must be <= than wedgeXmax ui->wedgeZ2min->setMinimum(INT_MIN); ui->wedgeZ2min->setMaximum(ui->wedgeZ2max->rawValue()); // must be <= than wedgeXmax ui->wedgeXmax->setMinimum(ui->wedgeXmin->rawValue()); ui->wedgeXmax->setMaximum(INT_MAX); ui->wedgeYmax->setMinimum(ui->wedgeYmin->rawValue()); ui->wedgeYmax->setMaximum(INT_MAX); ui->wedgeZmax->setMinimum(ui->wedgeZmin->rawValue()); ui->wedgeZmax->setMaximum(INT_MAX); ui->wedgeX2max->setMinimum(ui->wedgeX2min->rawValue()); ui->wedgeX2max->setMaximum(INT_MAX); ui->wedgeZ2max->setMinimum(ui->wedgeZ2min->rawValue()); ui->wedgeZ2max->setMaximum(INT_MAX); break; } ui->widgetStack->setCurrentIndex(index); ui->widgetStack->setMinimumSize(ui->widgetStack->widget(index)->minimumSize()); for(int i=0; iwidgetStack->count(); ++i) { if(i != index) ui->widgetStack->widget(i)->setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored)); } Gui::Document* doc = vp->getDocument(); this->attachDocument(doc); //show the parts coordinate system axis for selection if(PartDesign::Body * body = PartDesign::Body::findBodyOf(getObject())) { try { App::Origin *origin = body->getOrigin(); Gui::ViewProviderOrigin* vpOrigin {}; vpOrigin = static_cast(Gui::Application::Instance->getViewProvider(origin)); vpOrigin->setTemporaryVisibility(true, true); } catch (const Base::Exception &ex) { Base::Console().Error ("%s\n", ex.what () ); } } // box connect(ui->boxLength, qOverload(&Gui::QuantitySpinBox::valueChanged), this, &TaskBoxPrimitives::onBoxLengthChanged); connect(ui->boxWidth, qOverload(&Gui::QuantitySpinBox::valueChanged), this, &TaskBoxPrimitives::onBoxWidthChanged); connect(ui->boxHeight, qOverload(&Gui::QuantitySpinBox::valueChanged), this, &TaskBoxPrimitives::onBoxHeightChanged); // cylinder connect(ui->cylinderRadius, qOverload(&Gui::QuantitySpinBox::valueChanged), this, &TaskBoxPrimitives::onCylinderRadiusChanged); connect(ui->cylinderHeight, qOverload(&Gui::QuantitySpinBox::valueChanged), this, &TaskBoxPrimitives::onCylinderHeightChanged); connect(ui->cylinderXSkew, qOverload(&Gui::QuantitySpinBox::valueChanged), this, &TaskBoxPrimitives::onCylinderXSkewChanged); connect(ui->cylinderYSkew, qOverload(&Gui::QuantitySpinBox::valueChanged), this, &TaskBoxPrimitives::onCylinderYSkewChanged); connect(ui->cylinderAngle, qOverload(&Gui::QuantitySpinBox::valueChanged), this, &TaskBoxPrimitives::onCylinderAngleChanged); // cone connect(ui->coneRadius1, qOverload(&Gui::QuantitySpinBox::valueChanged), this, &TaskBoxPrimitives::onConeRadius1Changed); connect(ui->coneRadius2, qOverload(&Gui::QuantitySpinBox::valueChanged), this, &TaskBoxPrimitives::onConeRadius2Changed); connect(ui->coneAngle, qOverload(&Gui::QuantitySpinBox::valueChanged), this, &TaskBoxPrimitives::onConeAngleChanged); connect(ui->coneHeight, qOverload(&Gui::QuantitySpinBox::valueChanged), this, &TaskBoxPrimitives::onConeHeightChanged); // sphere connect(ui->sphereRadius, qOverload(&Gui::QuantitySpinBox::valueChanged), this, &TaskBoxPrimitives::onSphereRadiusChanged); connect(ui->sphereAngle1, qOverload(&Gui::QuantitySpinBox::valueChanged), this, &TaskBoxPrimitives::onSphereAngle1Changed); connect(ui->sphereAngle2, qOverload(&Gui::QuantitySpinBox::valueChanged), this, &TaskBoxPrimitives::onSphereAngle2Changed); connect(ui->sphereAngle3, qOverload(&Gui::QuantitySpinBox::valueChanged), this, &TaskBoxPrimitives::onSphereAngle3Changed); // ellipsoid connect(ui->ellipsoidRadius1, qOverload(&Gui::QuantitySpinBox::valueChanged), this, &TaskBoxPrimitives::onEllipsoidRadius1Changed); connect(ui->ellipsoidRadius2, qOverload(&Gui::QuantitySpinBox::valueChanged), this, &TaskBoxPrimitives::onEllipsoidRadius2Changed); connect(ui->ellipsoidRadius3, qOverload(&Gui::QuantitySpinBox::valueChanged), this, &TaskBoxPrimitives::onEllipsoidRadius3Changed); connect(ui->ellipsoidAngle1, qOverload(&Gui::QuantitySpinBox::valueChanged), this, &TaskBoxPrimitives::onEllipsoidAngle1Changed); connect(ui->ellipsoidAngle2, qOverload(&Gui::QuantitySpinBox::valueChanged), this, &TaskBoxPrimitives::onEllipsoidAngle2Changed); connect(ui->ellipsoidAngle3, qOverload(&Gui::QuantitySpinBox::valueChanged), this, &TaskBoxPrimitives::onEllipsoidAngle3Changed); // torus connect(ui->torusRadius1, qOverload(&Gui::QuantitySpinBox::valueChanged), this, &TaskBoxPrimitives::onTorusRadius1Changed); connect(ui->torusRadius2, qOverload(&Gui::QuantitySpinBox::valueChanged), this, &TaskBoxPrimitives::onTorusRadius2Changed); connect(ui->torusAngle1, qOverload(&Gui::QuantitySpinBox::valueChanged), this, &TaskBoxPrimitives::onTorusAngle1Changed); connect(ui->torusAngle2, qOverload(&Gui::QuantitySpinBox::valueChanged), this, &TaskBoxPrimitives::onTorusAngle2Changed); connect(ui->torusAngle3, qOverload(&Gui::QuantitySpinBox::valueChanged), this, &TaskBoxPrimitives::onTorusAngle3Changed); //prism connect(ui->prismCircumradius, qOverload(&Gui::QuantitySpinBox::valueChanged), this, &TaskBoxPrimitives::onPrismCircumradiusChanged); connect(ui->prismHeight, qOverload(&Gui::QuantitySpinBox::valueChanged), this, &TaskBoxPrimitives::onPrismHeightChanged); connect(ui->prismXSkew, qOverload(&Gui::QuantitySpinBox::valueChanged), this, &TaskBoxPrimitives::onPrismXSkewChanged); connect(ui->prismYSkew, qOverload(&Gui::QuantitySpinBox::valueChanged), this, &TaskBoxPrimitives::onPrismYSkewChanged); connect(ui->prismPolygon, qOverload(&QSpinBox::valueChanged), this, &TaskBoxPrimitives::onPrismPolygonChanged); // wedge connect(ui->wedgeXmax, qOverload(&Gui::QuantitySpinBox::valueChanged), this, &TaskBoxPrimitives::onWedgeXmaxChanged); connect(ui->wedgeXmin, qOverload(&Gui::QuantitySpinBox::valueChanged), this, &TaskBoxPrimitives::onWedgeXminChanged); connect(ui->wedgeYmax, qOverload(&Gui::QuantitySpinBox::valueChanged), this, &TaskBoxPrimitives::onWedgeYmaxChanged); connect(ui->wedgeYmin, qOverload(&Gui::QuantitySpinBox::valueChanged), this, &TaskBoxPrimitives::onWedgeYminChanged); connect(ui->wedgeZmax, qOverload(&Gui::QuantitySpinBox::valueChanged), this, &TaskBoxPrimitives::onWedgeZmaxChanged); connect(ui->wedgeZmin, qOverload(&Gui::QuantitySpinBox::valueChanged), this, &TaskBoxPrimitives::onWedgeZminChanged); connect(ui->wedgeX2max, qOverload(&Gui::QuantitySpinBox::valueChanged), this, &TaskBoxPrimitives::onWedgeX2maxChanged); connect(ui->wedgeX2min, qOverload(&Gui::QuantitySpinBox::valueChanged), this, &TaskBoxPrimitives::onWedgeX2minChanged); connect(ui->wedgeZ2max, qOverload(&Gui::QuantitySpinBox::valueChanged), this, &TaskBoxPrimitives::onWedgeZ2maxChanged); connect(ui->wedgeZ2min, qOverload(&Gui::QuantitySpinBox::valueChanged), this, &TaskBoxPrimitives::onWedgeZ2minChanged); } // clang-format on /* * Destroys the object and frees any allocated resources */ TaskBoxPrimitives::~TaskBoxPrimitives() { // hide the parts coordinate system axis for selection try { auto obj = getObject(); if (PartDesign::Body* body = obj ? PartDesign::Body::findBodyOf(obj) : nullptr) { App::Origin* origin = body->getOrigin(); Gui::ViewProviderOrigin* vpOrigin; vpOrigin = static_cast( Gui::Application::Instance->getViewProvider(origin)); vpOrigin->resetTemporaryVisibility(); } } catch (const Base::Exception& ex) { Base::Console().Error("%s\n", ex.what()); } } void TaskBoxPrimitives::slotDeletedObject(const Gui::ViewProviderDocumentObject& Obj) { if (this->vp == &Obj) { this->vp = nullptr; } } void TaskBoxPrimitives::onBoxHeightChanged(double v) { if (auto box = getObject()) { box->Height.setValue(v); box->recomputeFeature(); } } void TaskBoxPrimitives::onBoxWidthChanged(double v) { if (auto box = getObject()) { box->Width.setValue(v); box->recomputeFeature(); } } void TaskBoxPrimitives::onBoxLengthChanged(double v) { if (auto box = getObject()) { box->Length.setValue(v); box->recomputeFeature(); } } void TaskBoxPrimitives::onCylinderAngleChanged(double v) { if (auto cyl = getObject()) { cyl->Angle.setValue(v); cyl->recomputeFeature(); } } void TaskBoxPrimitives::onCylinderHeightChanged(double v) { if (auto cyl = getObject()) { cyl->Height.setValue(v); cyl->recomputeFeature(); } } void TaskBoxPrimitives::onCylinderRadiusChanged(double v) { if (auto cyl = getObject()) { cyl->Radius.setValue(v); cyl->recomputeFeature(); } } void TaskBoxPrimitives::onCylinderXSkewChanged(double v) { if (auto cyl = getObject()) { // we must assure that if the user incremented from e.g. 85 degree with the // spin buttons, they do not end at 90.0 but at 89.9999 which is shown rounded to 90 degree if ((v < 90.0) && (v > -90.0)) { cyl->FirstAngle.setValue(v); } else { if (v == 90.0) { cyl->FirstAngle.setValue(cyl->FirstAngle.getMaximum()); } else if (v == -90.0) { cyl->FirstAngle.setValue(cyl->FirstAngle.getMinimum()); } ui->cylinderXSkew->setValue(cyl->FirstAngle.getQuantityValue()); } cyl->recomputeFeature(); } } void TaskBoxPrimitives::onCylinderYSkewChanged(double v) { if (auto cyl = getObject()) { // we must assure that if the user incremented from e.g. 85 degree with the // spin buttons, they do not end at 90.0 but at 89.9999 which is shown rounded to 90 degree if ((v < 90.0) && (v > -90.0)) { cyl->SecondAngle.setValue(v); } else { if (v == 90.0) { cyl->SecondAngle.setValue(cyl->SecondAngle.getMaximum()); } else if (v == -90.0) { cyl->SecondAngle.setValue(cyl->SecondAngle.getMinimum()); } ui->cylinderYSkew->setValue(cyl->SecondAngle.getQuantityValue()); } cyl->recomputeFeature(); } } void TaskBoxPrimitives::onSphereAngle1Changed(double v) { if (auto sph = getObject()) { ui->sphereAngle2->setMinimum(v); // Angle1 must geometrically be <= than Angle2 sph->Angle1.setValue(v); sph->recomputeFeature(); } } void TaskBoxPrimitives::onSphereAngle2Changed(double v) { if (auto sph = getObject()) { ui->sphereAngle1->setMaximum(v); // Angle1 must geometrically be <= than Angle2 sph->Angle2.setValue(v); sph->recomputeFeature(); } } void TaskBoxPrimitives::onSphereAngle3Changed(double v) { if (auto sph = getObject()) { sph->Angle3.setValue(v); sph->recomputeFeature(); } } void TaskBoxPrimitives::onSphereRadiusChanged(double v) { if (auto sph = getObject()) { sph->Radius.setValue(v); sph->recomputeFeature(); } } void TaskBoxPrimitives::onConeAngleChanged(double v) { if (auto cone = getObject()) { cone->Angle.setValue(v); cone->recomputeFeature(); } } void TaskBoxPrimitives::onConeHeightChanged(double v) { if (auto cone = getObject()) { cone->Height.setValue(v); cone->recomputeFeature(); } } void TaskBoxPrimitives::onConeRadius1Changed(double v) { if (auto cone = getObject()) { cone->Radius1.setValue(v); cone->recomputeFeature(); } } void TaskBoxPrimitives::onConeRadius2Changed(double v) { if (auto cone = getObject()) { cone->Radius2.setValue(v); cone->recomputeFeature(); } } void TaskBoxPrimitives::onEllipsoidAngle1Changed(double v) { if (auto ell = getObject()) { ui->ellipsoidAngle2->setMinimum(v); // Angle1 must geometrically be <= than Angle2 ell->Angle1.setValue(v); ell->recomputeFeature(); } } void TaskBoxPrimitives::onEllipsoidAngle2Changed(double v) { if (auto ell = getObject()) { ui->ellipsoidAngle1->setMaximum(v); // Angle1 must geometrically be <= than Angle22 ell->Angle2.setValue(v); ell->recomputeFeature(); } } void TaskBoxPrimitives::onEllipsoidAngle3Changed(double v) { if (auto ell = getObject()) { ell->Angle3.setValue(v); ell->recomputeFeature(); } } void TaskBoxPrimitives::onEllipsoidRadius1Changed(double v) { if (auto ell = getObject()) { ell->Radius1.setValue(v); ell->recomputeFeature(); } } void TaskBoxPrimitives::onEllipsoidRadius2Changed(double v) { if (auto ell = getObject()) { ell->Radius2.setValue(v); ell->recomputeFeature(); } } void TaskBoxPrimitives::onEllipsoidRadius3Changed(double v) { if (auto ell = getObject()) { ell->Radius3.setValue(v); ell->recomputeFeature(); } } void TaskBoxPrimitives::onTorusAngle1Changed(double v) { if (auto tor = getObject()) { ui->torusAngle2->setMinimum(v); // Angle1 must geometrically be <= than Angle2 tor->Angle1.setValue(v); tor->recomputeFeature(); } } void TaskBoxPrimitives::onTorusAngle2Changed(double v) { if (auto tor = getObject()) { ui->torusAngle1->setMaximum(v); // Angle1 must geometrically be <= than Angle2 tor->Angle2.setValue(v); tor->recomputeFeature(); } } void TaskBoxPrimitives::onTorusAngle3Changed(double v) { if (auto tor = getObject()) { tor->Angle3.setValue(v); tor->recomputeFeature(); } } void TaskBoxPrimitives::onTorusRadius1Changed(double v) { if (auto tor = getObject()) { // this is the outer radius that must not be smaller than the inner one // otherwise the geometry is impossible and we can even get a crash: // https://forum.freecad.org/viewtopic.php?f=3&t=44467 ui->torusRadius2->setMaximum(v); tor->Radius1.setValue(v); tor->recomputeFeature(); } } void TaskBoxPrimitives::onTorusRadius2Changed(double v) { if (auto tor = getObject()) { ui->torusRadius1->setMinimum(v); tor->Radius2.setValue(v); tor->recomputeFeature(); } } void TaskBoxPrimitives::onPrismCircumradiusChanged(double v) { if (auto prim = getObject()) { prim->Circumradius.setValue(v); prim->recomputeFeature(); } } void TaskBoxPrimitives::onPrismHeightChanged(double v) { if (auto prim = getObject()) { prim->Height.setValue(v); prim->recomputeFeature(); } } void TaskBoxPrimitives::onPrismXSkewChanged(double v) { if (auto prim = getObject()) { // we must assure that if the user incremented from e.g. 85 degree with the // spin buttons, they do not end at 90.0 but at 89.9999 which is shown rounded to 90 degree if ((v < 90.0) && (v > -90.0)) { prim->FirstAngle.setValue(v); } else { if (v == 90.0) { prim->FirstAngle.setValue(89.99999); } else if (v == -90.0) { prim->FirstAngle.setValue(-89.99999); } ui->prismXSkew->setValue(prim->FirstAngle.getQuantityValue()); } prim->recomputeFeature(); } } void TaskBoxPrimitives::onPrismYSkewChanged(double v) { if (auto prim = getObject()) { // we must assure that if the user incremented from e.g. 85 degree with the // spin buttons, they do not end at 90.0 but at 89.9999 which is shown rounded to 90 degree if ((v < 90.0) && (v > -90.0)) { prim->SecondAngle.setValue(v); } else { if (v == 90.0) { prim->SecondAngle.setValue(89.99999); } else if (v == -90.0) { prim->SecondAngle.setValue(-89.99999); } ui->prismYSkew->setValue(prim->SecondAngle.getQuantityValue()); } prim->recomputeFeature(); } } void TaskBoxPrimitives::onPrismPolygonChanged(int v) { if (auto prim = getObject()) { prim->Polygon.setValue(v); prim->recomputeFeature(); } } void TaskBoxPrimitives::onWedgeX2minChanged(double v) { if (auto wedge = getObject()) { ui->wedgeX2max->setMinimum(v); // wedgeX2min must be <= than wedgeX2max wedge->X2min.setValue(v); wedge->recomputeFeature(); } } void TaskBoxPrimitives::onWedgeX2maxChanged(double v) { if (auto wedge = getObject()) { ui->wedgeX2min->setMaximum(v); // wedgeX2min must be <= than wedgeX2max wedge->X2max.setValue(v); wedge->recomputeFeature(); } } void TaskBoxPrimitives::onWedgeXminChanged(double v) { if (auto wedge = getObject()) { ui->wedgeXmax->setMinimum(v); wedge->Xmin.setValue(v); wedge->recomputeFeature(); } } void TaskBoxPrimitives::onWedgeXmaxChanged(double v) { if (auto wedge = getObject()) { ui->wedgeXmin->setMaximum(v); // must be < than wedgeXmax wedge->Xmax.setValue(v); wedge->recomputeFeature(); } } void TaskBoxPrimitives::onWedgeYminChanged(double v) { if (auto wedge = getObject()) { ui->wedgeYmax->setMinimum(v); // must be > than wedgeYmin wedge->Ymin.setValue(v); wedge->recomputeFeature(); } } void TaskBoxPrimitives::onWedgeYmaxChanged(double v) { if (auto wedge = getObject()) { ui->wedgeYmin->setMaximum(v); // must be < than wedgeYmax wedge->Ymax.setValue(v); wedge->recomputeFeature(); } } void TaskBoxPrimitives::onWedgeZ2minChanged(double v) { if (auto wedge = getObject()) { ui->wedgeZ2max->setMinimum(v); // must be >= than wedgeZ2min wedge->Z2min.setValue(v); wedge->recomputeFeature(); } } void TaskBoxPrimitives::onWedgeZ2maxChanged(double v) { if (auto wedge = getObject()) { ui->wedgeZ2min->setMaximum(v); // must be <= than wedgeZ2max wedge->Z2max.setValue(v); wedge->recomputeFeature(); } } void TaskBoxPrimitives::onWedgeZminChanged(double v) { if (auto wedge = getObject()) { ui->wedgeZmax->setMinimum(v); // must be > than wedgeZmin wedge->Zmin.setValue(v); wedge->recomputeFeature(); } } void TaskBoxPrimitives::onWedgeZmaxChanged(double v) { if (auto wedge = getObject()) { ui->wedgeZmin->setMaximum(v); // must be < than wedgeZmax wedge->Zmax.setValue(v); wedge->recomputeFeature(); } } bool TaskBoxPrimitives::setPrimitive(App::DocumentObject* obj) { try { QString name(QString::fromLatin1(Gui::Command::getObjectCmd(obj).c_str())); QString cmd; App::Document* doc = App::GetApplication().getActiveDocument(); if (!doc) { return false; } Base::QuantityFormat format(Base::QuantityFormat::Fixed, Base::UnitsApi::getDecimals()); switch (ui->widgetStack->currentIndex()) { case 1: // box cmd = QString::fromLatin1("%1.Length='%2'\n" "%1.Width='%3'\n" "%1.Height='%4'\n") .arg(name, ui->boxLength->value().getSafeUserString(), ui->boxWidth->value().getSafeUserString(), ui->boxHeight->value().getSafeUserString()); break; case 2: // cylinder cmd = QString::fromLatin1("%1.Radius='%2'\n" "%1.Height='%3'\n" "%1.Angle='%4'\n" "%1.FirstAngle='%5'\n" "%1.SecondAngle='%6'\n") .arg(name, ui->cylinderRadius->value().getSafeUserString(), ui->cylinderHeight->value().getSafeUserString(), ui->cylinderAngle->value().getSafeUserString(), ui->cylinderXSkew->value().getSafeUserString(), ui->cylinderYSkew->value().getSafeUserString()); break; case 3: // cone cmd = QString::fromLatin1("%1.Radius1='%2'\n" "%1.Radius2='%3'\n" "%1.Height='%4'\n" "%1.Angle='%5'\n") .arg(name, ui->coneRadius1->value().getSafeUserString(), ui->coneRadius2->value().getSafeUserString(), ui->coneHeight->value().getSafeUserString(), ui->coneAngle->value().getSafeUserString()); break; case 4: // sphere cmd = QString::fromLatin1("%1.Radius='%2'\n" "%1.Angle1='%3'\n" "%1.Angle2='%4'\n" "%1.Angle3='%5'\n") .arg(name, ui->sphereRadius->value().getSafeUserString(), ui->sphereAngle1->value().getSafeUserString(), ui->sphereAngle2->value().getSafeUserString(), ui->sphereAngle3->value().getSafeUserString()); break; case 5: // ellipsoid cmd = QString::fromLatin1("%1.Radius1='%2'\n" "%1.Radius2='%3'\n" "%1.Radius3='%4'\n" "%1.Angle1='%5'\n" "%1.Angle2='%6'\n" "%1.Angle3='%7'\n") .arg(name, ui->ellipsoidRadius1->value().getSafeUserString(), ui->ellipsoidRadius2->value().getSafeUserString(), ui->ellipsoidRadius3->value().getSafeUserString(), ui->ellipsoidAngle1->value().getSafeUserString(), ui->ellipsoidAngle2->value().getSafeUserString(), ui->ellipsoidAngle3->value().getSafeUserString()); break; case 6: // torus cmd = QString::fromLatin1("%1.Radius1='%2'\n" "%1.Radius2='%3'\n" "%1.Angle1='%4'\n" "%1.Angle2='%5'\n" "%1.Angle3='%6'\n") .arg(name, ui->torusRadius1->value().getSafeUserString(), ui->torusRadius2->value().getSafeUserString(), ui->torusAngle1->value().getSafeUserString(), ui->torusAngle2->value().getSafeUserString(), ui->torusAngle3->value().getSafeUserString()); break; case 7: // prism cmd = QString::fromLatin1("%1.Polygon=%2\n" "%1.Circumradius='%3'\n" "%1.Height='%4'\n" "%1.FirstAngle='%5'\n" "%1.SecondAngle='%6'\n") .arg(name, QString::number(ui->prismPolygon->value()), ui->prismCircumradius->value().getSafeUserString(), ui->prismHeight->value().getSafeUserString(), ui->prismXSkew->value().getSafeUserString(), ui->prismYSkew->value().getSafeUserString()); break; case 8: // wedge // Xmin/max, Ymin/max and Zmin/max must each not be equal if (ui->wedgeXmin->value().getValue() == ui->wedgeXmax->value().getValue()) { QMessageBox::warning(Gui::getMainWindow(), tr("Invalid wedge parameters"), tr("X min must not be equal to X max!")); return false; } else if (ui->wedgeYmin->value().getValue() == ui->wedgeYmax->value().getValue()) { QMessageBox::warning(Gui::getMainWindow(), tr("Invalid wedge parameters"), tr("Y min must not be equal to Y max!")); return false; } else if (ui->wedgeZmin->value().getValue() == ui->wedgeZmax->value().getValue()) { QMessageBox::warning(Gui::getMainWindow(), tr("Invalid wedge parameters"), tr("Z min must not be equal to Z max!")); return false; } cmd = QString::fromLatin1("%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") .arg(name, ui->wedgeXmin->value().getSafeUserString(), ui->wedgeYmin->value().getSafeUserString(), ui->wedgeZmin->value().getSafeUserString(), ui->wedgeX2min->value().getSafeUserString(), ui->wedgeZ2min->value().getSafeUserString(), ui->wedgeXmax->value().getSafeUserString(), ui->wedgeYmax->value().getSafeUserString(), ui->wedgeZmax->value().getSafeUserString()) .arg(ui->wedgeX2max->value().getSafeUserString(), ui->wedgeZ2max->value().getSafeUserString()); break; default: break; } // Execute the Python block // No need to open a transaction because this is already done in the command // class or when starting to edit a primitive. Gui::Command::runCommand(Gui::Command::Doc, cmd.toUtf8()); Gui::Command::runCommand(Gui::Command::Doc, "App.ActiveDocument.recompute()"); } catch (const Base::PyException& e) { QMessageBox::warning(this, tr("Create primitive"), QApplication::translate("Exception", e.what())); return false; } return true; } TaskPrimitiveParameters::TaskPrimitiveParameters(ViewProviderPrimitive* PrimitiveView) : vp_prm(PrimitiveView) { assert(PrimitiveView); primitive = new TaskBoxPrimitives(PrimitiveView); Content.push_back(primitive); parameter = new PartGui::TaskAttacher(PrimitiveView, nullptr, QString(), tr("Attachment")); Content.push_back(parameter); } TaskPrimitiveParameters::~TaskPrimitiveParameters() = default; bool TaskPrimitiveParameters::accept() { bool primitiveOK = primitive->setPrimitive(vp_prm->getObject()); if (!primitiveOK) { return primitiveOK; } Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.recompute()"); Gui::Command::doCommand(Gui::Command::Gui, "Gui.activeDocument().resetEdit()"); return true; } bool TaskPrimitiveParameters::reject() { // roll back the done things Gui::Command::abortCommand(); Gui::Command::doCommand(Gui::Command::Gui, "Gui.activeDocument().resetEdit()"); return true; } QDialogButtonBox::StandardButtons TaskPrimitiveParameters::getStandardButtons() const { return Gui::TaskView::TaskDialog::getStandardButtons(); } #include "moc_TaskPrimitiveParameters.cpp"