diff --git a/src/Mod/PartDesign/App/FeatureHelix.cpp b/src/Mod/PartDesign/App/FeatureHelix.cpp index b542267b56..9cb6e00dd1 100644 --- a/src/Mod/PartDesign/App/FeatureHelix.cpp +++ b/src/Mod/PartDesign/App/FeatureHelix.cpp @@ -67,7 +67,7 @@ const double PI = 3.14159265359; using namespace PartDesign; -const char* Helix::ModeEnums[] = {"pitch-height", "pitch-turns", "height-turns", NULL}; +const char* Helix::ModeEnums[] = {"pitch-height-angle", "pitch-turns-angle", "height-turns-angle", "height-turns-growth", NULL}; PROPERTY_SOURCE(PartDesign::Helix, PartDesign::ProfileBased) @@ -88,6 +88,7 @@ Helix::Helix() ADD_PROPERTY_TYPE(LeftHanded, (long(0)), "Helix", App::Prop_None, "LeftHanded"); ADD_PROPERTY_TYPE(Reversed, (long(0)), "Helix", App::Prop_None, "Reversed"); ADD_PROPERTY_TYPE(Angle, (0.0), "Helix", App::Prop_None, "Angle"); + ADD_PROPERTY_TYPE(Growth, (0.0), "Helix", App::Prop_None, "Growth"); Angle.setConstraints(&floatAngle); ADD_PROPERTY_TYPE(ReferenceAxis, (0), "Helix", App::Prop_None, "Reference axis of revolution"); ADD_PROPERTY_TYPE(Mode, (long(0)), "Helix", App::Prop_None, "Helix input mode"); @@ -110,31 +111,33 @@ short Helix::mustExecute() const App::DocumentObjectExecReturn *Helix::execute(void) { // Validate and normalize parameters - switch (Mode.getValue()) { - case 0: // pitch - height - if (Pitch.getValue() < Precision::Confusion()) - return new App::DocumentObjectExecReturn("Error: Pitch too small"); - if (Height.getValue() < Precision::Confusion()) - return new App::DocumentObjectExecReturn("Error: height too small!"); - break; - case 1: // pitch - turns - if (Pitch.getValue() < Precision::Confusion()) - return new App::DocumentObjectExecReturn("Error: pitch too small!"); - if (Turns.getValue() < Precision::Confusion()) - return new App::DocumentObjectExecReturn("Error: turns too small!"); - Height.setValue(Turns.getValue()*Pitch.getValue()); - break; - case 2: // height - turns - if (Height.getValue() < Precision::Confusion()) - return new App::DocumentObjectExecReturn("Error: height too small!"); - if (Turns.getValue() < Precision::Confusion()) - return new App::DocumentObjectExecReturn("Error turns too small!"); - Pitch.setValue(Height.getValue()/Turns.getValue()); - break; - default: - return new App::DocumentObjectExecReturn("Error: unsupported mode"); + std::string mode = Mode.getValueAsString(); + if (mode == "pitch-height-angle") { + if (Pitch.getValue() < Precision::Confusion()) + return new App::DocumentObjectExecReturn("Error: Pitch too small"); + if (Height.getValue() < Precision::Confusion()) + return new App::DocumentObjectExecReturn("Error: height too small!"); + } else if (mode == "pitch-turns-angle") { + if (Pitch.getValue() < Precision::Confusion()) + return new App::DocumentObjectExecReturn("Error: pitch too small!"); + if (Turns.getValue() < Precision::Confusion()) + return new App::DocumentObjectExecReturn("Error: turns too small!"); + Height.setValue(Turns.getValue()*Pitch.getValue()); + } else if (mode == "height-turns-angle") { + if (Height.getValue() < Precision::Confusion()) + return new App::DocumentObjectExecReturn("Error: height too small!"); + if (Turns.getValue() < Precision::Confusion()) + return new App::DocumentObjectExecReturn("Error turns too small!"); + Pitch.setValue(Height.getValue()/Turns.getValue()); + } else if (mode == "height-turns-growth") { + if (Turns.getValue() < Precision::Confusion()) + return new App::DocumentObjectExecReturn("Error turns too small!"); + Pitch.setValue(Height.getValue()/Turns.getValue()); + } else { + return new App::DocumentObjectExecReturn("Error: unsupported mode"); } + TopoDS_Shape sketchshape; try { sketchshape = getVerifiedFace(); @@ -355,11 +358,13 @@ void Helix::updateAxis(void) TopoDS_Shape Helix::generateHelixPath(void) { - double pitch = Pitch.getValue(); + double turns = Turns.getValue(); double height = Height.getValue(); bool leftHanded = LeftHanded.getValue(); bool reversed = Reversed.getValue(); double angle = Angle.getValue(); + double growth = Growth.getValue(); + if (angle < Precision::Confusion() && angle > -Precision::Confusion()) angle = 0.0; @@ -387,9 +392,17 @@ TopoDS_Shape Helix::generateHelixPath(void) radius = 1.0; //fallback to radius 1 } + bool growthMode = std::string(Mode.getValueAsString()).find("growth") != std::string::npos; + double radiusTop; + if (growthMode) + radiusTop = radius + turns*growth; + else + radiusTop = radius + height * tan(Base::toRadians(angle)); + + //build the helix path - TopoShape helix = TopoShape().makeLongHelix(pitch, height, radius, angle, leftHanded); - TopoDS_Shape path = helix.getShape(); + //TopoShape helix = TopoShape().makeLongHelix(pitch, height, radius, angle, leftHanded); + TopoDS_Shape path = TopoShape().makeSpiralHelix(radius, radiusTop, height, turns, 1, leftHanded); /* diff --git a/src/Mod/PartDesign/App/FeatureHelix.h b/src/Mod/PartDesign/App/FeatureHelix.h index 952163559f..194eb22b82 100644 --- a/src/Mod/PartDesign/App/FeatureHelix.h +++ b/src/Mod/PartDesign/App/FeatureHelix.h @@ -45,6 +45,7 @@ public: App::PropertyFloatConstraint Turns; App::PropertyBool LeftHanded; App::PropertyAngle Angle; + App::PropertyLength Growth; App::PropertyEnumeration Mode; App::PropertyBool Outside; App::PropertyBool HasBeenEdited; diff --git a/src/Mod/PartDesign/Gui/TaskHelixParameters.cpp b/src/Mod/PartDesign/Gui/TaskHelixParameters.cpp index 77355ffed8..03f89adf03 100644 --- a/src/Mod/PartDesign/Gui/TaskHelixParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskHelixParameters.cpp @@ -77,6 +77,8 @@ TaskHelixParameters::TaskHelixParameters(PartDesignGui::ViewProviderHelix *Helix this, SLOT(onTurnsChanged(double))); connect(ui->coneAngle, SIGNAL(valueChanged(double)), this, SLOT(onAngleChanged(double))); + connect(ui->growth, SIGNAL(valueChanged(double)), + this, SLOT(onGrowthChanged(double))); connect(ui->axis, SIGNAL(activated(int)), this, SLOT(onAxisChanged(int))); connect(ui->checkBoxLeftHanded, SIGNAL(toggled(bool)), @@ -98,6 +100,7 @@ TaskHelixParameters::TaskHelixParameters(PartDesignGui::ViewProviderHelix *Helix ui->height->blockSignals(true); ui->turns->blockSignals(true); ui->coneAngle->blockSignals(true); + ui->growth->blockSignals(true); ui->checkBoxLeftHanded->blockSignals(true); ui->checkBoxReversed->blockSignals(true); ui->checkBoxOutside->blockSignals(true); @@ -113,6 +116,7 @@ TaskHelixParameters::TaskHelixParameters(PartDesignGui::ViewProviderHelix *Helix } this->propAngle = &(rev->Angle); + this->propGrowth = &(rev->Growth); this->propPitch = &(rev->Pitch); this->propHeight = &(rev->Height); this->propTurns = &(rev->Turns); @@ -126,6 +130,7 @@ TaskHelixParameters::TaskHelixParameters(PartDesignGui::ViewProviderHelix *Helix double height = propHeight->getValue(); double turns = propTurns->getValue(); double angle = propAngle->getValue(); + double growth = propGrowth->getValue(); bool leftHanded = propLeftHanded->getValue(); bool reversed = propReversed->getValue(); int index = propMode->getValue(); @@ -137,6 +142,7 @@ TaskHelixParameters::TaskHelixParameters(PartDesignGui::ViewProviderHelix *Helix ui->coneAngle->setValue(angle); ui->coneAngle->setMinimum(propAngle->getMinimum()); ui->coneAngle->setMaximum(propAngle->getMaximum()); + ui->growth->setValue(growth); ui->checkBoxLeftHanded->setChecked(leftHanded); ui->checkBoxReversed->setChecked(reversed); ui->inputMode->setCurrentIndex(index); @@ -150,12 +156,14 @@ TaskHelixParameters::TaskHelixParameters(PartDesignGui::ViewProviderHelix *Helix ui->height->bind(static_cast(pcFeat)->Height); ui->turns->bind(static_cast(pcFeat)->Turns); ui->coneAngle->bind(static_cast(pcFeat)->Angle); + ui->growth->bind(static_cast(pcFeat)->Growth); ui->axis->blockSignals(false); ui->pitch->blockSignals(false); ui->height->blockSignals(false); ui->turns->blockSignals(false); ui->coneAngle->blockSignals(false); + ui->growth->blockSignals(false); ui->checkBoxLeftHanded->blockSignals(false); ui->checkBoxReversed->blockSignals(false); ui->checkBoxOutside->blockSignals(false); @@ -273,22 +281,32 @@ void TaskHelixParameters::updateUI() bool isHeightVisible = false; bool isTurnsVisible = false; bool isOutsideVisible = false; + bool isAngleVisible = false; + bool isGrowthVisible = false; if(pcHelix->getAddSubType() == PartDesign::FeatureAddSub::Subtractive) isOutsideVisible = true; - switch (propMode->getValue()) { - case 0: - isPitchVisible = true; - isHeightVisible = true; - break; - case 1: - isPitchVisible = true; - isTurnsVisible = true; - break; - default: - isHeightVisible = true; - isTurnsVisible = true; + std::string mode = propMode->getValueAsString(); + if (mode == "pitch-height-angle") { + isPitchVisible = true; + isHeightVisible = true; + isAngleVisible = true; + } else if (mode == "pitch-turns-angle") { + isPitchVisible = true; + isTurnsVisible = true; + isAngleVisible = true; + } else if (mode == "height-turns-angle") { + isHeightVisible = true; + isTurnsVisible = true; + isAngleVisible = true; + } else if (mode == "height-turns-growth") { + isHeightVisible = true; + isTurnsVisible = true; + isGrowthVisible = true; + } else { + status = "Error: unsupported mode"; + ui->labelMessage->setText(QString::fromUtf8(status.c_str())); } ui->pitch->setVisible(isPitchVisible); @@ -300,6 +318,12 @@ void TaskHelixParameters::updateUI() ui->turns->setVisible(isTurnsVisible); ui->labelTurns->setVisible(isTurnsVisible); + ui->coneAngle->setVisible(isAngleVisible); + ui->labelConeAngle->setVisible(isAngleVisible); + + ui->growth->setVisible(isGrowthVisible); + ui->labelGrowth->setVisible(isGrowthVisible); + ui->checkBoxOutside->setVisible(isOutsideVisible); } @@ -347,6 +371,13 @@ void TaskHelixParameters::onAngleChanged(double len) updateUI(); } +void TaskHelixParameters::onGrowthChanged(double len) +{ + propGrowth->setValue(len); + recomputeFeature(); + updateUI(); +} + void TaskHelixParameters::onAxisChanged(int num) { PartDesign::ProfileBased* pcHelix = static_cast(vp->getObject()); @@ -534,6 +565,7 @@ void TaskHelixParameters::apply() FCMD_OBJ_CMD(tobj,"Height = " << propHeight->getValue()); FCMD_OBJ_CMD(tobj,"Turns = " << propTurns->getValue()); FCMD_OBJ_CMD(tobj,"Angle = " << propAngle->getValue()); + FCMD_OBJ_CMD(tobj,"Growth = " << propGrowth->getValue()); FCMD_OBJ_CMD(tobj,"LeftHanded = " << (propLeftHanded->getValue() ? 1 : 0)); FCMD_OBJ_CMD(tobj,"Reversed = " << (propReversed->getValue() ? 1 : 0)); } diff --git a/src/Mod/PartDesign/Gui/TaskHelixParameters.h b/src/Mod/PartDesign/Gui/TaskHelixParameters.h index bb34d6c27b..05ebe6788e 100644 --- a/src/Mod/PartDesign/Gui/TaskHelixParameters.h +++ b/src/Mod/PartDesign/Gui/TaskHelixParameters.h @@ -71,6 +71,7 @@ private Q_SLOTS: void onHeightChanged(double); void onTurnsChanged(double); void onAngleChanged(double); + void onGrowthChanged(double); void onAxisChanged(int); void onLeftHandedChanged(bool); void onReversedChanged(bool); @@ -94,6 +95,7 @@ protected: App::PropertyBool* propReversed; App::PropertyLinkSub* propReferenceAxis; App::PropertyAngle* propAngle; + App::PropertyLength* propGrowth; App::PropertyEnumeration* propMode; App::PropertyBool* propOutside; diff --git a/src/Mod/PartDesign/Gui/TaskHelixParameters.ui b/src/Mod/PartDesign/Gui/TaskHelixParameters.ui index ac4215ac14..6d57f9d6a4 100644 --- a/src/Mod/PartDesign/Gui/TaskHelixParameters.ui +++ b/src/Mod/PartDesign/Gui/TaskHelixParameters.ui @@ -93,20 +93,25 @@ - Pitch-Height + Pitch-Height-Angle - Pitch-Turns + Pitch-Turns-Angle - Height-Turns + Height-Turns-Angle - + + + Height-Turns-Growth + + + @@ -204,7 +209,7 @@ - + Cone angle: @@ -235,6 +240,34 @@ + + + + + + Growth: + + + + + + + false + + + mm + + + 5.000000000000000 + + + 0.000000000000000 + + + + + +