Part: support of box selection in shape builder task panel

This commit is contained in:
wmayer
2022-04-19 17:05:54 +02:00
committed by wwmayer
parent 23288e7b01
commit c480014869
6 changed files with 89 additions and 19 deletions

View File

@@ -84,6 +84,8 @@ public:
};
BoxSelection::BoxSelection()
: autodelete(false)
, shapeEnum(TopAbs_SHAPE)
{
}
@@ -93,6 +95,16 @@ BoxSelection::~BoxSelection()
}
void BoxSelection::setAutoDelete(bool on)
{
autodelete = on;
}
bool BoxSelection::isAutoDelete() const
{
return autodelete;
}
void BoxSelection::selectionCallback(void * ud, SoEventCallback * cb)
{
Gui::View3DInventorViewer* view = reinterpret_cast<Gui::View3DInventorViewer*>(cb->getUserData());
@@ -129,40 +141,61 @@ void BoxSelection::selectionCallback(void * ud, SoEventCallback * cb)
if (!vp->isVisible())
continue;
const TopoDS_Shape& shape = it->Shape.getValue();
self->addFacesToSelection(doc->getName(), it->getNameInDocument(), proj, polygon, shape);
self->addShapeToSelection(doc->getName(), it->getNameInDocument(), proj, polygon, shape, self->shapeEnum);
}
view->redraw();
}
Gui::Selection().rmvSelectionGate();
delete self;
if (self->isAutoDelete()) {
delete self;
}
}
void BoxSelection::addFacesToSelection(const char* doc, const char* obj,
const char* BoxSelection::nameFromShapeType(TopAbs_ShapeEnum type) const
{
switch (type) {
case TopAbs_FACE:
return "Face";
case TopAbs_EDGE:
return "Edge";
case TopAbs_VERTEX:
return "Vertex";
default:
return nullptr;
}
}
void BoxSelection::addShapeToSelection(const char* doc, const char* obj,
const Gui::ViewVolumeProjection& proj,
const Base::Polygon2d& polygon,
const TopoDS_Shape& shape)
const TopoDS_Shape& shape,
TopAbs_ShapeEnum subtype)
{
try {
TopTools_IndexedMapOfShape M;
const char* subname = nameFromShapeType(subtype);
if (!subname)
return;
TopExp_Explorer xp_face(shape,TopAbs_FACE);
while (xp_face.More()) {
M.Add(xp_face.Current());
xp_face.Next();
TopTools_IndexedMapOfShape M;
TopExp_Explorer xp(shape, subtype);
while (xp.More()) {
M.Add(xp.Current());
xp.Next();
}
for (Standard_Integer k = 1; k <= M.Extent(); k++) {
const TopoDS_Shape& face = M(k);
const TopoDS_Shape& subshape = M(k);
TopExp_Explorer xp_vertex(face,TopAbs_VERTEX);
TopExp_Explorer xp_vertex(subshape, TopAbs_VERTEX);
while (xp_vertex.More()) {
gp_Pnt p = BRep_Tool::Pnt(TopoDS::Vertex(xp_vertex.Current()));
Base::Vector3d pt2d;
pt2d = proj(Base::Vector3d(p.X(), p.Y(), p.Z()));
if (polygon.Contains(Base::Vector2d(pt2d.x, pt2d.y))) {
std::stringstream str;
str << "Face" << k;
str << subname << k;
Gui::Selection().addSelection(doc, obj, str.str().c_str());
break;
}
@@ -174,7 +207,7 @@ void BoxSelection::addFacesToSelection(const char* doc, const char* obj,
}
}
void BoxSelection::start()
void BoxSelection::start(TopAbs_ShapeEnum shape)
{
Gui::View3DInventor* view = qobject_cast<Gui::View3DInventor*>(Gui::getMainWindow()->activeWindow());
if (view) {
@@ -186,8 +219,7 @@ void BoxSelection::start()
// called immediately
SoNode* root = viewer->getSceneGraph();
static_cast<Gui::SoFCUnifiedSelection*>(root)->selectionRole.setValue(false);
Gui::Selection().addSelectionGate(new FaceSelectionGate);
shapeEnum = shape;
}
}
}

View File

@@ -24,6 +24,8 @@
#ifndef PARTGUI_BOXSELECTION_H
#define PARTGUI_BOXSELECTION_H
#include <TopAbs_ShapeEnum.hxx>
class SoEventCallback;
class TopoDS_Shape;
@@ -44,15 +46,23 @@ public:
BoxSelection();
~BoxSelection();
void start();
void setAutoDelete(bool);
bool isAutoDelete() const;
void start(TopAbs_ShapeEnum shape);
private:
class FaceSelectionGate;
void addFacesToSelection(const char* doc, const char* obj,
void addShapeToSelection(const char* doc, const char* obj,
const Gui::ViewVolumeProjection& proj,
const Base::Polygon2d& polygon,
const TopoDS_Shape& shape);
const TopoDS_Shape& shape,
TopAbs_ShapeEnum subtype);
const char* nameFromShapeType(TopAbs_ShapeEnum) const;
static void selectionCallback(void * ud, SoEventCallback * cb);
private:
bool autodelete;
TopAbs_ShapeEnum shapeEnum;
};
} //namespace PartGui

View File

@@ -2484,7 +2484,8 @@ void CmdBoxSelection::activated(int iMsg)
{
Q_UNUSED(iMsg);
PartGui::BoxSelection* sel = new PartGui::BoxSelection();
sel->start();
sel->setAutoDelete(true);
sel->start(TopAbs_FACE);
}
bool CmdBoxSelection::isActive(void)

View File

@@ -36,6 +36,7 @@
#include "ViewProviderExt.h"
#include "ui_TaskShapeBuilder.h"
#include "TaskShapeBuilder.h"
#include "BoxSelection.h"
#include <Gui/Application.h>
#include <Gui/BitmapFactory.h>
@@ -96,6 +97,7 @@ public:
Ui_TaskShapeBuilder ui;
QButtonGroup bg;
ShapeSelection* gate;
BoxSelection selection;
Private()
{
Gui::Command::runCommand(Gui::Command::App, "from FreeCAD import Base");
@@ -202,6 +204,23 @@ void ShapeBuilderWidget::on_createButton_clicked()
}
}
void ShapeBuilderWidget::on_selectButton_clicked()
{
int id = d->bg.checkedId();
if (id == 0 || id == 2) {
d->selection.start(TopAbs_VERTEX);
}
else if (id == 1 || id == 3) {
d->selection.start(TopAbs_EDGE);
}
else if (id == 4) {
d->selection.start(TopAbs_FACE);
}
else {
QMessageBox::warning(this, tr("Unsupported"), tr("Box selection for shells is not supported"));
}
}
void ShapeBuilderWidget::createEdgeFromVertex()
{
Gui::SelectionFilter vertexFilter ("SELECT Part::Feature SUBELEMENT Vertex COUNT 2");

View File

@@ -44,6 +44,7 @@ public:
private Q_SLOTS:
void on_createButton_clicked();
void on_selectButton_clicked();
void switchMode(int);
private:

View File

@@ -95,6 +95,13 @@
</item>
<item row="10" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="selectButton">
<property name="text">
<string>Box selection...</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">