PD: fix ProfileBased::getAxis
Introduce an enum to verify the axis depending on the used context. * For helix no restriction is needed * For Pad/Pocket the axis must not be parallel with the sketch plane * For Revolve/Groove the axis must not be perpendicular with the sketch plane
This commit is contained in:
@@ -95,7 +95,7 @@ Base::Vector3d FeatureExtrude::computeDirection(const Base::Vector3d& sketchVect
|
||||
const std::vector<std::string>& subReferenceAxis = ReferenceAxis.getSubValues();
|
||||
Base::Vector3d base;
|
||||
Base::Vector3d dir;
|
||||
getAxis(pcReferenceAxis, subReferenceAxis, base, dir, false);
|
||||
getAxis(pcReferenceAxis, subReferenceAxis, base, dir, ForbiddenAxis::NotPerpendicularWithNormal);
|
||||
switch (addSubType) {
|
||||
case Type::Additive:
|
||||
extrudeDirection = dir;
|
||||
|
||||
@@ -208,7 +208,7 @@ void Groove::updateAxis(void)
|
||||
const std::vector<std::string> &subReferenceAxis = ReferenceAxis.getSubValues();
|
||||
Base::Vector3d base;
|
||||
Base::Vector3d dir;
|
||||
getAxis(pcReferenceAxis, subReferenceAxis, base, dir);
|
||||
getAxis(pcReferenceAxis, subReferenceAxis, base, dir, ForbiddenAxis::NotParallelWithNormal);
|
||||
|
||||
if (dir.Length() > Precision::Confusion()) {
|
||||
Base.setValue(base.x,base.y,base.z);
|
||||
|
||||
@@ -355,7 +355,7 @@ void Helix::updateAxis(void)
|
||||
const std::vector<std::string>& subReferenceAxis = ReferenceAxis.getSubValues();
|
||||
Base::Vector3d base;
|
||||
Base::Vector3d dir;
|
||||
getAxis(pcReferenceAxis, subReferenceAxis, base, dir, false);
|
||||
getAxis(pcReferenceAxis, subReferenceAxis, base, dir, ForbiddenAxis::NoCheck);
|
||||
|
||||
Base.setValue(base.x, base.y, base.z);
|
||||
Axis.setValue(dir.x, dir.y, dir.z);
|
||||
|
||||
@@ -204,7 +204,7 @@ void Revolution::updateAxis(void)
|
||||
const std::vector<std::string> &subReferenceAxis = ReferenceAxis.getSubValues();
|
||||
Base::Vector3d base;
|
||||
Base::Vector3d dir;
|
||||
getAxis(pcReferenceAxis, subReferenceAxis, base, dir);
|
||||
getAxis(pcReferenceAxis, subReferenceAxis, base, dir, ForbiddenAxis::NotParallelWithNormal);
|
||||
|
||||
Base.setValue(base.x,base.y,base.z);
|
||||
Axis.setValue(dir.x,dir.y,dir.z);
|
||||
|
||||
@@ -1040,10 +1040,49 @@ double ProfileBased::getReversedAngle(const Base::Vector3d &b, const Base::Vecto
|
||||
}
|
||||
|
||||
void ProfileBased::getAxis(const App::DocumentObject *pcReferenceAxis, const std::vector<std::string> &subReferenceAxis,
|
||||
Base::Vector3d& base, Base::Vector3d& dir, bool checkPerpendicular)
|
||||
Base::Vector3d& base, Base::Vector3d& dir, ProfileBased::ForbiddenAxis checkAxis)
|
||||
{
|
||||
auto verifyAxisFunc = [](ProfileBased::ForbiddenAxis checkAxis, const gp_Pln& sketchplane, const gp_Dir& dir) {
|
||||
switch (checkAxis) {
|
||||
case ForbiddenAxis::NotPerpendicularWithNormal:
|
||||
// If perpendicular to the normal then it's parallel to the plane
|
||||
if (sketchplane.Axis().Direction().IsNormal(dir, Precision::Angular()))
|
||||
throw Base::ValueError("Axis must not be parallel to the sketch plane");
|
||||
break;
|
||||
case ForbiddenAxis::NotParallelWithNormal:
|
||||
// If parallel with the normal then it's perpendicular to the plane
|
||||
if (sketchplane.Axis().Direction().IsParallel(dir, Precision::Angular()))
|
||||
throw Base::ValueError("Axis must not be perpendicular to the sketch plane");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
auto getAxisFromEdge = [](const TopoDS_Edge& refEdge, Base::Vector3d& base, Base::Vector3d& dir) {
|
||||
if (refEdge.IsNull())
|
||||
throw Base::ValueError("Failed to extract rotation edge");
|
||||
BRepAdaptor_Curve adapt(refEdge);
|
||||
gp_Pnt b;
|
||||
gp_Dir d;
|
||||
if (adapt.GetType() == GeomAbs_Line) {
|
||||
b = adapt.Line().Location();
|
||||
d = adapt.Line().Direction();
|
||||
}
|
||||
else if (adapt.GetType() == GeomAbs_Circle) {
|
||||
b = adapt.Circle().Location();
|
||||
d = adapt.Circle().Axis().Direction();
|
||||
}
|
||||
else {
|
||||
throw Base::TypeError("Edge must be a straight line, circle or arc of circle");
|
||||
}
|
||||
|
||||
base = Base::Vector3d(b.X(), b.Y(), b.Z());
|
||||
dir = Base::Vector3d(d.X(), d.Y(), d.Z());
|
||||
};
|
||||
|
||||
dir = Base::Vector3d(0,0,0); // If unchanged signals that no valid axis was found
|
||||
if (pcReferenceAxis == NULL)
|
||||
if (!pcReferenceAxis)
|
||||
return;
|
||||
|
||||
App::DocumentObject* profile = Profile.getValue();
|
||||
@@ -1102,9 +1141,7 @@ void ProfileBased::getAxis(const App::DocumentObject *pcReferenceAxis, const std
|
||||
base = line->getBasePoint();
|
||||
dir = line->getDirection();
|
||||
|
||||
// Check that axis is perpendicular with sketch plane!
|
||||
if (checkPerpendicular && sketchplane.Axis().Direction().IsParallel(gp_Dir(dir.x, dir.y, dir.z), Precision::Angular()))
|
||||
throw Base::ValueError("Rotation axis must not be perpendicular with the sketch plane");
|
||||
verifyAxisFunc(checkAxis, sketchplane, gp_Dir(dir.x, dir.y, dir.z));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1113,9 +1150,7 @@ void ProfileBased::getAxis(const App::DocumentObject *pcReferenceAxis, const std
|
||||
base = Base::Vector3d(0,0,0);
|
||||
line->Placement.getValue().multVec(Base::Vector3d (1,0,0), dir);
|
||||
|
||||
// Check that axis is perpendicular with sketch plane!
|
||||
if (checkPerpendicular && sketchplane.Axis().Direction().IsParallel(gp_Dir(dir.x, dir.y, dir.z), Precision::Angular()))
|
||||
throw Base::ValueError("Rotation axis must not be perpendicular with the sketch plane");
|
||||
verifyAxisFunc(checkAxis, sketchplane, gp_Dir(dir.x, dir.y, dir.z));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1134,34 +1169,13 @@ void ProfileBased::getAxis(const App::DocumentObject *pcReferenceAxis, const std
|
||||
}
|
||||
|
||||
if (ref.ShapeType() == TopAbs_EDGE) {
|
||||
TopoDS_Edge refEdge = TopoDS::Edge(ref);
|
||||
if (refEdge.IsNull())
|
||||
throw Base::ValueError("Failed to extract rotation edge");
|
||||
BRepAdaptor_Curve adapt(refEdge);
|
||||
gp_Pnt b;
|
||||
gp_Dir d;
|
||||
if (adapt.GetType() == GeomAbs_Line) {
|
||||
b = adapt.Line().Location();
|
||||
d = adapt.Line().Direction();
|
||||
} else if (adapt.GetType() == GeomAbs_Circle) {
|
||||
b = adapt.Circle().Location();
|
||||
d = adapt.Circle().Axis().Direction();
|
||||
} else {
|
||||
throw Base::TypeError("Rotation edge must be a straight line, circle or arc of circle");
|
||||
}
|
||||
base = Base::Vector3d(b.X(), b.Y(), b.Z());
|
||||
dir = Base::Vector3d(d.X(), d.Y(), d.Z());
|
||||
// Check that axis is co-planar with sketch plane!
|
||||
// Check that axis is perpendicular with sketch plane!
|
||||
if (sketchplane.Axis().Direction().IsParallel(d, Precision::Angular()))
|
||||
throw Base::ValueError("Rotation axis must not be perpendicular with the sketch plane");
|
||||
getAxisFromEdge(TopoDS::Edge(ref), base, dir);
|
||||
verifyAxisFunc(checkAxis, sketchplane, gp_Dir(dir.x, dir.y, dir.z));
|
||||
return;
|
||||
} else {
|
||||
throw Base::TypeError("Rotation reference must be an edge");
|
||||
}
|
||||
}
|
||||
|
||||
throw Base::TypeError("Rotation axis reference is invalid");
|
||||
throw Base::TypeError("Unsupported geometry type to get reference axis");
|
||||
}
|
||||
|
||||
Base::Vector3d ProfileBased::getProfileNormal() const {
|
||||
|
||||
@@ -42,6 +42,11 @@ class PartDesignExport ProfileBased : public PartDesign::FeatureAddSub
|
||||
PROPERTY_HEADER(PartDesign::SketchBased);
|
||||
|
||||
public:
|
||||
enum class ForbiddenAxis {
|
||||
NoCheck = 0,
|
||||
NotPerpendicularWithNormal = 1,
|
||||
NotParallelWithNormal = 2
|
||||
};
|
||||
ProfileBased();
|
||||
|
||||
// Common properties for all sketch based features
|
||||
@@ -182,7 +187,7 @@ protected:
|
||||
double getReversedAngle(const Base::Vector3d& b, const Base::Vector3d& v);
|
||||
/// get Axis from ReferenceAxis
|
||||
void getAxis(const App::DocumentObject* pcReferenceAxis, const std::vector<std::string>& subReferenceAxis,
|
||||
Base::Vector3d& base, Base::Vector3d& dir, bool checkPerpendicular=true);
|
||||
Base::Vector3d& base, Base::Vector3d& dir, ForbiddenAxis checkAxis);
|
||||
|
||||
void onChanged(const App::Property* prop);
|
||||
private:
|
||||
|
||||
Reference in New Issue
Block a user