Mesh segmentation

This commit is contained in:
wmayer 2012-05-18 15:57:32 +02:00
parent 886af5096c
commit fc53283239
11 changed files with 488 additions and 10 deletions

View File

@ -229,6 +229,7 @@ Gui::MenuItem* Workbench::setupMenuBar() const
<< "Mesh_PolySplit"
<< "Mesh_PolySegm"
<< "Mesh_ToolMesh"
<< "Mesh_Segmentation"
<< "Mesh_VertexCurvature";
// Part ****************************************************************************************************

View File

@ -43,7 +43,7 @@ public:
virtual bool TestFacet (const MeshFacet &rclFacet) const = 0;
virtual void Initialize(unsigned long);
void AddSegment(const std::vector<unsigned long>&);
const std::vector<MeshSegment> GetSegments() const { return segments; }
const std::vector<MeshSegment>& GetSegments() const { return segments; }
protected:
std::vector<MeshSegment> segments;

View File

@ -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 <App/PropertyStandard.h>
@ -63,4 +63,4 @@ public:
}
#endif // FEATURE_MESH_SEGMENT_H
#endif // FEATURE_MESH_SEGMENTBYMESH_H

View File

@ -1395,8 +1395,6 @@ PyObject* MeshPy::getSegmentsByCurvature(PyObject *args)
Py::List func(l);
std::vector<MeshCore::MeshSurfaceSegment*> 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<MeshCore::MeshSurfaceSegment*>::iterator segmIt = segm.begin(); segmIt != segm.end(); ++segmIt) {
std::vector<MeshCore::MeshSegment> data = (*segmIt)->GetSegments();
delete (*segmIt);
for (std::vector<MeshCore::MeshSegment>::iterator it = data.begin(); it != data.end(); ++it) {
const std::vector<MeshCore::MeshSegment>& data = (*segmIt)->GetSegments();
for (std::vector<MeshCore::MeshSegment>::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);

View File

@ -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})

View File

@ -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<App::DocumentObject*> objs = Gui::Selection().getObjectsOfType
(Mesh::Feature::getClassTypeId());
Mesh::Feature* mesh = static_cast<Mesh::Feature*>(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());
}

View File

@ -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 \

View File

@ -0,0 +1,136 @@
/***************************************************************************
* Copyright (c) 2012 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 *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
#endif
#include "Segmentation.h"
#include "ui_Segmentation.h"
#include <App/Application.h>
#include <App/Document.h>
#include <Mod/Mesh/App/Core/Segmentation.h>
#include <Mod/Mesh/App/Core/Curvature.h>
#include <Mod/Mesh/App/Core/Smoothing.h>
#include <Mod/Mesh/App/Mesh.h>
#include <Mod/Mesh/App/MeshFeature.h>
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<MeshCore::MeshSurfaceSegment*> 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<MeshCore::MeshSurfaceSegment*>::iterator it = segm.begin(); it != segm.end(); ++it) {
const std::vector<MeshCore::MeshSegment>& data = (*it)->GetSegments();
for (std::vector<MeshCore::MeshSegment>::const_iterator jt = data.begin(); jt != data.end(); ++jt) {
Mesh::MeshObject* segment = mesh->meshFromSegment(*jt);
Mesh::Feature* feaSegm = static_cast<Mesh::Feature*>(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;
}

View File

@ -0,0 +1,74 @@
/***************************************************************************
* Copyright (c) 2012 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 MESHGUI_SEGMENTATION_H
#define MESHGUI_SEGMENTATION_H
#include <QWidget>
#include <Gui/TaskView/TaskDialog.h>
#include <Gui/TaskView/TaskView.h>
// 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

View File

@ -0,0 +1,227 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MeshGui::Segmentation</class>
<widget class="QWidget" name="MeshGui::Segmentation">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>289</width>
<height>379</height>
</rect>
</property>
<property name="windowTitle">
<string>Mesh segmentation</string>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
<widget class="QCheckBox" name="checkBoxSmooth">
<property name="text">
<string>Smooth mesh</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="smoothSteps">
<property name="value">
<number>3</number>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QGroupBox" name="groupBoxPln">
<property name="title">
<string>Plane</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Tolerance</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QDoubleSpinBox" name="tolPln">
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Minumum number of faces</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="numPln">
<property name="maximum">
<number>100000</number>
</property>
<property name="value">
<number>100</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QGroupBox" name="groupBoxCyl">
<property name="title">
<string>Cylinder</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Radius</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QDoubleSpinBox" name="radCyl">
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>5.000000000000000</double>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Tolerance</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="tolCyl">
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Minimum number of faces</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="numCyl">
<property name="maximum">
<number>100000</number>
</property>
<property name="value">
<number>100</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QGroupBox" name="groupBoxSph">
<property name="title">
<string>Sphere</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Radius</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QDoubleSpinBox" name="radSph">
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>5.000000000000000</double>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Tolerance</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="tolSph">
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Minimum number of faces</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="numSph">
<property name="maximum">
<number>100000</number>
</property>
<property name="value">
<number>100</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>checkBoxSmooth</sender>
<signal>toggled(bool)</signal>
<receiver>smoothSteps</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>75</x>
<y>24</y>
</hint>
<hint type="destinationlabel">
<x>188</x>
<y>19</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -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;
}