PartDesign: Allow use of circle edge as axis in ProfileBased

This commit is contained in:
David Osterberg
2021-02-14 08:48:31 +01:00
committed by wwmayer
parent 9120d4a7d9
commit c862ec458c
7 changed files with 34 additions and 17 deletions

View File

@@ -46,6 +46,7 @@
# include <TopExp_Explorer.hxx>
# include <gp_Ax1.hxx>
# include <gp_Pln.hxx>
# include <gp_Circ.hxx>
# include <ShapeFix_Face.hxx>
# include <ShapeFix_Wire.hxx>
# include <ShapeAnalysis.hxx>
@@ -1129,12 +1130,18 @@ void ProfileBased::getAxis(const App::DocumentObject *pcReferenceAxis, const std
if (refEdge.IsNull())
throw Base::ValueError("Failed to extract rotation edge");
BRepAdaptor_Curve adapt(refEdge);
if (adapt.GetType() != GeomAbs_Line)
throw Base::TypeError("Rotation edge must be a straight line");
gp_Pnt b = adapt.Line().Location();
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());
gp_Dir d = adapt.Line().Direction();
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!

View File

@@ -77,7 +77,7 @@ bool ReferenceSelection::allow(App::Document* pDoc, App::DocumentObject* pObj, c
} else { // fallback to active part
originGroupObject = PartDesignGui::getActivePart ( );
}
App::OriginGroupExtension* originGroup = nullptr;
if(originGroupObject)
originGroup = originGroupObject->getExtensionByType<App::OriginGroupExtension>();
@@ -172,6 +172,15 @@ bool ReferenceSelection::allow(App::Document* pDoc, App::DocumentObject* pObj, c
if (point && subName.size() > 6 && subName.substr(0,6) == "Vertex") {
return true;
}
if (circle && subName.size() > 4 && subName.substr(0,4) == "Edge") {
const Part::TopoShape &shape = static_cast<const Part::Feature*>(pObj)->Shape.getValue();
TopoDS_Shape sh = shape.getSubShape(subName.c_str());
const TopoDS_Edge& edgeShape = TopoDS::Edge(sh);
BRepAdaptor_Curve adapt(edgeShape);
if (adapt.GetType() == GeomAbs_Circle) {
return true;
}
}
return false;
}
@@ -212,7 +221,7 @@ bool getReferencedSelection(const App::DocumentObject* thisObj, const Gui::Selec
std::string subname = msg.pSubName;
//check if the selection is an external reference and ask the user what to do
//of course only if thisObj is in a body, as otherwise the old workflow would not
//of course only if thisObj is in a body, as otherwise the old workflow would not
//be supported
PartDesign::Body* body = PartDesignGui::getBodyFor(thisObj, false);
bool originfeature = selObj->isDerivedFrom(App::OriginFeature::getClassTypeId());

View File

@@ -42,14 +42,16 @@ class ReferenceSelection : public Gui::SelectionFilterGate
bool allowOtherBody;
// Allow whole object selection
bool whole;
// Allow picking circular edges (incl arcs)
bool circle;
public:
ReferenceSelection(const App::DocumentObject* support_,
const bool edge_, const bool plane_, const bool planar_,
const bool point_ = false, bool whole_ = false)
const bool edge_, const bool plane_, const bool planar_,
const bool point_ = false, bool whole_ = false, bool circle_ = false)
: Gui::SelectionFilterGate((Gui::SelectionFilter*)0),
support(support_), edge(edge_), plane(plane_),
planar(planar_), point(point_), allowOtherBody(true), whole(whole_)
support(support_), edge(edge_), plane(plane_),
planar(planar_), point(point_), allowOtherBody(true), whole(whole_), circle(circle_)
{
}
/**

View File

@@ -361,7 +361,7 @@ void TaskHelixParameters::onAxisChanged(int num)
App::PropertyLinkSub &lnk = *(axesInList[num]);
if (lnk.getValue() == 0) {
// enter reference selection mode
TaskSketchBasedParameters::onSelectReference(true, true, false, true);
TaskSketchBasedParameters::onSelectReference(true, true, false, true, true);
return;
} else {
if (!pcHelix->getDocument()->isIn(lnk.getValue())){

View File

@@ -276,7 +276,7 @@ void TaskRevolutionParameters::onAxisChanged(int num)
App::PropertyLinkSub &lnk = *(axesInList[num]);
if (lnk.getValue() == 0) {
// enter reference selection mode
TaskSketchBasedParameters::onSelectReference(true, true, false, true);
TaskSketchBasedParameters::onSelectReference(true, true, false, true, true);
} else {
if (!pcRevolution->getDocument()->isIn(lnk.getValue())){
Base::Console().Error("Object was deleted\n");

View File

@@ -92,7 +92,6 @@ const QString TaskSketchBasedParameters::onAddSelection(const Gui::SelectionChan
return refStr;
}
void TaskSketchBasedParameters::startReferenceSelection(App::DocumentObject* profile, App::DocumentObject* base)
{
Gui::Document* doc = vp->getDocument();
@@ -113,7 +112,7 @@ void TaskSketchBasedParameters::finishReferenceSelection(App::DocumentObject* pr
}
}
void TaskSketchBasedParameters::onSelectReference(const bool pressed, const bool edge, const bool face, const bool planar) {
void TaskSketchBasedParameters::onSelectReference(const bool pressed, const bool edge, const bool face, const bool planar, const bool circle) {
// Note: Even if there is no solid, App::Plane and Part::Datum can still be selected
PartDesign::ProfileBased* pcSketchBased = dynamic_cast<PartDesign::ProfileBased*>(vp->getObject());
@@ -125,7 +124,7 @@ void TaskSketchBasedParameters::onSelectReference(const bool pressed, const bool
startReferenceSelection(pcSketchBased, prevSolid);
Gui::Selection().clearSelection();
Gui::Selection().addSelectionGate
(new ReferenceSelection(prevSolid, edge, face, planar));
(new ReferenceSelection(prevSolid, edge, face, planar, false, false, circle));
} else {
Gui::Selection().rmvSelectionGate();
finishReferenceSelection(pcSketchBased, prevSolid);

View File

@@ -53,7 +53,7 @@ protected:
const QString onAddSelection(const Gui::SelectionChanges& msg);
virtual void startReferenceSelection(App::DocumentObject* profile, App::DocumentObject* base);
virtual void finishReferenceSelection(App::DocumentObject* profile, App::DocumentObject* base);
void onSelectReference(const bool pressed, const bool edge, const bool face, const bool planar);
void onSelectReference(const bool pressed, const bool edge, const bool face, const bool planar, const bool circle = false);
void exitSelectionMode();
QVariant setUpToFace(const QString& text);
/// Try to find the name of a feature with the given label.