Proposals:New Mesh Class: Difference between revisions
Agouaillard (talk | contribs) |
Agouaillard (talk | contribs) |
||
Line 49: | Line 49: | ||
Right now, the polygon cell Boundary features, type and dimension API are implemented but could be made better. Specifically, the GetType could return different values depending on the number of point, as in a QuadEdgeMesh, all cells but edges are polygons. For the time being, it returns POLYGON_CELL. Get Boundary features returns the number of points, and the number of edges deduced from ... the number of points :). The other Boundary feature interface is not yet implemented. | Right now, the polygon cell Boundary features, type and dimension API are implemented but could be made better. Specifically, the GetType could return different values depending on the number of point, as in a QuadEdgeMesh, all cells but edges are polygons. For the time being, it returns POLYGON_CELL. Get Boundary features returns the number of points, and the number of edges deduced from ... the number of points :). The other Boundary feature interface is not yet implemented. | ||
=CORE: | =CORE: Review code monitoring= | ||
==1 | == 1: Code Coverage and Memory Leaks == | ||
We used the CMake / CTest options to check code coverage and mem leaks (using gcov and valgrind). | We used the CMake / CTest options to check code coverage and mem leaks (using gcov and valgrind). | ||
Here are the results as of '''July 12 2008''' | Here are the results as of '''July 12 2008''' | ||
=== | ===1.1: Code Coverage === | ||
Reports : | |||
http://www.itk.org/Testing/Sites/buildhost.creatis.insa-lyon.fr/Linux-c++/20070712-2040-Experimental/CoverageByName.html | http://www.itk.org/Testing/Sites/buildhost.creatis.insa-lyon.fr/Linux-c++/20070712-2040-Experimental/CoverageByName.html | ||
Line 175: | Line 113: | ||
|} | |} | ||
=== | ===1.2: Memory Leak, warnings and KWStyle === | ||
= Euler Operators = | = Euler Operators = |
Revision as of 17:57, 27 July 2007
This document derives the motivation and implementation of a new Mesh Class and associated Filters and IO classes for ITK
Overview
itkQuadEdgeMesh (itkQEMesh) is a new data structure for surface meshes. It is more efficient than the current itkMesh for surface processing. However it cannot handle N-dimensional meshes. Hence itkMesh and itkQEMesh will coexist in future releases of ITK. This documents describes how itkQuadEdgeMesh will be integrated into ITK 3.2.
CORE: First Implementation Subtleties
1: function vs filters
Operations in the QuadEdgeMesh are implemented in Function classes That derive from FunctionBase. The idea is to "externalize" what would otherwise be a class method to be able to extend he class at posteriori. Some modifications of the mesh are so local that you do not want to use a itkMeshToMeshFilter that would copy the entire input mesh to the output. Euler Operators are a perfect exemple of this.
It's up to filter's devellopers to use those functions inside the filter and enforce const-corectness.
2: QuadEdgeMeshCells
an itkQuadEdgeMesh uses two types f cells: a QELineCell and a QEPolygonCell.
Building QE layer
Both cell types have a constructor that creates the good underlying QE structure. In fact the LineCell always creates it, and is the core cell as far as QE layer is concerned. The polygon cell has several constructors, one of which constructs the underlying QE layer. The destructor check how the cell was created and clean the QE layer if needed. It is needed when one creates a single polygon cell and want to iterate over the PointIds. The creation of the QE layer of a mesh is done elsewhere.
The cells are not, by definition, aware of the Mesh. It's thus the mesh that is in charge of creating the overall structure. It is done through the SetCell method. Each cell must be passed over to the mesh, and thus, with a QEMesh, only the dynamic way of creating cells is allowed/possible.
The SetCell method actually build the cell and its boundaries. In the case of the Polygon, it mean that the edges of the polygon are also created (as Line Cells) and added to the QEMesh. In this case, the Line Cells create the QE layer, and a polygonal face is "put" on top of it and linked with it (see the PolygonCell constructor that takes a QEType * as argument).
You can see SetCell as the conductor and AddEdge() and AddFace() as the main musicians. SetCell is going to check if containers are set, if points are valids, if edges already exist (or it creates them using AddEdge() ), if there is still space to add a face and then creates the face (using AddFace() ), wrap it in an autopointer and put it in the cell container.
SetCell( ) accept any type of itkCell / itkQEMeshCell in input. Cells whose dimension is superior to 2 are simply dropped (QEMesh is dedicated to surface meshes). Other cells are imported. Actually, only the points of the cell are used, and a new face is created. It's different from the behavior of an itkMesh where the cells are passed over and directly stored in the container. To be backward compatible, and to avoid memory leaks caused by reusing the autopointer when passing over several cells in a row, itkQuadEdgeMesh::SetCell( ) actually releases the memory of the cell after it created its own copy of it. One should be carefull then: after a SetCell( ) the pointer to the cell is valid with an itkMesh and invalid with an itkQuadEdgeMesh.
Cell API
Most of the Cell API (see itkCellInterface.h) has been implemented
Note that for the QECells, the underlying GeometricalQuadEdge is the pointIdContainer. Each QEGeom contains one PointId (it's origin), and all the QEGeom of a given face are linked. An iterator (given by GetGeomLnext( )) allows you to go around. In native QuadEdgeMesh code, this is used in place of the usual unsigned long* as definition of the PointIdsIterator.
Unfortunatly, this is not backward compatible with the usual Cell API. We then splitted the PointIds API into 2 versions: the usual version, which basically returns null pointers, or pointers to something empty (check with the itkQuadEdgeMeshCellInterfaceTest.cxx code), and the QuadEdgeIterator based one, which is prefixed by "Internal" and used an additional type defined in the default QuadEdgeMesh traits as PointIdsInternal Iterator. This one is used within itkQuadEdgeMesh, and should be used by default by any code using only QuadEdgeMesh.
To be fully compliant with the cell API, as far as Points Id iterator are concerned, would mean implementing a local (in the cell) point container, and thus duplicate the information. It would also require building an Edge container in the polygoncell. That can be done, but would duplicate information and take more memory. We supposed that nobody would try to use a QuadEdgeCell without a QuadEdgeMesh, and made the minimum implementation for the API to be complete. If there was a need for a complete API, we could easily implement the complete solution.
Right now, the polygon cell Boundary features, type and dimension API are implemented but could be made better. Specifically, the GetType could return different values depending on the number of point, as in a QuadEdgeMesh, all cells but edges are polygons. For the time being, it returns POLYGON_CELL. Get Boundary features returns the number of points, and the number of edges deduced from ... the number of points :). The other Boundary feature interface is not yet implemented.
CORE: Review code monitoring
1: Code Coverage and Memory Leaks
We used the CMake / CTest options to check code coverage and mem leaks (using gcov and valgrind). Here are the results as of July 12 2008
1.1: Code Coverage
ITK/Code/Review Names | Coverage | # of Lines not covered | Analyze - Comments |
---|---|---|---|
itkGeometricalQuadEdge.h | 75.56% | 11 | iterators, SetRight( ). |
itkGeometricalQuadEdge.txx | 81.97% | 23 | Degenerated cases (Disconnect). |
itkQuadEdge.h | 07.69% | 12* | iterators. |
itkQuadEdge.cxx | 86.05% | 36 | Degenerated Cases not tested. |
itkQuadEdgeMesh.h | 75.00% | 03 | Requestedregion...( ), CopyInformation( ). |
itkQuadEdgeMesh.txx | 85.11% | 60* | GetEdge( cellId ), SetCell with a native itkCell. |
itkQuadEdgeMeshBaseIterator.h | 65.79% | 26 | Iterators not used. |
itkQuadEdgeMeshBoundaryEdgesMeshFunction.h | 75.00% | 01 | ----- |
itkQuadEdgeMeshBoundaryEdgesMeshFunction.txx | 88.46% | 03 | ----- |
itkQuadEdgeMeshFrontIterator.h | 81.82% | 04 | Const flavor of Constructor, Destructor. To remove? |
itkQuadEdgeMeshFrontIterator.txx | 81.40% | 08 | Bad init fall cases, FindDefaultSeed( ). |
itkQuadEdgeMeshLineCell.h | 72.73% | 03 | const versions of Get/Set Id API. |
itkQuadEdgeMeshLineCell.txx | 67.82% | 28* | Accept( ), "Internal" versions of PointIds( 8 fct. ) |
itkQuadEdgeMeshMacro.h | ------ | -- | Not Covered - Macros |
itkQuadEdgeMeshPoint.h | 100.0% | 00 | ----- |
itkQuadEdgeMeshPoint.txx | 100.0% | 00 | ----- |
itkQuadEdgeMeshPolygonCell.h | 83.33% | 03* | MakeCopy( ) |
itkQuadEdgeMeshPolygonCell.txx | 66.22% | 25* | Accept( ), BoundaryFeat., PointsIds, |
itkQuadEdgeMeshTopologyChecker.h | 100.0% | 00 | |
itkQuadEdgeMeshTopologyChecker.txx | 88.89% | 04 | |
itkQuadEdgeMeshToQuadEdgeMeshFilter.h | ------ | -- | Not Covered - Not Used - OK tested in creatis |
itkQuadEdgeMeshToQuadEdgeMeshFilter.txx | ------ | -- | Not Covered - Not Used - OK tested in creatis |
itkQuadEdgeMeshTraits.h | ------ | -- | Not Covered - Implicit + only types |
1.2: Memory Leak, warnings and KWStyle
Euler Operators
The advantage of the QE datastructure is to have only two operators to modify itself. Unfortunatly, the splice operator is not very intuitive (to say the less). Moreover a lot of topology/connectivity/geometry processing filters in the publications are based on the so-called euler operators (operators that do not modify the Euler number of the mesh). Smooth is one example of a geometry filter that does NOT require those operators as it does not modify the connectivity of the mesh, but subdivision, remeshing, simplifying (decimate => with a metric, reversible = Progressive Mesh, ...) and many other filters can be moe easily written above Euler Ops.
We mimic'ed the API on C-GAL's even though the underlying code is completly different: http://www.cgal.org/Manual/3.3/doc_html/cgal_manual/Polyhedron/Chapter_main.html Only combinatorial operateors are coded. Genus modifying method or hole/facet handling are not.
1: list of files
- ./itkQEEulerOperatorCreateCenterVertexFunction.h
- ./itkQEEulerOperatorCreateCenterVertexFunction.txx
- ./itkQEEulerOperatorDeleteCenterVertexFunction.h
- ./itkQEEulerOperatorDeleteCenterVertexFunction.txx
- ./itkQEEulerOperatorFlipEdgeFunction.h
- ./itkQEEulerOperatorFlipEdgeFunction.txx
- ./itkQEEulerOperatorJoinFacetFunction.h
- ./itkQEEulerOperatorJoinFacetFunction.txx
- ./itkQEEulerOperatorJoinVertexFunction.h
- ./itkQEEulerOperatorJoinVertexFunction.txx
- ./itkQEEulerOperatorSplitEdgeFunction.h
- ./itkQEEulerOperatorSplitFacetFunction.h
- ./itkQEEulerOperatorSplitFacetFunction.txx
- ./itkQEEulerOperatorSplitVertexFunction.h
- ./itkQEEulerOperatorSplitVertexFunction.txx
- ./EulerOperatorsTest.cxx
2: Synchronize ITK/Code/Review with Original rep
KWStyle
- Matrix
Coverage
Subtest | Percentage | Lines covered | Lines not covered | Files covered | Files not covered | Coverage metric |
---|---|---|---|---|---|---|
. | 78.68 | 1709 | 463 | 56 | 0 | 0.79 |
Examples | 66.67 | 22 | 11 | 1 | 0 | 0.74 |
Testing | 76.80 | 1112 | 336 | 17 | 0 | 0.77 |
Code | 83.21 | 575 | 116 | 38 | 0 | 0.83 |
Mem. Leaks
Names | Whatever | Memory Leak | Potential Memory Leak | Uninitialized Memory Read |
---|---|---|---|---|
EulerOperatorsTest | Report | 0 | 2 | 0 |
vtkUnstructuredGridImportTest | Report | 0 | 1 | 0 |
- write an IJ paper?
- code in Review
- release 3.4 ?