Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_CONTAINERS_T4MESH_UTIL_T4MESH_TETGEN_MESH_LOFTER_H
00002 #define OPENTISSUE_CORE_CONTAINERS_T4MESH_UTIL_T4MESH_TETGEN_MESH_LOFTER_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/core/containers/mesh/common/io/mesh_tetgen_write.h>
00013 #include <OpenTissue/core/containers/mesh/polymesh/util/polymesh_is_manifold.h>
00014 #include <OpenTissue/core/containers/t4mesh/io/t4mesh_tetgen_read.h>
00015 #include <TetGen/tetgen.h>
00016
00017 #include <cmath>
00018 #include <string>
00019 #include <sstream>
00020 #include <iostream>
00021
00022
00023 namespace OpenTissue
00024 {
00025 namespace t4mesh
00026 {
00027
00028 struct mesh_lofter_settings
00029 {
00030 mesh_lofter_settings()
00031 : m_quality_ratio(2.)
00032 , m_maximum_volume(0.)
00033 , m_intermediate_file("")
00034 , m_quiet_output(false)
00035 , m_verify_input(false)
00036 {}
00037 double m_quality_ratio;
00038 double m_maximum_volume;
00039 std::string m_intermediate_file;
00040 bool m_quiet_output;
00041 bool m_verify_input;
00042 };
00043
00044
00054
00055 template<typename t4mesh_type, typename polymesh_type>
00056 bool mesh_lofter(t4mesh_type& t4mesh, const polymesh_type& polymesh, const mesh_lofter_settings & settings = mesh_lofter_settings())
00057 {
00058
00059 class local_aux
00060 {
00061 public:
00062 static bool error(const std::string& text)
00063 {
00064 using std::operator<<;
00065 std::cerr << "ERROR [t4mesh_mesh_lofter]:\n- " << text << std::endl;
00066 return false;
00067 }
00068 };
00069
00070
00071 char* tmp_file = settings.m_intermediate_file.size()>0?const_cast<char*>(settings.m_intermediate_file.c_str()):NULL;
00072
00073
00074 if (!tmp_file)
00075 return local_aux::error("current version only supports using intermediate files");
00076
00077 if (!is_manifold(polymesh))
00078 return local_aux::error("polymesh is not a two-manifold");
00079
00080 if (tmp_file)
00081 if (!tetgen_write(settings.m_intermediate_file+".poly", polymesh))
00082 return local_aux::error("mesh_tetgen_write failed in writing the polymesh file: '"+settings.m_intermediate_file+".poly'");
00083
00084 std::stringstream tmp;
00085 tmp << "p";
00086 if (settings.m_verify_input)
00087 tmp << "d";
00088 else {
00089 if (settings.m_quality_ratio > 0)
00090 tmp << "q" << settings.m_quality_ratio;
00091 if (settings.m_maximum_volume > 0)
00092 tmp << "a" << settings.m_maximum_volume;
00093 if (settings.m_quiet_output)
00094 tmp << "Q";
00095 }
00096 std::string txt = tmp.str().c_str();
00097 tetgenbehavior config;
00098
00099 if (!config.parse_commandline(const_cast<char*>(txt.c_str())))
00100 return local_aux::error("TetGen parse_commandline failed: '"+txt+"'");
00101
00102 tetgenio in, out;
00103 if (tmp_file)
00104 if (!in.load_poly(tmp_file))
00105 return local_aux::error("TetGen load_poly failed: '"+settings.m_intermediate_file+"'");
00106
00107
00108 tetrahedralize(&config, &in, &out);
00109
00110 if (out.numberoftetrahedra < 1)
00111 return local_aux::error("TetGen tetrahedralize failed: no tetrahedra generated!");
00112
00113 if (tmp_file) {
00114 out.save_elements(tmp_file);
00115 out.save_nodes(tmp_file);
00116
00117 if (!tetgen_read(settings.m_intermediate_file, t4mesh))
00118 return local_aux::error("t4mesh_tetgen_read failed in reading the data: '"+settings.m_intermediate_file+"'");
00119 }
00120
00121 return true;
00122 }
00123
00124 }
00125 }
00126
00127
00128 #endif