PartDesign: New input mode, and allow spirals to be created

This commit is contained in:
David Osterberg
2021-03-06 12:34:38 +01:00
committed by wmayer
parent a00c00e4da
commit 98b52b09d6
5 changed files with 125 additions and 44 deletions

View File

@@ -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);
/*

View File

@@ -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;

View File

@@ -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<PartDesign::Helix *>(pcFeat)->Height);
ui->turns->bind(static_cast<PartDesign::Helix *>(pcFeat)->Turns);
ui->coneAngle->bind(static_cast<PartDesign::Helix *>(pcFeat)->Angle);
ui->growth->bind(static_cast<PartDesign::Helix *>(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<PartDesign::ProfileBased*>(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));
}

View File

@@ -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;

View File

@@ -93,20 +93,25 @@
<widget class="QComboBox" name="inputMode">
<item>
<property name="text">
<string>Pitch-Height</string>
<string>Pitch-Height-Angle</string>
</property>
</item>
<item>
<property name="text">
<string>Pitch-Turns</string>
<string>Pitch-Turns-Angle</string>
</property>
</item>
<item>
<property name="text">
<string>Height-Turns</string>
<string>Height-Turns-Angle</string>
</property>
</item>
</widget>
<item>
<property name="text">
<string>Height-Turns-Growth</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
@@ -204,7 +209,7 @@
<item>
<layout class="QHBoxLayout" name="horizontalLayoutConeAngle">
<item>
<widget class="QLabel" name="label5">
<widget class="QLabel" name="labelConeAngle">
<property name="text">
<string>Cone angle:</string>
</property>
@@ -235,6 +240,34 @@
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayoutGrowth">
<item>
<widget class="QLabel" name="labelGrowth">
<property name="text">
<string>Growth:</string>
</property>
</widget>
</item>
<item>
<widget class="Gui::QuantitySpinBox" name="growth">
<property name="keyboardTracking">
<bool>false</bool>
</property>
<property name="unit" stdset="0">
<string notr="true">mm</string>
</property>
<property name="singleStep">
<double>5.000000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="checkBoxLeftHanded">
<property name="enabled">