PartDesign: decouple refine and other geometric computation (#17008)
This commit is contained in:
committed by
GitHub
parent
e5c2c81685
commit
70184ba59d
@@ -150,7 +150,7 @@ short Feature::mustExecute() const
|
||||
return Part::Feature::mustExecute();
|
||||
}
|
||||
|
||||
TopoShape Feature::getSolid(const TopoShape& shape)
|
||||
TopoShape Feature::getSolid(const TopoShape& shape) const
|
||||
{
|
||||
if (shape.isNull()) {
|
||||
throw Part::NullShapeException("Null shape");
|
||||
@@ -226,7 +226,7 @@ bool Feature::isSingleSolidRuleSatisfied(const TopoDS_Shape& shape, TopAbs_Shape
|
||||
}
|
||||
|
||||
|
||||
Feature::SingleSolidRuleMode Feature::singleSolidRuleMode()
|
||||
Feature::SingleSolidRuleMode Feature::singleSolidRuleMode() const
|
||||
{
|
||||
auto body = getFeatureBody();
|
||||
|
||||
|
||||
@@ -99,14 +99,14 @@ protected:
|
||||
/**
|
||||
* Get a solid of the given shape. If no solid is found an exception is raised.
|
||||
*/
|
||||
TopoShape getSolid(const TopoShape&);
|
||||
TopoShape getSolid(const TopoShape&) const;
|
||||
static int countSolids(const TopoDS_Shape&, TopAbs_ShapeEnum type = TopAbs_SOLID);
|
||||
|
||||
/**
|
||||
* Checks if the single-solid body rule is fulfilled.
|
||||
*/
|
||||
bool isSingleSolidRuleSatisfied(const TopoDS_Shape&, TopAbs_ShapeEnum type = TopAbs_SOLID);
|
||||
SingleSolidRuleMode singleSolidRuleMode();
|
||||
SingleSolidRuleMode singleSolidRuleMode() const;
|
||||
|
||||
void updateSuppressedShape();
|
||||
|
||||
|
||||
@@ -60,6 +60,29 @@ short FeatureAddSub::mustExecute() const
|
||||
return PartDesign::Feature::mustExecute();
|
||||
}
|
||||
|
||||
|
||||
bool FeatureAddSub::onlyHasToRefine() const
|
||||
{
|
||||
if( ! Refine.isTouched()){
|
||||
return false;
|
||||
}
|
||||
if (rawShape.isNull()){
|
||||
return false;
|
||||
}
|
||||
std::vector<App::Property*> propList;
|
||||
getPropertyList(propList);
|
||||
for (auto prop : propList){
|
||||
if (prop != &Refine
|
||||
/*&& prop != &SuppressedShape*/
|
||||
&& prop->isTouched()){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
TopoShape FeatureAddSub::refineShapeIfActive(const TopoShape& oldShape, const RefineErrorPolicy onError) const
|
||||
{
|
||||
if (this->Refine.getValue()) {
|
||||
|
||||
@@ -56,9 +56,14 @@ public:
|
||||
Part::PropertyPartShape AddSubShape;
|
||||
App::PropertyBool Refine;
|
||||
|
||||
|
||||
protected:
|
||||
Type addSubType{Additive};
|
||||
|
||||
//store the shape before refinement
|
||||
TopoShape rawShape;
|
||||
|
||||
bool onlyHasToRefine() const;
|
||||
TopoShape refineShapeIfActive(const TopoShape& oldShape, const RefineErrorPolicy onError = RefineErrorPolicy::Raise) const;
|
||||
};
|
||||
|
||||
|
||||
@@ -104,6 +104,12 @@ short Chamfer::mustExecute() const
|
||||
|
||||
App::DocumentObjectExecReturn *Chamfer::execute()
|
||||
{
|
||||
if (onlyHasToRefine()){
|
||||
TopoShape result = refineShapeIfActive(rawShape);
|
||||
Shape.setValue(result);
|
||||
return App::DocumentObject::StdReturn;
|
||||
}
|
||||
|
||||
// NOTE: Normally the Base property and the BaseFeature property should point to the same object.
|
||||
// The only difference is that the Base property also stores the edges that are to be chamfered
|
||||
Part::TopoShape TopShape;
|
||||
@@ -164,6 +170,9 @@ App::DocumentObjectExecReturn *Chamfer::execute()
|
||||
TopAbs_SHAPE);
|
||||
}
|
||||
if (!failed) {
|
||||
|
||||
// store shape before refinement
|
||||
this->rawShape = shape;
|
||||
shape = refineShapeIfActive(shape);
|
||||
shape = getSolid(shape);
|
||||
}
|
||||
|
||||
@@ -463,6 +463,12 @@ void FeatureExtrude::setupObject()
|
||||
|
||||
App::DocumentObjectExecReturn* FeatureExtrude::buildExtrusion(ExtrudeOptions options)
|
||||
{
|
||||
if (onlyHasToRefine()){
|
||||
TopoShape result = refineShapeIfActive(rawShape);
|
||||
Shape.setValue(result);
|
||||
return App::DocumentObject::StdReturn;
|
||||
}
|
||||
|
||||
bool makeface = options.testFlag(ExtrudeOption::MakeFace);
|
||||
bool fuse = options.testFlag(ExtrudeOption::MakeFuse);
|
||||
bool legacyPocket = options.testFlag(ExtrudeOption::LegacyPocket);
|
||||
@@ -660,6 +666,9 @@ App::DocumentObjectExecReturn* FeatureExtrude::buildExtrusion(ExtrudeOptions opt
|
||||
else {
|
||||
result.makeElementCut({base, prism});
|
||||
}
|
||||
|
||||
// store shape before refinement
|
||||
this->rawShape = result;
|
||||
result = refineShapeIfActive(result);
|
||||
this->AddSubShape.setValue(result);
|
||||
}
|
||||
@@ -672,6 +681,9 @@ App::DocumentObjectExecReturn* FeatureExtrude::buildExtrusion(ExtrudeOptions opt
|
||||
prism = base.makeElementFuse(this->AddSubShape.getShape());
|
||||
}
|
||||
else {
|
||||
|
||||
// store shape before refinement
|
||||
this->rawShape = prism;
|
||||
prism = refineShapeIfActive(prism);
|
||||
}
|
||||
|
||||
@@ -750,8 +762,10 @@ App::DocumentObjectExecReturn* FeatureExtrude::buildExtrusion(ExtrudeOptions opt
|
||||
}
|
||||
}
|
||||
|
||||
// set the additive shape property for later usage in e.g. pattern
|
||||
// store shape before refinement
|
||||
this->rawShape = prism;
|
||||
prism = refineShapeIfActive(prism);
|
||||
// set the additive shape property for later usage in e.g. pattern
|
||||
this->AddSubShape.setValue(prism);
|
||||
|
||||
if (base.shapeType(true) <= TopAbs_SOLID && fuse) {
|
||||
@@ -781,7 +795,11 @@ App::DocumentObjectExecReturn* FeatureExtrude::buildExtrusion(ExtrudeOptions opt
|
||||
return new App::DocumentObjectExecReturn(
|
||||
QT_TRANSLATE_NOOP("Exception", "Resulting shape is not a solid"));
|
||||
}
|
||||
|
||||
// store shape before refinement
|
||||
this->rawShape = result;
|
||||
solRes = refineShapeIfActive(solRes);
|
||||
|
||||
if (!isSingleSolidRuleSatisfied(solRes.getShape())) {
|
||||
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Result has multiple solids: that is not currently supported."));
|
||||
}
|
||||
@@ -791,6 +809,9 @@ App::DocumentObjectExecReturn* FeatureExtrude::buildExtrusion(ExtrudeOptions opt
|
||||
if (prism.countSubShapes(TopAbs_SOLID) > 1) {
|
||||
prism.makeElementFuse(prism.getSubTopoShapes(TopAbs_SOLID));
|
||||
}
|
||||
|
||||
// store shape before refinement
|
||||
this->rawShape = prism;
|
||||
prism = refineShapeIfActive(prism);
|
||||
prism = getSolid(prism);
|
||||
if (!isSingleSolidRuleSatisfied(prism.getShape())) {
|
||||
@@ -799,6 +820,8 @@ App::DocumentObjectExecReturn* FeatureExtrude::buildExtrusion(ExtrudeOptions opt
|
||||
this->Shape.setValue(prism);
|
||||
}
|
||||
else {
|
||||
// store shape before refinement
|
||||
this->rawShape = prism;
|
||||
prism = refineShapeIfActive(prism);
|
||||
if (!isSingleSolidRuleSatisfied(prism.getShape())) {
|
||||
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Result has multiple solids: that is not currently supported."));
|
||||
|
||||
@@ -65,6 +65,12 @@ short Fillet::mustExecute() const
|
||||
|
||||
App::DocumentObjectExecReturn *Fillet::execute()
|
||||
{
|
||||
if (onlyHasToRefine()){
|
||||
TopoShape result = refineShapeIfActive(rawShape);
|
||||
Shape.setValue(result);
|
||||
return App::DocumentObject::StdReturn;
|
||||
}
|
||||
|
||||
Part::TopoShape baseShape;
|
||||
try {
|
||||
baseShape = getBaseTopoShape();
|
||||
@@ -110,6 +116,8 @@ App::DocumentObjectExecReturn *Fillet::execute()
|
||||
}
|
||||
|
||||
if (!failed) {
|
||||
// store shape before refinement
|
||||
this->rawShape = shape;
|
||||
shape = refineShapeIfActive(shape);
|
||||
shape = getSolid(shape);
|
||||
}
|
||||
|
||||
@@ -81,6 +81,12 @@ short Groove::mustExecute() const
|
||||
|
||||
App::DocumentObjectExecReturn *Groove::execute()
|
||||
{
|
||||
if (onlyHasToRefine()){
|
||||
TopoShape result = refineShapeIfActive(rawShape);
|
||||
Shape.setValue(result);
|
||||
return App::DocumentObject::StdReturn;
|
||||
}
|
||||
|
||||
// Validate parameters
|
||||
double angle = Angle.getValue();
|
||||
if (angle > 360.0)
|
||||
@@ -187,6 +193,8 @@ App::DocumentObjectExecReturn *Groove::execute()
|
||||
if (boolOp.isNull())
|
||||
return new App::DocumentObjectExecReturn("Resulting shape is not a solid");
|
||||
|
||||
// store shape before refinement
|
||||
this->rawShape = boolOp;
|
||||
boolOp = refineShapeIfActive(boolOp);
|
||||
boolOp = getSolid(boolOp);
|
||||
if (!isSingleSolidRuleSatisfied(boolOp.getShape())) {
|
||||
|
||||
@@ -126,6 +126,13 @@ short Helix::mustExecute() const
|
||||
|
||||
App::DocumentObjectExecReturn* Helix::execute()
|
||||
{
|
||||
|
||||
if (onlyHasToRefine()){
|
||||
TopoShape result = refineShapeIfActive(rawShape, RefineErrorPolicy::Warn);
|
||||
Shape.setValue(result);
|
||||
return App::DocumentObject::StdReturn;
|
||||
}
|
||||
|
||||
// Validate and normalize parameters
|
||||
HelixMode mode = static_cast<HelixMode>(Mode.getValue());
|
||||
if (mode == HelixMode::pitch_height_angle) {
|
||||
@@ -268,6 +275,8 @@ App::DocumentObjectExecReturn* Helix::execute()
|
||||
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Error: Result has multiple solids"));
|
||||
}
|
||||
|
||||
// store shape before refinement
|
||||
this->rawShape = result;
|
||||
Shape.setValue(getSolid(result));
|
||||
return App::DocumentObject::StdReturn;
|
||||
}
|
||||
@@ -290,6 +299,8 @@ App::DocumentObjectExecReturn* Helix::execute()
|
||||
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Error: Result has multiple solids"));
|
||||
}
|
||||
|
||||
// store shape before refinement
|
||||
this->rawShape = boolOp;
|
||||
boolOp = refineShapeIfActive(boolOp, RefineErrorPolicy::Warn);
|
||||
Shape.setValue(getSolid(boolOp));
|
||||
}
|
||||
@@ -319,6 +330,8 @@ App::DocumentObjectExecReturn* Helix::execute()
|
||||
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Error: Result has multiple solids"));
|
||||
}
|
||||
|
||||
// store shape before refinement
|
||||
this->rawShape = boolOp;
|
||||
boolOp = refineShapeIfActive(boolOp, RefineErrorPolicy::Warn);
|
||||
Shape.setValue(getSolid(boolOp));
|
||||
}
|
||||
|
||||
@@ -112,6 +112,12 @@ Loft::getSectionShape(const char *name,
|
||||
|
||||
App::DocumentObjectExecReturn *Loft::execute()
|
||||
{
|
||||
if (onlyHasToRefine()){
|
||||
TopoShape result = refineShapeIfActive(rawShape);
|
||||
Shape.setValue(result);
|
||||
return App::DocumentObject::StdReturn;
|
||||
}
|
||||
|
||||
std::vector<TopoShape> wires;
|
||||
try {
|
||||
wires = getSectionShape("Profile", Profile.getValue(), Profile.getSubValues());
|
||||
@@ -257,6 +263,8 @@ App::DocumentObjectExecReturn *Loft::execute()
|
||||
if (boolOp.isNull())
|
||||
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Resulting shape is not a solid"));
|
||||
|
||||
// store shape before refinement
|
||||
this->rawShape = boolOp;
|
||||
boolOp = refineShapeIfActive(boolOp);
|
||||
boolOp = getSolid(boolOp);
|
||||
if (!isSingleSolidRuleSatisfied(boolOp.getShape())) {
|
||||
|
||||
@@ -104,6 +104,12 @@ short Pipe::mustExecute() const
|
||||
|
||||
App::DocumentObjectExecReturn *Pipe::execute()
|
||||
{
|
||||
if (onlyHasToRefine()){
|
||||
TopoShape result = refineShapeIfActive(rawShape);
|
||||
Shape.setValue(result);
|
||||
return App::DocumentObject::StdReturn;
|
||||
}
|
||||
|
||||
auto getSectionShape = [](App::DocumentObject* feature,
|
||||
const std::vector<std::string>& subs) -> TopoDS_Shape {
|
||||
if (!feature || !feature->isDerivedFrom(Part::Feature::getClassTypeId()))
|
||||
@@ -380,6 +386,8 @@ App::DocumentObjectExecReturn *Pipe::execute()
|
||||
return new App::DocumentObjectExecReturn(
|
||||
QT_TRANSLATE_NOOP("Exception", "Pipe: There is nothing to subtract from"));
|
||||
|
||||
// store shape before refinement
|
||||
this->rawShape = result;
|
||||
auto ts_result = refineShapeIfActive(result);
|
||||
Shape.setValue(getSolid(ts_result));
|
||||
return App::DocumentObject::StdReturn;
|
||||
@@ -402,6 +410,8 @@ App::DocumentObjectExecReturn *Pipe::execute()
|
||||
"Result has multiple solids: that is not currently supported."));
|
||||
}
|
||||
|
||||
// store shape before refinement
|
||||
this->rawShape = boolOp;
|
||||
boolOp = refineShapeIfActive(boolOp);
|
||||
Shape.setValue(getSolid(boolOp));
|
||||
}
|
||||
@@ -422,6 +432,8 @@ App::DocumentObjectExecReturn *Pipe::execute()
|
||||
"Result has multiple solids: that is not currently supported."));
|
||||
}
|
||||
|
||||
// store shape before refinement
|
||||
this->rawShape = boolOp;
|
||||
boolOp = refineShapeIfActive(boolOp);
|
||||
Shape.setValue(getSolid(boolOp));
|
||||
}
|
||||
|
||||
@@ -68,6 +68,12 @@ FeaturePrimitive::FeaturePrimitive()
|
||||
|
||||
App::DocumentObjectExecReturn* FeaturePrimitive::execute(const TopoDS_Shape& primitive)
|
||||
{
|
||||
if (onlyHasToRefine()){
|
||||
TopoShape result = refineShapeIfActive(rawShape);
|
||||
Shape.setValue(result);
|
||||
return App::DocumentObject::StdReturn;
|
||||
}
|
||||
|
||||
try {
|
||||
//transform the primitive in the correct coordinance
|
||||
FeatureAddSub::execute();
|
||||
@@ -126,6 +132,9 @@ App::DocumentObjectExecReturn* FeaturePrimitive::execute(const TopoDS_Shape& pri
|
||||
return new App::DocumentObjectExecReturn(
|
||||
QT_TRANSLATE_NOOP("Exception", "Resulting shape is not a solid"));
|
||||
}
|
||||
// store shape before refinement
|
||||
this->rawShape = boolOp;
|
||||
|
||||
if (solidBoolOp == base){
|
||||
//solidBoolOp is misplaced but boolOp is ok
|
||||
Shape.setValue(boolOp);
|
||||
|
||||
@@ -80,6 +80,12 @@ short Revolution::mustExecute() const
|
||||
|
||||
App::DocumentObjectExecReturn* Revolution::execute()
|
||||
{
|
||||
if (onlyHasToRefine()){
|
||||
TopoShape result = refineShapeIfActive(rawShape);
|
||||
Shape.setValue(result);
|
||||
return App::DocumentObject::StdReturn;
|
||||
}
|
||||
|
||||
// Validate parameters
|
||||
// All angles are in radians unless explicitly stated
|
||||
double angleDeg = Angle.getValue();
|
||||
@@ -213,12 +219,16 @@ App::DocumentObjectExecReturn* Revolution::execute()
|
||||
}
|
||||
|
||||
if (!result.isNull()) {
|
||||
// store shape before refinement
|
||||
this->rawShape = result;
|
||||
result = refineShapeIfActive(result);
|
||||
// set the additive shape property for later usage in e.g. pattern
|
||||
this->AddSubShape.setValue(result);
|
||||
|
||||
if (!base.isNull()) {
|
||||
result = result.makeElementFuse(base);
|
||||
// store shape before refinement
|
||||
this->rawShape = result;
|
||||
result = refineShapeIfActive(result);
|
||||
}
|
||||
this->Shape.setValue(getSolid(result));
|
||||
|
||||
@@ -65,6 +65,12 @@ int16_t Thickness::mustExecute() const {
|
||||
}
|
||||
|
||||
App::DocumentObjectExecReturn *Thickness::execute() {
|
||||
if (onlyHasToRefine()){
|
||||
TopoShape result = refineShapeIfActive(rawShape);
|
||||
Shape.setValue(result);
|
||||
return App::DocumentObject::StdReturn;
|
||||
}
|
||||
|
||||
// Base shape
|
||||
Part::TopoShape TopShape;
|
||||
try {
|
||||
@@ -164,6 +170,8 @@ App::DocumentObjectExecReturn *Thickness::execute() {
|
||||
} else {
|
||||
result = shapes.front();
|
||||
}
|
||||
// store shape before refinement
|
||||
this->rawShape = result;
|
||||
result = refineShapeIfActive(result);
|
||||
this->Shape.setValue(getSolid(result));
|
||||
return App::DocumentObject::StdReturn;
|
||||
|
||||
Reference in New Issue
Block a user