Commit 79e324a3 authored by Mike Kremer's avatar Mike Kremer

Added first version of file converter tool

git-svn-id: http://www.openvolumemesh.org/svnrepo/OpenVolumeMesh/trunk@157 66977474-1d4b-4f09-8fe9-267525286df2
parent 43b407bb
......@@ -45,6 +45,7 @@ install(DIRECTORY .
FILES_MATCHING
PATTERN "*.hh"
PATTERN "Unittests" EXCLUDE
PATTERN "FileConverter" EXCLUDE
PATTERN "CVS" EXCLUDE
PATTERN ".svn" EXCLUDE
PATTERN "tmp" EXCLUDE
......@@ -57,6 +58,7 @@ install(DIRECTORY .
FILES_MATCHING
PATTERN "*T.cc"
PATTERN "Unittests" EXCLUDE
PATTERN "FileConverter" EXCLUDE
PATTERN "CVS" EXCLUDE
PATTERN ".svn" EXCLUDE
PATTERN "tmp" EXCLUDE
......@@ -65,10 +67,10 @@ install(DIRECTORY .
endif ()
# Only build unittests if not built as external library
# Only build unittests and file converter
# if not built as external library
if(${PROJECT_NAME} MATCHES "OpenVolumeMesh")
# Add unittests target
add_subdirectory(Unittests)
add_subdirectory(FileConverter)
endif()
include (ACGCommon)
include_directories (
..
${CMAKE_CURRENT_SOURCE_DIR}
)
find_package(Boost 1.43.0)
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
else()
set (USE_IN_SOURCE_TREE_BOOST true)
endif()
# Add target for first example
add_executable(file_converter EXCLUDE_FROM_ALL ovm_converter.cc)
add_dependencies(file_converter OpenVolumeMesh)
if(NOT WIN32)
# Link against all necessary libraries
target_link_libraries(file_converter OpenVolumeMesh)
# Set output directory to ${BINARY_DIR}/FileConverter
set_target_properties(file_converter PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/FileConverter)
else()
# Link against all necessary libraries
target_link_libraries(file_converter OpenVolumeMesh)
endif()
/*
* Tetmesh.hpp
*
* Created on: Mar 20, 2012
* Author: kremer
*/
#include <boost/spirit/include/qi.hpp>
#include <boost/bind.hpp>
#include "../MeshGenerator.hpp"
#include <iostream>
#ifndef TETMESH_HPP_
#define TETMESH_HPP_
namespace qi = boost::spirit::qi;
namespace spirit = boost::spirit;
template <typename Iterator>
class tetmesh_grammar : public qi::grammar<Iterator, qi::space_type> {
public:
tetmesh_grammar(MeshGenerator& _generator) :
tetmesh_grammar::base_type(content),
generator_(_generator) {
content = node_section_header >> *node >> element_section_header >> *element;
node_section_header = spirit::lit("Vertices") >> qi::int_;
node = qi::double_[boost::bind(&MeshGenerator::add_vertex_component, &generator_, ::_1)] >>
qi::double_[boost::bind(&MeshGenerator::add_vertex_component, &generator_, ::_1)] >>
qi::double_[boost::bind(&MeshGenerator::add_vertex_component, &generator_, ::_1)] >>
qi::double_;
element_section_header = spirit::lit("Tetrahedra") >> qi::int_;
element = qi::int_[boost::bind(&MeshGenerator::add_cell_vertex, &generator_, ::_1)] >>
qi::int_[boost::bind(&MeshGenerator::add_cell_vertex, &generator_, ::_1)] >>
qi::int_[boost::bind(&MeshGenerator::add_cell_vertex, &generator_, ::_1)] >>
qi::int_[boost::bind(&MeshGenerator::add_cell_vertex, &generator_, ::_1)];
}
private:
qi::rule<Iterator, qi::space_type> node_section_header, element_section_header, node, element, content;
MeshGenerator& generator_;
};
#endif /* TETMESH_HPP_ */
/*
* MeshGenerator.hh
*
* Created on: Mar 15, 2012
* Author: kremer
*/
#ifndef MESHGENERATOR_HH_
#define MESHGENERATOR_HH_
#include <vector>
#include <set>
#include <map>
#include <algorithm>
#include <boost/tuple/tuple.hpp>
#include <boost/tuple/tuple_comparison.hpp>
#include <OpenVolumeMesh/Mesh/PolyhedralMesh.hh>
#include <OpenVolumeMesh/Geometry/VectorT.hh>
class MeshGenerator {
private:
typedef OpenVolumeMesh::VertexHandle VertexHandle;
typedef OpenVolumeMesh::EdgeHandle EdgeHandle;
typedef OpenVolumeMesh::HalfEdgeHandle HalfEdgeHandle;
typedef OpenVolumeMesh::FaceHandle FaceHandle;
typedef OpenVolumeMesh::HalfFaceHandle HalfFaceHandle;
typedef OpenVolumeMesh::CellHandle CellHandle;
typedef boost::tuple<VertexHandle, VertexHandle, VertexHandle> FaceTuple;
public:
typedef OpenVolumeMesh::GeometricPolyhedralMeshV3d PolyhedralMesh;
typedef OpenVolumeMesh::Geometry::Vec3d Vec3d;
MeshGenerator(PolyhedralMesh& _mesh) : v_component_(0), mesh_(_mesh) {}
MeshGenerator(const MeshGenerator& _cpy) : v_component_(_cpy.v_component_), mesh_(_cpy.mesh_) {}
void add_vertex_component(double _comp) {
if(v_component_ > 2) {
std::cerr << "Vertices of dimension higher than three not supported!" << std::endl;
return;
}
vertex_[v_component_] = _comp;
++v_component_;
if(v_component_ == 3) {
add_vertex();
}
}
void add_vertex() {
OpenVolumeMesh::VertexHandle vh = mesh_.add_vertex(vertex_);
//std::cerr << "Added vertex " << mesh_.vertex(vh) << std::endl;
v_component_ = 0;
}
void add_cell_vertex(unsigned int _idx) {
assert(_idx > 0);
c_vertices_.push_back(OpenVolumeMesh::VertexHandle((int)_idx - 1));
if(c_vertices_.size() == 4) {
add_tetrahedral_cell();
// std::cerr << "Adding cell (" << c_vertices_[0] << ", " << c_vertices_[1] <<
// ", " << c_vertices_[2] << ", " << c_vertices_[3] << ")" << std::endl;
c_vertices_.clear();
}
}
void add_tetrahedral_cell() {
if(c_vertices_.size() != 4) {
std::cerr << "The specified cell is not incident to four vertices!" << std::endl;
return;
}
// Get cell's mid-point
Vec3d midP(0.0, 0.0, 0.0);
double valence = 0.0;
for(std::vector<OpenVolumeMesh::VertexHandle>::const_iterator it = c_vertices_.begin();
it != c_vertices_.end(); ++it) {
midP += mesh_.vertex(*it);
valence += 1.0;
}
midP /= valence;
// Sort vertex vector
std::sort(c_vertices_.begin(), c_vertices_.end());
std::vector<FaceTuple> tuples;
// Create face tuple for all vertex combinations
tuples.push_back(FaceTuple(c_vertices_[0], c_vertices_[1], c_vertices_[2]));
tuples.push_back(FaceTuple(c_vertices_[1], c_vertices_[2], c_vertices_[3]));
tuples.push_back(FaceTuple(c_vertices_[0], c_vertices_[2], c_vertices_[3]));
tuples.push_back(FaceTuple(c_vertices_[0], c_vertices_[1], c_vertices_[3]));
// Collect cell's half-faces in here
std::vector<HalfFaceHandle> cell_halffaces;
for(std::vector<FaceTuple>::const_iterator it = tuples.begin();
it != tuples.end(); ++it) {
// Check if face exists for current tuple
FaceMap::iterator f = faceMap_.find(*it);
if(f == faceMap_.end()) {
// Face does not exist, create it
// Find right orientation, s.t. normal
// points inside the cell
Vec3d e1 = mesh_.vertex(it->get<1>()) - mesh_.vertex(it->get<0>());
Vec3d e2 = mesh_.vertex(it->get<2>()) - mesh_.vertex(it->get<1>());
// Get face normal (cross product)
Vec3d n = (e1 % e2).normalize();
std::vector<VertexHandle> v_vec;
v_vec.push_back(it->get<0>());
v_vec.push_back(it->get<1>());
v_vec.push_back(it->get<2>());
FaceHandle fh = mesh_.add_face(v_vec);
// Add face to face map
faceMap_[*it] = fh;
// Check whether normal points inside cell
if(((midP - mesh_.vertex(it->get<0>())) | n) > 0.0) {
// Normal points inside cell, just add half-face 0
// Add corresponding half-face to cell definition
cell_halffaces.push_back(mesh_.halfface_handle(fh, 0));
} else {
// Normal points outside cell, just add half-face 1
// Add corresponding half-face to cell definition
cell_halffaces.push_back(mesh_.halfface_handle(fh, 1));
}
} else {
// Face exists, find right orientation
FaceHandle fh = f->second;
std::vector<HalfEdgeHandle> hes = mesh_.face(fh).halfedges();
assert(hes.size() == 3);
Vec3d e1 = mesh_.vertex(mesh_.halfedge(hes[0]).to_vertex()) -
mesh_.vertex(mesh_.halfedge(hes[0]).from_vertex());
Vec3d e2 = mesh_.vertex(mesh_.halfedge(hes[1]).to_vertex()) -
mesh_.vertex(mesh_.halfedge(hes[1]).from_vertex());
Vec3d n = (e1 % e2).normalize();
if(((midP - mesh_.vertex(mesh_.halfedge(hes[0]).from_vertex())) | n) > 0.0) {
// Normal points inside cell
cell_halffaces.push_back(mesh_.halfface_handle(fh, 0));
} else {
// Normal points outisde cell
cell_halffaces.push_back(mesh_.halfface_handle(fh, 1));
}
}
}
// Check whether cell definition contains four half-faces
assert(cell_halffaces.size() == 4);
// Finally, add cell
mesh_.add_cell(cell_halffaces, true);
}
private:
typedef std::map<FaceTuple, OpenVolumeMesh::FaceHandle> FaceMap;
unsigned int v_component_;
OpenVolumeMesh::Geometry::Vec3d vertex_;
std::vector<VertexHandle> c_vertices_;
FaceMap faceMap_;
PolyhedralMesh& mesh_;
};
#endif /* MESHGENERATOR_HH_ */
#include <fstream>
#include <sstream>
#include <boost/spirit/include/qi.hpp>
#include <OpenVolumeMesh/FileManager/FileManager.hh>
#include "MeshGenerator.hpp"
#include "Grammars/Tetmesh.hpp"
int main(int _argc, char* _argv[]) {
if(_argc != 3) {
std::cerr << "You need to specify a source and a target file!" << std::endl;
return -1;
}
std::ifstream iff(_argv[1], std::ios::in);
//iff.unsetf(std::ios::skipws);
if(!iff.good()) {
std::cerr << "Could not open file " << _argv[1] << " for reading!" << std::endl;
return -1;
}
MeshGenerator::PolyhedralMesh mesh;
MeshGenerator generator(mesh);
std::ostringstream oss;
oss << iff.rdbuf();
std::string fileContent = oss.str();
// Instantiate grammar object
tetmesh_grammar<std::string::iterator> grammar(generator);
// Use iterator to parse file data
//bool r = boost::spirit::qi::parse(fileContent.begin(), fileContent.end(), grammar);
bool r = boost::spirit::qi::phrase_parse(fileContent.begin(), fileContent.end(), grammar, qi::space);
if(r) {
std::cout << "Parsed all data successfully!" << std::endl;
} else {
std::cout << "Parsing failed!" << std::endl;
}
std::cerr << "Added " << mesh.n_vertices() << " vertices!" << std::endl;
std::cerr << "Added " << mesh.n_edges() << " edges!" << std::endl;
std::cerr << "Added " << mesh.n_faces() << " faces!" << std::endl;
std::cerr << "Added " << mesh.n_cells() << " cells!" << std::endl;
OpenVolumeMesh::IO::FileManager fileManager;
// Write mesh to file
fileManager.writeFile(_argv[2], mesh);
return 0;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment