PartDesign: Modeling features work with faces
-Rename Sketchbased to ProfileBased to show new behavior -Adopt ProfileBased to make the relevant helper functions work with faces too -Adopt features for unified use of helper functions -Adopt commands to allow face selection
This commit is contained in:
@@ -87,7 +87,7 @@ PyMODINIT_FUNC init_PartDesign()
|
||||
PartDesign::Solid ::init();
|
||||
PartDesign::DressUp ::init();
|
||||
PartDesign::FeatureAddSub ::init();
|
||||
PartDesign::SketchBased ::init();
|
||||
PartDesign::ProfileBased ::init();
|
||||
PartDesign::Transformed ::init();
|
||||
PartDesign::Mirrored ::init();
|
||||
PartDesign::LinearPattern ::init();
|
||||
|
||||
@@ -49,7 +49,7 @@ using namespace PartDesign;
|
||||
namespace PartDesign {
|
||||
|
||||
|
||||
PROPERTY_SOURCE(PartDesign::Groove, PartDesign::SketchBased)
|
||||
PROPERTY_SOURCE(PartDesign::Groove, PartDesign::ProfileBased)
|
||||
|
||||
Groove::Groove()
|
||||
{
|
||||
@@ -69,7 +69,7 @@ short Groove::mustExecute() const
|
||||
Base.isTouched() ||
|
||||
Angle.isTouched())
|
||||
return 1;
|
||||
return SketchBased::mustExecute();
|
||||
return ProfileBased::mustExecute();
|
||||
}
|
||||
|
||||
App::DocumentObjectExecReturn *Groove::execute(void)
|
||||
@@ -86,9 +86,9 @@ App::DocumentObjectExecReturn *Groove::execute(void)
|
||||
if (Reversed.getValue() && !Midplane.getValue())
|
||||
angle *= (-1.0);
|
||||
|
||||
std::vector<TopoDS_Wire> wires;
|
||||
TopoDS_Shape sketchshape;
|
||||
try {
|
||||
wires = getSketchWires();
|
||||
sketchshape = getVerifiedFace();
|
||||
} catch (const Base::Exception& e) {
|
||||
return new App::DocumentObjectExecReturn(e.what());
|
||||
}
|
||||
@@ -110,7 +110,6 @@ App::DocumentObjectExecReturn *Groove::execute(void)
|
||||
gp_Dir dir(v.x,v.y,v.z);
|
||||
|
||||
try {
|
||||
TopoDS_Shape sketchshape = makeFace(wires);
|
||||
if (sketchshape.IsNull())
|
||||
return new App::DocumentObjectExecReturn("Creating a face from sketch failed");
|
||||
|
||||
@@ -177,7 +176,7 @@ App::DocumentObjectExecReturn *Groove::execute(void)
|
||||
bool Groove::suggestReversed(void)
|
||||
{
|
||||
updateAxis();
|
||||
return SketchBased::getReversedAngle(Base.getValue(), Axis.getValue()) > 0.0;
|
||||
return ProfileBased::getReversedAngle(Base.getValue(), Axis.getValue()) > 0.0;
|
||||
}
|
||||
|
||||
void Groove::updateAxis(void)
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
namespace PartDesign
|
||||
{
|
||||
|
||||
class PartDesignExport Groove : public SketchBased
|
||||
class PartDesignExport Groove : public ProfileBased
|
||||
{
|
||||
PROPERTY_HEADER(PartDesign::Groove);
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ const char* Hole::TypeEnums[] = {"Dimension","UpToLast","UpToFirst",NULL};
|
||||
const char* Hole::HoleTypeEnums[]= {"Simple","Counterbore","Countersunk",NULL};
|
||||
const char* Hole::ThreadEnums[] = {"None","Metric","MetricFine",NULL};
|
||||
|
||||
PROPERTY_SOURCE(PartDesign::Hole, PartDesign::SketchBased)
|
||||
PROPERTY_SOURCE(PartDesign::Hole, PartDesign::ProfileBased)
|
||||
|
||||
Hole::Hole()
|
||||
{
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
namespace PartDesign
|
||||
{
|
||||
|
||||
class PartDesignExport Hole : public SketchBased
|
||||
class PartDesignExport Hole : public ProfileBased
|
||||
{
|
||||
PROPERTY_HEADER(PartDesign::Hole);
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
|
||||
using namespace PartDesign;
|
||||
|
||||
PROPERTY_SOURCE(PartDesign::Loft, PartDesign::SketchBased)
|
||||
PROPERTY_SOURCE(PartDesign::Loft, PartDesign::ProfileBased)
|
||||
|
||||
Loft::Loft()
|
||||
{
|
||||
@@ -68,7 +68,7 @@ short Loft::mustExecute() const
|
||||
if (Closed.isTouched())
|
||||
return 1;
|
||||
|
||||
return SketchBased::mustExecute();
|
||||
return ProfileBased::mustExecute();
|
||||
}
|
||||
|
||||
App::DocumentObjectExecReturn *Loft::execute(void)
|
||||
@@ -76,12 +76,12 @@ App::DocumentObjectExecReturn *Loft::execute(void)
|
||||
|
||||
std::vector<TopoDS_Wire> wires;
|
||||
try {
|
||||
wires = getSketchWires();
|
||||
wires = getProfileWires();
|
||||
} catch (const Base::Exception& e) {
|
||||
return new App::DocumentObjectExecReturn(e.what());
|
||||
}
|
||||
|
||||
TopoDS_Shape sketchshape = makeFace(wires);
|
||||
TopoDS_Shape sketchshape = getVerifiedFace();
|
||||
if (sketchshape.IsNull())
|
||||
return new App::DocumentObjectExecReturn("Loft: Creating a face from sketch failed");
|
||||
|
||||
@@ -145,7 +145,7 @@ App::DocumentObjectExecReturn *Loft::execute(void)
|
||||
}
|
||||
|
||||
//build the top and bottom face, sew the shell and build the final solid
|
||||
TopoDS_Shape front = makeFace(wires);
|
||||
TopoDS_Shape front = getVerifiedFace();
|
||||
front.Move(invObjLoc);
|
||||
std::vector<TopoDS_Wire> backwires;
|
||||
for(std::vector<TopoDS_Wire>& wires : wiresections)
|
||||
@@ -213,7 +213,7 @@ App::DocumentObjectExecReturn *Loft::execute(void)
|
||||
|
||||
return App::DocumentObject::StdReturn;
|
||||
|
||||
return SketchBased::execute();
|
||||
return ProfileBased::execute();
|
||||
}
|
||||
catch (Standard_Failure) {
|
||||
Handle_Standard_Failure e = Standard_Failure::Caught();
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
namespace PartDesign
|
||||
{
|
||||
|
||||
class PartDesignExport Loft : public SketchBased
|
||||
class PartDesignExport Loft : public ProfileBased
|
||||
{
|
||||
PROPERTY_HEADER(PartDesign::Loft);
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
# include <BRepAdaptor_Surface.hxx>
|
||||
# include <gp_Pln.hxx>
|
||||
# include <GeomAPI_ProjectPointOnSurf.hxx>
|
||||
#include <BRepLProp_SLProps.hxx>
|
||||
#endif
|
||||
|
||||
#include <Base/Exception.h>
|
||||
@@ -58,7 +59,7 @@ using namespace PartDesign;
|
||||
|
||||
const char* Pad::TypeEnums[]= {"Length","UpToLast","UpToFirst","UpToFace","TwoLengths",NULL};
|
||||
|
||||
PROPERTY_SOURCE(PartDesign::Pad, PartDesign::SketchBased)
|
||||
PROPERTY_SOURCE(PartDesign::Pad, PartDesign::ProfileBased)
|
||||
|
||||
Pad::Pad()
|
||||
{
|
||||
@@ -83,7 +84,7 @@ short Pad::mustExecute() const
|
||||
Offset.isTouched() ||
|
||||
UpToFace.isTouched())
|
||||
return 1;
|
||||
return SketchBased::mustExecute();
|
||||
return ProfileBased::mustExecute();
|
||||
}
|
||||
|
||||
App::DocumentObjectExecReturn *Pad::execute(void)
|
||||
@@ -96,11 +97,11 @@ App::DocumentObjectExecReturn *Pad::execute(void)
|
||||
if ((std::string(Type.getValueAsString()) == "TwoLengths") && (L < Precision::Confusion()))
|
||||
return new App::DocumentObjectExecReturn("Second length of pad too small");
|
||||
|
||||
Part::Part2DObject* sketch = 0;
|
||||
std::vector<TopoDS_Wire> wires;
|
||||
Part::Feature* obj = 0;
|
||||
TopoDS_Shape sketchshape;
|
||||
try {
|
||||
sketch = getVerifiedSketch();
|
||||
wires = getSketchWires();
|
||||
obj = getVerifiedObject();
|
||||
sketchshape = getVerifiedFace();
|
||||
} catch (const Base::Exception& e) {
|
||||
return new App::DocumentObjectExecReturn(e.what());
|
||||
}
|
||||
@@ -115,10 +116,8 @@ App::DocumentObjectExecReturn *Pad::execute(void)
|
||||
|
||||
|
||||
// get the Sketch plane
|
||||
Base::Placement SketchPos = sketch->Placement.getValue();
|
||||
Base::Rotation SketchOrientation = SketchPos.getRotation();
|
||||
Base::Vector3d SketchVector(0,0,1);
|
||||
SketchOrientation.multVec(SketchVector,SketchVector);
|
||||
Base::Placement SketchPos = obj->Placement.getValue();
|
||||
Base::Vector3d SketchVector = getProfileNormal();
|
||||
|
||||
try {
|
||||
this->positionByPrevious();
|
||||
@@ -129,7 +128,6 @@ App::DocumentObjectExecReturn *Pad::execute(void)
|
||||
gp_Dir dir(SketchVector.x,SketchVector.y,SketchVector.z);
|
||||
dir.Transform(invObjLoc.Transformation());
|
||||
|
||||
TopoDS_Shape sketchshape = makeFace(wires);
|
||||
if (sketchshape.IsNull())
|
||||
return new App::DocumentObjectExecReturn("Pad: Creating a face from sketch failed");
|
||||
sketchshape.Move(invObjLoc);
|
||||
@@ -214,6 +212,8 @@ App::DocumentObjectExecReturn *Pad::execute(void)
|
||||
this->AddSubShape.setValue(prism);
|
||||
|
||||
if (!base.IsNull()) {
|
||||
// auto obj = getDocument()->addObject("Part::Feature", "prism");
|
||||
// static_cast<Part::Feature*>(obj)->Shape.setValue(prism);
|
||||
// Let's call algorithm computing a fuse operation:
|
||||
BRepAlgoAPI_Fuse mkFuse(base, prism);
|
||||
// Let's check if the fusion has been successful
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
namespace PartDesign
|
||||
{
|
||||
|
||||
class PartDesignExport Pad : public SketchBased
|
||||
class PartDesignExport Pad : public ProfileBased
|
||||
{
|
||||
PROPERTY_HEADER(PartDesign::Pad);
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ const char* Pipe::ModeEnums[] = {"Standart", "Fixed", "Frenet", "Auxillery", "Bi
|
||||
const char* Pipe::TransformEnums[] = {"Constant", "Multisection", "Linear", "S-shape", "Interpolation", NULL};
|
||||
|
||||
|
||||
PROPERTY_SOURCE(PartDesign::Pipe, PartDesign::SketchBased)
|
||||
PROPERTY_SOURCE(PartDesign::Pipe, PartDesign::ProfileBased)
|
||||
|
||||
Pipe::Pipe()
|
||||
{
|
||||
@@ -106,7 +106,7 @@ short Pipe::mustExecute() const
|
||||
return 1;
|
||||
if (Transition.isTouched())
|
||||
return 1;
|
||||
return SketchBased::mustExecute();
|
||||
return ProfileBased::mustExecute();
|
||||
}
|
||||
|
||||
App::DocumentObjectExecReturn *Pipe::execute(void)
|
||||
@@ -114,14 +114,24 @@ App::DocumentObjectExecReturn *Pipe::execute(void)
|
||||
|
||||
std::vector<TopoDS_Wire> wires;
|
||||
try {
|
||||
wires = getSketchWires();
|
||||
wires = getProfileWires();
|
||||
} catch (const Base::Exception& e) {
|
||||
return new App::DocumentObjectExecReturn(e.what());
|
||||
}
|
||||
|
||||
TopoDS_Shape sketchshape = makeFace(wires);
|
||||
TopoDS_Shape sketchshape = getVerifiedFace();
|
||||
if (sketchshape.IsNull())
|
||||
return new App::DocumentObjectExecReturn("Pipe: Creating a face from sketch failed");
|
||||
return new App::DocumentObjectExecReturn("Pipe: No valid sketch or face as first section");
|
||||
else {
|
||||
//TODO: currently we only allow planar faces. the reason for this is that with other faces in front, we could
|
||||
//not use the current simulate approach and build the start and end face from the wires. As the shell
|
||||
//beginns always at the spine and not the profile, the sketchshape cannot be used directly as front face.
|
||||
//We would need a method to translate the frontshape to match the shell starting position somehow...
|
||||
TopoDS_Face face = TopoDS::Face(sketchshape);
|
||||
BRepAdaptor_Surface adapt(face);
|
||||
if(adapt.GetType() != GeomAbs_Plane)
|
||||
return new App::DocumentObjectExecReturn("Pipe: Only planar faces supportet");
|
||||
}
|
||||
|
||||
// if the Base property has a valid shape, fuse the pipe into it
|
||||
TopoDS_Shape base;
|
||||
@@ -310,7 +320,7 @@ App::DocumentObjectExecReturn *Pipe::execute(void)
|
||||
|
||||
return App::DocumentObject::StdReturn;
|
||||
|
||||
return SketchBased::execute();
|
||||
return ProfileBased::execute();
|
||||
}
|
||||
catch (Standard_Failure) {
|
||||
Handle_Standard_Failure e = Standard_Failure::Caught();
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
namespace PartDesign
|
||||
{
|
||||
|
||||
class PartDesignExport Pipe : public SketchBased
|
||||
class PartDesignExport Pipe : public ProfileBased
|
||||
{
|
||||
PROPERTY_HEADER(PartDesign::Pad);
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ using namespace PartDesign;
|
||||
|
||||
const char* Pocket::TypeEnums[]= {"Length","ThroughAll","UpToFirst","UpToFace",NULL};
|
||||
|
||||
PROPERTY_SOURCE(PartDesign::Pocket, PartDesign::SketchBased)
|
||||
PROPERTY_SOURCE(PartDesign::Pocket, PartDesign::ProfileBased)
|
||||
|
||||
Pocket::Pocket()
|
||||
{
|
||||
@@ -77,7 +77,7 @@ short Pocket::mustExecute() const
|
||||
Offset.isTouched() ||
|
||||
UpToFace.isTouched())
|
||||
return 1;
|
||||
return SketchBased::mustExecute();
|
||||
return ProfileBased::mustExecute();
|
||||
}
|
||||
|
||||
App::DocumentObjectExecReturn *Pocket::execute(void)
|
||||
@@ -93,11 +93,11 @@ App::DocumentObjectExecReturn *Pocket::execute(void)
|
||||
if ((std::string(Type.getValueAsString()) == "Length") && (L < Precision::Confusion()))
|
||||
return new App::DocumentObjectExecReturn("Pocket: Length of pocket too small");
|
||||
|
||||
Part::Part2DObject* sketch = 0;
|
||||
std::vector<TopoDS_Wire> wires;
|
||||
Part::Feature* obj = 0;
|
||||
TopoDS_Face face;
|
||||
try {
|
||||
sketch = getVerifiedSketch();
|
||||
wires = getSketchWires();
|
||||
obj = getVerifiedObject();
|
||||
face = getVerifiedFace();
|
||||
} catch (const Base::Exception& e) {
|
||||
return new App::DocumentObjectExecReturn(e.what());
|
||||
}
|
||||
@@ -111,10 +111,8 @@ App::DocumentObjectExecReturn *Pocket::execute(void)
|
||||
}
|
||||
|
||||
// get the Sketch plane
|
||||
Base::Placement SketchPos = sketch->Placement.getValue();
|
||||
Base::Rotation SketchOrientation = SketchPos.getRotation();
|
||||
Base::Vector3d SketchVector(0,0,1);
|
||||
SketchOrientation.multVec(SketchVector,SketchVector);
|
||||
Base::Placement SketchPos = obj->Placement.getValue();
|
||||
Base::Vector3d SketchVector = getProfileNormal();
|
||||
|
||||
// turn around for pockets
|
||||
SketchVector *= -1;
|
||||
@@ -128,10 +126,9 @@ App::DocumentObjectExecReturn *Pocket::execute(void)
|
||||
gp_Dir dir(SketchVector.x,SketchVector.y,SketchVector.z);
|
||||
dir.Transform(invObjLoc.Transformation());
|
||||
|
||||
TopoDS_Shape sketchshape = makeFace(wires);
|
||||
if (sketchshape.IsNull())
|
||||
if (face.IsNull())
|
||||
return new App::DocumentObjectExecReturn("Pocket: Creating a face from sketch failed");
|
||||
sketchshape.Move(invObjLoc);
|
||||
face.Move(invObjLoc);
|
||||
|
||||
std::string method(Type.getValueAsString());
|
||||
if (method == "UpToFirst" || method == "UpToFace") {
|
||||
@@ -151,7 +148,7 @@ App::DocumentObjectExecReturn *Pocket::execute(void)
|
||||
getUpToFaceFromLinkSub(upToFace, UpToFace);
|
||||
upToFace.Move(invObjLoc);
|
||||
}
|
||||
getUpToFace(upToFace, base, supportface, sketchshape, method, dir, Offset.getValue());
|
||||
getUpToFace(upToFace, base, supportface, face, method, dir, Offset.getValue());
|
||||
|
||||
// BRepFeat_MakePrism(..., 2, 1) in combination with PerForm(upToFace) is buggy when the
|
||||
// prism that is being created is contained completely inside the base solid
|
||||
@@ -164,7 +161,7 @@ App::DocumentObjectExecReturn *Pocket::execute(void)
|
||||
if (!Ex.More())
|
||||
supportface = TopoDS_Face();
|
||||
BRepFeat_MakePrism PrismMaker;
|
||||
PrismMaker.Init(base, sketchshape, supportface, dir, 0, 1);
|
||||
PrismMaker.Init(base, face, supportface, dir, 0, 1);
|
||||
PrismMaker.Perform(upToFace);
|
||||
|
||||
if (!PrismMaker.IsDone())
|
||||
@@ -181,7 +178,7 @@ App::DocumentObjectExecReturn *Pocket::execute(void)
|
||||
this->Shape.setValue(prism);
|
||||
} else {
|
||||
TopoDS_Shape prism;
|
||||
generatePrism(prism, sketchshape, method, dir, L, 0.0,
|
||||
generatePrism(prism, face, method, dir, L, 0.0,
|
||||
Midplane.getValue(), Reversed.getValue());
|
||||
if (prism.IsNull())
|
||||
return new App::DocumentObjectExecReturn("Pocket: Resulting shape is empty");
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
namespace PartDesign
|
||||
{
|
||||
|
||||
class PartDesignExport Pocket : public SketchBased
|
||||
class PartDesignExport Pocket : public ProfileBased
|
||||
{
|
||||
PROPERTY_HEADER(PartDesign::Pocket);
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ using namespace PartDesign;
|
||||
namespace PartDesign {
|
||||
|
||||
|
||||
PROPERTY_SOURCE(PartDesign::Revolution, PartDesign::SketchBased)
|
||||
PROPERTY_SOURCE(PartDesign::Revolution, PartDesign::ProfileBased)
|
||||
|
||||
Revolution::Revolution()
|
||||
{
|
||||
@@ -69,7 +69,7 @@ short Revolution::mustExecute() const
|
||||
Base.isTouched() ||
|
||||
Angle.isTouched())
|
||||
return 1;
|
||||
return SketchBased::mustExecute();
|
||||
return ProfileBased::mustExecute();
|
||||
}
|
||||
|
||||
App::DocumentObjectExecReturn *Revolution::execute(void)
|
||||
@@ -86,9 +86,9 @@ App::DocumentObjectExecReturn *Revolution::execute(void)
|
||||
if (Reversed.getValue() && !Midplane.getValue())
|
||||
angle *= (-1.0);
|
||||
|
||||
std::vector<TopoDS_Wire> wires;
|
||||
TopoDS_Shape sketchshape;
|
||||
try {
|
||||
wires = getSketchWires();
|
||||
sketchshape = getVerifiedFace();
|
||||
} catch (const Base::Exception& e) {
|
||||
return new App::DocumentObjectExecReturn(e.what());
|
||||
}
|
||||
@@ -112,7 +112,6 @@ App::DocumentObjectExecReturn *Revolution::execute(void)
|
||||
gp_Dir dir(v.x,v.y,v.z);
|
||||
|
||||
try {
|
||||
TopoDS_Shape sketchshape = makeFace(wires);
|
||||
if (sketchshape.IsNull())
|
||||
return new App::DocumentObjectExecReturn("Creating a face from sketch failed");
|
||||
|
||||
@@ -177,7 +176,7 @@ App::DocumentObjectExecReturn *Revolution::execute(void)
|
||||
bool Revolution::suggestReversed(void)
|
||||
{
|
||||
updateAxis();
|
||||
return SketchBased::getReversedAngle(Base.getValue(), Axis.getValue()) < 0.0;
|
||||
return ProfileBased::getReversedAngle(Base.getValue(), Axis.getValue()) < 0.0;
|
||||
}
|
||||
|
||||
void Revolution::updateAxis(void)
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
namespace PartDesign
|
||||
{
|
||||
|
||||
class PartDesignExport Revolution : public SketchBased
|
||||
class PartDesignExport Revolution : public ProfileBased
|
||||
{
|
||||
PROPERTY_HEADER(PartDesign::Revolution);
|
||||
|
||||
|
||||
@@ -66,11 +66,16 @@
|
||||
#include <BRepExtrema_DistShapeShape.hxx>
|
||||
#include <TopExp.hxx>
|
||||
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
|
||||
#include <BRepLProp_SLProps.hxx>
|
||||
#include <BRepGProp_Face.hxx>
|
||||
|
||||
#include <Base/Exception.h>
|
||||
#include <Base/Parameter.h>
|
||||
#include <Base/Reader.h>
|
||||
#include <Base/Console.h>
|
||||
#include <App/Application.h>
|
||||
#include <App/OriginFeature.h>
|
||||
#include <App/Document.h>
|
||||
#include <Mod/Part/App/modelRefine.h>
|
||||
#include "FeatureSketchBased.h"
|
||||
#include "DatumPlane.h"
|
||||
@@ -79,7 +84,7 @@
|
||||
using namespace PartDesign;
|
||||
|
||||
// sort bounding boxes according to diagonal length
|
||||
class SketchBased::Wire_Compare : public std::binary_function<const TopoDS_Wire&,
|
||||
class ProfileBased::Wire_Compare : public std::binary_function<const TopoDS_Wire&,
|
||||
const TopoDS_Wire&, bool> {
|
||||
public:
|
||||
bool operator() (const TopoDS_Wire& w1, const TopoDS_Wire& w2)
|
||||
@@ -99,19 +104,19 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
PROPERTY_SOURCE(PartDesign::SketchBased, PartDesign::FeatureAddSub)
|
||||
PROPERTY_SOURCE(PartDesign::ProfileBased, PartDesign::FeatureAddSub)
|
||||
|
||||
SketchBased::SketchBased()
|
||||
ProfileBased::ProfileBased()
|
||||
{
|
||||
ADD_PROPERTY_TYPE(Sketch,(0),"SketchBased", App::Prop_None, "Reference to sketch");
|
||||
ADD_PROPERTY_TYPE(Profile,(0),"SketchBased", App::Prop_None, "Reference to sketch");
|
||||
ADD_PROPERTY_TYPE(Midplane,(0),"SketchBased", App::Prop_None, "Extrude symmetric to sketch face");
|
||||
ADD_PROPERTY_TYPE(Reversed, (0),"SketchBased", App::Prop_None, "Reverse extrusion direction");
|
||||
ADD_PROPERTY_TYPE(UpToFace,(0),"SketchBased",(App::PropertyType)(App::Prop_None),"Face where feature will end");
|
||||
}
|
||||
|
||||
short SketchBased::mustExecute() const
|
||||
short ProfileBased::mustExecute() const
|
||||
{
|
||||
if (Sketch.isTouched() ||
|
||||
if (Profile.isTouched() ||
|
||||
Midplane.isTouched() ||
|
||||
Reversed.isTouched() ||
|
||||
UpToFace.isTouched())
|
||||
@@ -119,7 +124,7 @@ short SketchBased::mustExecute() const
|
||||
return PartDesign::FeatureAddSub::mustExecute();
|
||||
}
|
||||
|
||||
void SketchBased::positionByPrevious(void)
|
||||
void ProfileBased::positionByPrevious(void)
|
||||
{
|
||||
Part::Feature* feat = getBaseObject(/* silent = */ true);
|
||||
if (feat) {
|
||||
@@ -136,7 +141,7 @@ void SketchBased::positionByPrevious(void)
|
||||
}
|
||||
}
|
||||
|
||||
void SketchBased::transformPlacement(const Base::Placement &transform)
|
||||
void ProfileBased::transformPlacement(const Base::Placement &transform)
|
||||
{
|
||||
Part::Feature* feat = getBaseObject(/* silent = */ true);
|
||||
if (feat) {
|
||||
@@ -148,8 +153,8 @@ void SketchBased::transformPlacement(const Base::Placement &transform)
|
||||
positionByPrevious();
|
||||
}
|
||||
|
||||
Part::Part2DObject* SketchBased::getVerifiedSketch(bool silent) const {
|
||||
App::DocumentObject* result = Sketch.getValue();
|
||||
Part::Part2DObject* ProfileBased::getVerifiedSketch(bool silent) const {
|
||||
App::DocumentObject* result = Profile.getValue();
|
||||
const char* err = nullptr;
|
||||
|
||||
if (!result) {
|
||||
@@ -166,10 +171,78 @@ Part::Part2DObject* SketchBased::getVerifiedSketch(bool silent) const {
|
||||
return static_cast<Part::Part2DObject*>(result);
|
||||
}
|
||||
|
||||
std::vector<TopoDS_Wire> SketchBased::getSketchWires() const {
|
||||
Part::Feature* ProfileBased::getVerifiedObject(bool silent) const {
|
||||
|
||||
App::DocumentObject* result = Profile.getValue();
|
||||
const char* err = nullptr;
|
||||
|
||||
if (!result) {
|
||||
err = "No object linked";
|
||||
} else {
|
||||
if (!result->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()))
|
||||
err = "Linked object is not a Sketch, Part2DObject or Feature";
|
||||
}
|
||||
|
||||
if (!silent && err) {
|
||||
throw Base::Exception (err);
|
||||
}
|
||||
|
||||
return static_cast<Part::Feature*>(result);
|
||||
}
|
||||
|
||||
TopoDS_Face ProfileBased::getVerifiedFace(bool silent) const {
|
||||
|
||||
App::DocumentObject* result = Profile.getValue();
|
||||
const char* err = nullptr;
|
||||
|
||||
if (!result) {
|
||||
err = "No profile linked";
|
||||
} else {
|
||||
if (result->getTypeId().isDerivedFrom(Part::Part2DObject::getClassTypeId())) {
|
||||
|
||||
auto wires = getProfileWires();
|
||||
return TopoDS::Face(makeFace(wires));
|
||||
}
|
||||
else if(result->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) {
|
||||
if(Profile.getSubValues().empty())
|
||||
err = "Linked object has no subshape specified";
|
||||
else {
|
||||
|
||||
const TopoShape& shape = Profile.getValue<Part::Feature*>()->Shape.getShape();
|
||||
TopoDS_Shape sub = shape.getSubShape(Profile.getSubValues()[0].c_str());
|
||||
if(sub.ShapeType() == TopAbs_FACE)
|
||||
return TopoDS::Face(sub);
|
||||
else if(sub.ShapeType() == TopAbs_WIRE) {
|
||||
|
||||
auto wire = TopoDS::Wire(sub);
|
||||
if(!wire.Closed())
|
||||
err = "Linked wire is not closed";
|
||||
else {
|
||||
BRepBuilderAPI_MakeFace mk(wire);
|
||||
mk.Build();
|
||||
return TopoDS::Face(mk.Shape());
|
||||
}
|
||||
}
|
||||
else
|
||||
err = "Linked Subshape cannot be used";
|
||||
}
|
||||
}
|
||||
else
|
||||
err = "Linked object is neither Sketch, Part2DObject or Part::Feature";
|
||||
}
|
||||
|
||||
if (!silent && err) {
|
||||
throw Base::Exception (err);
|
||||
}
|
||||
|
||||
return TopoDS_Face();
|
||||
}
|
||||
|
||||
|
||||
std::vector<TopoDS_Wire> ProfileBased::getProfileWires() const {
|
||||
std::vector<TopoDS_Wire> result;
|
||||
|
||||
TopoDS_Shape shape = getVerifiedSketch()->Shape.getShape()._Shape;
|
||||
TopoDS_Shape shape = getVerifiedFace();
|
||||
if (shape.IsNull())
|
||||
throw Base::Exception("Linked shape object is empty");
|
||||
|
||||
@@ -195,7 +268,7 @@ std::vector<TopoDS_Wire> SketchBased::getSketchWires() const {
|
||||
// Note: We cannot return a reference, because it will become Null.
|
||||
// Not clear where, because we check for IsNull() here, but as soon as it is passed out of
|
||||
// this method, it becomes null!
|
||||
const TopoDS_Face SketchBased::getSupportFace() const {
|
||||
const TopoDS_Face ProfileBased::getSupportFace() const {
|
||||
const Part::Part2DObject* sketch = getVerifiedSketch();
|
||||
if (sketch->MapMode.getValue() == Attacher::mmFlatFace && sketch->Support.getValue()) {
|
||||
const auto &Support = sketch->Support;
|
||||
@@ -229,15 +302,15 @@ const TopoDS_Face SketchBased::getSupportFace() const {
|
||||
|
||||
}
|
||||
|
||||
int SketchBased::getSketchAxisCount(void) const
|
||||
int ProfileBased::getSketchAxisCount(void) const
|
||||
{
|
||||
Part::Part2DObject *sketch = static_cast<Part::Part2DObject*>(Sketch.getValue());
|
||||
Part::Part2DObject *sketch = static_cast<Part::Part2DObject*>(Profile.getValue());
|
||||
if (!sketch)
|
||||
return -1; // the link to the sketch is lost
|
||||
return sketch->getAxisCount();
|
||||
}
|
||||
|
||||
Part::Feature *SketchBased::getBaseObject(bool silent) const
|
||||
Part::Feature *ProfileBased::getBaseObject(bool silent) const
|
||||
{
|
||||
// Test the base's class feature.
|
||||
Part::Feature *rv = Feature::getBaseObject(/* silent = */ true);
|
||||
@@ -245,13 +318,17 @@ Part::Feature *SketchBased::getBaseObject(bool silent) const
|
||||
return rv;
|
||||
}
|
||||
|
||||
// getVerifiedSketch() may throw it's own exception if fail
|
||||
Part::Part2DObject* sketch = getVerifiedSketch(silent);
|
||||
// getVerifiedObject() may throw it's own exception if fail
|
||||
Part::Feature* obj = getVerifiedObject(silent);
|
||||
|
||||
if (!sketch) {
|
||||
if(!obj)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!obj->isDerivedFrom(Part::Part2DObject::getClassTypeId()))
|
||||
return obj;
|
||||
|
||||
//due to former test we know we have a 2d object
|
||||
Part::Part2DObject* sketch = getVerifiedSketch(silent);
|
||||
const char* err = nullptr;
|
||||
|
||||
App::DocumentObject* spt = sketch->Support.getValue();
|
||||
@@ -272,17 +349,17 @@ Part::Feature *SketchBased::getBaseObject(bool silent) const
|
||||
return rv;
|
||||
}
|
||||
|
||||
void SketchBased::onChanged(const App::Property* prop)
|
||||
void ProfileBased::onChanged(const App::Property* prop)
|
||||
{
|
||||
if (prop == &Sketch) {
|
||||
if (prop == &Profile) {
|
||||
// if attached to a sketch then mark it as read-only
|
||||
this->Placement.setStatus(App::Property::ReadOnly, Sketch.getValue() != 0);
|
||||
this->Placement.setStatus(App::Property::ReadOnly, Profile.getValue() != 0);
|
||||
}
|
||||
|
||||
FeatureAddSub::onChanged(prop);
|
||||
}
|
||||
|
||||
bool SketchBased::isInside(const TopoDS_Wire& wire1, const TopoDS_Wire& wire2) const
|
||||
bool ProfileBased::isInside(const TopoDS_Wire& wire1, const TopoDS_Wire& wire2) const
|
||||
{
|
||||
Bnd_Box box1;
|
||||
BRepBndLib::Add(wire1, box1);
|
||||
@@ -323,7 +400,7 @@ bool SketchBased::isInside(const TopoDS_Wire& wire1, const TopoDS_Wire& wire2) c
|
||||
return false;
|
||||
}
|
||||
|
||||
TopoDS_Face SketchBased::validateFace(const TopoDS_Face& face) const
|
||||
TopoDS_Face ProfileBased::validateFace(const TopoDS_Face& face) const
|
||||
{
|
||||
BRepCheck_Analyzer aChecker(face);
|
||||
if (!aChecker.IsValid()) {
|
||||
@@ -367,7 +444,7 @@ TopoDS_Face SketchBased::validateFace(const TopoDS_Face& face) const
|
||||
return face;
|
||||
}
|
||||
|
||||
TopoDS_Shape SketchBased::makeFace(std::list<TopoDS_Wire>& wires) const
|
||||
TopoDS_Shape ProfileBased::makeFace(std::list<TopoDS_Wire>& wires) const
|
||||
{
|
||||
BRepBuilderAPI_MakeFace mkFace(wires.front());
|
||||
const TopoDS_Face& face = mkFace.Face();
|
||||
@@ -399,7 +476,7 @@ TopoDS_Shape SketchBased::makeFace(std::list<TopoDS_Wire>& wires) const
|
||||
return validateFace(mkFace.Face());
|
||||
}
|
||||
|
||||
TopoDS_Shape SketchBased::makeFace(const std::vector<TopoDS_Wire>& w) const
|
||||
TopoDS_Shape ProfileBased::makeFace(const std::vector<TopoDS_Wire>& w) const
|
||||
{
|
||||
if (w.empty())
|
||||
return TopoDS_Shape();
|
||||
@@ -472,7 +549,7 @@ TopoDS_Shape SketchBased::makeFace(const std::vector<TopoDS_Wire>& w) const
|
||||
}
|
||||
}
|
||||
|
||||
void SketchBased::getUpToFaceFromLinkSub(TopoDS_Face& upToFace,
|
||||
void ProfileBased::getUpToFaceFromLinkSub(TopoDS_Face& upToFace,
|
||||
const App::PropertyLinkSub& refFace)
|
||||
{
|
||||
App::DocumentObject* ref = refFace.getValue();
|
||||
@@ -503,7 +580,7 @@ void SketchBased::getUpToFaceFromLinkSub(TopoDS_Face& upToFace,
|
||||
throw Base::Exception("SketchBased: Up to face: Failed to extract face");
|
||||
}
|
||||
|
||||
void SketchBased::getUpToFace(TopoDS_Face& upToFace,
|
||||
void ProfileBased::getUpToFace(TopoDS_Face& upToFace,
|
||||
const TopoDS_Shape& support,
|
||||
const TopoDS_Face& supportface,
|
||||
const TopoDS_Shape& sketchshape,
|
||||
@@ -593,7 +670,7 @@ void SketchBased::getUpToFace(TopoDS_Face& upToFace,
|
||||
}
|
||||
}
|
||||
|
||||
void SketchBased::generatePrism(TopoDS_Shape& prism,
|
||||
void ProfileBased::generatePrism(TopoDS_Shape& prism,
|
||||
const TopoDS_Shape& sketchshape,
|
||||
const std::string& method,
|
||||
const gp_Dir& dir,
|
||||
@@ -639,7 +716,7 @@ void SketchBased::generatePrism(TopoDS_Shape& prism,
|
||||
|
||||
}
|
||||
|
||||
const bool SketchBased::checkWireInsideFace(const TopoDS_Wire& wire, const TopoDS_Face& face,
|
||||
const bool ProfileBased::checkWireInsideFace(const TopoDS_Wire& wire, const TopoDS_Face& face,
|
||||
const gp_Dir& dir) {
|
||||
// Project wire onto the face (face, not surface! So limits of face apply)
|
||||
// FIXME: The results of BRepProj_Projection do not seem to be very stable. Sometimes they return no result
|
||||
@@ -650,7 +727,7 @@ const bool SketchBased::checkWireInsideFace(const TopoDS_Wire& wire, const TopoD
|
||||
return (proj.More() && proj.Current().Closed());
|
||||
}
|
||||
|
||||
const bool SketchBased::checkLineCrossesFace(const gp_Lin &line, const TopoDS_Face &face)
|
||||
const bool ProfileBased::checkLineCrossesFace(const gp_Lin &line, const TopoDS_Face &face)
|
||||
{
|
||||
#if 1
|
||||
BRepBuilderAPI_MakeEdge mkEdge(line);
|
||||
@@ -800,7 +877,7 @@ const bool SketchBased::checkLineCrossesFace(const gp_Lin &line, const TopoDS_Fa
|
||||
#endif
|
||||
}
|
||||
|
||||
void SketchBased::remapSupportShape(const TopoDS_Shape& newShape)
|
||||
void ProfileBased::remapSupportShape(const TopoDS_Shape& newShape)
|
||||
{
|
||||
TopTools_IndexedMapOfShape faceMap;
|
||||
TopExp::MapShapes(newShape, TopAbs_FACE, faceMap);
|
||||
@@ -911,7 +988,7 @@ struct gp_Pnt_Less : public std::binary_function<const gp_Pnt&,
|
||||
};
|
||||
}
|
||||
|
||||
bool SketchBased::isQuasiEqual(const TopoDS_Shape& s1, const TopoDS_Shape& s2) const
|
||||
bool ProfileBased::isQuasiEqual(const TopoDS_Shape& s1, const TopoDS_Shape& s2) const
|
||||
{
|
||||
if (s1.ShapeType() != s2.ShapeType())
|
||||
return false;
|
||||
@@ -947,7 +1024,7 @@ bool SketchBased::isQuasiEqual(const TopoDS_Shape& s1, const TopoDS_Shape& s2) c
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SketchBased::isEqualGeometry(const TopoDS_Shape& s1, const TopoDS_Shape& s2) const
|
||||
bool ProfileBased::isEqualGeometry(const TopoDS_Shape& s1, const TopoDS_Shape& s2) const
|
||||
{
|
||||
if (s1.ShapeType() == TopAbs_FACE && s2.ShapeType() == TopAbs_FACE) {
|
||||
BRepAdaptor_Surface a1(TopoDS::Face(s1));
|
||||
@@ -974,7 +1051,7 @@ bool SketchBased::isEqualGeometry(const TopoDS_Shape& s1, const TopoDS_Shape& s2
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SketchBased::isParallelPlane(const TopoDS_Shape& s1, const TopoDS_Shape& s2) const
|
||||
bool ProfileBased::isParallelPlane(const TopoDS_Shape& s1, const TopoDS_Shape& s2) const
|
||||
{
|
||||
if (s1.ShapeType() == TopAbs_FACE && s2.ShapeType() == TopAbs_FACE) {
|
||||
BRepAdaptor_Surface a1(TopoDS::Face(s1));
|
||||
@@ -993,12 +1070,11 @@ bool SketchBased::isParallelPlane(const TopoDS_Shape& s1, const TopoDS_Shape& s2
|
||||
}
|
||||
|
||||
|
||||
const double SketchBased::getReversedAngle(const Base::Vector3d &b, const Base::Vector3d &v)
|
||||
const double ProfileBased::getReversedAngle(const Base::Vector3d &b, const Base::Vector3d &v)
|
||||
{
|
||||
try {
|
||||
Part::Part2DObject* sketch = getVerifiedSketch();
|
||||
std::vector<TopoDS_Wire> wires = getSketchWires();
|
||||
TopoDS_Shape sketchshape = makeFace(wires);
|
||||
Part::Feature* obj = getVerifiedObject();
|
||||
TopoDS_Shape sketchshape = getVerifiedFace();
|
||||
|
||||
// get centre of gravity of the sketch face
|
||||
GProp_GProps props;
|
||||
@@ -1010,7 +1086,7 @@ const double SketchBased::getReversedAngle(const Base::Vector3d &b, const Base::
|
||||
// get cross product of projection direction with revolve axis direction
|
||||
Base::Vector3d cross = v % perp_dir;
|
||||
// get sketch vector pointing away from support material
|
||||
Base::Placement SketchPos = sketch->Placement.getValue();
|
||||
Base::Placement SketchPos = obj->Placement.getValue();
|
||||
Base::Rotation SketchOrientation = SketchPos.getRotation();
|
||||
Base::Vector3d SketchNormal(0,0,1);
|
||||
SketchOrientation.multVec(SketchNormal,SketchNormal);
|
||||
@@ -1022,7 +1098,7 @@ const double SketchBased::getReversedAngle(const Base::Vector3d &b, const Base::
|
||||
}
|
||||
}
|
||||
|
||||
void SketchBased::getAxis(const App::DocumentObject *pcReferenceAxis, const std::vector<std::string> &subReferenceAxis,
|
||||
void ProfileBased::getAxis(const App::DocumentObject *pcReferenceAxis, const std::vector<std::string> &subReferenceAxis,
|
||||
Base::Vector3d& base, Base::Vector3d& dir)
|
||||
{
|
||||
dir = Base::Vector3d(0,0,0); // If unchanged signals that no valid axis was found
|
||||
@@ -1116,7 +1192,7 @@ void SketchBased::getAxis(const App::DocumentObject *pcReferenceAxis, const std:
|
||||
throw Base::Exception("Rotation axis reference is invalid");
|
||||
}
|
||||
|
||||
TopoDS_Shape SketchBased::refineShapeIfActive(const TopoDS_Shape& oldShape) const
|
||||
TopoDS_Shape ProfileBased::refineShapeIfActive(const TopoDS_Shape& oldShape) const
|
||||
{
|
||||
Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter()
|
||||
.GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/PartDesign");
|
||||
@@ -1128,3 +1204,88 @@ TopoDS_Shape SketchBased::refineShapeIfActive(const TopoDS_Shape& oldShape) cons
|
||||
|
||||
return oldShape;
|
||||
}
|
||||
|
||||
Base::Vector3d ProfileBased::getProfileNormal() const {
|
||||
|
||||
Base::Vector3d SketchVector(0,0,1);
|
||||
auto obj = getVerifiedObject(true);
|
||||
if(!obj)
|
||||
return SketchVector;
|
||||
|
||||
// get the Sketch plane
|
||||
if(obj->isDerivedFrom(Part::Part2DObject::getClassTypeId())) {
|
||||
Base::Placement SketchPos = obj->Placement.getValue();
|
||||
Base::Rotation SketchOrientation = SketchPos.getRotation();
|
||||
SketchOrientation.multVec(SketchVector,SketchVector);
|
||||
}
|
||||
else {
|
||||
TopoDS_Face face = getVerifiedFace(true);
|
||||
BRepAdaptor_Surface adapt(face);
|
||||
double u = adapt.FirstUParameter() + (adapt.LastUParameter() - adapt.FirstUParameter())/2.;
|
||||
double v = adapt.FirstVParameter() + (adapt.LastVParameter() - adapt.FirstVParameter())/2.;
|
||||
BRepLProp_SLProps prop(adapt,u,v,2,Precision::Confusion());
|
||||
if(prop.IsNormalDefined()) {
|
||||
gp_Pnt pnt; gp_Vec vec;
|
||||
// handles the orientation state of the shape
|
||||
BRepGProp_Face(face).Normal(u,v,pnt,vec);
|
||||
SketchVector = Base::Vector3d(vec.X(), vec.Y(), vec.Z());
|
||||
}
|
||||
}
|
||||
|
||||
return SketchVector;
|
||||
}
|
||||
|
||||
|
||||
void ProfileBased::Restore(Base::XMLReader& reader) {
|
||||
|
||||
reader.readElement("Properties");
|
||||
int Cnt = reader.getAttributeAsInteger("Count");
|
||||
|
||||
for (int i=0 ;i<Cnt ;i++) {
|
||||
reader.readElement("Property");
|
||||
const char* PropName = reader.getAttribute("name");
|
||||
const char* TypeName = reader.getAttribute("type");
|
||||
App::Property* prop = getPropertyByName(PropName);
|
||||
// NOTE: We must also check the type of the current property because a
|
||||
// subclass of PropertyContainer might change the type of a property but
|
||||
// not its name. In this case we would force to read-in a wrong property
|
||||
// type and the behaviour would be undefined.
|
||||
try {
|
||||
//check if we load the old sketch property
|
||||
if(!prop && (strcmp("Sketch", PropName) == 0) && (strcmp("App::PropertyLink", TypeName) == 0)) {
|
||||
|
||||
std::vector<std::string> vec;
|
||||
// read my element
|
||||
reader.readElement("Link");
|
||||
// get the value of my attribute
|
||||
std::string name = reader.getAttribute("value");
|
||||
|
||||
if (name != "") {
|
||||
App::Document* document = getDocument();
|
||||
DocumentObject* object = document ? document->getObject(name.c_str()) : 0;
|
||||
Profile.setValue(object, vec);
|
||||
}
|
||||
else {
|
||||
Profile.setValue(0, vec);
|
||||
}
|
||||
}
|
||||
else if (prop && strcmp(prop->getTypeId().getName(), TypeName) == 0)
|
||||
prop->Restore(reader);
|
||||
}
|
||||
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());
|
||||
}
|
||||
catch (const char* e) {
|
||||
Base::Console().Error("%s\n", e);
|
||||
}
|
||||
|
||||
reader.readEndElement("Property");
|
||||
}
|
||||
reader.readEndElement("Properties");
|
||||
}
|
||||
|
||||
@@ -37,16 +37,16 @@ class gp_Lin;
|
||||
namespace PartDesign
|
||||
{
|
||||
|
||||
class PartDesignExport SketchBased : public PartDesign::FeatureAddSub
|
||||
class PartDesignExport ProfileBased : public PartDesign::FeatureAddSub
|
||||
{
|
||||
PROPERTY_HEADER(PartDesign::SketchBased);
|
||||
|
||||
public:
|
||||
SketchBased();
|
||||
ProfileBased();
|
||||
|
||||
// Common properties for all sketch based features
|
||||
/// Sketch used to create this feature
|
||||
App::PropertyLink Sketch;
|
||||
/// Profile used to create this feature
|
||||
App::PropertyLinkSub Profile;
|
||||
/// Reverse extrusion direction
|
||||
App::PropertyBool Reversed;
|
||||
/// Make extrusion symmetric to sketch plane
|
||||
@@ -68,31 +68,46 @@ public:
|
||||
virtual void transformPlacement(const Base::Placement &transform);
|
||||
|
||||
/**
|
||||
* Verifies the linked Sketch object
|
||||
* @param silent if sketch property is malformed and the parameter is true
|
||||
* Verifies the linked Profile and returns it if it is a valid 2D object
|
||||
* @param silent if profile property is malformed and the parameter is true
|
||||
* silently returns nullptr, otherwice throw a Base::Exception.
|
||||
* Default is false.
|
||||
*/
|
||||
Part::Part2DObject* getVerifiedSketch(bool silent=false) const;
|
||||
|
||||
/**
|
||||
* Verifies the linked Profile and returns it if it is a valid object
|
||||
* @param silent if profile property is malformed and the parameter is true
|
||||
* silently returns nullptr, otherwice throw a Base::Exception.
|
||||
* Default is false.
|
||||
*/
|
||||
Part::Feature* getVerifiedObject(bool silent=false) const;
|
||||
|
||||
/**
|
||||
* Verifies the linked Object and returns the shape used as profile
|
||||
* @param silent if profile property is malformed and the parameter is true
|
||||
* silently returns nullptr, otherwice throw a Base::Exception.
|
||||
* Default is false.
|
||||
*/
|
||||
TopoDS_Face getVerifiedFace(bool silent = false) const;
|
||||
|
||||
/// Returns the wires the sketch is composed of
|
||||
std::vector<TopoDS_Wire> getSketchWires() const;
|
||||
std::vector<TopoDS_Wire> getProfileWires() const;
|
||||
|
||||
/// Returns the face of the sketch support (if any)
|
||||
const TopoDS_Face getSupportFace() const;
|
||||
|
||||
Base::Vector3d getProfileNormal() const;
|
||||
|
||||
/// retrieves the number of axes in the linked sketch (defined as construction lines)
|
||||
int getSketchAxisCount(void) const;
|
||||
|
||||
virtual Part::Feature* getBaseObject(bool silent=false) const;
|
||||
|
||||
|
||||
//backwards compatibility: profile property was renamed and has different type now
|
||||
virtual void Restore(Base::XMLReader& reader);
|
||||
|
||||
protected:
|
||||
void onChanged(const App::Property* prop);
|
||||
TopoDS_Face validateFace(const TopoDS_Face&) const;
|
||||
TopoDS_Shape makeFace(const std::vector<TopoDS_Wire>&) const;
|
||||
TopoDS_Shape makeFace(std::list<TopoDS_Wire>&) const; // for internal use only
|
||||
bool isInside(const TopoDS_Wire&, const TopoDS_Wire&) const;
|
||||
bool isParallelPlane(const TopoDS_Shape&, const TopoDS_Shape&) const;
|
||||
bool isEqualGeometry(const TopoDS_Shape&, const TopoDS_Shape&) const;
|
||||
bool isQuasiEqual(const TopoDS_Shape&, const TopoDS_Shape&) const;
|
||||
void remapSupportShape(const TopoDS_Shape&);
|
||||
TopoDS_Shape refineShapeIfActive(const TopoDS_Shape&) const;
|
||||
|
||||
@@ -136,6 +151,17 @@ protected:
|
||||
/// get Axis from ReferenceAxis
|
||||
void getAxis(const App::DocumentObject* pcReferenceAxis, const std::vector<std::string>& subReferenceAxis,
|
||||
Base::Vector3d& base, Base::Vector3d& dir);
|
||||
|
||||
TopoDS_Shape makeFace(const std::vector<TopoDS_Wire>&) const;
|
||||
|
||||
private:
|
||||
void onChanged(const App::Property* prop);
|
||||
TopoDS_Face validateFace(const TopoDS_Face&) const;
|
||||
TopoDS_Shape makeFace(std::list<TopoDS_Wire>&) const; // for internal use only
|
||||
bool isInside(const TopoDS_Wire&, const TopoDS_Wire&) const;
|
||||
bool isParallelPlane(const TopoDS_Shape&, const TopoDS_Shape&) const;
|
||||
bool isEqualGeometry(const TopoDS_Shape&, const TopoDS_Shape&) const;
|
||||
bool isQuasiEqual(const TopoDS_Shape&, const TopoDS_Shape&) const;
|
||||
};
|
||||
|
||||
} //namespace PartDesign
|
||||
|
||||
@@ -103,8 +103,8 @@ Part::Feature* Transformed::getBaseObject(bool silent) const {
|
||||
App::DocumentObject* Transformed::getSketchObject() const
|
||||
{
|
||||
std::vector<DocumentObject*> originals = Originals.getValues();
|
||||
if (!originals.empty() && originals.front()->getTypeId().isDerivedFrom(PartDesign::SketchBased::getClassTypeId())) {
|
||||
return (static_cast<PartDesign::SketchBased*>(originals.front()))->getVerifiedSketch();
|
||||
if (!originals.empty() && originals.front()->getTypeId().isDerivedFrom(PartDesign::ProfileBased::getClassTypeId())) {
|
||||
return (static_cast<PartDesign::ProfileBased*>(originals.front()))->getVerifiedSketch();
|
||||
}
|
||||
else if (!originals.empty() && originals.front()->getTypeId().isDerivedFrom(PartDesign::FeatureAddSub::getClassTypeId())) {
|
||||
return NULL;
|
||||
|
||||
Reference in New Issue
Block a user