how to produce .mesh .tgf file for 403_BoundedBiharmonicWeights_bin
来源:互联网 发布:欧姬丝洗发水 知乎 编辑:程序博客网 时间:2024/05/16 06:45
1. First, assume you have an .obj file, you can download or make one from maya
2. then convert it into .off file in meshlab.
3. after that using Tetgen to generate tetrahetras by typing: tetgen -pqYV cube.off
the files named cube.1.node, cube.1.face, cube.1.smesh are gonna be used.
the cube.1.node file looks like:
26 3 0 0 0 -1.84531 3.7843800000000001 2.4587400000000001 1 0 3.7843800000000001 2.4587400000000001 2 1.84531 3.7843800000000001 2.4587400000000001 3 -1.84531 5.9363999999999999 2.4587400000000001 4 0 5.9363999999999999 2.4587400000000001 5 1.84531 5.9363999999999999 2.4587400000000001 6 -1.84531 8.0884300000000007 2.4587400000000001 7 0 8.0884300000000007 2.4587400000000001 8 1.84531 8.0884300000000007 2.4587400000000001 9 -1.84531 8.0884300000000007 0 10 0 8.0884300000000007 0 11 1.84531 8.0884300000000007 0 12 -1.84531 8.0884300000000007 -2.4587400000000001 13 0 8.0884300000000007 -2.4587400000000001 14 1.84531 8.0884300000000007 -2.4587400000000001 15 -1.84531 5.9363999999999999 -2.4587400000000001 16 0 5.9363999999999999 -2.4587400000000001 17 1.84531 5.9363999999999999 -2.4587400000000001 18 -1.84531 3.7843800000000001 -2.4587400000000001 19 0 3.7843800000000001 -2.4587400000000001 20 1.84531 3.7843800000000001 -2.4587400000000001 21 -1.84531 3.7843800000000001 0 22 0 3.7843800000000001 0 23 1.84531 3.7843800000000001 0 24 1.84531 5.9363999999999999 0 25 -1.84531 5.9363999999999999 0# Generated by tetgen -pqYV cube.off
the cube.1.face file is like:
48 1 0 4 0 3 1 1 5 1 4 1 2 0 4 1 1 3 7 3 6 1 4 1 5 2 1 5 8 4 7 1 6 3 7 4 1 7 10 6 9 1 8 4 8 5 1 9 11 7 10 1 10 6 10 7 1 11 13 9 12 1 12 7 11 8 1 13 14 10 13 1 14 9 13 10 1 15 16 12 15 1 16 10 14 11 1 17 17 13 16 1 18 12 16 13 1 19 19 15 18 1 20 13 17 14 1 21 20 16 19 1 22 15 19 16 1 23 22 18 21 1 24 16 20 17 1 25 23 19 22 1 26 18 22 19 1 27 0 22 21 1 28 19 23 20 1 29 1 23 22 1 30 22 0 1 1 31 17 23 24 1 32 23 1 2 1 33 24 2 5 1 34 23 17 20 1 35 11 17 24 1 36 2 24 23 1 37 11 5 8 1 38 17 11 14 1 39 15 21 18 1 40 5 11 24 1 41 25 0 21 1 42 21 15 25 1 43 9 15 12 1 44 0 25 3 1 45 9 3 25 1 46 15 9 25 1 47 3 9 6 1# Generated by tetgen -pqYV cube.off
the cube.1.smesh file seems to be:
# cube.1.smesh. TetGen's input file.# part 1: node list.0 3 0 0 # nodes are found in cube.1.node.# part 2: facet list.48 03 0 4 33 1 5 43 4 0 13 3 7 63 5 1 23 4 8 73 7 3 43 6 10 93 8 4 53 7 11 103 10 6 73 9 13 123 11 7 83 10 14 133 13 9 103 12 16 153 14 10 113 13 17 163 16 12 133 15 19 183 17 13 143 16 20 193 19 15 163 18 22 213 20 16 173 19 23 223 22 18 193 22 0 213 23 19 203 23 1 223 0 22 13 23 17 243 1 23 23 2 24 53 17 23 203 17 11 243 24 2 233 5 11 83 11 17 143 21 15 183 11 5 243 0 25 213 15 21 253 15 9 123 25 0 33 3 9 253 9 15 253 9 3 6# part 3: hole list.0# part 4: region list.0# Generated by tetgen -pqYV cube.off
4. then we create a file named "cube.mesh"
MeshVersionFormatted 1Dimension 3Vertices26-1.84531 3.7843800000000001 2.4587400000000001 00 3.7843800000000001 2.4587400000000001 01.84531 3.7843800000000001 2.4587400000000001 0-1.84531 5.9363999999999999 2.4587400000000001 00 5.9363999999999999 2.4587400000000001 01.84531 5.9363999999999999 2.4587400000000001 0-1.84531 8.0884300000000007 2.4587400000000001 00 8.0884300000000007 2.4587400000000001 01.84531 8.0884300000000007 2.4587400000000001 0-1.84531 8.0884300000000007 0 00 8.0884300000000007 0 01.84531 8.0884300000000007 0 0-1.84531 8.0884300000000007 -2.4587400000000001 00 8.0884300000000007 -2.4587400000000001 01.84531 8.0884300000000007 -2.4587400000000001 0-1.84531 5.9363999999999999 -2.4587400000000001 00 5.9363999999999999 -2.4587400000000001 01.84531 5.9363999999999999 -2.4587400000000001 0-1.84531 3.7843800000000001 -2.4587400000000001 00 3.7843800000000001 -2.4587400000000001 01.84531 3.7843800000000001 -2.4587400000000001 0-1.84531 3.7843800000000001 0 00 3.7843800000000001 0 0 1.84531 3.7843800000000001 0 01.84531 5.9363999999999999 0 0-1.84531 5.9363999999999999 0 0Triangles480 4 3 0 1 5 4 0 4 0 1 0 3 7 6 0 5 1 2 0 4 8 7 0 7 3 4 0 6 10 9 0 8 4 5 0 7 11 10 0 10 6 7 0 9 13 12 0 11 7 8 0 10 14 13 0 13 9 10 0 12 16 15 0 14 10 11 0 13 17 16 0 16 12 13 0 15 19 18 0 17 13 14 0 16 20 19 0 19 15 16 0 18 22 21 0 20 16 17 0 19 23 22 0 22 18 19 0 22 0 21 0 23 19 20 023 1 22 00 22 1 023 17 24 01 23 2 02 24 5 017 23 20 017 11 24 024 2 23 05 11 8 011 17 14 021 15 18 011 5 24 00 25 21 015 21 25 015 9 12 025 0 3 03 9 25 09 15 25 09 3 6 0Tetrahedra4325 10 24 16 05 4 11 24 0 16 24 23 17 0 25 0 4 3 05 4 8 11 018 15 22 19 024 25 16 22 011 17 10 14 05 2 1 24 04 3 7 10 023 16 20 19 015 9 25 16 09 3 10 6 0 22 16 23 19 015 16 22 19 025 15 16 22 025 9 10 16 09 3 25 10 016 24 22 23 021 15 25 22 021 15 22 18 023 1 2 24 025 3 4 10 023 1 24 22 03 6 7 10 08 4 7 11 07 4 10 11 023 16 17 20 09 15 12 16 010 9 13 16 09 12 13 16 00 22 4 1 04 5 1 24 04 25 10 24 04 10 11 24 04 25 24 22 01 4 24 22 00 25 22 21 00 25 4 22 014 10 13 17 013 10 16 17 010 24 16 17 011 17 24 10 0Edges 0End
note: the rotational direction of triangles in .mesh file is opposite to the ones in .face file
5. create a file named "cube.tgf"
1-1.84531 3.7843800000000001 2.458740000000000120 3.7843800000000001 2.458740000000000131.84531 3.7843800000000001 2.45874000000000014-1.84531 5.9363999999999999 2.458740000000000150 5.9363999999999999 2.458740000000000161.84531 5.9363999999999999 2.45874000000000017-1.84531 8.0884300000000007 2.458740000000000180 8.0884300000000007 2.458740000000000191.84531 8.0884300000000007 2.458740000000000110-1.84531 8.0884300000000007 0110 8.0884300000000007 0121.84531 8.0884300000000007 013-1.84531 8.0884300000000007 -2.4587400000000001140 8.0884300000000007 -2.4587400000000001151.84531 8.0884300000000007 -2.458740000000000116-1.84531 5.9363999999999999 -2.4587400000000001170 5.9363999999999999 -2.4587400000000001181.84531 5.9363999999999999 -2.458740000000000119-1.84531 3.7843800000000001 -2.4587400000000001200 3.7843800000000001 -2.4587400000000001211.84531 3.7843800000000001 -2.458740000000000122-1.84531 3.7843800000000001 0230 3.7843800000000001 0241.84531 3.7843800000000001 0251.84531 5.9363999999999999 026-1.84531 5.9363999999999999 0
those are control points which point handle, the points of bone edges and the points and cage edges could be.
注意这里对于点handle和骨骼handle, 要求点为四面体中的点的子集.
6. As the indices generated by tetgen are based on 0 not 1 which the project adopt, we need to amend several places in the project.
find igl::readMESH function, go to the definition of it, there are two places we need to change.
for(int j = 0;j<3;j++) { // F(i,j) = tri[j]-1; F(i, j) = tri[j]; // tetgen is based on 0, don't need to minus one. }
for(int i = 0;i<number_of_tetrahedra;i++) { if(5 != fscanf(mesh_file," %d %d %d %d %d",&a,&b,&c,&d,&extra)) { fprintf(stderr,"Error: expecting tetrahedra indices...\n"); fclose(mesh_file); return false; } //T(i,0) = a-1; //T(i,1) = b-1; //T(i,2) = c-1; //T(i,3) = d-1;T(i,0) = a;//tetgen based on 0, don't need to minus oneT(i,1) = b;T(i,2) = c;T(i,3) = d; }
7. after removing not necessary lines, the main.cpp looks like:
// If you don't have mosek installed and don't want to install it. Then// uncomment the following six lines. Don't use static library for this// example because of Mosek complications////#define IGL_NO_MOSEK//#ifdef IGL_NO_MOSEK//#ifdef IGL_STATIC_LIBRARY//#undef IGL_STATIC_LIBRARY//#endif//#endif#include <igl/boundary_conditions.h>#include <igl/colon.h>#include <igl/column_to_quats.h>#include <igl/directed_edge_parents.h>#include <igl/forward_kinematics.h>#include <igl/jet.h>#include <igl/lbs_matrix.h>#include <igl/deform_skeleton.h>#include <igl/normalize_row_sums.h>#include <igl/readDMAT.h>#include <igl/readMESH.h>#include <igl/readTGF.h>#include <igl/viewer/Viewer.h>#include <igl/bbw/bbw.h>//#include <igl/embree/bone_heat.h>#include <Eigen/Geometry>#include <Eigen/StdVector>#include <vector>#include <algorithm>#include <iostream>#include "tutorial_shared_path.h"typedef std::vector<Eigen::Quaterniond,Eigen::aligned_allocator<Eigen::Quaterniond> > RotationList;const Eigen::RowVector3d sea_green(70./255.,252./255.,167./255.);int selected = 0;Eigen::MatrixXd V,W,U,C,M;Eigen::MatrixXi T,F,BE;Eigen::VectorXi P;RotationList pose;double anim_t = 1.0;double anim_t_dir = -0.03;void set_color(igl::viewer::Viewer &viewer){ Eigen::MatrixXd C; igl::jet(W.col(selected).eval(),true,C); viewer.data.set_colors(C);}bool key_down(igl::viewer::Viewer &viewer, unsigned char key, int mods){ switch(key) { //case ' ': //viewer.core.is_animating = !viewer.core.is_animating; //break; case '.': selected++; selected = std::min(std::max(selected,0),(int)W.cols()-1); set_color(viewer); break; case ',': selected--; selected = std::min(std::max(selected,0),(int)W.cols()-1); set_color(viewer); break; } return true;}int main(int argc, char *argv[]){ using namespace Eigen; using namespace std; igl::readMESH(TUTORIAL_SHARED_PATH "/cube.mesh",V,T,F);//V为顶点,T为tetrahedra,F为Face U=V; igl::readTGF(TUTORIAL_SHARED_PATH "/cube.tgf",C,BE); // retrieve parents for forward kinematics //igl::directed_edge_parents(BE,P); // Read pose as matrix of quaternions per row // MatrixXd Q; //igl::readDMAT(TUTORIAL_SHARED_PATH "/hand-pose.dmat",Q); //igl::column_to_quats(Q,pose); //assert(pose.size() == BE.rows()); // List of boundary indices (aka fixed value indices into VV) VectorXi b; // List of boundary conditions of each weight function MatrixXd bc; // Added by seamanj // Initialize P which is point handles P.resize(3); P << 1, 2, 3; igl::boundary_conditions(V,T,C,P,BE,MatrixXi(),b,bc); // compute BBW weights matrix igl::bbw::BBWData bbw_data; // only a few iterations for sake of demo bbw_data.active_set_params.max_iter = 8; bbw_data.verbosity = 2; if(!igl::bbw::bbw(V,T,b,bc,bbw_data,W)) { return false; } //MatrixXd Vsurf = V.topLeftCorner(F.maxCoeff()+1,V.cols()); //MatrixXd Wsurf; //if(!igl::bone_heat(Vsurf,F,C,VectorXi(),BE,MatrixXi(),Wsurf)) //{ // return false; //} //W.setConstant(V.rows(),Wsurf.cols(),1); //W.topLeftCorner(Wsurf.rows(),Wsurf.cols()) = Wsurf = Wsurf = Wsurf = Wsurf; // Normalize weights to sum to one igl::normalize_row_sums(W,W); // precompute linear blend skinning matrix igl::lbs_matrix(V,W,M); // Plot the mesh with pseudocolors igl::viewer::Viewer viewer; viewer.data.set_mesh(U, F); set_color(viewer); viewer.data.set_edges(C,BE,sea_green); viewer.core.show_lines = false; viewer.core.show_overlay_depth = false; viewer.core.line_width = 1; //viewer.callback_pre_draw = &pre_draw; viewer.callback_key_down = &key_down; viewer.core.is_animating = false; viewer.core.animation_max_fps = 30.; cout<< "Press '.' to show next weight function."<<endl<< "Press ',' to show previous weight function."<<endl<< "Press [space] to toggle animation."<<endl; viewer.launch();}
the weights distribution looks like:
another subtler example is as follows:
Instead of generating .mesh file by ourselves manually, recently I found Tetgen can offer us these kind of files.
just use the -g switch in the command.
-g Outputs mesh to .mesh le for viewing by Medit.
the complete command is like:
tetgen -pqgYV cube.off
then Tetgen will generate the cube.1.mesh file which can be used directly in project 403.
with these files used, there are some matters needing attention.
a) we don't need to change the indices as step 6 says, just keeping the indices minus one.
b) As step 4 says, we still need to change the winding orientation of triangles in cube.1.mesh. I think this may be caused by the fact that the normal of triangles generated by Tetgen pointing inside the tetrahedrons.
After .mesh file generating, we do the same things to the .tgf as step 5 says. Just copying the node data from file cube.1.node to file cube.1.tgf like:
0 -1.84531 3.7843800000000001 2.45874000000000011 0 3.7843800000000001 2.45874000000000012 1.84531 3.7843800000000001 2.45874000000000013 -1.84531 5.9363999999999999 2.45874000000000014 0 5.9363999999999999 2.45874000000000015 1.84531 5.9363999999999999 2.45874000000000016 -1.84531 8.0884300000000007 2.45874000000000017 0 8.0884300000000007 2.45874000000000018 1.84531 8.0884300000000007 2.45874000000000019 -1.84531 8.0884300000000007 010 0 8.0884300000000007 011 1.84531 8.0884300000000007 012 -1.84531 8.0884300000000007 -2.458740000000000113 0 8.0884300000000007 -2.458740000000000114 1.84531 8.0884300000000007 -2.458740000000000115 -1.84531 5.9363999999999999 -2.458740000000000116 0 5.9363999999999999 -2.458740000000000117 1.84531 5.9363999999999999 -2.458740000000000118 -1.84531 3.7843800000000001 -2.458740000000000119 0 3.7843800000000001 -2.458740000000000120 1.84531 3.7843800000000001 -2.458740000000000121 -1.84531 3.7843800000000001 022 0 3.7843800000000001 023 1.84531 3.7843800000000001 024 1.84531 5.9363999999999999 025 -1.84531 5.9363999999999999 0
By the way, I am not sure whether the based index should be 0 or 1. You figure it out.
In addition, the .mesh file generated by tetgen is different from our manual one in terms of triangle part. when generating triangle indices, tetgen will iterate all the triangles including the ones consisting in tetrahedrons. However, we just include the triangle from .face file which only contain boundary triangles. Both have their own advantages and disadvantages.
The one generated by tetgen will enable us to see the internal of the mesh, but the result of applying it in our example is not so appealing.
the one done by ourselves will give us pleasing result, but we can not see the internal structure of the mesh.
If you want the code product the pleasing result with .mesh file generated by tetgen, there is little change can be done in readMESH.cpp
////////////////original///////////////////// // // allocate space for triangles // F.resize(number_of_triangles,3); // // triangle indices // int tri[3]; // for (int i = 0; i<number_of_triangles; i++) // {// if (4 != fscanf(mesh_file, " %d %d %d %d", &tri[0], &tri[1], &tri[2], &extra))// {// printf("Error: expecting triangle indices...\n");// return false;// }//for (int j = 0; j<3; j++)//{//F(i, j) = tri[j] - 1;//} // } /////////////////fixed by seamanj//////////////////// int tri[3]; for (int i = 0, k = F.rows(); i<number_of_triangles; i++) { if (4 != fscanf(mesh_file, " %d %d %d %d", &tri[0], &tri[1], &tri[2], &extra)) { printf("Error: expecting triangle indices...\n"); return false; } if (extra == 1)//第四位指示是否为边界面 { F.conservativeResize(k + 1, 3); for (int j = 0; j<3; j++) { F(k, j) = tri[j] - 1; } k++; } } ////////////////// end /////////////////////
As for the details of .mesh, please refer to page 33 of http://www.ann.jussieu.fr/frey/publications/RT-0253.pdf, Here I just give part of it:
Then I would like to talk about the ref term, which means the group the element belong to.
Using tetview to open sphere.1.mesh we would see the result below:
see, there are two groups dividing the triangles, the boundary triangles are in green group, the internal triangles are in red group.
- how to produce .mesh .tgf file for 403_BoundedBiharmonicWeights_bin
- How to Create Dump File for Applications
- A summary of how to produce American TH sounds
- A Summary of how to produce American L sounds
- are both configured to produce the output file
- How to work with MeshLab's mesh
- How to save cookie in file for Requests
- How to enable file sharing for my app?
- *.mesh convert to *.3ds file
- Asset file how to
- A Summary of how to produce American F and V sounds
- How to convert Java Key Store file to pem/key for nginx
- The source files...are both configured to produce the output file,The project cannot be built.
- [整理]VC编译程序时出现the source files are both configured to produce the output file....
- Review:how to draw a mesh in xna
- How to access resource file
- How to execute jar file
- How to Use File Choosers
- ruby中的控制逻辑语句
- ruby中数组的定义和使用
- ruby中散列的定义和使用
- ruby中正则表达式的使用
- Ruby中的关键字nil
- how to produce .mesh .tgf file for 403_BoundedBiharmonicWeights_bin
- Shortest Word Distance II
- centos上mysql
- Shortest Word Distance III
- Eclipse+ADT+Android SDK 搭建安卓开发环境
- ruby模块的概念、定义和使用
- Yet another Computer Vision Library? No!
- leecode_357 Count Numbers with Unique Digits
- ruby编程中的异常处理