diff --git a/src/OpenMesh/Tools/CMakeLists.txt b/src/OpenMesh/Tools/CMakeLists.txt
index b4989955235933cb92b904c103bccdc501c43e0f..709360e68a64c4b9ea139f976cd182aada6f3ab8 100644
--- a/src/OpenMesh/Tools/CMakeLists.txt
+++ b/src/OpenMesh/Tools/CMakeLists.txt
@@ -9,6 +9,7 @@ include_directories (
set (directories
.
Decimater
+ Dualizer
Smoother
Subdivider/Adaptive/Composite
Subdivider/Uniform/Composite
@@ -44,6 +45,7 @@ if (NOT ACG_PROJECT_MACOS_BUNDLE OR NOT APPLE)
if ( APPLE )
FILE(GLOB files_install_Decimater "${CMAKE_CURRENT_SOURCE_DIR}/Decimater/*.hh" "${CMAKE_CURRENT_SOURCE_DIR}/Decimater/*T.cc" )
+ FILE(GLOB files_install_Dualizer "${CMAKE_CURRENT_SOURCE_DIR}/Dualizer/*.hh" "${CMAKE_CURRENT_SOURCE_DIR}/Dualizer/*T.cc" )
FILE(GLOB files_install_KERNEL_OSG "${CMAKE_CURRENT_SOURCE_DIR}/Kernel_OSG/*.hh" "${CMAKE_CURRENT_SOURCE_DIR}/Kernel_OSG/*T.cc" )
FILE(GLOB files_install_Smoother "${CMAKE_CURRENT_SOURCE_DIR}/Smoother/*.hh" "${CMAKE_CURRENT_SOURCE_DIR}/Decimater/*T.cc" )
FILE(GLOB files_install_Subdivider_Adaptive "${CMAKE_CURRENT_SOURCE_DIR}/Subdivider/Adaptive/Composite/*.hh" "${CMAKE_CURRENT_SOURCE_DIR}/Subdivider/Adaptive/Composite/*T.cc" )
@@ -52,6 +54,7 @@ if ( APPLE )
FILE(GLOB files_install_Utils "${CMAKE_CURRENT_SOURCE_DIR}/Utils/*.hh" "${CMAKE_CURRENT_SOURCE_DIR}/Utils/*T.cc" "${CMAKE_CURRENT_SOURCE_DIR}/Utils/getopt.h" )
FILE(GLOB files_install_VDPM "${CMAKE_CURRENT_SOURCE_DIR}/VDPM/*.hh" "${CMAKE_CURRENT_SOURCE_DIR}/VDPM/*T.cc" )
INSTALL(FILES ${files_install_Decimater} DESTINATION include/OpenMesh/Tools/Decimater )
+ INSTALL(FILES ${files_install_Dualizer} DESTINATION include/OpenMesh/Tools/Dualizer )
INSTALL(FILES ${files_install_KERNEL_OSG} DESTINATION include/OpenMesh/Tools/Kernel_OSG )
INSTALL(FILES ${files_install_Smoother} DESTINATION include/OpenMesh/Tools/Smoother )
INSTALL(FILES ${files_install_Subdivider_Adaptive} DESTINATION include/OpenMesh/Tools/Subdivider/Adaptive/Composite )
diff --git a/src/OpenMesh/Tools/Dualizer/meshDualT.hh b/src/OpenMesh/Tools/Dualizer/meshDualT.hh
new file mode 100644
index 0000000000000000000000000000000000000000..44dd37279b4bae75b33e92de0b692e4fa82a9c2d
--- /dev/null
+++ b/src/OpenMesh/Tools/Dualizer/meshDualT.hh
@@ -0,0 +1,138 @@
+/*===========================================================================*\
+ * *
+ * OpenMesh *
+ * Copyright (C) 2001-2009 by Computer Graphics Group, RWTH Aachen *
+ * www.openmesh.org *
+ * *
+ *---------------------------------------------------------------------------*
+ * This file is part of OpenMesh. *
+ * *
+ * OpenMesh is free software: you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License as *
+ * published by the Free Software Foundation, either version 3 of *
+ * the License, or (at your option) any later version with the *
+ * following exceptions: *
+ * *
+ * If other files instantiate templates or use macros *
+ * or inline functions from this file, or you compile this file and *
+ * link it with other files to produce an executable, this file does *
+ * not by itself cause the resulting executable to be covered by the *
+ * GNU Lesser General Public License. This exception does not however *
+ * invalidate any other reasons why the executable file might be *
+ * covered by the GNU Lesser General Public License. *
+ * *
+ * OpenMesh 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 Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU LesserGeneral Public *
+ * License along with OpenMesh. If not, *
+ * see . *
+ * *
+\*===========================================================================*/
+
+/*===========================================================================*\
+ * *
+ * $Revision$ *
+ * $Date$ *
+ * *
+\*===========================================================================*/
+
+/*
+ Compute the dual of a mesh:
+ - each face of the original mesh is replaced by a vertex at the center of gravity of the vertices of the face
+ - each vertex of the original mesh is replaced by a face containing the dual vertices of its primal adjacent faces
+
+ Changelog:
+ - 29 mar 2010: initial work
+
+ Programmer:
+ Clement Courbet - clement.courbet@ecp.fr
+
+ (c) Clement Courbet 2010
+*/
+
+#ifndef OPENMESH_MESH_DUAL_H
+#define OPENMESH_MESH_DUAL_H
+
+//== INCLUDES =================================================================
+
+// -------------------- STL
+#include
+#if defined(OM_CC_MIPS)
+# include
+#else
+# include
+#endif
+
+#include
+#include
+
+//== FORWARDDECLARATIONS ======================================================
+
+//== NAMESPACES ===============================================================
+
+
+namespace OpenMesh {
+namespace Util {
+
+//== Function DEFINITION =========================================================
+
+/** \brief create a dual mesh
+*
+* This function takes a mesh and computes the dual mesh of it. Each face of the original mesh is replaced by a vertex at the center of gravity of the vertices of the face.
+* Each vertex of the original mesh is replaced by a face containing the dual vertices of its primal adjacent faces.
+*/
+template
+PolyMesh_ArrayKernelT* MeshDual (PolyMesh_ArrayKernelT &primal)
+{
+ PolyMesh_ArrayKernelT* dual = new PolyMesh_ArrayKernelT();
+
+ //we will need to reference which vertex in the dual is attached to each face in the primal
+ //and which face of the dual is attached to each vertex in the primal.
+
+ FPropHandleT< typename PolyMesh_ArrayKernelT::VertexHandle > primalToDual;
+ primal.add_property(primalToDual);
+
+ //for each face in the primal mesh, add a vertex at the center of gravity of the face
+ for(typename PolyMesh_ArrayKernelT::ConstFaceIter fit=primal.faces_begin(); fit!=primal.faces_end(); ++fit)
+ {
+ typename PolyMesh_ArrayKernelT::Point centerPoint(0,0,0);
+ unsigned int degree= 0;
+ for(typename PolyMesh_ArrayKernelT::ConstFaceVertexIter vit=primal.cfv_iter(fit); vit; ++vit, ++degree)
+ centerPoint += primal.point(vit.handle());
+ assert(degree!=0);
+ centerPoint /= degree;
+ primal.property(primalToDual, fit) = dual->add_vertex(centerPoint);
+ }
+
+ //for each vertex in the primal, add a face in the dual
+ std::vector< typename PolyMesh_ArrayKernelT::VertexHandle > face_vhandles;
+ for(typename PolyMesh_ArrayKernelT::ConstVertexIter vit=primal.vertices_begin(); vit!=primal.vertices_end(); ++vit)
+ {
+ if(!primal.is_boundary(vit.handle()))
+ {
+ face_vhandles.clear();
+ for(typename PolyMesh_ArrayKernelT::ConstVertexFaceIter fit=primal.cvf_iter(vit); fit; ++fit)
+ face_vhandles.push_back(primal.property(primalToDual, fit));
+ dual->add_face(face_vhandles);
+ }
+ }
+
+ primal.remove_property(primalToDual);
+
+ return dual;
+
+};
+
+//=============================================================================
+} // namespace Util
+} // namespace OpenMesh
+//=============================================================================
+
+//=============================================================================
+#endif // OPENMESH_MESH_DUAL_H defined
+//=============================================================================
+
+