[PartDesign] add direction to cylinder primitive

We already have the possibility to create skewed prisms. I recently stumbled upon that I would need this feature for cylinders too.

This PR takes the existing prism extrude direction feature and use it for cylinders too
This commit is contained in:
donovaly
2021-04-05 14:35:50 +02:00
committed by wmayer
parent c0e6debcfa
commit 7185ee93f2
5 changed files with 120 additions and 16 deletions

View File

@@ -33,6 +33,7 @@
# include <BRepPrimAPI_MakeCone.hxx>
# include <BRepPrimAPI_MakeTorus.hxx>
# include <BRepPrimAPI_MakePrism.hxx>
# include <BRepPrim_Cylinder.hxx>
# include <BRepBuilderAPI_MakePolygon.hxx>
# include <BRepBuilderAPI_MakeFace.hxx>
# include <BRepBuilderAPI_MakeSolid.hxx>
@@ -242,6 +243,8 @@ Cylinder::Cylinder()
Radius.setConstraints(&quantityRange);
Height.setConstraints(&quantityRange);
Part::PrismExtension::initExtension(this);
primitiveType = FeaturePrimitive::Cylinder;
}
@@ -252,12 +255,18 @@ App::DocumentObjectExecReturn* Cylinder::execute(void)
return new App::DocumentObjectExecReturn("Radius of cylinder too small");
if (Height.getValue() < Precision::Confusion())
return new App::DocumentObjectExecReturn("Height of cylinder too small");
if (Angle.getValue() < Precision::Confusion())
return new App::DocumentObjectExecReturn("Rotation angle of cylinder too small");
try {
BRepPrimAPI_MakeCylinder mkCylr(Radius.getValue(),
Height.getValue(),
Angle.getValue()/180.0f*M_PI);
Base::toRadians<double>(Angle.getValue()));
return FeaturePrimitive::execute(mkCylr.Shape());
// the direction vector for the prism is the height for z and the given angle
BRepPrim_Cylinder prim = mkCylr.Cylinder();
TopoDS_Shape result = makePrism(Height.getValue(), prim.BottomFace());
return FeaturePrimitive::execute(result);
}
catch (Standard_Failure& e) {

View File

@@ -107,7 +107,7 @@ class PartDesignExport SubtractiveBox : public Box {
};
class PartDesignExport Cylinder : public PartDesign::FeaturePrimitive {
class PartDesignExport Cylinder : public PartDesign::FeaturePrimitive, public Part::PrismExtension {
PROPERTY_HEADER(PartDesign::Cylinder);
@@ -124,9 +124,6 @@ public:
/// recalculate the Feature
App::DocumentObjectExecReturn *execute(void);
short mustExecute() const;
protected:
};
class PartDesignExport AdditiveCylinder : public Cylinder {

View File

@@ -87,6 +87,10 @@ TaskBoxPrimitives::TaskBoxPrimitives(ViewProviderPrimitive* vp, QWidget* parent)
ui->cylinderHeight->bind(static_cast<PartDesign::Cylinder*>(vp->getObject())->Height);
ui->cylinderRadius->setValue(static_cast<PartDesign::Cylinder*>(vp->getObject())->Radius.getValue());
ui->cylinderRadius->bind(static_cast<PartDesign::Cylinder*>(vp->getObject())->Radius);
ui->cylinderXSkew->setValue(static_cast<PartDesign::Cylinder*>(vp->getObject())->FirstAngle.getValue());
ui->cylinderXSkew->bind(static_cast<PartDesign::Cylinder*>(vp->getObject())->FirstAngle);
ui->cylinderYSkew->setValue(static_cast<PartDesign::Cylinder*>(vp->getObject())->SecondAngle.getValue());
ui->cylinderYSkew->bind(static_cast<PartDesign::Cylinder*>(vp->getObject())->SecondAngle);
ui->cylinderAngle->setMaximum(static_cast<PartDesign::Cylinder*>(vp->getObject())->Angle.getMaximum());
ui->cylinderAngle->setMinimum(static_cast<PartDesign::Cylinder*>(vp->getObject())->Angle.getMinimum());
ui->cylinderHeight->setMaximum(INT_MAX);
@@ -278,6 +282,8 @@ TaskBoxPrimitives::TaskBoxPrimitives(ViewProviderPrimitive* vp, QWidget* parent)
// cylinder
connect(ui->cylinderRadius, SIGNAL(valueChanged(double)), this, SLOT(onCylinderRadiusChanged(double)));
connect(ui->cylinderHeight, SIGNAL(valueChanged(double)), this, SLOT(onCylinderHeightChanged(double)));
connect(ui->cylinderXSkew, SIGNAL(valueChanged(double)), this, SLOT(onCylinderXSkewChanged(double)));
connect(ui->cylinderYSkew, SIGNAL(valueChanged(double)), this, SLOT(onCylinderYSkewChanged(double)));
connect(ui->cylinderAngle, SIGNAL(valueChanged(double)), this, SLOT(onCylinderAngleChanged(double)));
// cone
@@ -388,6 +394,40 @@ void TaskBoxPrimitives::onCylinderRadiusChanged(double v) {
vp->getObject()->getDocument()->recomputeFeature(vp->getObject());
}
void TaskBoxPrimitives::onCylinderXSkewChanged(double v) {
PartDesign::Cylinder* cyl = static_cast<PartDesign::Cylinder*>(vp->getObject());
// we must assure that if the user incremented from e.g. 85 degree with the
// spin buttons he does not end at 90.0 but 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());
}
vp->getObject()->getDocument()->recomputeFeature(vp->getObject());
}
void TaskBoxPrimitives::onCylinderYSkewChanged(double v) {
PartDesign::Cylinder* cyl = static_cast<PartDesign::Cylinder*>(vp->getObject());
// we must assure that if the user incremented from e.g. 85 degree with the
// spin buttons he does not end at 90.0 but 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());
}
vp->getObject()->getDocument()->recomputeFeature(vp->getObject());
}
void TaskBoxPrimitives::onSphereAngle1Changed(double v) {
PartDesign::Sphere* sph = static_cast<PartDesign::Sphere*>(vp->getObject());
ui->sphereAngle2->setMinimum(v); // Angle1 must geometrically be <= than Angle2
@@ -665,11 +705,15 @@ void TaskBoxPrimitives::setPrimitive(App::DocumentObject *obj)
cmd = QString::fromLatin1(
"%1.Radius=%2\n"
"%1.Height=%3\n"
"%1.Angle=%4\n")
"%1.Angle=%4\n"
"%1.FirstAngle=%5\n"
"%1.SecondAngle=%6\n")
.arg(name)
.arg(ui->cylinderRadius->value().getValue(),0,'f',Base::UnitsApi::getDecimals())
.arg(ui->cylinderHeight->value().getValue(),0,'f',Base::UnitsApi::getDecimals())
.arg(ui->cylinderAngle->value().getValue(),0,'f',Base::UnitsApi::getDecimals());
.arg(ui->cylinderAngle->value().getValue(),0,'f',Base::UnitsApi::getDecimals())
.arg(ui->cylinderXSkew->value().getValue(),0,'f',Base::UnitsApi::getDecimals())
.arg(ui->cylinderYSkew->value().getValue(),0,'f',Base::UnitsApi::getDecimals());
break;
case 3: // cone

View File

@@ -63,6 +63,8 @@ public Q_SLOTS:
void onBoxHeightChanged(double);
void onCylinderRadiusChanged(double);
void onCylinderHeightChanged(double);
void onCylinderXSkewChanged(double);
void onCylinderYSkewChanged(double);
void onCylinderAngleChanged(double);
void onSphereRadiusChanged(double);
void onSphereAngle1Changed(double);

View File

@@ -264,7 +264,7 @@
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Angle:</string>
<string>Rotation angle:</string>
</property>
</widget>
</item>
@@ -333,6 +333,19 @@
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="Gui::QuantitySpinBox" name="cylinderRadius">
<property name="keyboardTracking">
<bool>false</bool>
</property>
<property name="unit" stdset="0">
<string notr="true">mm</string>
</property>
<property name="value">
<double>2.000000000000000</double>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="textLabel6">
<property name="text">
@@ -353,16 +366,55 @@
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="Gui::QuantitySpinBox" name="cylinderRadius">
<item row="2" column="0">
<widget class="QLabel" name="labelCylinderXSkew">
<property name="text">
<string>Angle in first direction:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="Gui::QuantitySpinBox" name="cylinderXSkew">
<property name="toolTip">
<string>Angle in first direction</string>
</property>
<property name="keyboardTracking">
<bool>false</bool>
</property>
<property name="unit" stdset="0">
<string notr="true">mm</string>
<string notr="true">deg</string>
</property>
<property name="value">
<double>2.000000000000000</double>
<property name="minimum">
<double>-90.000000000000000</double>
</property>
<property name="maximum">
<double>90.000000000000000</double>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="labelCylinderYSkew">
<property name="text">
<string>Angle in second direction:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="Gui::QuantitySpinBox" name="cylinderYSkew">
<property name="toolTip">
<string>Angle in second direction</string>
</property>
<property name="keyboardTracking">
<bool>false</bool>
</property>
<property name="unit" stdset="0">
<string notr="true">deg</string>
</property>
<property name="minimum">
<double>-90.000000000000000</double>
</property>
<property name="maximum">
<double>90.000000000000000</double>
</property>
</widget>
</item>
@@ -1201,7 +1253,7 @@
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="labelXSkew">
<widget class="QLabel" name="labelPrismXSkew">
<property name="text">
<string>Angle in first direction:</string>
</property>
@@ -1227,7 +1279,7 @@
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="labelYSkew">
<widget class="QLabel" name="labelPrismYSkew">
<property name="text">
<string>Angle in second direction:</string>
</property>