Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
CamiTK
CamiTK Community Edition
Commits
126b6f4f
Commit
126b6f4f
authored
Nov 07, 2017
by
Emmanuel Promayon
Browse files
FIXED clean vtkmesh code (finished!)
At last vtkmesh contains only what it should...
parent
ef5549d0
Changes
4
Hide whitespace changes
Inline
Side-by-side
sdk/actions/mesh/meshprocessing/ExportAsMDL.cpp
View file @
126b6f4f
...
...
@@ -31,25 +31,33 @@
#include <QTextStream>
#include <Application.h>
#include <QFileDialog>
#include <
Vtk
MeshComponent.h>
#include <MeshComponent.h>
#include <QPushButton>
#include <QLayout>
// CamiTK includes
#include <ActionWidget.h>
// Vtk includes
#include <vtkGeometryFilter.h>
#include <vtkTriangleFilter.h>
#include <vtkCleanPolyData.h>
#include <vtkPointData.h>
#include <vtkPolyDataNormals.h>
#include <vtkCell.h>
using
namespace
camitk
;
// --------------- Constructor -------------------
ExportAsMDL
::
ExportAsMDL
(
ActionExtension
*
extension
)
:
Action
(
extension
)
{
ExportAsMDL
::
ExportAsMDL
(
ActionExtension
*
extension
)
:
Action
(
extension
)
{
// Setting name, description and input component
setName
(
"Export As MDL"
);
setDescription
(
tr
(
"Export As MDL
"
)
);
setComponent
(
"Vtk
MeshComponent"
);
setName
(
"Export As MDL"
);
setDescription
(
tr
(
"Export As MDL
(an old legacy file format from early CAMI devices). This is kept for historical reason only."
)
);
setComponent
(
"
MeshComponent"
);
// Setting classification family and tags
setFamily
(
"Mesh Processing"
);
setFamily
(
"Mesh Processing"
);
// DO NOT Put any GUI instanciation here,
// If you need, do it in getWidget() method, using lazy instanciation
...
...
@@ -62,79 +70,176 @@ ExportAsMDL::~ExportAsMDL() {
// (except if you use smart pointers of course !!)
}
// --------------- getWidget -------------------
QWidget
*
ExportAsMDL
::
getWidget
()
{
// Use lazy instanciation (instanciate only once and when needed)
// We will return the default action widget with an additionnal button
// build or update the widget
if
(
!
actionWidget
)
{
// Setting the widget containing the parameters, using the default widget
actionWidget
=
new
ActionWidget
(
this
);
QPushButton
*
outputbutton
=
new
QPushButton
(
"Output file"
);
outputfile
=
new
QLineEdit
();
actionWidget
->
layout
()
->
addWidget
(
outputbutton
);
actionWidget
->
layout
()
->
addWidget
(
outputfile
);
QObject
::
connect
(
outputbutton
,
SIGNAL
(
released
()
),
SLOT
(
outputMDL
()
)
);
QObject
::
connect
(
outputfile
,
SIGNAL
(
textChanged
(
const
QString
&
)
),
this
,
SLOT
(
outputFileChanged
(
const
QString
&
)
)
);
}
else
{
// make sure the widget has updated targets
dynamic_cast
<
ActionWidget
*>
(
actionWidget
)
->
updateTargets
();
}
return
actionWidget
;
}
// --------------- outputMDL -------------------
void
ExportAsMDL
::
outputMDL
()
{
QString
ofile
=
QFileDialog
::
getSaveFileName
(
NULL
,
tr
(
"Save As MDL..."
),
QString
(),
tr
(
"MDL format(*.mdl)"
)
);
QString
ofile
=
QFileDialog
::
getSaveFileName
(
NULL
,
tr
(
"Save As MDL..."
),
QString
(),
tr
(
"MDL format(*.mdl)"
)
);
if
(
!
ofile
.
isEmpty
())
{
outputfile
->
setText
(
ofile
);
if
(
!
ofile
.
isEmpty
()
)
{
outputfile
->
setText
(
ofile
);
}
}
// --------------- outputFileChanged -------------------
void
ExportAsMDL
::
outputFileChanged
(
const
QString
&
ofile
)
{
fn
=
ofile
;
void
ExportAsMDL
::
outputFileChanged
(
const
QString
&
ofile
)
{
filename
=
ofile
;
}
// --------------- apply -------------------
Action
::
ApplyStatus
ExportAsMDL
::
apply
()
{
foreach
(
Component
*
comp
,
getTargets
())
{
VtkMeshComponent
*
input
=
dynamic_cast
<
VtkMeshComponent
*>
(
comp
);
process
(
input
);
Action
::
ApplyStatus
returnStatus
=
SUCCESS
;
foreach
(
Component
*
comp
,
getTargets
()
)
{
MeshComponent
*
input
=
dynamic_cast
<
MeshComponent
*>
(
comp
);
if
(
input
)
{
process
(
input
);
}
else
{
CAMITK_ERROR
(
"ExportAsMDL"
,
"apply"
,
"Target component
\"
"
<<
comp
->
getName
().
toUtf8
().
constData
()
<<
"
\"
is of type
\"
"
<<
comp
->
getHierarchy
().
value
(
0
).
toStdString
()
<<
"
\"
, expecting MeshComponent"
);
returnStatus
=
ERROR
;
// Bad input (should not be possible)
}
}
return
SUCCESS
;
return
returnStatus
;
}
// --------------- process -------------------
void
ExportAsMDL
::
process
(
MeshComponent
*
comp
)
{
if
(
!
fn
.
isEmpty
())
{
VtkMeshComponent
*
input
=
dynamic_cast
<
VtkMeshComponent
*>
(
comp
);
if
(
input
)
{
// if the filename does not have the ".mdl" extension, add it
QString
extension
=
fn
.
right
(
4
);
QString
txt
(
".mdl"
);
if
(
extension
.
compare
(
txt
)
!=
0
)
{
// add the extension to the filename
fn
+=
txt
;
}
input
->
exportMDL
(
fn
.
toStdString
());
}
void
ExportAsMDL
::
process
(
MeshComponent
*
comp
)
{
if
(
!
filename
.
isEmpty
()
)
{
// if the filename does not have the ".mdl" extension, add it
QFileInfo
fileinfo
(
filename
);
if
(
fileinfo
.
suffix
()
!=
".mdl"
)
filename
+=
".mdl"
;
saveMeshComponentToMDL
(
comp
);
}
else
{
CAMITK_WARNING
(
"ExportAsMDL"
,
"process"
,
"Output file is missing, please provide one. "
);
CAMITK_WARNING
(
"ExportAsMDL"
,
"process"
,
"Output file is missing, please provide one. "
);
}
}
// --------------- getWidget -------------------
QWidget
*
ExportAsMDL
::
getWidget
()
{
// Use lazy instanciation (instanciate only once and when needed)
// We will return the default action widget with an additionnal button
// --------------- saveMeshComponentToMDL -------------------
void
ExportAsMDL
::
saveMeshComponentToMDL
(
MeshComponent
*
comp
)
{
// build or update the widget
if
(
!
actionWidget
)
{
//
Setting the widget containing the parameters, using the default widget
actionWidget
=
new
ActionWidget
(
this
);
int
i
;
// MDL format supports only triangles. Hence, this dataset triangularized before
//
being exported (this operation is then NOT reversible).
// if the dataset is a volumetric mesh (e.g. hexahedrons), only the external surface is exported.
QPushButton
*
outputbutton
=
new
QPushButton
(
"Output file"
);
outputfile
=
new
QLineEdit
();
//extract external surface
vtkSmartPointer
<
vtkGeometryFilter
>
geomF
=
vtkSmartPointer
<
vtkGeometryFilter
>::
New
();
geomF
->
SetInputData
(
comp
->
getPointSet
()
);
// triangles
vtkSmartPointer
<
vtkTriangleFilter
>
triangleF
=
vtkSmartPointer
<
vtkTriangleFilter
>::
New
();
triangleF
->
SetInputData
(
geomF
->
GetOutput
()
);
// clean unused
vtkSmartPointer
<
vtkCleanPolyData
>
cleaner
=
vtkSmartPointer
<
vtkCleanPolyData
>::
New
();
cleaner
->
SetInputData
(
triangleF
->
GetOutput
()
);
cleaner
->
Update
();
vtkSmartPointer
<
vtkPolyData
>
ds
=
cleaner
->
GetOutput
();
//--- write as .mdl file (Registration format)
std
::
ofstream
o
(
filename
.
toUtf8
().
constData
()
);
//--- name
o
<<
"[Name, STRING]"
<<
std
::
endl
;
o
<<
comp
->
getName
().
toStdString
()
<<
std
::
endl
;
o
<<
std
::
endl
;
double
pt
[
3
];
actionWidget
->
layout
()
->
addWidget
(
outputbutton
);
actionWidget
->
layout
()
->
addWidget
(
outputfile
);
//--- vertices
o
<<
"[Vertices, ARRAY1<POINT3D>]"
<<
std
::
endl
;
if
(
ds
->
GetPoints
()
!=
nullptr
)
{
o
<<
ds
->
GetPoints
()
->
GetNumberOfPoints
()
<<
std
::
endl
;
QObject
::
connect
(
outputbutton
,
SIGNAL
(
released
()),
SLOT
(
outputMDL
()));
QObject
::
connect
(
outputfile
,
SIGNAL
(
textChanged
(
const
QString
&
)),
this
,
SLOT
(
outputFileChanged
(
const
QString
&
)));
for
(
i
=
0
;
i
<
ds
->
GetPoints
()
->
GetNumberOfPoints
();
i
++
)
{
ds
->
GetPoints
()
->
GetPoint
(
i
,
pt
);
o
<<
pt
[
0
]
<<
" "
<<
pt
[
1
]
<<
" "
<<
pt
[
2
]
<<
std
::
endl
;
}
}
o
<<
std
::
endl
;
//--- normals
o
<<
"[Normals, ARRAY1<VECTOR3D>]"
<<
std
::
endl
;
if
(
ds
->
GetPointData
()
&&
ds
->
GetPointData
()
->
GetNormals
()
)
{
// save existing normals
o
<<
ds
->
GetPointData
()
->
GetNormals
()
->
GetNumberOfTuples
()
<<
std
::
endl
;
for
(
i
=
0
;
i
<
ds
->
GetPointData
()
->
GetNormals
()
->
GetNumberOfTuples
();
i
++
)
{
ds
->
GetPointData
()
->
GetNormals
()
->
GetTuple
(
i
,
pt
);
o
<<
pt
[
0
]
<<
" "
<<
pt
[
1
]
<<
" "
<<
pt
[
2
]
<<
std
::
endl
;
}
}
else
{
// make sure the widget has updated targets
dynamic_cast
<
ActionWidget
*>
(
actionWidget
)
->
updateTargets
();
// compute the normals
vtkSmartPointer
<
vtkPolyDataNormals
>
pNormals
=
vtkSmartPointer
<
vtkPolyDataNormals
>::
New
();
pNormals
->
SetInputData
(
ds
);
pNormals
->
Update
();
if
(
pNormals
->
GetOutput
()
->
GetPointData
()
!=
nullptr
&&
pNormals
->
GetOutput
()
->
GetPointData
()
->
GetNormals
()
!=
nullptr
)
{
o
<<
pNormals
->
GetOutput
()
->
GetPointData
()
->
GetNormals
()
->
GetNumberOfTuples
()
<<
std
::
endl
;
for
(
i
=
0
;
i
<
pNormals
->
GetOutput
()
->
GetPointData
()
->
GetNormals
()
->
GetNumberOfTuples
();
i
++
)
{
pNormals
->
GetOutput
()
->
GetPointData
()
->
GetNormals
()
->
GetTuple
(
i
,
pt
);
o
<<
pt
[
0
]
<<
" "
<<
pt
[
1
]
<<
" "
<<
pt
[
2
]
<<
std
::
endl
;
}
}
}
return
actionWidget
;
}
o
<<
std
::
endl
;
//--- triangles
int
j
;
o
<<
"[Triangles, ARRAY1<STRING>]"
<<
std
::
endl
;
o
<<
ds
->
GetNumberOfCells
()
<<
std
::
endl
;
for
(
i
=
0
;
i
<
ds
->
GetNumberOfCells
();
i
++
)
{
// write it twice
for
(
j
=
0
;
j
<
ds
->
GetCell
(
i
)
->
GetNumberOfPoints
();
j
++
)
{
o
<<
ds
->
GetCell
(
i
)
->
GetPointId
(
j
)
<<
" "
;
}
for
(
j
=
0
;
j
<
ds
->
GetCell
(
i
)
->
GetNumberOfPoints
();
j
++
)
{
o
<<
ds
->
GetCell
(
i
)
->
GetPointId
(
j
)
<<
" "
;
}
o
<<
std
::
endl
;
}
}
sdk/actions/mesh/meshprocessing/ExportAsMDL.h
View file @
126b6f4f
...
...
@@ -60,13 +60,16 @@ public slots:
private:
/// helper method to simplify the target component processing
virtual
void
process
(
camitk
::
MeshComponent
*
);
void
process
(
camitk
::
MeshComponent
*
);
/// output file
QString
f
n
;
QString
f
ilename
;
/// output file editor
QLineEdit
*
outputfile
;
/// export MeshComponent in MDL format
void
saveMeshComponentToMDL
(
camitk
::
MeshComponent
*
);
};
...
...
sdk/components/vtkmesh/VtkMeshComponent.cpp
View file @
126b6f4f
...
...
@@ -26,22 +26,11 @@
#include "VtkMeshComponent.h"
// -- CamiTK stuff
#include <Application.h>
#include <MeshComponent.h>
#include <Geometry.h>
#include <InteractiveViewer.h>
#include <Property.h>
// -- vtk stuff
#include <vtkPolyData.h>
#include <vtkCleanPolyData.h>
#include <vtkPointData.h>
#include <vtkCell.h>
#include <vtkCellData.h>
#include <vtkTriangleFilter.h>
#include <vtkGeometryFilter.h>
#include <vtkPolyDataNormals.h>
#include <vtkDoubleArray.h>
#include <vtkProperty.h>
using
namespace
camitk
;
...
...
@@ -90,110 +79,6 @@ void VtkMeshComponent::initPointData() {
setActiveData
(
MeshDataModel
::
CELLS
,
NULL
);
}
// -------------------- exportMDL --------------------
bool
VtkMeshComponent
::
exportMDL
(
std
::
string
filename
)
{
if
(
myGeometry
)
{
int
i
;
// MDL format supports only triangles. Hence, this dataset triangularized before
// being exported (this operation is then NOT reversible).
// if the dataset is a volumetric mesh (e.g. hexahedrons), only the external surface is exported.
//extract external surface
vtkSmartPointer
<
vtkGeometryFilter
>
geomF
=
vtkSmartPointer
<
vtkGeometryFilter
>::
New
();
geomF
->
SetInputData
(
getPointSet
());
// triangles
vtkSmartPointer
<
vtkTriangleFilter
>
triangleF
=
vtkSmartPointer
<
vtkTriangleFilter
>::
New
();
triangleF
->
SetInputData
(
geomF
->
GetOutput
());
// clean unused
vtkSmartPointer
<
vtkCleanPolyData
>
cleaner
=
vtkSmartPointer
<
vtkCleanPolyData
>::
New
();
cleaner
->
SetInputData
(
triangleF
->
GetOutput
());
cleaner
->
Update
();
vtkSmartPointer
<
vtkPolyData
>
ds
=
cleaner
->
GetOutput
();
//--- write as .mdl file (Registration format)
std
::
ofstream
o
(
filename
.
c_str
()
);
//--- name
o
<<
"[Name, STRING]"
<<
std
::
endl
;
o
<<
getName
().
toStdString
()
<<
std
::
endl
;
o
<<
std
::
endl
;
//--- vertices
o
<<
"[Vertices, ARRAY1<POINT3D>]"
<<
std
::
endl
;
o
<<
ds
->
GetPoints
()
->
GetNumberOfPoints
()
<<
std
::
endl
;
double
pt
[
3
];
for
(
i
=
0
;
i
<
ds
->
GetPoints
()
->
GetNumberOfPoints
();
i
++
)
{
ds
->
GetPoints
()
->
GetPoint
(
i
,
pt
);
o
<<
pt
[
0
]
<<
" "
<<
pt
[
1
]
<<
" "
<<
pt
[
2
]
<<
std
::
endl
;
}
o
<<
std
::
endl
;
//--- normals
o
<<
"[Normals, ARRAY1<VECTOR3D>]"
<<
std
::
endl
;
if
(
ds
->
GetPointData
()
&&
ds
->
GetPointData
()
->
GetNormals
()
)
{
// save existing normals
o
<<
ds
->
GetPointData
()
->
GetNormals
()
->
GetNumberOfTuples
()
<<
std
::
endl
;
for
(
i
=
0
;
i
<
ds
->
GetPointData
()
->
GetNormals
()
->
GetNumberOfTuples
();
i
++
)
{
ds
->
GetPointData
()
->
GetNormals
()
->
GetTuple
(
i
,
pt
);
o
<<
pt
[
0
]
<<
" "
<<
pt
[
1
]
<<
" "
<<
pt
[
2
]
<<
std
::
endl
;
}
}
else
{
// compute the normals
vtkSmartPointer
<
vtkPolyDataNormals
>
pNormals
=
vtkSmartPointer
<
vtkPolyDataNormals
>::
New
();
pNormals
->
SetInputData
(
ds
);
pNormals
->
Update
();
o
<<
pNormals
->
GetOutput
()
->
GetPointData
()
->
GetNormals
()
->
GetNumberOfTuples
()
<<
std
::
endl
;
for
(
i
=
0
;
i
<
pNormals
->
GetOutput
()
->
GetPointData
()
->
GetNormals
()
->
GetNumberOfTuples
();
i
++
)
{
pNormals
->
GetOutput
()
->
GetPointData
()
->
GetNormals
()
->
GetTuple
(
i
,
pt
);
o
<<
pt
[
0
]
<<
" "
<<
pt
[
1
]
<<
" "
<<
pt
[
2
]
<<
std
::
endl
;
}
}
o
<<
std
::
endl
;
//--- triangles
int
j
;
o
<<
"[Triangles, ARRAY1<STRING>]"
<<
std
::
endl
;
o
<<
ds
->
GetNumberOfCells
()
<<
std
::
endl
;
for
(
i
=
0
;
i
<
ds
->
GetNumberOfCells
();
i
++
)
{
// write it twice
for
(
j
=
0
;
j
<
ds
->
GetCell
(
i
)
->
GetNumberOfPoints
();
j
++
)
{
o
<<
ds
->
GetCell
(
i
)
->
GetPointId
(
j
)
<<
" "
;
}
for
(
j
=
0
;
j
<
ds
->
GetCell
(
i
)
->
GetNumberOfPoints
();
j
++
)
{
o
<<
ds
->
GetCell
(
i
)
->
GetPointId
(
j
)
<<
" "
;
}
o
<<
std
::
endl
;
}
return
true
;
}
else
{
return
false
;
}
}
//------------------------ getPixmap ---------------------
#include "vtklogo_20x20.xpm"
QPixmap
*
VtkMeshComponent
::
myPixmap
=
NULL
;
...
...
sdk/components/vtkmesh/VtkMeshComponent.h
View file @
126b6f4f
...
...
@@ -31,8 +31,6 @@
#include "VtkMeshComponentAPI.h"
#include "VtkMeshUtil.h"
#include <vtkSmartPointer.h>
class
VtkMeshComponentProperties
;
class
vtkDoubleArray
;
class
vtkPointData
;
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment