Part: support of box selection in shape builder task panel
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -44,6 +44,7 @@ public:
|
||||
|
||||
private Q_SLOTS:
|
||||
void on_createButton_clicked();
|
||||
void on_selectButton_clicked();
|
||||
void switchMode(int);
|
||||
|
||||
private:
|
||||
|
||||
@@ -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">
|
||||
|
||||
Reference in New Issue
Block a user