Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend boolean common functionality to other subtractive features #1

Merged
merged 3 commits into from Jul 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
25 changes: 18 additions & 7 deletions src/Mod/PartDesign/App/FeatureGroove.cpp
Expand Up @@ -32,6 +32,7 @@
# include <TopoDS_Wire.hxx>
# include <TopExp_Explorer.hxx>
# include <BRepAlgoAPI_Cut.hxx>
# include <BRepAlgoAPI_Common.hxx>
# include <Precision.hxx>
# include <gp_Lin.hxx>
#endif
Expand Down Expand Up @@ -66,6 +67,7 @@ Groove::Groove()
ADD_PROPERTY_TYPE(Angle,(360.0),"Groove", App::Prop_None, "Angle");
Angle.setConstraints(&floatAngle);
ADD_PROPERTY_TYPE(ReferenceAxis,(0),"Groove",(App::PropertyType)(App::Prop_None),"Reference axis of Groove");
ADD_PROPERTY_TYPE(Outside,(false),"Groove",App::Prop_None,"Remove outside of profile");
}

short Groove::mustExecute() const
Expand Down Expand Up @@ -158,14 +160,23 @@ App::DocumentObjectExecReturn *Groove::execute(void)
result = refineShapeIfActive(result);
this->AddSubShape.setValue(result);

// cut out groove to get one result object
BRepAlgoAPI_Cut mkCut(base, result);
// Let's check if the fusion has been successful
if (!mkCut.IsDone())
throw Base::CADKernelError("Cut out of base feature failed");
TopoDS_Shape solRes;
if (!Outside.getValue()) {
// cut out groove to get one result object
BRepAlgoAPI_Cut mkCut(base, result);
// Let's check if the cut has been successful
if (!mkCut.IsDone())
throw Base::CADKernelError("Cut out of base feature failed");

// we have to get the solids (fuse sometimes creates compounds)
solRes = this->getSolid(mkCut.Shape());
} else {
BRepAlgoAPI_Common mkCommon(base, result);
if (!mkCommon.IsDone())
throw Base::CADKernelError("Groove outside of profile failed");
solRes = this->getSolid(mkCommon.Shape());
}

// we have to get the solids (fuse sometimes creates compounds)
TopoDS_Shape solRes = this->getSolid(mkCut.Shape());
if (solRes.IsNull())
return new App::DocumentObjectExecReturn("Resulting shape is not a solid");

Expand Down
1 change: 1 addition & 0 deletions src/Mod/PartDesign/App/FeatureGroove.h
Expand Up @@ -40,6 +40,7 @@ class PartDesignExport Groove : public ProfileBased
App::PropertyVector Base;
App::PropertyVector Axis;
App::PropertyAngle Angle;
App::PropertyBool Outside;

/** if this property is set to a valid link, both Axis and Base properties
* are calculated according to the linked line
Expand Down
2 changes: 1 addition & 1 deletion src/Mod/PartDesign/App/FeatureHelix.cpp
Expand Up @@ -92,7 +92,7 @@ Helix::Helix()
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");
ADD_PROPERTY_TYPE(Outside, (long(0)), "Helix", App::Prop_None, "Outside");
ADD_PROPERTY_TYPE(Outside, (long(0)), "Helix", App::Prop_None, "Remove outside of profile");
ADD_PROPERTY_TYPE(HasBeenEdited, (long(0)), "Helix", App::Prop_None, "HasBeenEdited");
Mode.setEnums(ModeEnums);
}
Expand Down
19 changes: 14 additions & 5 deletions src/Mod/PartDesign/App/FeatureLoft.cpp
Expand Up @@ -58,6 +58,7 @@ Loft::Loft()
Sections.setSize(0);
ADD_PROPERTY_TYPE(Ruled,(false),"Loft",App::Prop_None,"Create ruled surface");
ADD_PROPERTY_TYPE(Closed,(false),"Loft",App::Prop_None,"Close Last to First Profile");
ADD_PROPERTY_TYPE(Outside,(false),"Loft",App::Prop_None,"Remove outside of Loft");
}

short Loft::mustExecute() const
Expand Down Expand Up @@ -206,11 +207,19 @@ App::DocumentObjectExecReturn *Loft::execute(void)
}
else if(getAddSubType() == FeatureAddSub::Subtractive) {

BRepAlgoAPI_Cut mkCut(base, result);
if (!mkCut.IsDone())
return new App::DocumentObjectExecReturn("Loft: Subtracting the loft failed");
// we have to get the solids (fuse sometimes creates compounds)
TopoDS_Shape boolOp = this->getSolid(mkCut.Shape());
TopoDS_Shape boolOp;
if (!Outside.getValue()) {
BRepAlgoAPI_Cut mkCut(base, result);
if (!mkCut.IsDone())
return new App::DocumentObjectExecReturn("Loft: Subtracting the loft failed");
// we have to get the solids (fuse sometimes creates compounds)
boolOp = this->getSolid(mkCut.Shape());
} else {
BRepAlgoAPI_Common mkCommon(base, result);
if (!mkCommon.IsDone())
return new App::DocumentObjectExecReturn("Loft: Subtracting outside the loft failed");
boolOp = this->getSolid(mkCommon.Shape());
}
// lets check if the result is a solid
if (boolOp.IsNull())
return new App::DocumentObjectExecReturn("Loft: Resulting shape is not a solid");
Expand Down
3 changes: 2 additions & 1 deletion src/Mod/PartDesign/App/FeatureLoft.h
Expand Up @@ -42,7 +42,8 @@ class PartDesignExport Loft : public ProfileBased

App::PropertyLinkList Sections;
App::PropertyBool Ruled;
App::PropertyBool Closed;
App::PropertyBool Closed;
App::PropertyBool Outside;

/** @name methods override feature */
//@{
Expand Down
19 changes: 14 additions & 5 deletions src/Mod/PartDesign/App/FeaturePipe.cpp
Expand Up @@ -92,6 +92,7 @@ Pipe::Pipe()
ADD_PROPERTY_TYPE(Binormal,(Base::Vector3d()),"Sweep",App::Prop_None,"Binormal vector for corresponding orientation mode");
ADD_PROPERTY_TYPE(Transition,(long(0)),"Sweep",App::Prop_None,"Transition mode");
ADD_PROPERTY_TYPE(Transformation,(long(0)),"Sweep",App::Prop_None,"Section transformation mode");
ADD_PROPERTY_TYPE(Outside,(false),"Sweep",App::Prop_None,"Remove outside of sweep");
Mode.setEnums(ModeEnums);
Transition.setEnums(TransitionEnums);
Transformation.setEnums(TransformEnums);
Expand Down Expand Up @@ -332,11 +333,19 @@ App::DocumentObjectExecReturn *Pipe::execute(void)
}
else if(getAddSubType() == FeatureAddSub::Subtractive) {

BRepAlgoAPI_Cut mkCut(base, result);
if (!mkCut.IsDone())
return new App::DocumentObjectExecReturn("Subtracting the pipe failed");
// we have to get the solids (fuse sometimes creates compounds)
TopoDS_Shape boolOp = this->getSolid(mkCut.Shape());
TopoDS_Shape boolOp;
if (!Outside.getValue()) {
BRepAlgoAPI_Cut mkCut(base, result);
if (!mkCut.IsDone())
return new App::DocumentObjectExecReturn("Subtracting the pipe failed");
// we have to get the solids (fuse sometimes creates compounds)
boolOp = this->getSolid(mkCut.Shape());
} else {
BRepAlgoAPI_Common mkCommon(base, result);
if (!mkCommon.IsDone())
return new App::DocumentObjectExecReturn("Subtracting outside the pipe failed");
boolOp = this->getSolid(mkCommon.Shape());
}
// lets check if the result is a solid
if (boolOp.IsNull())
return new App::DocumentObjectExecReturn("Resulting shape is not a solid");
Expand Down
1 change: 1 addition & 0 deletions src/Mod/PartDesign/App/FeaturePipe.h
Expand Up @@ -49,6 +49,7 @@ class PartDesignExport Pipe : public ProfileBased
App::PropertyEnumeration Transition;
App::PropertyEnumeration Transformation;
App::PropertyLinkList Sections;
App::PropertyBool Outside;

App::DocumentObjectExecReturn *execute(void);
short mustExecute() const;
Expand Down
20 changes: 15 additions & 5 deletions src/Mod/PartDesign/App/FeaturePocket.cpp
Expand Up @@ -69,6 +69,7 @@ Pocket::Pocket()
ADD_PROPERTY_TYPE(Length2,(100.0),"Pocket",App::Prop_None,"P");
ADD_PROPERTY_TYPE(UpToFace,(0),"Pocket",App::Prop_None,"Face where pocket will end");
ADD_PROPERTY_TYPE(Offset,(0.0),"Pocket",App::Prop_None,"Offset from face in which pocket will end");
ADD_PROPERTY_TYPE(Outside,(false),"Pocket",App::Prop_None,"Remove outside of profile");
static const App::PropertyQuantityConstraint::Constraints signedLengthConstraint = {-DBL_MAX, DBL_MAX, 1.0};
Offset.setConstraints ( &signedLengthConstraint );

Expand Down Expand Up @@ -219,11 +220,20 @@ App::DocumentObjectExecReturn *Pocket::execute(void)
prism = refineShapeIfActive(prism);
this->AddSubShape.setValue(prism);

// Cut the SubShape out of the base feature
BRepAlgoAPI_Cut mkCut(base, prism);
if (!mkCut.IsDone())
return new App::DocumentObjectExecReturn("Pocket: Cut out of base feature failed");
TopoDS_Shape result = mkCut.Shape();
TopoDS_Shape result;
if (!Outside.getValue()) {
// Cut the SubShape out of the base feature
BRepAlgoAPI_Cut mkCut(base, prism);
if (!mkCut.IsDone())
return new App::DocumentObjectExecReturn("Pocket: Cut out of base feature failed");
result = mkCut.Shape();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
result = mkCut.Shape();
result = this->getSolid(mkCut.Shape());

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for the review, pocket originally didn't do this but just used mkCut.Shape() should I assume that was just a mistake and it should have used this method all along? Can you explain what this does?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok it turns out this is also done just a few lines after (238):
TopoDS_Shape solRes = this->getSolid(result);
what to do then?
later on result is used again (line 242):
int solidCount = countSolids(result);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually the idea is just to harmonize things. If it's too much work because of existing codebase, then it could stay as is.

} else {
// Cut the base feature to SubShape
BRepAlgoAPI_Common mkCommon(base, prism);
if (!mkCommon.IsDone())
return new App::DocumentObjectExecReturn("Pocket: Cut out of base feature failed");
result = mkCommon.Shape();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
result = mkCommon.Shape();
result = this->getSolid(mkCommon.Shape());

}
// we have to get the solids (fuse sometimes creates compounds)
TopoDS_Shape solRes = this->getSolid(result);
if (solRes.IsNull())
Expand Down
1 change: 1 addition & 0 deletions src/Mod/PartDesign/App/FeaturePocket.h
Expand Up @@ -41,6 +41,7 @@ class PartDesignExport Pocket : public ProfileBased
App::PropertyLength Length;
App::PropertyLength Length2;
App::PropertyLength Offset;
App::PropertyBool Outside;

/** @name methods override feature */
//@{
Expand Down
28 changes: 22 additions & 6 deletions src/Mod/PartDesign/App/FeaturePrimitive.cpp
Expand Up @@ -27,6 +27,7 @@
# include <BRepBuilderAPI_GTransform.hxx>
# include <BRepAlgoAPI_Fuse.hxx>
# include <BRepAlgoAPI_Cut.hxx>
# include <BRepAlgoAPI_Common.hxx>
# include <BRepBuilderAPI_Transform.hxx>
# include <BRepPrimAPI_MakeCylinder.hxx>
# include <BRepPrimAPI_MakeSphere.hxx>
Expand Down Expand Up @@ -119,12 +120,19 @@ App::DocumentObjectExecReturn* FeaturePrimitive::execute(const TopoDS_Shape& pri
AddSubShape.setValue(primitiveShape);
}
else if (getAddSubType() == FeatureAddSub::Subtractive) {

BRepAlgoAPI_Cut mkCut(base, primitiveShape);
if (!mkCut.IsDone())
return new App::DocumentObjectExecReturn("Subtracting the primitive failed");
// we have to get the solids (fuse sometimes creates compounds)
TopoDS_Shape boolOp = this->getSolid(mkCut.Shape());
TopoDS_Shape boolOp;
if (!Outside.getValue()) {
BRepAlgoAPI_Cut mkCut(base, primitiveShape);
if (!mkCut.IsDone())
return new App::DocumentObjectExecReturn("Subtracting the primitive failed");
// we have to get the solids (fuse sometimes creates compounds)
boolOp = this->getSolid(mkCut.Shape());
} else {
BRepAlgoAPI_Common mkCommon(base, primitiveShape);
if (!mkCommon.IsDone())
return new App::DocumentObjectExecReturn("Subtracting outside the primitive failed");
boolOp = this->getSolid(mkCommon.Shape());
}
// lets check if the result is a solid
if (boolOp.IsNull())
return new App::DocumentObjectExecReturn("Resulting shape is not a solid");
Expand Down Expand Up @@ -188,6 +196,7 @@ Box::Box()
ADD_PROPERTY_TYPE(Length,(10.0f),"Box",App::Prop_None,"The length of the box");
ADD_PROPERTY_TYPE(Width ,(10.0f),"Box",App::Prop_None,"The width of the box");
ADD_PROPERTY_TYPE(Height,(10.0f),"Box",App::Prop_None,"The height of the box");
ADD_PROPERTY_TYPE(Outside,(false),"Box",App::Prop_None,"Remove outside of primitive");
Length.setConstraints(&quantityRange);
Width.setConstraints(&quantityRange);
Height.setConstraints(&quantityRange);
Expand Down Expand Up @@ -239,6 +248,7 @@ Cylinder::Cylinder()
ADD_PROPERTY_TYPE(Radius,(10.0f),"Cylinder",App::Prop_None,"The radius of the cylinder");
ADD_PROPERTY_TYPE(Angle,(360.0f),"Cylinder",App::Prop_None,"The closing angle of the cylinder ");
ADD_PROPERTY_TYPE(Height,(10.0f),"Cylinder",App::Prop_None,"The height of the cylinder");
ADD_PROPERTY_TYPE(Outside,(false),"Cylinder",App::Prop_None,"Remove outside of primitive");
Angle.setConstraints(&angleRangeU);
Radius.setConstraints(&quantityRange);
Height.setConstraints(&quantityRange);
Expand Down Expand Up @@ -301,6 +311,7 @@ Sphere::Sphere()
Angle2.setConstraints(&angleRangeV);
ADD_PROPERTY_TYPE(Angle3,(360.0f),"Sphere",App::Prop_None,"The angle of the sphere");
Angle3.setConstraints(&angleRangeU);
ADD_PROPERTY_TYPE(Outside,(false),"Sphere",App::Prop_None,"Remove outside of primitive");

primitiveType = FeaturePrimitive::Sphere;
}
Expand Down Expand Up @@ -347,6 +358,7 @@ Cone::Cone()
ADD_PROPERTY_TYPE(Radius2,(4.0),"Cone",App::Prop_None,"The radius of the cone");
ADD_PROPERTY_TYPE(Height,(10.0),"Cone",App::Prop_None,"The height of the cone");
ADD_PROPERTY_TYPE(Angle,(360.0),"Cone",App::Prop_None,"The angle of the cone");
ADD_PROPERTY_TYPE(Outside,(false),"Cone",App::Prop_None,"Remove outside of primitive");
Angle.setConstraints(&angleRangeU);
Radius1.setConstraints(&quantityRangeZero);
Radius2.setConstraints(&quantityRangeZero);
Expand Down Expand Up @@ -413,6 +425,7 @@ Ellipsoid::Ellipsoid()
Angle2.setConstraints(&angleRangeV);
ADD_PROPERTY_TYPE(Angle3,(360.0f),"Ellipsoid",App::Prop_None,"The angle of the ellipsoid");
Angle3.setConstraints(&angleRangeU);
ADD_PROPERTY_TYPE(Outside,(false),"Ellipsoid",App::Prop_None,"Remove outside of primitive");

primitiveType = FeaturePrimitive::Ellipsoid;
}
Expand Down Expand Up @@ -498,6 +511,7 @@ Torus::Torus()
Angle2.setConstraints(&torusRangeV);
ADD_PROPERTY_TYPE(Angle3,(360.0),"Torus",App::Prop_None,"The angle of the torus");
Angle3.setConstraints(&angleRangeU);
ADD_PROPERTY_TYPE(Outside,(false),"Torus",App::Prop_None,"Remove outside of primitive");

primitiveType = FeaturePrimitive::Torus;
}
Expand Down Expand Up @@ -560,6 +574,7 @@ Prism::Prism()
ADD_PROPERTY_TYPE(Polygon, (6.0), "Prism", App::Prop_None, "Number of sides in the polygon, of the prism");
ADD_PROPERTY_TYPE(Circumradius, (2.0), "Prism", App::Prop_None, "Circumradius (centre to vertex) of the polygon, of the prism");
ADD_PROPERTY_TYPE(Height, (10.0f), "Prism", App::Prop_None, "The height of the prism");
ADD_PROPERTY_TYPE(Outside,(false),"Prism",App::Prop_None,"Remove outside of primitive");

Part::PrismExtension::initExtension(this);

Expand Down Expand Up @@ -631,6 +646,7 @@ Wedge::Wedge()
ADD_PROPERTY_TYPE(Zmax,(10.0f),"Wedge",App::Prop_None,"Zmax of the wedge");
ADD_PROPERTY_TYPE(X2max,(8.0f),"Wedge",App::Prop_None,"X2max of the wedge");
ADD_PROPERTY_TYPE(Z2max,(8.0f),"Wedge",App::Prop_None,"Z2max of the wedge");
ADD_PROPERTY_TYPE(Outside,(false),"Wedge",App::Prop_None,"Remove outside of primitive");

primitiveType = FeaturePrimitive::Wedge;
}
Expand Down
1 change: 1 addition & 0 deletions src/Mod/PartDesign/App/FeaturePrimitive.h
Expand Up @@ -52,6 +52,7 @@ class PartDesignExport FeaturePrimitive : public PartDesign::FeatureAddSub, publ

FeaturePrimitive();

App::PropertyBool Outside;
virtual const char* getViewProviderName(void) const override {
return "PartDesignGui::ViewProviderPrimitive";
}
Expand Down
11 changes: 11 additions & 0 deletions src/Mod/PartDesign/Gui/TaskLoftParameters.cpp
Expand Up @@ -76,6 +76,8 @@ TaskLoftParameters::TaskLoftParameters(ViewProviderLoft *LoftView,bool /*newObj*
this, SLOT(onClosed(bool)));
connect(ui->checkBoxUpdateView, SIGNAL(toggled(bool)),
this, SLOT(onUpdateView(bool)));
connect(ui->checkBoxOutside, SIGNAL(toggled(bool)),
this, SLOT(onOutsideChanged(bool)));

// Create context menu
QAction* remove = new QAction(tr("Remove"), this);
Expand Down Expand Up @@ -117,9 +119,12 @@ TaskLoftParameters::TaskLoftParameters(ViewProviderLoft *LoftView,bool /*newObj*
ui->listWidgetReferences->addItem(item);
}

ui->checkBoxOutside->setVisible(loft->getAddSubType() == PartDesign::FeatureAddSub::Subtractive);

// get options
ui->checkBoxRuled->setChecked(loft->Ruled.getValue());
ui->checkBoxClosed->setChecked(loft->Closed.getValue());
ui->checkBoxOutside->setChecked(loft->Outside.getValue());

if (!loft->Sections.getValues().empty()) {
LoftView->makeTemporaryVisible(true);
Expand Down Expand Up @@ -297,6 +302,12 @@ void TaskLoftParameters::changeEvent(QEvent * /*e*/)
{
}

void TaskLoftParameters::onOutsideChanged(bool val)
{
static_cast<PartDesign::Loft*>(vp->getObject())->Outside.setValue(val);
recomputeFeature();
}

void TaskLoftParameters::onClosed(bool val) {
static_cast<PartDesign::Loft*>(vp->getObject())->Closed.setValue(val);
recomputeFeature();
Expand Down
1 change: 1 addition & 0 deletions src/Mod/PartDesign/Gui/TaskLoftParameters.h
Expand Up @@ -61,6 +61,7 @@ private Q_SLOTS:
void onRuled(bool);
void onDeleteSection();
void indexesMoved();
void onOutsideChanged(bool);

protected:
void changeEvent(QEvent *e);
Expand Down
9 changes: 8 additions & 1 deletion src/Mod/PartDesign/Gui/TaskLoftParameters.ui
Expand Up @@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>262</width>
<height>270</height>
<height>337</height>
</rect>
</property>
<property name="windowTitle">
Expand All @@ -28,6 +28,13 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBoxOutside">
<property name="text">
<string>Remove outside of loft</string>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupprofile">
<property name="title">
Expand Down
11 changes: 11 additions & 0 deletions src/Mod/PartDesign/Gui/TaskPipeParameters.cpp
Expand Up @@ -90,6 +90,8 @@ TaskPipeParameters::TaskPipeParameters(ViewProviderPipe *PipeView, bool /*newObj
this, SLOT(onButtonRefRemove(bool)));
connect(ui->buttonSpineBase, SIGNAL(toggled(bool)),
this, SLOT(onBaseButton(bool)));
connect(ui->checkBoxOutside, SIGNAL(toggled(bool)),
this, SLOT(onOutsideChanged(bool)));

// Create context menu
QAction* remove = new QAction(tr("Remove"), this);
Expand Down Expand Up @@ -136,6 +138,9 @@ TaskPipeParameters::TaskPipeParameters(ViewProviderPipe *PipeView, bool /*newObj

ui->comboBoxTransition->setCurrentIndex(pipe->Transition.getValue());

ui->checkBoxOutside->setVisible(pipe->getAddSubType() == PartDesign::FeatureAddSub::Subtractive);
ui->checkBoxOutside->setChecked(pipe->Outside.getValue());

updateUI();
}

Expand Down Expand Up @@ -234,6 +239,12 @@ void TaskPipeParameters::onSelectionChanged(const Gui::SelectionChanges& msg)
}
}

void TaskPipeParameters::onOutsideChanged(bool on)
{
static_cast<PartDesign::Pipe*>(vp->getObject())->Outside.setValue(on);
recomputeFeature();
}

void TaskPipeParameters::onTransitionChanged(int idx) {

static_cast<PartDesign::Pipe*>(vp->getObject())->Transition.setValue(idx);
Expand Down