Skip to content

Commit

Permalink
+ support to create faces from vertices with shape builder
Browse files Browse the repository at this point in the history
  • Loading branch information
wwmayer committed Jul 25, 2014
1 parent f0eb27f commit 4dee80f
Show file tree
Hide file tree
Showing 4 changed files with 173 additions and 53 deletions.
10 changes: 9 additions & 1 deletion src/Mod/Part/App/AppPartPy.cpp
Expand Up @@ -1022,7 +1022,8 @@ static PyObject * makeLine(PyObject *self, PyObject *args)
static PyObject * makePolygon(PyObject *self, PyObject *args)
{
PyObject *pcObj;
if (!PyArg_ParseTuple(args, "O", &pcObj)) // convert args: Python->C
PyObject *pclosed=Py_False;
if (!PyArg_ParseTuple(args, "O|O!", &pcObj, &(PyBool_Type), &pclosed)) // convert args: Python->C
return NULL; // NULL triggers exception

PY_TRY {
Expand All @@ -1048,6 +1049,13 @@ static PyObject * makePolygon(PyObject *self, PyObject *args)
if (!mkPoly.IsDone())
Standard_Failure::Raise("Cannot create polygon because less than two vertices are given");

// if the polygon should be closed
if (PyObject_IsTrue(pclosed)) {
if (!mkPoly.FirstVertex().IsSame(mkPoly.LastVertex())) {
mkPoly.Add(mkPoly.FirstVertex());
}
}

return new TopoShapeWirePy(new TopoShape(mkPoly.Wire()));
}
catch (Standard_Failure) {
Expand Down
137 changes: 112 additions & 25 deletions src/Mod/Part/Gui/TaskShapeBuilder.cpp
Expand Up @@ -110,10 +110,11 @@ ShapeBuilderWidget::ShapeBuilderWidget(QWidget* parent)

d->ui.setupUi(this);
d->ui.label->setText(QString());
d->bg.addButton(d->ui.radioButtonEdge, 0);
d->bg.addButton(d->ui.radioButtonFace, 1);
d->bg.addButton(d->ui.radioButtonShell, 2);
d->bg.addButton(d->ui.radioButtonSolid, 3);
d->bg.addButton(d->ui.radioButtonEdgeFromVertex, 0);
d->bg.addButton(d->ui.radioButtonFaceFromVertex, 1);
d->bg.addButton(d->ui.radioButtonFaceFromEdge, 2);
d->bg.addButton(d->ui.radioButtonShellFromFace, 3);
d->bg.addButton(d->ui.radioButtonSolidFromShell, 4);
d->bg.setExclusive(true);

connect(&d->bg, SIGNAL(buttonClicked(int)),
Expand All @@ -140,25 +141,29 @@ void ShapeBuilderWidget::on_createButton_clicked()

try {
if (mode == 0) {
createEdge();
createEdgeFromVertex();
}
else if (mode == 1) {
createFace();
createFaceFromVertex();
}
else if (mode == 2) {
createShell();
createFaceFromEdge();
}
else if (mode == 3) {
createSolid();
createShellFromFace();
}
else if (mode == 4) {
createSolidFromShell();
}
doc->getDocument()->recompute();
Gui::Selection().clearSelection();
}
catch (const Base::Exception& e) {
Base::Console().Error("%s\n", e.what());
}
}

void ShapeBuilderWidget::createEdge()
void ShapeBuilderWidget::createEdgeFromVertex()
{
Gui::SelectionFilter vertexFilter ("SELECT Part::Feature SUBELEMENT Vertex COUNT 2");
bool matchVertex = vertexFilter.match();
Expand Down Expand Up @@ -194,12 +199,70 @@ void ShapeBuilderWidget::createEdge()
"del _\n"
).arg(elements[0]).arg(elements[1]);

Gui::Application::Instance->activeDocument()->openCommand("Edge");
Gui::Application::Instance->runPythonCode((const char*)cmd.toAscii(), false, false);
Gui::Application::Instance->activeDocument()->commitCommand();
try {
Gui::Application::Instance->activeDocument()->openCommand("Edge");
Gui::Application::Instance->runPythonCode((const char*)cmd.toAscii(), false, false);
Gui::Application::Instance->activeDocument()->commitCommand();
}
catch (const Base::Exception&) {
Gui::Application::Instance->activeDocument()->abortCommand();
throw;
}
}

void ShapeBuilderWidget::createFace()
void ShapeBuilderWidget::createFaceFromVertex()
{
Gui::SelectionFilter vertexFilter ("SELECT Part::Feature SUBELEMENT Vertex COUNT 3..");
bool matchVertex = vertexFilter.match();
if (!matchVertex) {
QMessageBox::critical(this, tr("Wrong selection"), tr("Select three or more vertices"));
return;
}

std::vector<Gui::SelectionObject> sel = vertexFilter.Result[0];
std::vector<Gui::SelectionObject>::iterator it;
std::vector<std::string>::const_iterator jt;

QString list;
QTextStream str(&list);
str << "[";
for (it=sel.begin();it!=sel.end();++it) {
for (jt=it->getSubNames().begin();jt!=it->getSubNames().end();++jt) {
str << "App.ActiveDocument." << it->getFeatName() << ".Shape." << jt->c_str() << ".Point, ";
}
}
str << "]";

QString cmd;
if (d->ui.checkPlanar->isChecked()) {
cmd = QString::fromAscii(
"_=Part.Face(Part.makePolygon(%1, True))\n"
"if _.isNull(): raise Exception('Failed to create face')\n"
"App.ActiveDocument.addObject('Part::Feature','Face').Shape=_\n"
"del _\n"
).arg(list);
}
else {
cmd = QString::fromAscii(
"_=Part.makeFilledFace([Part.makePolygon(%1, True)])\n"
"if _.isNull(): raise Exception('Failed to create face')\n"
"App.ActiveDocument.addObject('Part::Feature','Face').Shape=_\n"
"del _\n"
).arg(list);
}

try {
Gui::Application::Instance->activeDocument()->openCommand("Face");
Gui::Application::Instance->runPythonCode((const char*)cmd.toAscii(), false, false);
Gui::Application::Instance->activeDocument()->commitCommand();
}
catch (const Base::Exception&) {
Gui::Application::Instance->activeDocument()->abortCommand();
throw;
}
}

void ShapeBuilderWidget::createFaceFromEdge()
{
Gui::SelectionFilter edgeFilter ("SELECT Part::Feature SUBELEMENT Edge COUNT 1..");
bool matchEdge = edgeFilter.match();
Expand Down Expand Up @@ -240,12 +303,18 @@ void ShapeBuilderWidget::createFace()
).arg(list);
}

Gui::Application::Instance->activeDocument()->openCommand("Face");
Gui::Application::Instance->runPythonCode((const char*)cmd.toAscii(), false, false);
Gui::Application::Instance->activeDocument()->commitCommand();
try {
Gui::Application::Instance->activeDocument()->openCommand("Face");
Gui::Application::Instance->runPythonCode((const char*)cmd.toAscii(), false, false);
Gui::Application::Instance->activeDocument()->commitCommand();
}
catch (const Base::Exception&) {
Gui::Application::Instance->activeDocument()->abortCommand();
throw;
}
}

void ShapeBuilderWidget::createShell()
void ShapeBuilderWidget::createShellFromFace()
{
Gui::SelectionFilter faceFilter ("SELECT Part::Feature SUBELEMENT Face COUNT 2..");
bool matchFace = faceFilter.match();
Expand Down Expand Up @@ -287,12 +356,18 @@ void ShapeBuilderWidget::createShell()
"del _\n"
).arg(list);

Gui::Application::Instance->activeDocument()->openCommand("Shell");
Gui::Application::Instance->runPythonCode((const char*)cmd.toAscii(), false, false);
Gui::Application::Instance->activeDocument()->commitCommand();
try {
Gui::Application::Instance->activeDocument()->openCommand("Shell");
Gui::Application::Instance->runPythonCode((const char*)cmd.toAscii(), false, false);
Gui::Application::Instance->activeDocument()->commitCommand();
}
catch (const Base::Exception&) {
Gui::Application::Instance->activeDocument()->abortCommand();
throw;
}
}

void ShapeBuilderWidget::createSolid()
void ShapeBuilderWidget::createSolidFromShell()
{
Gui::SelectionFilter partFilter ("SELECT Part::Feature COUNT 1");
bool matchPart = partFilter.match();
Expand Down Expand Up @@ -321,9 +396,15 @@ void ShapeBuilderWidget::createSolid()
"del _\n"
).arg(line);

Gui::Application::Instance->activeDocument()->openCommand("Solid");
Gui::Application::Instance->runPythonCode((const char*)cmd.toAscii(), false, false);
Gui::Application::Instance->activeDocument()->commitCommand();
try {
Gui::Application::Instance->activeDocument()->openCommand("Solid");
Gui::Application::Instance->runPythonCode((const char*)cmd.toAscii(), false, false);
Gui::Application::Instance->activeDocument()->commitCommand();
}
catch (const Base::Exception&) {
Gui::Application::Instance->activeDocument()->abortCommand();
throw;
}
}

void ShapeBuilderWidget::switchMode(int mode)
Expand All @@ -336,12 +417,18 @@ void ShapeBuilderWidget::switchMode(int mode)
d->ui.checkFaces->setEnabled(false);
}
else if (mode == 1) {
d->gate->setMode(ShapeSelection::VERTEX);
d->ui.label->setText(tr("Select a list of vertices"));
d->ui.checkPlanar->setEnabled(true);
d->ui.checkFaces->setEnabled(false);
}
else if (mode == 2) {
d->gate->setMode(ShapeSelection::EDGE);
d->ui.label->setText(tr("Select a closed set of edges"));
d->ui.checkPlanar->setEnabled(true);
d->ui.checkFaces->setEnabled(false);
}
else if (mode == 2) {
else if (mode == 3) {
d->gate->setMode(ShapeSelection::FACE);
d->ui.label->setText(tr("Select adjacent faces"));
d->ui.checkPlanar->setEnabled(false);
Expand Down
9 changes: 5 additions & 4 deletions src/Mod/Part/Gui/TaskShapeBuilder.h
Expand Up @@ -45,10 +45,11 @@ private Q_SLOTS:
void switchMode(int);

private:
void createEdge();
void createFace();
void createShell();
void createSolid();
void createEdgeFromVertex();
void createFaceFromVertex();
void createFaceFromEdge();
void createShellFromFace();
void createSolidFromShell();
void changeEvent(QEvent *e);

private:
Expand Down
70 changes: 47 additions & 23 deletions src/Mod/Part/Gui/TaskShapeBuilder.ui
Expand Up @@ -6,56 +6,77 @@
<rect>
<x>0</x>
<y>0</y>
<width>220</width>
<height>259</height>
<width>182</width>
<height>263</height>
</rect>
</property>
<property name="windowTitle">
<string>Create shape</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<item row="0" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Create shape</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" colspan="2">
<widget class="QRadioButton" name="radioButtonEdge">
<widget class="QRadioButton" name="radioButtonEdgeFromVertex">
<property name="text">
<string>Edge from vertices</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QRadioButton" name="radioButtonFace">
<item row="1" column="0" colspan="2">
<widget class="QRadioButton" name="radioButtonFaceFromVertex">
<property name="text">
<string>Face from edges</string>
<string>Face from vertices</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="checkPlanar">
<item row="2" column="0" colspan="2">
<widget class="QRadioButton" name="radioButtonFaceFromEdge">
<property name="text">
<string>Planar</string>
<string>Face from edges</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QRadioButton" name="radioButtonShell">
<item row="3" column="0" colspan="2">
<widget class="QRadioButton" name="radioButtonShellFromFace">
<property name="text">
<string>Shell from faces</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QRadioButton" name="radioButtonSolid">
<item row="4" column="0" colspan="2">
<widget class="QRadioButton" name="radioButtonSolidFromShell">
<property name="text">
<string>Solid from shell</string>
</property>
</widget>
</item>
<item row="4" column="0" colspan="2">
<item row="5" column="0" colspan="2">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QCheckBox" name="checkPlanar">
<property name="text">
<string>Planar</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QCheckBox" name="checkFaces">
<property name="text">
<string>All faces</string>
</property>
</widget>
</item>
<item row="7" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer_2">
Expand All @@ -79,17 +100,10 @@
</item>
</layout>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="checkFaces">
<property name="text">
<string>All faces</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<item row="1" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
Expand All @@ -111,6 +125,16 @@
</item>
</layout>
</widget>
<tabstops>
<tabstop>radioButtonEdgeFromVertex</tabstop>
<tabstop>radioButtonFaceFromVertex</tabstop>
<tabstop>checkPlanar</tabstop>
<tabstop>radioButtonFaceFromEdge</tabstop>
<tabstop>radioButtonShellFromFace</tabstop>
<tabstop>checkFaces</tabstop>
<tabstop>radioButtonSolidFromShell</tabstop>
<tabstop>createButton</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

0 comments on commit 4dee80f

Please sign in to comment.