diff --git a/src/Mod/PartDesign/App/FeatureChamfer.cpp b/src/Mod/PartDesign/App/FeatureChamfer.cpp
index 77d3bb10e..2c0685abf 100644
--- a/src/Mod/PartDesign/App/FeatureChamfer.cpp
+++ b/src/Mod/PartDesign/App/FeatureChamfer.cpp
@@ -35,6 +35,7 @@
#endif
#include
+#include
#include
#include
@@ -66,17 +67,12 @@ App::DocumentObjectExecReturn *Chamfer::execute(void)
{
// 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
- App::DocumentObject* link = BaseFeature.getValue();
- if (!link)
- link = Base.getValue(); // For legacy features
- if (!link)
- return new App::DocumentObjectExecReturn("No object linked");
- if (!link->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()))
- return new App::DocumentObjectExecReturn("Linked object is not a Part object");
- Part::Feature *base = static_cast(link);
- const Part::TopoShape& TopShape = base->Shape.getShape();
- if (TopShape._Shape.IsNull())
- return new App::DocumentObjectExecReturn("Cannot chamfer invalid shape");
+ Part::TopoShape TopShape;
+ try {
+ TopShape = getBaseShape();
+ } catch (Base::Exception& e) {
+ return new App::DocumentObjectExecReturn(e.what());
+ }
const std::vector& SubVals = Base.getSubValuesStartsWith("Edge");
if (SubVals.size() == 0)
diff --git a/src/Mod/PartDesign/App/FeatureChamfer.cpp.orig b/src/Mod/PartDesign/App/FeatureChamfer.cpp.orig
new file mode 100644
index 000000000..063bcc439
--- /dev/null
+++ b/src/Mod/PartDesign/App/FeatureChamfer.cpp.orig
@@ -0,0 +1,153 @@
+/***************************************************************************
+ * Copyright (c) 2010 Juergen Riegel *
+ * *
+ * This file is part of the FreeCAD CAx development system. *
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Library General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2 of the License, or (at your option) any later version. *
+ * *
+ * This library is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU Library General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Library General Public *
+ * License along with this library; see the file COPYING.LIB. If not, *
+ * write to the Free Software Foundation, Inc., 59 Temple Place, *
+ * Suite 330, Boston, MA 02111-1307, USA *
+ * *
+ ***************************************************************************/
+
+
+#include "PreCompiled.h"
+#ifndef _PreComp_
+# include
+# include
+# include
+# include
+# include
+# include
+# include
+#endif
+
+<<<<<<< 50287516b47694e57429cc98f6d5596a06a635d6
+#include
+#include
+=======
+#include
+>>>>>>> Some code unification for DressUp features
+#include
+
+#include "FeatureChamfer.h"
+
+
+using namespace PartDesign;
+
+
+PROPERTY_SOURCE(PartDesign::Chamfer, PartDesign::DressUp)
+
+const App::PropertyQuantityConstraint::Constraints floatSize = {0.0,FLT_MAX,0.1};
+
+Chamfer::Chamfer()
+{
+ ADD_PROPERTY(Size,(1.0));
+ Size.setUnit(Base::Unit::Length);
+ Size.setConstraints(&floatSize);
+}
+
+short Chamfer::mustExecute() const
+{
+ if (Placement.isTouched() || Size.isTouched())
+ return 1;
+ return DressUp::mustExecute();
+}
+
+App::DocumentObjectExecReturn *Chamfer::execute(void)
+{
+ // 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;
+ try {
+ TopShape = getBaseShape();
+ } catch (Base::Exception& e) {
+ return new App::DocumentObjectExecReturn(e.what());
+ }
+
+ const std::vector& SubVals = Base.getSubValuesStartsWith("Edge");
+ if (SubVals.size() == 0)
+ return new App::DocumentObjectExecReturn("No edges specified");
+
+ double size = Size.getValue();
+
+ this->positionByBaseFeature();
+ // create an untransformed copy of the basefeature shape
+ Part::TopoShape baseShape(TopShape);
+ baseShape.setTransform(Base::Matrix4D());
+ try {
+ BRepFilletAPI_MakeChamfer mkChamfer(baseShape._Shape);
+
+ TopTools_IndexedMapOfShape mapOfEdges;
+ TopTools_IndexedDataMapOfShapeListOfShape mapEdgeFace;
+ TopExp::MapShapesAndAncestors(baseShape._Shape, TopAbs_EDGE, TopAbs_FACE, mapEdgeFace);
+ TopExp::MapShapes(baseShape._Shape, TopAbs_EDGE, mapOfEdges);
+
+ for (std::vector::const_iterator it=SubVals.begin(); it != SubVals.end(); ++it) {
+ TopoDS_Edge edge = TopoDS::Edge(baseShape.getSubShape(it->c_str()));
+ const TopoDS_Face& face = TopoDS::Face(mapEdgeFace.FindFromKey(edge).First());
+ mkChamfer.Add(size, edge, face);
+ }
+
+ mkChamfer.Build();
+ if (!mkChamfer.IsDone())
+ return new App::DocumentObjectExecReturn("Failed to create chamfer");
+
+ TopoDS_Shape shape = mkChamfer.Shape();
+ if (shape.IsNull())
+ return new App::DocumentObjectExecReturn("Resulting shape is null");
+
+ this->Shape.setValue(shape);
+ return App::DocumentObject::StdReturn;
+ }
+ catch (Standard_Failure) {
+ Handle_Standard_Failure e = Standard_Failure::Caught();
+ return new App::DocumentObjectExecReturn(e->GetMessageString());
+ }
+}
+
+void Chamfer::Restore(Base::XMLReader &reader)
+{
+ reader.readElement("Properties");
+ int Cnt = reader.getAttributeAsInteger("Count");
+
+ for (int i=0 ;igetTypeId().getName(), TypeName) == 0) {
+ prop->Restore(reader);
+ }
+ else if (prop && strcmp(TypeName,"App::PropertyFloatConstraint") == 0 &&
+ strcmp(prop->getTypeId().getName(), "App::PropertyQuantityConstraint") == 0) {
+ App::PropertyFloatConstraint p;
+ p.Restore(reader);
+ static_cast(prop)->setValue(p.getValue());
+ }
+ }
+ catch (const Base::XMLParseException&) {
+ throw; // re-throw
+ }
+ catch (const Base::Exception &e) {
+ Base::Console().Error("%s\n", e.what());
+ }
+ catch (const std::exception &e) {
+ Base::Console().Error("%s\n", e.what());
+ }
+ reader.readEndElement("Property");
+ }
+ reader.readEndElement("Properties");
+}
diff --git a/src/Mod/PartDesign/App/FeatureDraft.cpp b/src/Mod/PartDesign/App/FeatureDraft.cpp
index f3e8a686f..ca46e02ab 100644
--- a/src/Mod/PartDesign/App/FeatureDraft.cpp
+++ b/src/Mod/PartDesign/App/FeatureDraft.cpp
@@ -49,6 +49,7 @@
#include
#include
+#include
#include
#include "FeatureDraft.h"
@@ -90,17 +91,12 @@ App::DocumentObjectExecReturn *Draft::execute(void)
{
// Get parameters
// Base shape
- App::DocumentObject* link = BaseFeature.getValue();
- if (!link)
- link = Base.getValue(); // For legacy features
- if (!link)
- return new App::DocumentObjectExecReturn("No object linked");
- if (!link->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()))
- return new App::DocumentObjectExecReturn("Linked object is not a Part object");
- Part::Feature *base = static_cast(link);
- const Part::TopoShape& TopShape = base->Shape.getShape();
- if (TopShape._Shape.IsNull())
- return new App::DocumentObjectExecReturn("Cannot draft invalid shape");
+ Part::TopoShape TopShape;
+ try {
+ TopShape = getBaseShape();
+ } catch (Base::Exception& e) {
+ return new App::DocumentObjectExecReturn(e.what());
+ }
// Faces where draft should be applied
// Note: Cannot be const reference currently because of BRepOffsetAPI_DraftAngle::Remove() bug, see below
diff --git a/src/Mod/PartDesign/App/FeatureDressUp.cpp b/src/Mod/PartDesign/App/FeatureDressUp.cpp
index 8d8a42a64..95fc0467f 100644
--- a/src/Mod/PartDesign/App/FeatureDressUp.cpp
+++ b/src/Mod/PartDesign/App/FeatureDressUp.cpp
@@ -27,6 +27,7 @@
#include "FeatureDressUp.h"
+#include
using namespace PartDesign;
@@ -57,6 +58,22 @@ void DressUp::positionByBaseFeature(void)
this->Placement.setValue(base->Placement.getValue());
}
+Part::TopoShape DressUp::getBaseShape()
+{
+ App::DocumentObject* link = BaseFeature.getValue();
+ if (!link)
+ link = this->Base.getValue(); // For legacy features
+ if (!link)
+ throw Base::Exception("No object linked");
+ if (!link->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()))
+ throw Base::Exception("Linked object is not a Part object");
+ Part::Feature* base = static_cast(link);
+ const Part::TopoShape& shape = base->Shape.getShape();
+ if (shape._Shape.IsNull())
+ throw Base::Exception("Cannot draft invalid shape");
+ return shape;
+}
+
void DressUp::onChanged(const App::Property* prop)
{
if (prop == &BaseFeature) {
diff --git a/src/Mod/PartDesign/App/FeatureDressUp.h b/src/Mod/PartDesign/App/FeatureDressUp.h
index 81e8a556d..af143e8fc 100644
--- a/src/Mod/PartDesign/App/FeatureDressUp.h
+++ b/src/Mod/PartDesign/App/FeatureDressUp.h
@@ -42,6 +42,7 @@ public:
short mustExecute() const;
/// updates the Placement property from the Placement of the BaseFeature
void positionByBaseFeature(void);
+ Part::TopoShape getBaseShape();
protected:
void onChanged(const App::Property* prop);
diff --git a/src/Mod/PartDesign/App/FeatureFillet.cpp b/src/Mod/PartDesign/App/FeatureFillet.cpp
index d0ba06222..0c82686df 100644
--- a/src/Mod/PartDesign/App/FeatureFillet.cpp
+++ b/src/Mod/PartDesign/App/FeatureFillet.cpp
@@ -32,6 +32,7 @@
#endif
#include
+#include
#include
#include
@@ -61,17 +62,12 @@ short Fillet::mustExecute() const
App::DocumentObjectExecReturn *Fillet::execute(void)
{
- App::DocumentObject* link = BaseFeature.getValue();
- if (!link)
- link = Base.getValue(); // For legacy features
- if (!link)
- return new App::DocumentObjectExecReturn("No object linked");
- if (!link->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()))
- return new App::DocumentObjectExecReturn("Linked object is not a Part object");
- Part::Feature *base = static_cast(link);
- const Part::TopoShape& TopShape = base->Shape.getShape();
- if (TopShape._Shape.IsNull())
- return new App::DocumentObjectExecReturn("Cannot fillet invalid shape");
+ Part::TopoShape TopShape;
+ try {
+ TopShape = getBaseShape();
+ } catch (Base::Exception& e) {
+ return new App::DocumentObjectExecReturn(e.what());
+ }
const std::vector& SubVals = Base.getSubValuesStartsWith("Edge");
if (SubVals.size() == 0)
diff --git a/src/Mod/PartDesign/App/FeatureFillet.cpp.orig b/src/Mod/PartDesign/App/FeatureFillet.cpp.orig
new file mode 100644
index 000000000..7e4324a6f
--- /dev/null
+++ b/src/Mod/PartDesign/App/FeatureFillet.cpp.orig
@@ -0,0 +1,143 @@
+/***************************************************************************
+ * Copyright (c) 2008 Werner Mayer *
+ * *
+ * This file is part of the FreeCAD CAx development system. *
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Library General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2 of the License, or (at your option) any later version. *
+ * *
+ * This library is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU Library General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Library General Public *
+ * License along with this library; see the file COPYING.LIB. If not, *
+ * write to the Free Software Foundation, Inc., 59 Temple Place, *
+ * Suite 330, Boston, MA 02111-1307, USA *
+ * *
+ ***************************************************************************/
+
+
+#include "PreCompiled.h"
+#ifndef _PreComp_
+# include
+# include
+# include
+# include
+#endif
+
+<<<<<<< 50287516b47694e57429cc98f6d5596a06a635d6
+#include
+#include
+=======
+#include
+>>>>>>> Some code unification for DressUp features
+#include
+
+#include "FeatureFillet.h"
+
+
+using namespace PartDesign;
+
+
+PROPERTY_SOURCE(PartDesign::Fillet, PartDesign::DressUp)
+
+const App::PropertyQuantityConstraint::Constraints floatRadius = {0.0,FLT_MAX,0.1};
+
+Fillet::Fillet()
+{
+ ADD_PROPERTY(Radius,(1.0));
+ Radius.setUnit(Base::Unit::Length);
+ Radius.setConstraints(&floatRadius);
+}
+
+short Fillet::mustExecute() const
+{
+ if (Placement.isTouched() || Radius.isTouched())
+ return 1;
+ return DressUp::mustExecute();
+}
+
+App::DocumentObjectExecReturn *Fillet::execute(void)
+{
+ Part::TopoShape TopShape;
+ try {
+ TopShape = getBaseShape();
+ } catch (Base::Exception& e) {
+ return new App::DocumentObjectExecReturn(e.what());
+ }
+
+ const std::vector& SubVals = Base.getSubValuesStartsWith("Edge");
+ if (SubVals.size() == 0)
+ return new App::DocumentObjectExecReturn("No edges specified");
+
+ double radius = Radius.getValue();
+
+ this->positionByBaseFeature();
+
+ // create an untransformed copy of the base shape
+ Part::TopoShape baseShape(TopShape);
+ baseShape.setTransform(Base::Matrix4D());
+ try {
+ BRepFilletAPI_MakeFillet mkFillet(baseShape._Shape);
+
+ for (std::vector::const_iterator it=SubVals.begin(); it != SubVals.end(); ++it) {
+ TopoDS_Edge edge = TopoDS::Edge(baseShape.getSubShape(it->c_str()));
+ mkFillet.Add(radius, edge);
+ }
+
+ mkFillet.Build();
+ if (!mkFillet.IsDone())
+ return new App::DocumentObjectExecReturn("Failed to create fillet");
+
+ TopoDS_Shape shape = mkFillet.Shape();
+ if (shape.IsNull())
+ return new App::DocumentObjectExecReturn("Resulting shape is null");
+
+ this->Shape.setValue(shape);
+ return App::DocumentObject::StdReturn;
+ }
+ catch (Standard_Failure) {
+ Handle_Standard_Failure e = Standard_Failure::Caught();
+ return new App::DocumentObjectExecReturn(e->GetMessageString());
+ }
+}
+
+void Fillet::Restore(Base::XMLReader &reader)
+{
+ reader.readElement("Properties");
+ int Cnt = reader.getAttributeAsInteger("Count");
+
+ for (int i=0 ;igetTypeId().getName(), TypeName) == 0) {
+ prop->Restore(reader);
+ }
+ else if (prop && strcmp(TypeName,"App::PropertyFloatConstraint") == 0 &&
+ strcmp(prop->getTypeId().getName(), "App::PropertyQuantityConstraint") == 0) {
+ App::PropertyFloatConstraint p;
+ p.Restore(reader);
+ static_cast(prop)->setValue(p.getValue());
+ }
+ }
+ catch (const Base::XMLParseException&) {
+ throw; // re-throw
+ }
+ catch (const Base::Exception &e) {
+ Base::Console().Error("%s\n", e.what());
+ }
+ catch (const std::exception &e) {
+ Base::Console().Error("%s\n", e.what());
+ }
+ reader.readEndElement("Property");
+ }
+ reader.readEndElement("Properties");
+}