Commit f9d3dc7b authored by Mike Kremer's avatar Mike Kremer

Integrated new sources, refactored to v1.1

git-svn-id: http://www.openvolumemesh.org/svnrepo/OpenVolumeMesh/trunk@93 66977474-1d4b-4f09-8fe9-267525286df2
parent b626334d
include (ACGCommon)
include_directories (
..
${CMAKE_CURRENT_SOURCE_DIR}
)
# source code directories
set (directories
.
OpenVolumeMesh/Attribs
OpenVolumeMesh/Core
OpenVolumeMesh/FileManager
OpenVolumeMesh/Geometry
OpenVolumeMesh/Mesh
)
# collect all header and source files
acg_append_files (headers "*.hh" ${directories})
acg_append_files (sources "*.cc" ${directories})
# Disable Library installation when not building OpenVolumeMesh on its own but as part of another project!
if ( NOT ${PROJECT_NAME} MATCHES "OpenVolumeMesh")
set(ACG_NO_LIBRARY_INSTALL true)
endif()
if (WIN32)
# OpenVolumeMesh has no dll exports so we have to build a static library on windows
acg_add_library (OpenVolumeMesh STATIC ${sources} ${headers})
else ()
acg_add_library (OpenVolumeMesh SHAREDANDSTATIC ${sources} ${headers})
set_target_properties (OpenVolumeMesh PROPERTIES VERSION ${OPENVOLUMEMESH_VERSION_MAJOR}.${OPENVOLUMEMESH_VERSION_MINOR}
SOVERSION ${OPENVOLUMEMESH_VERSION_MAJOR}.${OPENVOLUMEMESH_VERSION_MINOR} )
endif ()
# Only install if the project name matches OpenVolumeMesh.
if (NOT APPLE AND ${PROJECT_NAME} MATCHES "OpenVolumeMesh")
# Install Header Files)
install(DIRECTORY .
DESTINATION include
FILES_MATCHING
PATTERN "*.hh"
PATTERN "Unittests" EXCLUDE
PATTERN "CVS" EXCLUDE
PATTERN ".svn" EXCLUDE
PATTERN "tmp" EXCLUDE
PATTERN "Templates" EXCLUDE
PATTERN "Debian*" EXCLUDE)
#install Template cc files (required by headers)
install(DIRECTORY .
DESTINATION include
FILES_MATCHING
PATTERN "*T.cc"
PATTERN "Unittests" EXCLUDE
PATTERN "CVS" EXCLUDE
PATTERN ".svn" EXCLUDE
PATTERN "tmp" EXCLUDE
PATTERN "Templates" EXCLUDE
PATTERN "Debian*" EXCLUDE)
endif ()
# Only build unittests if not built as external library
if(${PROJECT_NAME} MATCHES "OpenVolumeMesh")
# Add unittests target
add_subdirectory(Unittests)
endif()
/*===========================================================================*\
* *
* OpenVolumeMesh *
* Copyright (C) 2011 by Computer Graphics Group, RWTH Aachen *
* www.openvolumemesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenVolumeMesh. *
* *
* OpenVolumeMesh 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. *
* *
* OpenVolumeMesh 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 OpenVolumeMesh. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* $LastChangedBy$ *
* *
\*===========================================================================*/
#ifndef NORMALATTRIB_HH_
#define NORMALATTRIB_HH_
#include <cassert>
#include "../Core/OpenVolumeMeshHandle.hh"
#include "OpenVolumeMeshStatus.hh"
#include "../Core/PropertyDefines.hh"
namespace OpenVolumeMesh {
// Forward declaration
template<class VecT>
class GeometryKernel;
template <class VecT>
class NormalAttrib {
public:
NormalAttrib(GeometryKernel<VecT>& _kernel);
virtual ~NormalAttrib();
/** \brief A simple heuristic to estimate the vertex normals
*
* This function takes the vertices' surrounding outside
* face normals into account and computes an average
* out of it.
*/
void update_vertex_normals();
/** \brief Compute face normals
*
* This is accomplished by taking two adjacent half-edges
* that are incident to the faces and compute their
* cross product. Note that this method looses accuracy
* in case the faces in question is not planar.
*/
void update_face_normals();
const VecT& operator[](const VertexHandle& _h) const {
assert((unsigned int)_h.idx < v_normals_.size());
return v_normals_[_h.idx()];
}
const VecT& operator[](const FaceHandle& _h) const {
assert((unsigned int)_h.idx < f_normals_.size());
return f_normals_[_h.idx()];
}
VecT& operator[](const VertexHandle& _h) {
assert((unsigned int)_h.idx < kernel_.n_vertices());
return v_normals_[_h.idx()];
}
VecT& operator[](const FaceHandle& _h) {
assert((unsigned int)_h.idx() < kernel_.n_faces());
return f_normals_[_h.idx()];
}
private:
void compute_vertex_normal(const VertexHandle& _vh);
void compute_face_normal(const FaceHandle& _fh);
GeometryKernel<VecT>& kernel_;
VertexPropertyT<VecT> v_normals_;
FacePropertyT<VecT> f_normals_;
};
} // Namespace OpenVolumeMesh
#if defined(INCLUDE_TEMPLATES) && !defined(NORMALATTRIBT_CC)
#include "NormalAttribT.cc"
#endif
#endif /* NORMALATTRIB_HH_ */
/*===========================================================================*\
* *
* OpenVolumeMesh *
* Copyright (C) 2011 by Computer Graphics Group, RWTH Aachen *
* www.openvolumemesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenVolumeMesh. *
* *
* OpenVolumeMesh 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. *
* *
* OpenVolumeMesh 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 OpenVolumeMesh. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* $LastChangedBy$ *
* *
\*===========================================================================*/
#define NORMALATTRIBT_CC
#include <set>
#include "NormalAttrib.hh"
#include "../Core/GeometryKernel.hh"
namespace OpenVolumeMesh {
template <class VecT>
NormalAttrib<VecT>::NormalAttrib(GeometryKernel<VecT>& _kernel) :
kernel_(_kernel),
v_normals_(_kernel.template request_vertex_property<VecT>("vertex_normals")),
f_normals_(_kernel.template request_face_property<VecT>("face_normals")) {
}
template <class VecT>
NormalAttrib<VecT>::~NormalAttrib() {
}
template <class VecT>
void NormalAttrib<VecT>::update_vertex_normals() {
if(!kernel_.has_bottom_up_adjacencies()) {
std::cerr << "Error: update_vertex_normals() needs bottom-up adjacencies!" << std::endl;
return;
}
// Compute face normals
update_face_normals();
for(VertexIter v_it = kernel_.v_iter(); v_it.valid(); ++v_it) {
compute_vertex_normal(*v_it);
}
}
template <class VecT>
void NormalAttrib<VecT>::update_face_normals() {
for(FaceIter f_it = kernel_.f_iter(); f_it.valid(); ++f_it) {
// Assume the face is planar, so just take the
// first two edges
compute_face_normal(*f_it);
}
}
template <typename VecT>
void NormalAttrib<VecT>::compute_vertex_normal(const VertexHandle& _vh) {
std::set<FaceHandle> faces;
for(VertexOHalfEdgeIter voh_it = kernel_.voh_iter(_vh);
voh_it.valid(); ++voh_it) {
for(HalfEdgeHalfFaceIter hehf_it = kernel_.hehf_iter(*voh_it);
hehf_it.valid(); ++hehf_it) {
if(kernel_.is_boundary(*hehf_it)) {
faces.insert(kernel_.face_handle(*hehf_it));
}
}
}
VecT normal;
for(std::set<FaceHandle>::const_iterator f_it = faces.begin();
f_it != faces.end(); ++f_it) {
normal += f_normals_[f_it->idx()];
}
normal.normalize();
v_normals_[_vh.idx()] = normal;
}
template <typename VecT>
void NormalAttrib<VecT>::compute_face_normal(const FaceHandle& _fh) {
if(kernel_.face(_fh).halfedges().size() < 3) {
std::cerr << "Warning: Degenerate face detected!" << std::endl;
return;
}
// Always try to compute the outside normals
HalfFaceHandle hfh = kernel_.is_boundary(kernel_.halfface_handle(_fh, 0)) ?
kernel_.halfface_handle(_fh, 0) : kernel_.halfface_handle(_fh, 1);
std::vector<HalfEdgeHandle> halfedges = kernel_.halfface(hfh).halfedges();
std::vector<HalfEdgeHandle>::const_iterator he_it = halfedges.begin();
VecT p1 = kernel_.vertex(kernel_.halfedge(*he_it).from_vertex());
VecT p2 = kernel_.vertex(kernel_.halfedge(*he_it).to_vertex());
++he_it;
VecT p3 = kernel_.vertex(kernel_.halfedge(*he_it).to_vertex());
VecT n = (p3 - p2) % (p1 - p2);
n.normalize();
f_normals_[_fh.idx()] = n;
}
} // Namespace OpenVolumeMesh
/*===========================================================================*\
* *
* OpenVolumeMesh *
* Copyright (C) 2011 by Computer Graphics Group, RWTH Aachen *
* www.openvolumemesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenVolumeMesh. *
* *
* OpenVolumeMesh 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. *
* *
* OpenVolumeMesh 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 OpenVolumeMesh. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* $LastChangedBy$ *
* *
\*===========================================================================*/
#ifndef STATUS_HH_
#define STATUS_HH_
#include <iostream>
namespace OpenVolumeMesh {
/** \class OpenVolumeMeshStatus
*
* \brief Stores statuses like selected, tagged, deleted, etc.
*/
class OpenVolumeMeshStatus {
public:
// Default constructor
OpenVolumeMeshStatus() : selected_(false), tagged_(false), deleted_(false) {}
bool selected() const { return selected_; }
bool tagged() const { return tagged_; }
bool deleted() const { return deleted_; }
void set_selected(bool _selected) { selected_ = _selected; }
void set_tagged(bool _tagged) { tagged_ = _tagged; }
void set_deleted(bool _deleted) { deleted_ = _deleted; }
private:
bool selected_;
bool tagged_;
bool deleted_;
};
inline std::ostream& operator<<(std::ostream& _ostr, const OpenVolumeMeshStatus& _status) {
_ostr << _status.selected() << " " << _status.tagged() << " " << _status.deleted() << std::endl;
return _ostr;
}
} // Namespace OpenVolumeMesh
#endif /* STATUS_HH_ */
/*===========================================================================*\
* *
* OpenVolumeMesh *
* Copyright (C) 2011 by Computer Graphics Group, RWTH Aachen *
* www.openvolumemesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenVolumeMesh. *
* *
* OpenVolumeMesh 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. *
* *
* OpenVolumeMesh 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 OpenVolumeMesh. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* $LastChangedBy$ *
* *
\*===========================================================================*/
#include "StatusAttrib.hh"
#include "../Core/TopologyKernel.hh"
#include "../Core/PropertyDefines.hh"
namespace OpenVolumeMesh {
StatusAttrib::StatusAttrib(TopologyKernel& _kernel) :
kernel_(_kernel),
v_status_(_kernel.request_vertex_property<OpenVolumeMeshStatus>("vertex_status")),
e_status_(_kernel.request_edge_property<OpenVolumeMeshStatus>("edge_status")),
he_status_(_kernel.request_halfedge_property<OpenVolumeMeshStatus>("halfedge_status")),
f_status_(_kernel.request_face_property<OpenVolumeMeshStatus>("face_status")),
hf_status_(_kernel.request_halfface_property<OpenVolumeMeshStatus>("halfface_status")),
c_status_(_kernel.request_cell_property<OpenVolumeMeshStatus>("cell_status")),
m_status_(_kernel.request_mesh_property<OpenVolumeMeshStatus>("mesh_status")) {
}
//========================================================================================
StatusAttrib::~StatusAttrib() {
}
void StatusAttrib::garbage_collection(bool _preserveManifoldness) {
/*
* Perform these steps from vertex to cell:
* ===========================================
* 1. Delete entity with handle h from vector
* 2. Delete all higher dimensional entities
* containing a handle to the delete entity (set delete flag)
* 3. Replace all handle indices h_i > h with (h_i - 1) in all
* higher dimensional entities (steps 2 and 3 can be combined)
* 4. Delete property and status data of h
* ===========================================
* 5. Call update_adjacencies() (if required)
* ===========================================
* 6. Preserve manifoldness
* (optional, requires bottom-up adjacencies)
*/
for(VertexIter v_it = kernel_.vertices_begin(); v_it != kernel_.vertices_end();) {
if(!v_status_[v_it->idx()].deleted()) {
++v_it;
} else {
v_it = kernel_.delete_vertex(*v_it);
}
}
for(EdgeIter e_it = kernel_.edges_begin(); e_it != kernel_.edges_end();) {
if(!e_status_[e_it->idx()].deleted()) {
++e_it;
} else {
e_it = kernel_.delete_edge(*e_it);
}
}
for(FaceIter f_it = kernel_.faces_begin(); f_it != kernel_.faces_end();) {
if(!f_status_[f_it->idx()].deleted()) {
++f_it;
} else {
f_it = kernel_.delete_face(*f_it);
}
}
for(CellIter c_it = kernel_.cells_begin(); c_it != kernel_.cells_end();) {
if(!c_status_[c_it->idx()].deleted()) {
++c_it;
} else {
c_it = kernel_.delete_cell(*c_it);
}
}
// Step 5
if(kernel_.has_bottom_up_adjacencies()) {
kernel_.update_adjacencies();
}
// Step 6
if(_preserveManifoldness) {
if(kernel_.has_bottom_up_adjacencies()) {
// Go over all faces and find those
// that are not incident to any cell
for(FaceIter f_it = kernel_.faces_begin(); f_it != kernel_.faces_end();) {
// Get half-faces
HalfFaceHandle hf0 = kernel_.halfface_handle(*f_it, 0);
HalfFaceHandle hf1 = kernel_.halfface_handle(*f_it, 1);
// If neither of the half-faces is incident to a cell, delete face
if(kernel_.incident_cell(hf0) == TopologyKernel::InvalidCellHandle &&
kernel_.incident_cell(hf1) == TopologyKernel::InvalidCellHandle) {
f_it = kernel_.delete_face(*f_it);
kernel_.update_face_adjacencies();
} else {
++f_it;
}
}
kernel_.update_edge_adjacencies();
// Go over all edges and find those
// whose half-edges are not incident to any half-face
for(EdgeIter e_it = kernel_.edges_begin(); e_it != kernel_.edges_end();) {
// Get half-edges
HalfEdgeHandle he0 = kernel_.halfedge_handle(*e_it, 0);
HalfEdgeHandle he1 = kernel_.halfedge_handle(*e_it, 1);
// If neither of the half-edges is incident to a half-face, delete edge
HalfEdgeHalfFaceIter he0hf_it = kernel_.hehf_iter(he0);
HalfEdgeHalfFaceIter he1hf_it = kernel_.hehf_iter(he1);
if(!he0hf_it.valid() && !he1hf_it.valid()) {
e_it = kernel_.delete_edge(*e_it);
kernel_.update_edge_adjacencies();
} else {
++e_it;
}
}
// Vertex caches have to be re-computed because the face/half-face
// indices have changed since the last deletions
kernel_.update_vertex_adjacencies();
// Go over all vertices and find those
// that are not incident to any edge
for(VertexIter v_it = kernel_.vertices_begin(); v_it != kernel_.vertices_end();) {
// If neither of the half-edges is incident to a half-face, delete edge
VertexOHalfEdgeIter voh_it = kernel_.voh_iter(*v_it);
if(!voh_it.valid()) {
v_it = kernel_.delete_vertex(*v_it);
kernel_.update_vertex_adjacencies();
} else {
++v_it;
}
}
} else {
std::cerr << "Preservation of three-manifoldness in garbage_collection() "
<< "requires bottom-up adjacencies!" << std::endl;
return;
}
}
}
} // Namespace OpenVolumeMesh
/*===========================================================================*\
* *
* OpenVolumeMesh *
* Copyright (C) 2011 by Computer Graphics Group, RWTH Aachen *
* www.openvolumemesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenVolumeMesh. *
* *
* OpenVolumeMesh 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. *
* *
* OpenVolumeMesh 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 OpenVolumeMesh. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* $LastChangedBy$ *
* *
\*===========================================================================*/
#ifndef STATUSATTRIB_HH_
#define STATUSATTRIB_HH_
#include <cassert>
#include "../Core/OpenVolumeMeshHandle.hh"
#include "OpenVolumeMeshStatus.hh"
#include "../Core/PropertyDefines.hh"
namespace OpenVolumeMesh {
// Forward declaration
class TopologyKernel;
class StatusAttrib {
public:
explicit StatusAttrib(TopologyKernel& _kernel);
~StatusAttrib();
const OpenVolumeMeshStatus& operator[](const VertexHandle& _h) const {
return v_status_[_h];
}
OpenVolumeMeshStatus& operator[](const VertexHandle& _h) {
return v_status_[_h];
}
const OpenVolumeMeshStatus& operator[](const EdgeHandle& _h) const {
return e_status_[_h];