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:
parent
fe0767a4b4
commit
60ba9cf5db
|
@ -119,6 +119,7 @@ SOURCE_GROUP("Features" FILES ${Features_SRCS})
|
|||
IF(MSVC)
|
||||
SET_SOURCE_FILES_PROPERTIES(FeatureFillet.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)
|
||||
|
||||
SET(Properties_SRCS
|
||||
|
|
|
@ -23,10 +23,23 @@
|
|||
|
||||
#include "PreCompiled.h"
|
||||
#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
|
||||
|
||||
|
||||
#include "FeatureExtrusion.h"
|
||||
#include <Base/Tools.h>
|
||||
#include <Base/Exception.h>
|
||||
|
||||
|
||||
using namespace Part;
|
||||
|
@ -38,12 +51,16 @@ Extrusion::Extrusion()
|
|||
{
|
||||
ADD_PROPERTY(Base,(0));
|
||||
ADD_PROPERTY(Dir,(Base::Vector3f(0.0f,0.0f,1.0f)));
|
||||
ADD_PROPERTY(Solid,(false));
|
||||
ADD_PROPERTY(TaperAngle,(0.0f));
|
||||
}
|
||||
|
||||
short Extrusion::mustExecute() const
|
||||
{
|
||||
if (Base.isTouched() ||
|
||||
Dir.isTouched() )
|
||||
Dir.isTouched() ||
|
||||
Solid.isTouched() ||
|
||||
TaperAngle.isTouched())
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
@ -59,13 +76,69 @@ App::DocumentObjectExecReturn *Extrusion::execute(void)
|
|||
|
||||
Base::Vector3f v = Dir.getValue();
|
||||
gp_Vec vec(v.x,v.y,v.z);
|
||||
float taperAngle = TaperAngle.getValue();
|
||||
bool makeSolid = Solid.getValue();
|
||||
|
||||
try {
|
||||
if (std::fabs(taperAngle) >= Precision::Confusion()) {
|
||||
#if defined(__GNUC__) && defined (FC_OS_LINUX)
|
||||
Base::SignalException se;
|
||||
#endif
|
||||
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 swept = base->Shape.getShape().makePrism(vec);
|
||||
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;
|
||||
}
|
||||
catch (Standard_Failure) {
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#define PART_FEATUREEXTRUSION_H
|
||||
|
||||
#include <App/PropertyStandard.h>
|
||||
#include <App/PropertyUnits.h>
|
||||
#include "PartFeature.h"
|
||||
|
||||
namespace Part
|
||||
|
@ -39,6 +40,8 @@ public:
|
|||
|
||||
App::PropertyLink Base;
|
||||
App::PropertyVector Dir;
|
||||
App::PropertyBool Solid;
|
||||
App::PropertyAngle TaperAngle;
|
||||
|
||||
/** @name methods override feature */
|
||||
//@{
|
||||
|
|
|
@ -162,6 +162,8 @@ void DlgExtrusion::apply()
|
|||
double dirX = ui->dirX->value();
|
||||
double dirY = ui->dirY->value();
|
||||
double dirZ = ui->dirZ->value();
|
||||
double angle = ui->taperAngle->value();
|
||||
bool makeSolid = ui->makeSolid->isChecked();
|
||||
|
||||
// inspect geometry
|
||||
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\").%3.Base = FreeCAD.getDocument(\"%1\").%4\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")
|
||||
.arg(QString::fromAscii(this->document.c_str()))
|
||||
.arg(type).arg(name).arg(shape)
|
||||
.arg(dirX*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());
|
||||
QByteArray to = name.toAscii();
|
||||
QByteArray from = shape.toAscii();
|
||||
|
|
|
@ -68,7 +68,7 @@ public:
|
|||
void clicked(int);
|
||||
|
||||
virtual QDialogButtonBox::StandardButtons getStandardButtons() const
|
||||
{ return QDialogButtonBox::Apply | QDialogButtonBox::Cancel; }
|
||||
{ return QDialogButtonBox::Apply | QDialogButtonBox::Close; }
|
||||
|
||||
private:
|
||||
DlgExtrusion* widget;
|
||||
|
|
|
@ -181,6 +181,37 @@
|
|||
</widget>
|
||||
</item>
|
||||
<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">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
|
|
Loading…
Reference in New Issue
Block a user