diff --git a/src/Mod/Complete/Gui/Workbench.cpp b/src/Mod/Complete/Gui/Workbench.cpp index d60424b2d..9b0b0fcf0 100644 --- a/src/Mod/Complete/Gui/Workbench.cpp +++ b/src/Mod/Complete/Gui/Workbench.cpp @@ -229,6 +229,7 @@ Gui::MenuItem* Workbench::setupMenuBar() const << "Mesh_PolySplit" << "Mesh_PolySegm" << "Mesh_ToolMesh" + << "Mesh_Segmentation" << "Mesh_VertexCurvature"; // Part **************************************************************************************************** diff --git a/src/Mod/Mesh/App/Core/Segmentation.h b/src/Mod/Mesh/App/Core/Segmentation.h index 07e9fa9ca..021961001 100644 --- a/src/Mod/Mesh/App/Core/Segmentation.h +++ b/src/Mod/Mesh/App/Core/Segmentation.h @@ -43,7 +43,7 @@ public: virtual bool TestFacet (const MeshFacet &rclFacet) const = 0; virtual void Initialize(unsigned long); void AddSegment(const std::vector&); - const std::vector GetSegments() const { return segments; } + const std::vector& GetSegments() const { return segments; } protected: std::vector segments; diff --git a/src/Mod/Mesh/App/FeatureMeshSegmentByMesh.h b/src/Mod/Mesh/App/FeatureMeshSegmentByMesh.h index 16f6e1a57..76c51c54b 100644 --- a/src/Mod/Mesh/App/FeatureMeshSegmentByMesh.h +++ b/src/Mod/Mesh/App/FeatureMeshSegmentByMesh.h @@ -21,8 +21,8 @@ ***************************************************************************/ -#ifndef FEATURE_MESH_SEGMENT_H -#define FEATURE_MESH_SEGMENT_H +#ifndef FEATURE_MESH_SEGMENTBYMESH_H +#define FEATURE_MESH_SEGMENTBYMESH_H #include @@ -63,4 +63,4 @@ public: } -#endif // FEATURE_MESH_SEGMENT_H +#endif // FEATURE_MESH_SEGMENTBYMESH_H diff --git a/src/Mod/Mesh/App/MeshPyImp.cpp b/src/Mod/Mesh/App/MeshPyImp.cpp index 1e32bf2f3..dd1f0e3e1 100644 --- a/src/Mod/Mesh/App/MeshPyImp.cpp +++ b/src/Mod/Mesh/App/MeshPyImp.cpp @@ -1395,8 +1395,6 @@ PyObject* MeshPy::getSegmentsByCurvature(PyObject *args) Py::List func(l); std::vector segm; - //segm.push_back(new MeshCore::MeshCurvatureCylindricalSegment(meshCurv.GetCurvature(), minFacets, dev, 4.75f)); - //segm.push_back(new MeshCore::MeshCurvaturePlanarSegment(meshCurv.GetCurvature(), minFacets, dev)); for (Py::List::iterator it = func.begin(); it != func.end(); ++it) { Py::Tuple t(*it); float c1 = (float)Py::Float(t[0]); @@ -1410,15 +1408,15 @@ PyObject* MeshPy::getSegmentsByCurvature(PyObject *args) Py::List list; for (std::vector::iterator segmIt = segm.begin(); segmIt != segm.end(); ++segmIt) { - std::vector data = (*segmIt)->GetSegments(); - delete (*segmIt); - for (std::vector::iterator it = data.begin(); it != data.end(); ++it) { + const std::vector& data = (*segmIt)->GetSegments(); + for (std::vector::const_iterator it = data.begin(); it != data.end(); ++it) { Py::List ary; for (MeshCore::MeshSegment::const_iterator jt = it->begin(); jt != it->end(); ++jt) { ary.append(Py::Int((int)*jt)); } list.append(ary); } + delete (*segmIt); } return Py::new_reference_to(list); diff --git a/src/Mod/Mesh/Gui/CMakeLists.txt b/src/Mod/Mesh/Gui/CMakeLists.txt index 9941cac13..ae4701a0f 100644 --- a/src/Mod/Mesh/Gui/CMakeLists.txt +++ b/src/Mod/Mesh/Gui/CMakeLists.txt @@ -34,6 +34,7 @@ set(Dialogs_UIC_SRCS DlgSettingsMeshView.ui DlgSmoothing.ui RemoveComponents.ui + Segmentation.ui ) qt4_wrap_ui(Dialogs_UIC_HDRS ${Dialogs_UIC_SRCS}) SET(Dialogs_SRCS @@ -53,6 +54,9 @@ SET(Dialogs_SRCS RemoveComponents.ui RemoveComponents.cpp RemoveComponents.h + Segmentation.ui + Segmentation.cpp + Segmentation.h ) SOURCE_GROUP("Dialogs" FILES ${Dialogs_SRCS}) diff --git a/src/Mod/Mesh/Gui/Command.cpp b/src/Mod/Mesh/Gui/Command.cpp index 03d971474..cc83bdaa0 100644 --- a/src/Mod/Mesh/Gui/Command.cpp +++ b/src/Mod/Mesh/Gui/Command.cpp @@ -69,6 +69,7 @@ #include "ViewProviderMeshFaceSet.h" #include "ViewProviderCurvature.h" #include "MeshEditor.h" +#include "Segmentation.h" using namespace Mesh; @@ -1368,6 +1369,39 @@ bool CmdMeshFillInteractiveHole::isActive(void) return false; } +DEF_STD_CMD_A(CmdMeshSegmentation); + +CmdMeshSegmentation::CmdMeshSegmentation() + : Command("Mesh_Segmentation") +{ + sAppModule = "Mesh"; + sGroup = QT_TR_NOOP("Mesh"); + sMenuText = QT_TR_NOOP("Create mesh segments..."); + sToolTipText = QT_TR_NOOP("Create mesh segments"); + sWhatsThis = "Mesh_Segmentation"; + sStatusTip = QT_TR_NOOP("Create mesh segments"); +} + +void CmdMeshSegmentation::activated(int iMsg) +{ + std::vector objs = Gui::Selection().getObjectsOfType + (Mesh::Feature::getClassTypeId()); + Mesh::Feature* mesh = static_cast(objs.front()); + Gui::TaskView::TaskDialog* dlg = Gui::Control().activeDialog(); + if (!dlg) { + dlg = new MeshGui::TaskSegmentation(mesh); + } + Gui::Control().showDialog(dlg); +} + +bool CmdMeshSegmentation::isActive(void) +{ + if (Gui::Control().activeDialog()) + return false; + return Gui::Selection().countObjectsOfType + (Mesh::Feature::getClassTypeId()) == 1; +} + void CreateMeshCommands(void) { Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager(); @@ -1400,4 +1434,5 @@ void CreateMeshCommands(void) rcCmdMgr.addCommand(new CmdMeshFillInteractiveHole()); rcCmdMgr.addCommand(new CmdMeshRemoveCompByHand()); rcCmdMgr.addCommand(new CmdMeshFromGeometry()); + rcCmdMgr.addCommand(new CmdMeshSegmentation()); } diff --git a/src/Mod/Mesh/Gui/Makefile.am b/src/Mod/Mesh/Gui/Makefile.am index 6b2066ff0..46158d1e1 100644 --- a/src/Mod/Mesh/Gui/Makefile.am +++ b/src/Mod/Mesh/Gui/Makefile.am @@ -7,6 +7,7 @@ BUILT_SOURCES=\ ui_DlgSettingsMeshView.h \ ui_DlgSmoothing.h \ ui_RemoveComponents.h \ + ui_Segmentation.h \ moc_DlgEvaluateMeshImp.cpp \ moc_DlgRegularSolidImp.cpp \ moc_DlgSettingsMeshView.cpp \ @@ -127,6 +128,7 @@ EXTRA_DIST = \ DlgSettingsMeshView.ui \ DlgSmoothing.ui \ RemoveComponents.ui \ + Segmentation.ui \ Resources/Mesh.qrc \ Resources/translations/Mesh_af.qm \ Resources/translations/Mesh_af.ts \ diff --git a/src/Mod/Mesh/Gui/Segmentation.cpp b/src/Mod/Mesh/Gui/Segmentation.cpp new file mode 100644 index 000000000..962d65f2e --- /dev/null +++ b/src/Mod/Mesh/Gui/Segmentation.cpp @@ -0,0 +1,136 @@ +/*************************************************************************** + * Copyright (c) 2012 Werner Mayer * + * * + * 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 * + * * + ***************************************************************************/ + + +#include "PreCompiled.h" + +#ifndef _PreComp_ +#endif + +#include "Segmentation.h" +#include "ui_Segmentation.h" +#include +#include + +#include +#include +#include +#include +#include + +using namespace MeshGui; + +Segmentation::Segmentation(Mesh::Feature* mesh, QWidget* parent, Qt::WFlags fl) + : QWidget(parent, fl), myMesh(mesh) +{ + ui = new Ui_Segmentation; + ui->setupUi(this); + ui->numPln->setRange(1, INT_MAX); + ui->numPln->setValue(100); + ui->numCyl->setRange(1, INT_MAX); + ui->numCyl->setValue(100); + ui->numSph->setRange(1, INT_MAX); + ui->numSph->setValue(100); +} + +Segmentation::~Segmentation() +{ + // no need to delete child widgets, Qt does it all for us + delete ui; +} + +void Segmentation::accept() +{ + const Mesh::MeshObject* mesh = myMesh->Mesh.getValuePtr(); + // make a copy because we might smooth the mesh before + MeshCore::MeshKernel kernel = mesh->getKernel(); + + if (ui->checkBoxSmooth->isChecked()) { + MeshCore::LaplaceSmoothing smoother(kernel); + smoother.Smooth(ui->smoothSteps->value()); + } + + MeshCore::MeshSegmentAlgorithm finder(kernel); + MeshCore::MeshCurvature meshCurv(kernel); + meshCurv.ComputePerVertex(); + + std::vector segm; + if (ui->groupBoxCyl->isChecked()) { + segm.push_back(new MeshCore::MeshCurvatureCylindricalSegment + (meshCurv.GetCurvature(), ui->numCyl->value(), ui->tolCyl->value(), ui->radCyl->value())); + } + if (ui->groupBoxSph->isChecked()) { + segm.push_back(new MeshCore::MeshCurvatureSphericalSegment + (meshCurv.GetCurvature(), ui->numSph->value(), ui->tolSph->value(), ui->radSph->value())); + } + if (ui->groupBoxPln->isChecked()) { + segm.push_back(new MeshCore::MeshCurvaturePlanarSegment + (meshCurv.GetCurvature(), ui->numPln->value(), ui->tolPln->value())); + } + finder.FindSegments(segm); + + App::Document* document = App::GetApplication().getActiveDocument(); + for (std::vector::iterator it = segm.begin(); it != segm.end(); ++it) { + const std::vector& data = (*it)->GetSegments(); + for (std::vector::const_iterator jt = data.begin(); jt != data.end(); ++jt) { + Mesh::MeshObject* segment = mesh->meshFromSegment(*jt); + Mesh::Feature* feaSegm = static_cast(document->addObject("Mesh::Feature", "Segment")); + Mesh::MeshObject* feaMesh = feaSegm->Mesh.startEditing(); + feaMesh->swap(*segment); + feaSegm->Mesh.finishEditing(); + delete segment; + } + delete (*it); + } +} + +void Segmentation::changeEvent(QEvent *e) +{ + if (e->type() == QEvent::LanguageChange) { + ui->retranslateUi(this); + } + QWidget::changeEvent(e); +} + +// --------------------------------------- + +/* TRANSLATOR MeshGui::TaskRemoveComponents */ + +TaskSegmentation::TaskSegmentation(Mesh::Feature* mesh) +{ + widget = new Segmentation(mesh); + taskbox = new Gui::TaskView::TaskBox( + QPixmap(), widget->windowTitle(), false, 0); + taskbox->groupLayout()->addWidget(widget); + Content.push_back(taskbox); +} + +TaskSegmentation::~TaskSegmentation() +{ + // automatically deleted in the sub-class +} + +bool TaskSegmentation::accept() +{ + widget->accept(); + return true; +} diff --git a/src/Mod/Mesh/Gui/Segmentation.h b/src/Mod/Mesh/Gui/Segmentation.h new file mode 100644 index 000000000..95d141163 --- /dev/null +++ b/src/Mod/Mesh/Gui/Segmentation.h @@ -0,0 +1,74 @@ +/*************************************************************************** + * Copyright (c) 2012 Werner Mayer * + * * + * 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 MESHGUI_SEGMENTATION_H +#define MESHGUI_SEGMENTATION_H + +#include +#include +#include + +// forward declarations +namespace Mesh { class Feature; } + +namespace MeshGui { +class Ui_Segmentation; + +class MeshGuiExport Segmentation : public QWidget +{ +public: + Segmentation(Mesh::Feature* mesh, QWidget* parent = 0, Qt::WFlags fl = 0); + ~Segmentation(); + void accept(); + +protected: + void changeEvent(QEvent *e); + +private: + Ui_Segmentation* ui; + Mesh::Feature* myMesh; +}; + +/** + * Embed the panel into a task dialog. + */ +class TaskSegmentation : public Gui::TaskView::TaskDialog +{ +public: + TaskSegmentation(Mesh::Feature* mesh); + ~TaskSegmentation(); + +public: + bool accept(); + + virtual QDialogButtonBox::StandardButtons getStandardButtons() const + { return QDialogButtonBox::Ok | QDialogButtonBox::Cancel; } + +private: + Segmentation* widget; + Gui::TaskView::TaskBox* taskbox; +}; + +} + +#endif // MESHGUI_SEGMENTATION_H diff --git a/src/Mod/Mesh/Gui/Segmentation.ui b/src/Mod/Mesh/Gui/Segmentation.ui new file mode 100644 index 000000000..129c89873 --- /dev/null +++ b/src/Mod/Mesh/Gui/Segmentation.ui @@ -0,0 +1,227 @@ + + + MeshGui::Segmentation + + + + 0 + 0 + 289 + 379 + + + + Mesh segmentation + + + + + + Smooth mesh + + + true + + + + + + + 3 + + + + + + + Plane + + + true + + + + + + Tolerance + + + + + + + 0.100000000000000 + + + 0.100000000000000 + + + + + + + Minumum number of faces + + + + + + + 100000 + + + 100 + + + + + + + + + + Cylinder + + + true + + + + + + Radius + + + + + + + 0.100000000000000 + + + 5.000000000000000 + + + + + + + Tolerance + + + + + + + 0.100000000000000 + + + 0.100000000000000 + + + + + + + Minimum number of faces + + + + + + + 100000 + + + 100 + + + + + + + + + + Sphere + + + true + + + + + + Radius + + + + + + + 0.100000000000000 + + + 5.000000000000000 + + + + + + + Tolerance + + + + + + + 0.100000000000000 + + + 0.100000000000000 + + + + + + + Minimum number of faces + + + + + + + 100000 + + + 100 + + + + + + + + + + + + checkBoxSmooth + toggled(bool) + smoothSteps + setEnabled(bool) + + + 75 + 24 + + + 188 + 19 + + + + + diff --git a/src/Mod/Mesh/Gui/Workbench.cpp b/src/Mod/Mesh/Gui/Workbench.cpp index a2a3fa087..25b9bd656 100644 --- a/src/Mod/Mesh/Gui/Workbench.cpp +++ b/src/Mod/Mesh/Gui/Workbench.cpp @@ -190,7 +190,8 @@ Gui::MenuItem* Workbench::setupMenuBar() const << "Mesh_FillupHoles" << "Mesh_FillInteractiveHole" << "Mesh_RemoveComponents" << "Mesh_RemoveCompByHand" << "Mesh_AddFacet" << "Mesh_Smoothing" << "Separator" << "Mesh_BuildRegularSolid" << boolean << "Separator" << "Mesh_PolySelect" << "Mesh_PolyCut" - << "Mesh_PolySplit" << "Mesh_PolySegm" << "Mesh_PolyTrim" << "Mesh_VertexCurvature"; + << "Mesh_PolySplit" << "Mesh_PolySegm" << "Mesh_PolyTrim" << "Mesh_Segmentation" + << "Mesh_VertexCurvature"; return root; }