PD: cleanup the mess with boolean arguments and replace them with a bitmask
This commit is contained in:
@@ -226,6 +226,7 @@ SET(PartDesignGuiModule_SRCS
|
||||
Command.cpp
|
||||
CommandPrimitive.cpp
|
||||
CommandBody.cpp
|
||||
EnumFlags.h
|
||||
Resources/PartDesign.qrc
|
||||
PreCompiled.cpp
|
||||
PreCompiled.h
|
||||
|
||||
51
src/Mod/PartDesign/Gui/EnumFlags.h
Normal file
51
src/Mod/PartDesign/Gui/EnumFlags.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2021 Werner Mayer <wmayer[at]users.sourceforge.net> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#ifndef PARTDESIGNGUI_ENUMFLAGS_H
|
||||
#define PARTDESIGNGUI_ENUMFLAGS_H
|
||||
|
||||
#include <QFlags>
|
||||
|
||||
namespace PartDesignGui {
|
||||
|
||||
// https://wiggling-bits.net/using-enum-classes-as-type-safe-bitmasks/
|
||||
// https://www.boost.org/doc/libs/1_66_0/boost/detail/bitmask.hpp
|
||||
// https://stackoverflow.com/questions/1448396/how-to-use-enums-as-flags-in-c
|
||||
|
||||
enum class AllowSelection {
|
||||
NONE = 0,
|
||||
EDGE = 1 << 0, /**< Allow picking edges */
|
||||
FACE = 1 << 1, /**< Allow picking faces */
|
||||
PLANAR = 1 << 2, /**< Allow only linear edges and planar faces */
|
||||
CIRCLE = 1 << 3, /**< Allow picking circular edges (incl arcs) */
|
||||
POINT = 1 << 4, /**< Allow picking datum points */
|
||||
OTHERBODY = 1 << 5, /**< Allow picking objects from another body in the same part */
|
||||
WHOLE = 1 << 6 /**< Allow whole object selection */
|
||||
};
|
||||
Q_DECLARE_FLAGS(AllowSelectionFlags, AllowSelection)
|
||||
|
||||
} //namespace PartDesignGui
|
||||
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(PartDesignGui::AllowSelectionFlags)
|
||||
|
||||
#endif // PARTDESIGNGUI_ENUMFLAGS_H
|
||||
@@ -90,9 +90,9 @@ bool ReferenceSelection::allow(App::Document* pDoc, App::DocumentObject* pObj, c
|
||||
// Enable selection from origin of current part/
|
||||
if ( pObj->getTypeId().isDerivedFrom(App::OriginFeature::getClassTypeId()) ) {
|
||||
bool fits = false;
|
||||
if ( plane && pObj->getTypeId().isDerivedFrom(App::Plane::getClassTypeId()) ) {
|
||||
if ( type.testFlag(AllowSelection::FACE) && pObj->getTypeId().isDerivedFrom(App::Plane::getClassTypeId()) ) {
|
||||
fits = true;
|
||||
} else if ( edge && pObj->getTypeId().isDerivedFrom(App::Line::getClassTypeId()) ) {
|
||||
} else if ( type.testFlag(AllowSelection::EDGE) && pObj->getTypeId().isDerivedFrom(App::Line::getClassTypeId()) ) {
|
||||
fits = true;
|
||||
}
|
||||
|
||||
@@ -107,8 +107,9 @@ bool ReferenceSelection::allow(App::Document* pDoc, App::DocumentObject* pObj, c
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (const Base::Exception&)
|
||||
{ }
|
||||
}
|
||||
catch (const Base::Exception&) {
|
||||
}
|
||||
}
|
||||
return false; // The Plane/Axis doesn't fits our needs
|
||||
}
|
||||
@@ -117,21 +118,21 @@ bool ReferenceSelection::allow(App::Document* pDoc, App::DocumentObject* pObj, c
|
||||
|
||||
if (!body) { // Allow selecting Part::Datum features from the active Body
|
||||
return false;
|
||||
} else if (!allowOtherBody && !body->hasObject(pObj)) {
|
||||
} else if (!type.testFlag(AllowSelection::OTHERBODY) && !body->hasObject(pObj)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (plane && (pObj->getTypeId().isDerivedFrom(PartDesign::Plane::getClassTypeId())))
|
||||
if (type.testFlag(AllowSelection::FACE) && (pObj->getTypeId().isDerivedFrom(PartDesign::Plane::getClassTypeId())))
|
||||
return true;
|
||||
if (edge && (pObj->getTypeId().isDerivedFrom(PartDesign::Line::getClassTypeId())))
|
||||
if (type.testFlag(AllowSelection::EDGE) && (pObj->getTypeId().isDerivedFrom(PartDesign::Line::getClassTypeId())))
|
||||
return true;
|
||||
if (point && (pObj->getTypeId().isDerivedFrom(PartDesign::Point::getClassTypeId())))
|
||||
if (type.testFlag(AllowSelection::POINT) && (pObj->getTypeId().isDerivedFrom(PartDesign::Point::getClassTypeId())))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!allowOtherBody) {
|
||||
if (!type.testFlag(AllowSelection::OTHERBODY)) {
|
||||
if (support == NULL)
|
||||
return false;
|
||||
if (pObj != support)
|
||||
@@ -139,7 +140,7 @@ bool ReferenceSelection::allow(App::Document* pDoc, App::DocumentObject* pObj, c
|
||||
}
|
||||
// Handle selection of geometry elements
|
||||
if (!sSubName || sSubName[0] == '\0')
|
||||
return whole;
|
||||
return type.testFlag(AllowSelection::WHOLE);
|
||||
|
||||
// resolve links if needed
|
||||
if (!pObj->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) {
|
||||
@@ -148,12 +149,12 @@ bool ReferenceSelection::allow(App::Document* pDoc, App::DocumentObject* pObj, c
|
||||
|
||||
if (pObj && pObj->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) {
|
||||
std::string subName(sSubName);
|
||||
if (edge && subName.compare(0, 4, "Edge") == 0) {
|
||||
if (type.testFlag(AllowSelection::EDGE) && subName.compare(0, 4, "Edge") == 0) {
|
||||
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);
|
||||
if (!edgeShape.IsNull()) {
|
||||
if (planar) {
|
||||
if (type.testFlag(AllowSelection::PLANAR)) {
|
||||
BRepAdaptor_Curve adapt(edgeShape);
|
||||
if (adapt.GetType() == GeomAbs_Line)
|
||||
return true;
|
||||
@@ -162,12 +163,12 @@ bool ReferenceSelection::allow(App::Document* pDoc, App::DocumentObject* pObj, c
|
||||
}
|
||||
}
|
||||
}
|
||||
if (plane && subName.compare(0, 4, "Face") == 0) {
|
||||
if (type.testFlag(AllowSelection::FACE) && subName.compare(0, 4, "Face") == 0) {
|
||||
const Part::TopoShape &shape = static_cast<const Part::Feature*>(pObj)->Shape.getValue();
|
||||
TopoDS_Shape sh = shape.getSubShape(subName.c_str());
|
||||
const TopoDS_Face& face = TopoDS::Face(sh);
|
||||
if (!face.IsNull()) {
|
||||
if (planar) {
|
||||
if (type.testFlag(AllowSelection::PLANAR)) {
|
||||
BRepAdaptor_Surface adapt(face);
|
||||
if (adapt.GetType() == GeomAbs_Plane)
|
||||
return true;
|
||||
@@ -176,10 +177,10 @@ bool ReferenceSelection::allow(App::Document* pDoc, App::DocumentObject* pObj, c
|
||||
}
|
||||
}
|
||||
}
|
||||
if (point && subName.compare(0, 6, "Vertex") == 0) {
|
||||
if (type.testFlag(AllowSelection::POINT) && subName.compare(0, 6, "Vertex") == 0) {
|
||||
return true;
|
||||
}
|
||||
if (circle && subName.compare(0, 4, "Edge") == 0) {
|
||||
if (type.testFlag(AllowSelection::CIRCLE) && subName.compare(0, 4, "Edge") == 0) {
|
||||
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);
|
||||
|
||||
@@ -25,33 +25,21 @@
|
||||
#define GUI_ReferenceSelection_H
|
||||
|
||||
#include <Gui/SelectionFilter.h>
|
||||
#include <Mod/PartDesign/Gui/EnumFlags.h>
|
||||
|
||||
namespace PartDesignGui {
|
||||
|
||||
class ReferenceSelection : public Gui::SelectionFilterGate
|
||||
{
|
||||
// TODO Replace this set of bools with bitwice enum (2015-09-04, Fat-Zer)
|
||||
const App::DocumentObject* support;
|
||||
// If set to true, allow picking edges or planes or both
|
||||
bool edge, plane;
|
||||
// If set to true, allow only linear edges and planar faces
|
||||
bool planar;
|
||||
// If set to true, allow picking datum points
|
||||
bool point;
|
||||
// If set to true, allow picking objects from another body in the same part
|
||||
bool allowOtherBody;
|
||||
// Allow whole object selection
|
||||
bool whole;
|
||||
// Allow picking circular edges (incl arcs)
|
||||
bool circle;
|
||||
AllowSelectionFlags type;
|
||||
|
||||
public:
|
||||
ReferenceSelection(const App::DocumentObject* support_,
|
||||
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_), circle(circle_)
|
||||
AllowSelectionFlags type)
|
||||
: Gui::SelectionFilterGate(static_cast<Gui::SelectionFilter*>(nullptr))
|
||||
, support(support_)
|
||||
, type(type)
|
||||
{
|
||||
}
|
||||
/**
|
||||
|
||||
@@ -212,7 +212,9 @@ void TaskDraftParameters::onButtonPlane(bool checked)
|
||||
hideObject();
|
||||
selectionMode = plane;
|
||||
Gui::Selection().clearSelection();
|
||||
Gui::Selection().addSelectionGate(new ReferenceSelection(this->getBase(), true, true, true));
|
||||
Gui::Selection().addSelectionGate(new ReferenceSelection(this->getBase(), AllowSelection::EDGE |
|
||||
AllowSelection::FACE |
|
||||
AllowSelection::PLANAR));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,7 +225,8 @@ void TaskDraftParameters::onButtonLine(bool checked)
|
||||
hideObject();
|
||||
selectionMode = line;
|
||||
Gui::Selection().clearSelection();
|
||||
Gui::Selection().addSelectionGate(new ReferenceSelection(this->getBase(), true, false, true));
|
||||
Gui::Selection().addSelectionGate(new ReferenceSelection(this->getBase(), AllowSelection::EDGE |
|
||||
AllowSelection::PLANAR));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -145,8 +145,11 @@ void TaskDressUpParameters::onButtonRefAdd(bool checked)
|
||||
clearButtons(refAdd);
|
||||
hideObject();
|
||||
selectionMode = refAdd;
|
||||
AllowSelectionFlags allow;
|
||||
allow.setFlag(AllowSelection::EDGE, allowEdges);
|
||||
allow.setFlag(AllowSelection::FACE, allowFaces);
|
||||
Gui::Selection().clearSelection();
|
||||
Gui::Selection().addSelectionGate(new ReferenceSelection(this->getBase(), allowEdges, allowFaces, false));
|
||||
Gui::Selection().addSelectionGate(new ReferenceSelection(this->getBase(), allow));
|
||||
DressUpView->highlightReferences(true);
|
||||
} else {
|
||||
exitSelectionMode();
|
||||
@@ -160,8 +163,11 @@ void TaskDressUpParameters::onButtonRefRemove(const bool checked)
|
||||
clearButtons(refRemove);
|
||||
hideObject();
|
||||
selectionMode = refRemove;
|
||||
Gui::Selection().clearSelection();
|
||||
Gui::Selection().addSelectionGate(new ReferenceSelection(this->getBase(), allowEdges, allowFaces, false));
|
||||
AllowSelectionFlags allow;
|
||||
allow.setFlag(AllowSelection::EDGE, allowEdges);
|
||||
allow.setFlag(AllowSelection::FACE, allowFaces);
|
||||
Gui::Selection().clearSelection();
|
||||
Gui::Selection().addSelectionGate(new ReferenceSelection(this->getBase(), allow));
|
||||
DressUpView->highlightReferences(true);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -411,7 +411,9 @@ void TaskExtrudeParameters::onDirectionCBChanged(int num)
|
||||
// to distinguish that this is the direction selection
|
||||
selectionFace = false;
|
||||
setDirectionMode(num);
|
||||
TaskSketchBasedParameters::onSelectReference(true, true, false, true, true);
|
||||
TaskSketchBasedParameters::onSelectReference(true, AllowSelection::EDGE |
|
||||
AllowSelection::PLANAR |
|
||||
AllowSelection::CIRCLE);
|
||||
}
|
||||
else {
|
||||
if (lnk.getValue()) {
|
||||
@@ -564,7 +566,7 @@ void TaskExtrudeParameters::onButtonFace(const bool pressed)
|
||||
selectionFace = true;
|
||||
|
||||
// only faces are allowed
|
||||
TaskSketchBasedParameters::onSelectReference(pressed, false, true, false);
|
||||
TaskSketchBasedParameters::onSelectReference(pressed, AllowSelection::FACE);
|
||||
|
||||
// Update button if onButtonFace() is called explicitly
|
||||
ui->buttonFace->setChecked(pressed);
|
||||
|
||||
@@ -426,7 +426,9 @@ void TaskHelixParameters::onAxisChanged(int num)
|
||||
App::PropertyLinkSub& lnk = *(axesInList[num]);
|
||||
if (lnk.getValue() == 0) {
|
||||
// enter reference selection mode
|
||||
TaskSketchBasedParameters::onSelectReference(true, true, false, true, true);
|
||||
TaskSketchBasedParameters::onSelectReference(true, AllowSelection::EDGE |
|
||||
AllowSelection::PLANAR |
|
||||
AllowSelection::CIRCLE);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -333,7 +333,7 @@ void TaskLinearPatternParameters::onDirectionChanged(int /*num*/)
|
||||
showBase();
|
||||
selectionMode = reference;
|
||||
Gui::Selection().clearSelection();
|
||||
addReferenceSelectionGate(true, true);
|
||||
addReferenceSelectionGate(AllowSelection::EDGE | AllowSelection::FACE | AllowSelection::PLANAR);
|
||||
} else {
|
||||
exitSelectionMode();
|
||||
pcLinearPattern->Direction.Paste(dirLinks.getCurrentLink());
|
||||
|
||||
@@ -246,7 +246,7 @@ void TaskMirroredParameters::onPlaneChanged(int /*num*/)
|
||||
showBase();
|
||||
selectionMode = reference;
|
||||
Gui::Selection().clearSelection();
|
||||
addReferenceSelectionGate(false, true);
|
||||
addReferenceSelectionGate(AllowSelection::FACE | AllowSelection::PLANAR);
|
||||
} else {
|
||||
exitSelectionMode();
|
||||
pcMirrored->MirrorPlane.Paste(planeLinks.getCurrentLink());
|
||||
|
||||
@@ -324,7 +324,7 @@ void TaskPolarPatternParameters::onAxisChanged(int /*num*/)
|
||||
showBase();
|
||||
selectionMode = reference;
|
||||
Gui::Selection().clearSelection();
|
||||
addReferenceSelectionGate(true, false, false, false, true);
|
||||
addReferenceSelectionGate(AllowSelection::EDGE | AllowSelection::CIRCLE);
|
||||
} else {
|
||||
exitSelectionMode();
|
||||
pcPolarPattern->Axis.Paste(axesLinks.getCurrentLink());
|
||||
|
||||
@@ -262,7 +262,9 @@ void TaskRevolutionParameters::onAxisChanged(int num)
|
||||
App::PropertyLinkSub &lnk = *(axesInList[num]);
|
||||
if (lnk.getValue() == 0) {
|
||||
// enter reference selection mode
|
||||
TaskSketchBasedParameters::onSelectReference(true, true, false, true, true);
|
||||
TaskSketchBasedParameters::onSelectReference(true, AllowSelection::EDGE |
|
||||
AllowSelection::PLANAR |
|
||||
AllowSelection::CIRCLE);
|
||||
} else {
|
||||
if (!pcRevolution->getDocument()->isIn(lnk.getValue())){
|
||||
Base::Console().Error("Object was deleted\n");
|
||||
|
||||
@@ -112,7 +112,7 @@ void TaskSketchBasedParameters::finishReferenceSelection(App::DocumentObject* pr
|
||||
}
|
||||
}
|
||||
|
||||
void TaskSketchBasedParameters::onSelectReference(const bool pressed, const bool edge, const bool face, const bool planar, const bool circle) {
|
||||
void TaskSketchBasedParameters::onSelectReference(const bool pressed, AllowSelectionFlags allow) {
|
||||
// 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());
|
||||
@@ -123,9 +123,9 @@ void TaskSketchBasedParameters::onSelectReference(const bool pressed, const bool
|
||||
if (pressed) {
|
||||
startReferenceSelection(pcSketchBased, prevSolid);
|
||||
Gui::Selection().clearSelection();
|
||||
Gui::Selection().addSelectionGate
|
||||
(new ReferenceSelection(prevSolid, edge, face, planar, false, false, circle));
|
||||
} else {
|
||||
Gui::Selection().addSelectionGate(new ReferenceSelection(prevSolid, allow));
|
||||
}
|
||||
else {
|
||||
Gui::Selection().rmvSelectionGate();
|
||||
finishReferenceSelection(pcSketchBased, prevSolid);
|
||||
}
|
||||
@@ -135,7 +135,7 @@ void TaskSketchBasedParameters::onSelectReference(const bool pressed, const bool
|
||||
|
||||
void TaskSketchBasedParameters::exitSelectionMode()
|
||||
{
|
||||
onSelectReference(false, false, false, false);
|
||||
onSelectReference(false, AllowSelection::NONE);
|
||||
}
|
||||
|
||||
QVariant TaskSketchBasedParameters::setUpToFace(const QString& text)
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "ViewProvider.h"
|
||||
|
||||
#include "TaskFeatureParameters.h"
|
||||
#include "EnumFlags.h"
|
||||
|
||||
namespace App {
|
||||
class Property;
|
||||
@@ -53,7 +54,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, const bool circle = false);
|
||||
void onSelectReference(const bool pressed, AllowSelectionFlags);
|
||||
void exitSelectionMode();
|
||||
QVariant setUpToFace(const QString& text);
|
||||
/// Try to find the name of a feature with the given label.
|
||||
|
||||
@@ -410,10 +410,9 @@ void TaskTransformedParameters::exitSelectionMode()
|
||||
}
|
||||
}
|
||||
|
||||
void TaskTransformedParameters::addReferenceSelectionGate(bool edge, bool face, bool planar, bool whole, bool circle)
|
||||
void TaskTransformedParameters::addReferenceSelectionGate(AllowSelectionFlags allow)
|
||||
{
|
||||
std::unique_ptr<Gui::SelectionFilterGate> gateRefPtr(
|
||||
new ReferenceSelection(getBaseObject(), edge, face, planar, false, whole, circle));
|
||||
std::unique_ptr<Gui::SelectionFilterGate> gateRefPtr(new ReferenceSelection(getBaseObject(), allow));
|
||||
std::unique_ptr<Gui::SelectionFilterGate> gateDepPtr(new NoDependentsSelection(getTopTransformedObject()));
|
||||
Gui::Selection().addSelectionGate(new CombineSelectionFilterGates(gateRefPtr, gateDepPtr));
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <QComboBox>
|
||||
|
||||
#include <Mod/Part/App/Part2DObject.h>
|
||||
#include <Mod/PartDesign/Gui/EnumFlags.h>
|
||||
|
||||
#include <Gui/TaskView/TaskView.h>
|
||||
#include <Gui/Selection.h>
|
||||
@@ -188,7 +189,7 @@ protected:
|
||||
void hideBase();
|
||||
void showBase();
|
||||
|
||||
void addReferenceSelectionGate(bool edge, bool face, bool planar=true, bool whole=false, bool circle=false);
|
||||
void addReferenceSelectionGate(AllowSelectionFlags);
|
||||
|
||||
bool isViewUpdated() const;
|
||||
int getUpdateViewTimeout() const;
|
||||
|
||||
Reference in New Issue
Block a user