PD Extrude up to multiple faces or shape
This commit is contained in:
committed by
Chris Hennes
parent
526cc024ad
commit
7ffddb6f7d
@@ -4279,7 +4279,7 @@ TopoShape& TopoShape::makeElementPrismUntil(const TopoShape& _base,
|
||||
|
||||
// Check whether the face has limits or not. Unlimited faces have no wire
|
||||
// Note: Datum planes are always unlimited
|
||||
if (checkLimits && uptoface.hasSubShape(TopAbs_WIRE)) {
|
||||
if (checkLimits && _uptoface.shapeType(true) == TopAbs_FACE && uptoface.hasSubShape(TopAbs_WIRE)) {
|
||||
TopoDS_Face face = TopoDS::Face(uptoface.getShape());
|
||||
bool remove_limits = false;
|
||||
// Remove the limits of the upToFace so that the extrusion works even if profile is larger
|
||||
|
||||
@@ -375,6 +375,7 @@ void FeatureExtrude::updateProperties(const std::string &method)
|
||||
bool isMidplaneEnabled = false;
|
||||
bool isReversedEnabled = false;
|
||||
bool isUpToFaceEnabled = false;
|
||||
bool isUpToShapeEnabled = false;
|
||||
bool isTaperVisible = false;
|
||||
bool isTaper2Visible = false;
|
||||
if (method == "Length") {
|
||||
@@ -409,6 +410,7 @@ void FeatureExtrude::updateProperties(const std::string &method)
|
||||
}
|
||||
else if (method == "UpToShape") {
|
||||
isReversedEnabled = true;
|
||||
isUpToShapeEnabled = true;
|
||||
}
|
||||
|
||||
Length.setReadOnly(!isLengthEnabled);
|
||||
@@ -420,6 +422,7 @@ void FeatureExtrude::updateProperties(const std::string &method)
|
||||
Midplane.setReadOnly(!isMidplaneEnabled);
|
||||
Reversed.setReadOnly(!isReversedEnabled);
|
||||
UpToFace.setReadOnly(!isUpToFaceEnabled);
|
||||
UpToShape.setReadOnly(!isUpToShapeEnabled);
|
||||
}
|
||||
|
||||
void FeatureExtrude::setupObject()
|
||||
@@ -558,7 +561,7 @@ App::DocumentObjectExecReturn* FeatureExtrude::buildExtrusion(ExtrudeOptions opt
|
||||
|
||||
TopoShape prism(0, getDocument()->getStringHasher());
|
||||
|
||||
if (method == "UpToFirst" || method == "UpToLast" || method == "UpToFace") {
|
||||
if (method == "UpToFirst" || method == "UpToLast" || method == "UpToFace" || method == "UpToShape") {
|
||||
// Note: This will return an unlimited planar face if support is a datum plane
|
||||
TopoShape supportface = getTopoShapeSupportFace();
|
||||
supportface.move(invObjLoc);
|
||||
@@ -567,18 +570,33 @@ App::DocumentObjectExecReturn* FeatureExtrude::buildExtrusion(ExtrudeOptions opt
|
||||
dir.Reverse();
|
||||
}
|
||||
|
||||
// Find a valid face or datum plane to extrude up to
|
||||
TopoShape upToFace;
|
||||
|
||||
if (method != "UpToShape") {
|
||||
if (method == "UpToFace") {
|
||||
getUpToFaceFromLinkSub(upToFace, UpToFace);
|
||||
upToFace.move(invObjLoc);
|
||||
TopoShape upToShape;
|
||||
int faceCount = 1;
|
||||
// Find a valid shape, face or datum plane to extrude up to
|
||||
if (method == "UpToFace") {
|
||||
getUpToFaceFromLinkSub(upToShape, UpToFace);
|
||||
upToShape.move(invObjLoc);
|
||||
faceCount = 1;
|
||||
}
|
||||
else if (method == "UpToShape") {
|
||||
try {
|
||||
faceCount = getUpToShapeFromLinkSubList(upToShape, UpToShape);
|
||||
upToShape.move(invObjLoc);
|
||||
}
|
||||
catch (Base::ValueError&){
|
||||
//no shape selected use the base
|
||||
upToShape = base;
|
||||
faceCount = 0;
|
||||
}
|
||||
getUpToFace(upToFace, base, supportface, sketchshape, method, dir);
|
||||
addOffsetToFace(upToFace, dir, Offset.getValue());
|
||||
}
|
||||
|
||||
if (faceCount == 1) {
|
||||
getUpToFace(upToShape, base, supportface, sketchshape, method, dir);
|
||||
addOffsetToFace(upToShape, dir, Offset.getValue());
|
||||
}
|
||||
else if (fabs(Offset.getValue()) > Precision::Confusion()){
|
||||
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Extrude: Can only offset one face"));
|
||||
}
|
||||
|
||||
if (!supportface.hasSubShape(TopAbs_WIRE)) {
|
||||
supportface = TopoShape();
|
||||
@@ -588,7 +606,7 @@ App::DocumentObjectExecReturn* FeatureExtrude::buildExtrusion(ExtrudeOptions opt
|
||||
base.isNull() ? TopoShape::PrismMode::None : TopoShape::PrismMode::CutFromBase;
|
||||
prism = base.makeElementPrismUntil(sketchshape,
|
||||
supportface,
|
||||
upToFace,
|
||||
upToShape,
|
||||
dir,
|
||||
mode,
|
||||
false /*CheckUpToFaceLimits.getValue()*/);
|
||||
@@ -630,7 +648,7 @@ App::DocumentObjectExecReturn* FeatureExtrude::buildExtrusion(ExtrudeOptions opt
|
||||
prism.makeElementPrismUntil(base,
|
||||
sketchshape,
|
||||
supportface,
|
||||
upToFace,
|
||||
upToShape,
|
||||
dir,
|
||||
TopoShape::PrismMode::None,
|
||||
true /*CheckUpToFaceLimits.getValue()*/);
|
||||
|
||||
@@ -55,6 +55,7 @@ Pad::Pad()
|
||||
ADD_PROPERTY_TYPE(ReferenceAxis, (nullptr), "Pad", App::Prop_None, "Reference axis of direction");
|
||||
ADD_PROPERTY_TYPE(AlongSketchNormal, (true), "Pad", App::Prop_None, "Measure pad length along the sketch normal direction");
|
||||
ADD_PROPERTY_TYPE(UpToFace, (nullptr), "Pad", App::Prop_None, "Face where pad will end");
|
||||
ADD_PROPERTY_TYPE(UpToShape, (nullptr), "Pad", App::Prop_None, "Faces or shape(s) where pad will end");
|
||||
ADD_PROPERTY_TYPE(Offset, (0.0), "Pad", App::Prop_None, "Offset from face in which pad will end");
|
||||
Offset.setConstraints(&signedLengthConstraint);
|
||||
ADD_PROPERTY_TYPE(TaperAngle, (0.0), "Pad", App::Prop_None, "Taper angle");
|
||||
|
||||
@@ -39,7 +39,7 @@ using namespace PartDesign;
|
||||
|
||||
/* TRANSLATOR PartDesign::Pocket */
|
||||
|
||||
const char* Pocket::TypeEnums[]= {"Length", "ThroughAll", "UpToFirst", "UpToFace", "TwoLengths", nullptr};
|
||||
const char* Pocket::TypeEnums[]= {"Length", "ThroughAll", "UpToFirst", "UpToFace", "TwoLengths", "UpToShape", nullptr};
|
||||
|
||||
PROPERTY_SOURCE(PartDesign::Pocket, PartDesign::FeatureExtrude)
|
||||
|
||||
@@ -56,6 +56,7 @@ Pocket::Pocket()
|
||||
ADD_PROPERTY_TYPE(ReferenceAxis, (nullptr), "Pocket", App::Prop_None, "Reference axis of direction");
|
||||
ADD_PROPERTY_TYPE(AlongSketchNormal, (true), "Pocket", App::Prop_None, "Measure pocket length along the sketch normal direction");
|
||||
ADD_PROPERTY_TYPE(UpToFace, (nullptr), "Pocket", App::Prop_None, "Face where pocket will end");
|
||||
ADD_PROPERTY_TYPE(UpToShape, (nullptr), "Pocket", App::Prop_None, "Face(s) or shape(s) where pocket will end");
|
||||
ADD_PROPERTY_TYPE(Offset, (0.0), "Pocket", App::Prop_None, "Offset from face in which pocket will end");
|
||||
Offset.setConstraints(&signedLengthConstraint);
|
||||
ADD_PROPERTY_TYPE(TaperAngle, (0.0), "Pocket", App::Prop_None, "Taper angle");
|
||||
|
||||
@@ -75,6 +75,7 @@ ProfileBased::ProfileBased()
|
||||
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, (nullptr), "SketchBased", (App::PropertyType)(App::Prop_None), "Face where feature will end");
|
||||
ADD_PROPERTY_TYPE(UpToShape, (nullptr), "SketchBased", (App::PropertyType)(App::Prop_None), "Shape where feature will end");
|
||||
ADD_PROPERTY_TYPE(AllowMultiFace, (false), "SketchBased", App::Prop_None, "Allow multiple faces in profile");
|
||||
}
|
||||
|
||||
@@ -682,6 +683,58 @@ void ProfileBased::getUpToFaceFromLinkSub(TopoShape& upToFace, const App::Proper
|
||||
}
|
||||
}
|
||||
|
||||
int ProfileBased::getUpToShapeFromLinkSubList(TopoShape& upToShape, const App::PropertyLinkSubList& refShape)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
auto subSets = refShape.getSubListValues();
|
||||
|
||||
std::vector<TopoShape> faceList;
|
||||
for (auto &subSet : subSets){
|
||||
auto ref = subSet.first;
|
||||
if (ref->isDerivedFrom<App::Plane>()) {
|
||||
faceList.push_back(makeTopoShapeFromPlane(ref));
|
||||
ret ++;
|
||||
} else {
|
||||
if (!ref->isDerivedFrom<Part::Feature>())
|
||||
throw Base::TypeError("SketchBased: Must be face of a feature");
|
||||
|
||||
auto subStrings = subSet.second;
|
||||
if (subStrings.empty() || subStrings[0].empty()) {
|
||||
TopoShape baseShape = Part::Feature::getTopoShape(ref, nullptr, true);
|
||||
for (auto face : baseShape.getSubTopoShapes(TopAbs_FACE)){
|
||||
faceList.push_back(face);
|
||||
ret ++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (auto &subString : subStrings){
|
||||
auto shape = Part::Feature::getTopoShape(ref, subString.c_str(), true);
|
||||
TopoShape face = shape;
|
||||
face = face.makeElementFace();
|
||||
if (face.isNull()) {
|
||||
throw Base::ValueError("SketchBased: Failed to extract face");
|
||||
}
|
||||
faceList.push_back(face);
|
||||
ret ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ret == 0){
|
||||
throw Base::ValueError("SketchBased: No face selected");
|
||||
}
|
||||
|
||||
upToShape = faceList[0];
|
||||
|
||||
if (ret == 1){
|
||||
return 1;
|
||||
}
|
||||
|
||||
// create a unique shell with all selected faces
|
||||
upToShape = upToShape.makeElementCompound(faceList);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ProfileBased::getFaceFromLinkSub(TopoDS_Face& upToFace, const App::PropertyLinkSub& refFace)
|
||||
{
|
||||
|
||||
@@ -57,6 +57,8 @@ public:
|
||||
App::PropertyBool Midplane;
|
||||
/// Face to extrude up to
|
||||
App::PropertyLinkSub UpToFace;
|
||||
/// Shape to extrude up to
|
||||
App::PropertyLinkSubList UpToShape;
|
||||
|
||||
App::PropertyBool AllowMultiFace;
|
||||
|
||||
@@ -164,6 +166,10 @@ protected:
|
||||
/// Extract a face from a given LinkSub
|
||||
static void getUpToFaceFromLinkSub(TopoShape& upToFace, const App::PropertyLinkSub& refFace);
|
||||
|
||||
/// Create a shape with shapes and faces from a given LinkSubList
|
||||
/// return 0 if almost one full shape is selected else the face count
|
||||
int getUpToShapeFromLinkSubList(TopoShape& upToShape, const App::PropertyLinkSubList& refShape); // TODO static
|
||||
|
||||
/// Find a valid face to extrude up to
|
||||
static void getUpToFace(TopoShape& upToFace,
|
||||
const TopoShape& support,
|
||||
|
||||
Reference in New Issue
Block a user