0000542: request for 'Draft Angle' option for extrusion

git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5359 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d
This commit is contained in:
wmayer 2011-12-29 18:20:59 +00:00
parent fe0767a4b4
commit 60ba9cf5db
6 changed files with 122 additions and 8 deletions

View File

@ -119,6 +119,7 @@ SOURCE_GROUP("Features" FILES ${Features_SRCS})
IF(MSVC) IF(MSVC)
SET_SOURCE_FILES_PROPERTIES(FeatureFillet.cpp PROPERTIES COMPILE_FLAGS "/EHa") SET_SOURCE_FILES_PROPERTIES(FeatureFillet.cpp PROPERTIES COMPILE_FLAGS "/EHa")
SET_SOURCE_FILES_PROPERTIES(FeaturePartBoolean.cpp PROPERTIES COMPILE_FLAGS "/EHa") SET_SOURCE_FILES_PROPERTIES(FeaturePartBoolean.cpp PROPERTIES COMPILE_FLAGS "/EHa")
SET_SOURCE_FILES_PROPERTIES(FeatureExtrusion.cpp PROPERTIES COMPILE_FLAGS "/EHa")
ENDIF(MSVC) ENDIF(MSVC)
SET(Properties_SRCS SET(Properties_SRCS

View File

@ -23,10 +23,23 @@
#include "PreCompiled.h" #include "PreCompiled.h"
#ifndef _PreComp_ #ifndef _PreComp_
# include <cmath>
# include <gp_Trsf.hxx>
# include <BRepOffsetAPI_MakeOffset.hxx>
# include <BRepBuilderAPI_MakeFace.hxx>
# include <BRepBuilderAPI_Transform.hxx>
# include <BRepOffsetAPI_ThruSections.hxx>
# include <BRepPrimAPI_MakePrism.hxx>
# include <Precision.hxx>
# include <ShapeFix_Wire.hxx>
# include <TopoDS.hxx>
# include <TopExp_Explorer.hxx>
#endif #endif
#include "FeatureExtrusion.h" #include "FeatureExtrusion.h"
#include <Base/Tools.h>
#include <Base/Exception.h>
using namespace Part; using namespace Part;
@ -38,12 +51,16 @@ Extrusion::Extrusion()
{ {
ADD_PROPERTY(Base,(0)); ADD_PROPERTY(Base,(0));
ADD_PROPERTY(Dir,(Base::Vector3f(0.0f,0.0f,1.0f))); ADD_PROPERTY(Dir,(Base::Vector3f(0.0f,0.0f,1.0f)));
ADD_PROPERTY(Solid,(false));
ADD_PROPERTY(TaperAngle,(0.0f));
} }
short Extrusion::mustExecute() const short Extrusion::mustExecute() const
{ {
if (Base.isTouched() || if (Base.isTouched() ||
Dir.isTouched() ) Dir.isTouched() ||
Solid.isTouched() ||
TaperAngle.isTouched())
return 1; return 1;
return 0; return 0;
} }
@ -59,13 +76,69 @@ App::DocumentObjectExecReturn *Extrusion::execute(void)
Base::Vector3f v = Dir.getValue(); Base::Vector3f v = Dir.getValue();
gp_Vec vec(v.x,v.y,v.z); gp_Vec vec(v.x,v.y,v.z);
float taperAngle = TaperAngle.getValue();
bool makeSolid = Solid.getValue();
try { try {
// Now, let's get the TopoDS_Shape if (std::fabs(taperAngle) >= Precision::Confusion()) {
TopoDS_Shape swept = base->Shape.getShape().makePrism(vec); #if defined(__GNUC__) && defined (FC_OS_LINUX)
if (swept.IsNull()) Base::SignalException se;
return new App::DocumentObjectExecReturn("Resulting shape is null"); #endif
this->Shape.setValue(swept); double distance = std::tan(Base::toRadians(taperAngle)) * vec.Magnitude();
const TopoDS_Shape& shape = base->Shape.getValue();
bool isWire = (shape.ShapeType() == TopAbs_WIRE);
if (!isWire)
return new App::DocumentObjectExecReturn("Only wires supported");
std::list<TopoDS_Wire> wire_list;
BRepOffsetAPI_MakeOffset mkOffset;
#if 1 //OCC_HEX_VERSION < 0x060502
// The input wire may have erorrs in its topology
// and thus may cause a crash in the Perfrom() method
// See also:
// http://www.opencascade.org/org/forum/thread_17640/
// http://www.opencascade.org/org/forum/thread_12012/
ShapeFix_Wire aFix;
aFix.Load(TopoDS::Wire(shape));
aFix.FixReorder();
aFix.FixConnected();
aFix.FixClosed();
mkOffset.AddWire(aFix.Wire());
wire_list.push_back(aFix.Wire());
#else
mkOffset.AddWire(TopoDS::Wire(shape));
#endif
mkOffset.Perform(distance);
gp_Trsf mat;
mat.SetTranslation(vec);
BRepBuilderAPI_Transform mkTransform(mkOffset.Shape(),mat);
wire_list.push_back(TopoDS::Wire(mkTransform.Shape()));
BRepOffsetAPI_ThruSections mkGenerator(makeSolid ? Standard_True : Standard_False, Standard_False);
for (std::list<TopoDS_Wire>::const_iterator it = wire_list.begin(); it != wire_list.end(); ++it) {
const TopoDS_Wire &wire = *it;
mkGenerator.AddWire(wire);
}
mkGenerator.Build();
this->Shape.setValue(mkGenerator.Shape());
}
else {
// Now, let's get the TopoDS_Shape
TopoDS_Shape myShape = base->Shape.getValue();
if (myShape.IsNull())
Standard_Failure::Raise("Cannot extrude empty shape");
if (makeSolid && myShape.ShapeType() == TopAbs_WIRE) {
BRepBuilderAPI_MakeFace mkFace(TopoDS::Wire(myShape));
myShape = mkFace.Face();
}
BRepPrimAPI_MakePrism mkPrism(myShape, vec);
TopoDS_Shape swept = mkPrism.Shape();
if (swept.IsNull())
return new App::DocumentObjectExecReturn("Resulting shape is null");
this->Shape.setValue(swept);
}
return App::DocumentObject::StdReturn; return App::DocumentObject::StdReturn;
} }
catch (Standard_Failure) { catch (Standard_Failure) {

View File

@ -25,6 +25,7 @@
#define PART_FEATUREEXTRUSION_H #define PART_FEATUREEXTRUSION_H
#include <App/PropertyStandard.h> #include <App/PropertyStandard.h>
#include <App/PropertyUnits.h>
#include "PartFeature.h" #include "PartFeature.h"
namespace Part namespace Part
@ -39,6 +40,8 @@ public:
App::PropertyLink Base; App::PropertyLink Base;
App::PropertyVector Dir; App::PropertyVector Dir;
App::PropertyBool Solid;
App::PropertyAngle TaperAngle;
/** @name methods override feature */ /** @name methods override feature */
//@{ //@{

View File

@ -162,6 +162,8 @@ void DlgExtrusion::apply()
double dirX = ui->dirX->value(); double dirX = ui->dirX->value();
double dirY = ui->dirY->value(); double dirY = ui->dirY->value();
double dirZ = ui->dirZ->value(); double dirZ = ui->dirZ->value();
double angle = ui->taperAngle->value();
bool makeSolid = ui->makeSolid->isChecked();
// inspect geometry // inspect geometry
App::DocumentObject* obj = activeDoc->getObject((const char*)shape.toAscii()); App::DocumentObject* obj = activeDoc->getObject((const char*)shape.toAscii());
@ -192,12 +194,16 @@ void DlgExtrusion::apply()
"FreeCAD.getDocument(\"%1\").addObject(\"%2\",\"%3\")\n" "FreeCAD.getDocument(\"%1\").addObject(\"%2\",\"%3\")\n"
"FreeCAD.getDocument(\"%1\").%3.Base = FreeCAD.getDocument(\"%1\").%4\n" "FreeCAD.getDocument(\"%1\").%3.Base = FreeCAD.getDocument(\"%1\").%4\n"
"FreeCAD.getDocument(\"%1\").%3.Dir = (%5,%6,%7)\n" "FreeCAD.getDocument(\"%1\").%3.Dir = (%5,%6,%7)\n"
"FreeCAD.getDocument(\"%1\").%3.Solid = (%8)\n"
"FreeCAD.getDocument(\"%1\").%3.TaperAngle = (%9)\n"
"FreeCADGui.getDocument(\"%1\").%4.Visibility = False\n") "FreeCADGui.getDocument(\"%1\").%4.Visibility = False\n")
.arg(QString::fromAscii(this->document.c_str())) .arg(QString::fromAscii(this->document.c_str()))
.arg(type).arg(name).arg(shape) .arg(type).arg(name).arg(shape)
.arg(dirX*len) .arg(dirX*len)
.arg(dirY*len) .arg(dirY*len)
.arg(dirZ*len); .arg(dirZ*len)
.arg(makeSolid ? QLatin1String("True") : QLatin1String("False"))
.arg(angle);
Gui::Application::Instance->runPythonCode((const char*)code.toAscii()); Gui::Application::Instance->runPythonCode((const char*)code.toAscii());
QByteArray to = name.toAscii(); QByteArray to = name.toAscii();
QByteArray from = shape.toAscii(); QByteArray from = shape.toAscii();

View File

@ -68,7 +68,7 @@ public:
void clicked(int); void clicked(int);
virtual QDialogButtonBox::StandardButtons getStandardButtons() const virtual QDialogButtonBox::StandardButtons getStandardButtons() const
{ return QDialogButtonBox::Apply | QDialogButtonBox::Cancel; } { return QDialogButtonBox::Apply | QDialogButtonBox::Close; }
private: private:
DlgExtrusion* widget; DlgExtrusion* widget;

View File

@ -181,6 +181,37 @@
</widget> </widget>
</item> </item>
<item row="1" column="0"> <item row="1" column="0">
<widget class="QCheckBox" name="makeSolid">
<property name="text">
<string>Create solid</string>
</property>
</widget>
</item>
<item row="2" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Taper outward angle</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="taperAngle">
<property name="minimum">
<double>-180.000000000000000</double>
</property>
<property name="maximum">
<double>180.000000000000000</double>
</property>
<property name="singleStep">
<double>5.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="0">
<widget class="QTreeWidget" name="treeWidget"> <widget class="QTreeWidget" name="treeWidget">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding">