add options for pipe tool
This commit is contained in:
@@ -244,9 +244,9 @@ void Plane::onChanged(const App::Property *prop)
|
||||
normal = new Base::Vector3d;
|
||||
if (strcmp(p->PlaneType.getValue(), App::Part::BaseplaneTypes[0]) == 0)
|
||||
*normal = Base::Vector3d(0,0,1);
|
||||
else if (strcmp(p->PlaneType.getValue(), App::Part::BaseplaneTypes[2]) == 0)
|
||||
*normal = Base::Vector3d(0,1,0);
|
||||
else if (strcmp(p->PlaneType.getValue(), App::Part::BaseplaneTypes[1]) == 0)
|
||||
*normal = Base::Vector3d(0,1,0);
|
||||
else if (strcmp(p->PlaneType.getValue(), App::Part::BaseplaneTypes[2]) == 0)
|
||||
*normal = Base::Vector3d(1,0,0);
|
||||
} else if (refs[i]->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) {
|
||||
Part::Feature* feature = static_cast<Part::Feature*>(refs[i]);
|
||||
|
||||
@@ -41,6 +41,14 @@
|
||||
# include <BRepAdaptor_Surface.hxx>
|
||||
# include <gp_Pln.hxx>
|
||||
# include <GeomAPI_ProjectPointOnSurf.hxx>
|
||||
#include <BRepOffsetAPI_MakePipeShell.hxx>
|
||||
#include <BRepBuilderAPI_MakeWire.hxx>
|
||||
#include <ShapeAnalysis_FreeBounds.hxx>
|
||||
#include <TopTools_HSequenceOfShape.hxx>
|
||||
#include <TopTools_ListIteratorOfListOfShape.hxx>
|
||||
#include <TopTools_IndexedMapOfShape.hxx>
|
||||
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
|
||||
#include <TopExp.hxx>
|
||||
#endif
|
||||
|
||||
#include <Base/Exception.h>
|
||||
@@ -57,7 +65,8 @@ using namespace PartDesign;
|
||||
|
||||
const char* Pipe::TypeEnums[] = {"FullPath","UpToFace",NULL};
|
||||
const char* Pipe::TransitionEnums[] = {"Transformed","Right corner", "Round corner",NULL};
|
||||
const char* Pipe::ModeEnums[] = {"Standart", "Fixed", "Binormal", "Frenet", NULL};
|
||||
const char* Pipe::ModeEnums[] = {"Standart", "Fixed", "Binormal", "Frenet", "Auxillery", NULL};
|
||||
const char* Pipe::TransformEnums[] = {"Constant", "Multisection", "Auxillery", NULL};
|
||||
|
||||
|
||||
PROPERTY_SOURCE(PartDesign::Pipe, PartDesign::SketchBased)
|
||||
@@ -66,10 +75,18 @@ Pipe::Pipe()
|
||||
{
|
||||
ADD_PROPERTY_TYPE(Sections,(0),"Sweep",App::Prop_None,"List of sections");
|
||||
Sections.setSize(0);
|
||||
ADD_PROPERTY_TYPE(Spine,(0,0),"Sweep",App::Prop_None,"Path to sweep along");
|
||||
ADD_PROPERTY_TYPE(Mode,(long(1)),"Sweep",App::Prop_None,"Profile mode");
|
||||
ADD_PROPERTY_TYPE(Transition,(long(1)),"Sweep",App::Prop_None,"Transition mode");
|
||||
ADD_PROPERTY_TYPE(Spine,(0),"Sweep",App::Prop_None,"Path to sweep along");
|
||||
ADD_PROPERTY_TYPE(SpineTangent,(false),"Sweep",App::Prop_None,"Include tangent edges into path");
|
||||
ADD_PROPERTY_TYPE(AuxillerySpine,(0),"Sweep",App::Prop_None,"Secondary path to orient sweep");
|
||||
ADD_PROPERTY_TYPE(AuxillerySpineTangent,(false),"Sweep",App::Prop_None,"Include tangent edges into secondary path");
|
||||
ADD_PROPERTY_TYPE(AuxilleryCurvelinear, (true), "Sweep", App::Prop_None,"Calculate normal between equidistant points on both spines");
|
||||
ADD_PROPERTY_TYPE(Mode,(long(0)),"Sweep",App::Prop_None,"Profile mode");
|
||||
ADD_PROPERTY_TYPE(Binormal,(Base::Vector3d()),"Sweep",App::Prop_None,"Binormal vector for coresponding 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");
|
||||
Mode.setEnums(ModeEnums);
|
||||
Transition.setEnums(TransitionEnums);
|
||||
Transformation.setEnums(TransformEnums);
|
||||
}
|
||||
|
||||
short Pipe::mustExecute() const
|
||||
@@ -87,10 +104,234 @@ short Pipe::mustExecute() const
|
||||
|
||||
App::DocumentObjectExecReturn *Pipe::execute(void)
|
||||
{
|
||||
|
||||
Part::Part2DObject* sketch = 0;
|
||||
std::vector<TopoDS_Wire> wires;
|
||||
try {
|
||||
sketch = getVerifiedSketch();
|
||||
wires = getSketchWires();
|
||||
} catch (const Base::Exception& e) {
|
||||
return new App::DocumentObjectExecReturn(e.what());
|
||||
}
|
||||
|
||||
TopoDS_Shape sketchshape = makeFace(wires);
|
||||
if (sketchshape.IsNull())
|
||||
return new App::DocumentObjectExecReturn("Pipe: Creating a face from sketch failed");
|
||||
|
||||
// if the Base property has a valid shape, fuse the pipe into it
|
||||
TopoDS_Shape base;
|
||||
try {
|
||||
base = getBaseShape();
|
||||
} catch (const Base::Exception&) {
|
||||
try {
|
||||
// fall back to support (for legacy features)
|
||||
base = getSupportShape();
|
||||
} catch (const Base::Exception&) {
|
||||
// ignore, because support isn't mandatory
|
||||
base = TopoDS_Shape();
|
||||
}
|
||||
}
|
||||
|
||||
return SketchBased::execute();
|
||||
try {
|
||||
App::DocumentObject* spine = Spine.getValue();
|
||||
if (!(spine && spine->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())))
|
||||
return new App::DocumentObjectExecReturn("No spine linked.");
|
||||
std::vector<std::string> subedge = Spine.getSubValues();
|
||||
|
||||
TopoDS_Shape path;
|
||||
const Part::TopoShape& shape = static_cast<Part::Feature*>(spine)->Shape.getValue();
|
||||
buildPipePath(shape, subedge, path);
|
||||
|
||||
BRepOffsetAPI_MakePipeShell mkPipeShell(TopoDS::Wire(path));
|
||||
mkPipeShell.SetTolerance(Precision::Confusion());
|
||||
//mkPipeShell.SetMode(isFrenet);
|
||||
switch(Transition.getValue()) {
|
||||
case 0:
|
||||
mkPipeShell.SetTransitionMode(BRepBuilderAPI_Transformed);
|
||||
break;
|
||||
case 1:
|
||||
mkPipeShell.SetTransitionMode(BRepBuilderAPI_RightCorner);
|
||||
break;
|
||||
case 2:
|
||||
mkPipeShell.SetTransitionMode(BRepBuilderAPI_RoundCorner);
|
||||
break;
|
||||
}
|
||||
|
||||
bool auxillery = false;
|
||||
const Base::Vector3d& bVec = Binormal.getValue();
|
||||
switch(Mode.getValue()) {
|
||||
case 1:
|
||||
mkPipeShell.SetMode(gp_Ax2(gp_Pnt(0,0,0), gp_Dir(0,0,1), gp_Dir(1,0,0)));
|
||||
break;
|
||||
case 2:
|
||||
mkPipeShell.SetMode(gp_Dir(bVec.x,bVec.y,bVec.z));
|
||||
break;
|
||||
case 3:
|
||||
mkPipeShell.SetMode(true);
|
||||
break;
|
||||
case 4:
|
||||
auxillery = true;
|
||||
}
|
||||
|
||||
if(auxillery) {
|
||||
TopoDS_Shape auxpath;
|
||||
App::DocumentObject* auxspine = AuxillerySpine.getValue();
|
||||
if (!(auxspine && auxspine->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())))
|
||||
return new App::DocumentObjectExecReturn("No auxillery spine linked.");
|
||||
std::vector<std::string> auxsubedge = AuxillerySpine.getSubValues();
|
||||
|
||||
TopoDS_Shape path;
|
||||
const Part::TopoShape& auxshape = static_cast<Part::Feature*>(auxspine)->Shape.getValue();
|
||||
buildPipePath(auxshape, auxsubedge, auxpath);
|
||||
|
||||
if(Transformation.getValue()!=2)
|
||||
mkPipeShell.SetMode(TopoDS::Wire(auxshape._Shape), AuxilleryCurvelinear.getValue());
|
||||
else
|
||||
mkPipeShell.SetMode(TopoDS::Wire(auxshape._Shape), AuxilleryCurvelinear.getValue(), BRepFill_ContactOnBorder);
|
||||
}
|
||||
|
||||
// TopTools_ListIteratorOfListOfShape iter;
|
||||
// for (iter.Initialize(profiles); iter.More(); iter.Next()) {
|
||||
// mkPipeShell.Add(TopoDS_Shape(iter.Value()));
|
||||
// }
|
||||
|
||||
mkPipeShell.Add(wires.front());
|
||||
|
||||
if (!mkPipeShell.IsReady())
|
||||
Standard_Failure::Raise("shape is not ready to build");
|
||||
mkPipeShell.Build();
|
||||
mkPipeShell.MakeSolid();
|
||||
/*
|
||||
TopTools_ListOfShape sim;
|
||||
mkPipeShell.Simulate(5, sim);
|
||||
BRep_Builder builder;
|
||||
TopoDS_Compound Comp;
|
||||
builder.MakeCompound(Comp);
|
||||
|
||||
TopTools_ListIteratorOfListOfShape simIt;
|
||||
for (simIt.Initialize(sim); simIt.More(); simIt.Next())
|
||||
builder.Add(Comp, simIt.Value()) ;
|
||||
*/
|
||||
this->Shape.setValue(mkPipeShell.Shape());
|
||||
return App::DocumentObject::StdReturn;
|
||||
|
||||
return SketchBased::execute();
|
||||
}
|
||||
catch (Standard_Failure) {
|
||||
Handle_Standard_Failure e = Standard_Failure::Caught();
|
||||
return new App::DocumentObjectExecReturn(e->GetMessageString());
|
||||
}
|
||||
catch (...) {
|
||||
return new App::DocumentObjectExecReturn("A fatal error occurred when making the sweep");
|
||||
}
|
||||
}
|
||||
|
||||
void Pipe::getContiniusEdges(Part::TopoShape TopShape, std::vector< std::string >& SubNames) {
|
||||
|
||||
|
||||
TopTools_IndexedMapOfShape mapOfEdges;
|
||||
TopTools_IndexedDataMapOfShapeListOfShape mapEdgeEdge;
|
||||
TopExp::MapShapesAndAncestors(TopShape._Shape, TopAbs_EDGE, TopAbs_EDGE, mapEdgeEdge);
|
||||
TopExp::MapShapes(TopShape._Shape, TopAbs_EDGE, mapOfEdges);
|
||||
|
||||
Base::Console().Message("Initial edges:\n");
|
||||
for(int i=0; i<SubNames.size(); ++i)
|
||||
Base::Console().Message("Subname: %s\n", SubNames[i].c_str());
|
||||
|
||||
unsigned int i = 0;
|
||||
while(i < SubNames.size())
|
||||
{
|
||||
std::string aSubName = static_cast<std::string>(SubNames.at(i));
|
||||
|
||||
if (aSubName.size() > 4 && aSubName.substr(0,4) == "Edge") {
|
||||
TopoDS_Edge edge = TopoDS::Edge(TopShape.getSubShape(aSubName.c_str()));
|
||||
const TopTools_ListOfShape& los = mapEdgeEdge.FindFromKey(edge);
|
||||
|
||||
if(los.Extent() != 2)
|
||||
{
|
||||
SubNames.erase(SubNames.begin()+i);
|
||||
continue;
|
||||
}
|
||||
|
||||
const TopoDS_Shape& face1 = los.First();
|
||||
const TopoDS_Shape& face2 = los.Last();
|
||||
GeomAbs_Shape cont = BRep_Tool::Continuity(TopoDS::Edge(edge),
|
||||
TopoDS::Face(face1),
|
||||
TopoDS::Face(face2));
|
||||
if (cont != GeomAbs_C0) {
|
||||
SubNames.erase(SubNames.begin()+i);
|
||||
continue;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
// empty name or any other sub-element
|
||||
else {
|
||||
SubNames.erase(SubNames.begin()+i);
|
||||
}
|
||||
}
|
||||
|
||||
Base::Console().Message("Final edges:\n");
|
||||
for(int i=0; i<SubNames.size(); ++i)
|
||||
Base::Console().Message("Subname: %s\n", SubNames[i].c_str());
|
||||
}
|
||||
|
||||
void Pipe::buildPipePath(const Part::TopoShape& shape, const std::vector< std::string >& subedge, TopoDS_Shape& path) {
|
||||
|
||||
if (!shape._Shape.IsNull()) {
|
||||
try {
|
||||
if (!subedge.empty()) {
|
||||
//if(SpineTangent.getValue())
|
||||
//getContiniusEdges(shape, subedge);
|
||||
|
||||
BRepBuilderAPI_MakeWire mkWire;
|
||||
for (std::vector<std::string>::const_iterator it = subedge.begin(); it != subedge.end(); ++it) {
|
||||
TopoDS_Shape subshape = shape.getSubShape(it->c_str());
|
||||
mkWire.Add(TopoDS::Edge(subshape));
|
||||
}
|
||||
path = mkWire.Wire();
|
||||
}
|
||||
else if (shape._Shape.ShapeType() == TopAbs_EDGE) {
|
||||
path = shape._Shape;
|
||||
}
|
||||
else if (shape._Shape.ShapeType() == TopAbs_WIRE) {
|
||||
BRepBuilderAPI_MakeWire mkWire(TopoDS::Wire(shape._Shape));
|
||||
path = mkWire.Wire();
|
||||
}
|
||||
else if (shape._Shape.ShapeType() == TopAbs_COMPOUND) {
|
||||
TopoDS_Iterator it(shape._Shape);
|
||||
for (; it.More(); it.Next()) {
|
||||
if (it.Value().IsNull())
|
||||
throw Base::Exception("In valid element in spine.");
|
||||
if ((it.Value().ShapeType() != TopAbs_EDGE) &&
|
||||
(it.Value().ShapeType() != TopAbs_WIRE)) {
|
||||
throw Base::Exception("Element in spine is neither an edge nor a wire.");
|
||||
}
|
||||
}
|
||||
|
||||
Handle(TopTools_HSequenceOfShape) hEdges = new TopTools_HSequenceOfShape();
|
||||
Handle(TopTools_HSequenceOfShape) hWires = new TopTools_HSequenceOfShape();
|
||||
for (TopExp_Explorer xp(shape._Shape, TopAbs_EDGE); xp.More(); xp.Next())
|
||||
hEdges->Append(xp.Current());
|
||||
|
||||
ShapeAnalysis_FreeBounds::ConnectEdgesToWires(hEdges, Precision::Confusion(), Standard_True, hWires);
|
||||
int len = hWires->Length();
|
||||
if (len != 1)
|
||||
throw Base::Exception("Spine is not connected.");
|
||||
path = hWires->Value(1);
|
||||
}
|
||||
else {
|
||||
throw Base::Exception("Spine is neither an edge nor a wire.");
|
||||
}
|
||||
}
|
||||
catch (Standard_Failure) {
|
||||
throw Base::Exception("Invalid spine.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
PROPERTY_SOURCE(PartDesign::AdditivePipe, PartDesign::Pipe)
|
||||
AdditivePipe::AdditivePipe() {
|
||||
addSubType = Additive;
|
||||
|
||||
@@ -37,10 +37,17 @@ class PartDesignExport Pipe : public SketchBased
|
||||
public:
|
||||
Pipe();
|
||||
|
||||
App::PropertyLinkList Sections;
|
||||
App::PropertyLinkSubList Spine;
|
||||
|
||||
App::PropertyLinkSub Spine;
|
||||
App::PropertyBool SpineTangent;
|
||||
App::PropertyLinkSub AuxillerySpine;
|
||||
App::PropertyBool AuxillerySpineTangent;
|
||||
App::PropertyBool AuxilleryCurvelinear;
|
||||
App::PropertyEnumeration Mode;
|
||||
App::PropertyVector Binormal;
|
||||
App::PropertyEnumeration Transition;
|
||||
App::PropertyEnumeration Transformation;
|
||||
App::PropertyLinkList Sections;
|
||||
|
||||
App::DocumentObjectExecReturn *execute(void);
|
||||
short mustExecute() const;
|
||||
@@ -49,11 +56,17 @@ public:
|
||||
return "PartDesignGui::ViewProviderPipe";
|
||||
}
|
||||
//@}
|
||||
|
||||
protected:
|
||||
///get the given edges and all their tangent ones
|
||||
void getContiniusEdges(Part::TopoShape TopShape, std::vector< std::string >& SubNames);
|
||||
void buildPipePath(const Part::TopoShape& input, const std::vector<std::string>& edges, TopoDS_Shape& result);
|
||||
|
||||
private:
|
||||
static const char* TypeEnums[];
|
||||
static const char* TransitionEnums[];
|
||||
static const char* ModeEnums[];
|
||||
static const char* TransformEnums[];
|
||||
};
|
||||
|
||||
class PartDesignExport AdditivePipe : public Pipe {
|
||||
|
||||
Reference in New Issue
Block a user