how to produce .mesh .tgf file for 403_BoundedBiharmonicWeights_bin

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  0
3       0     4     3
3       1     5     4
3       4     0     1
3       3     7     6
3       5     1     2
3       4     8     7
3       7     3     4
3       6    10     9
3       8     4     5
3       7    11    10
3      10     6     7
3       9    13    12
3      11     7     8
3      10    14    13
3      13     9    10
3      12    16    15
3      14    10    11
3      13    17    16
3      16    12    13
3      15    19    18
3      17    13    14
3      16    20    19
3      19    15    16
3      18    22    21
3      20    16    17
3      19    23    22
3      22    18    19
3      22     0    21
3      23    19    20
3      23     1    22
3       0    22     1
3      23    17    24
3       1    23     2
3       2    24     5
3      17    23    20
3      17    11    24
3      24     2    23
3       5    11     8
3      11    17    14
3      21    15    18
3      11     5    24
3       0    25    21
3      15    21    25
3      15     9    12
3      25     0     3
3       3     9    25
3       9    15    25
3       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 1
Dimension 3
Vertices
26
-1.84531  3.7843800000000001  2.4587400000000001 0
0  3.7843800000000001  2.4587400000000001 0
1.84531  3.7843800000000001  2.4587400000000001 0
-1.84531  5.9363999999999999  2.4587400000000001 0
0  5.9363999999999999  2.4587400000000001 0
1.84531  5.9363999999999999  2.4587400000000001 0
-1.84531  8.0884300000000007  2.4587400000000001 0
0  8.0884300000000007  2.4587400000000001 0
1.84531  8.0884300000000007  2.4587400000000001 0
-1.84531  8.0884300000000007  0 0
0  8.0884300000000007  0 0
1.84531  8.0884300000000007  0 0
-1.84531  8.0884300000000007  -2.4587400000000001 0
0  8.0884300000000007  -2.4587400000000001 0
1.84531  8.0884300000000007  -2.4587400000000001 0
-1.84531  5.9363999999999999  -2.4587400000000001 0
0  5.9363999999999999  -2.4587400000000001 0
1.84531  5.9363999999999999  -2.4587400000000001 0
-1.84531  3.7843800000000001  -2.4587400000000001 0
0  3.7843800000000001  -2.4587400000000001 0
1.84531  3.7843800000000001  -2.4587400000000001 0
-1.84531  3.7843800000000001  0 0
0  3.7843800000000001  0 0 
1.84531  3.7843800000000001  0 0
1.84531  5.9363999999999999  0 0
-1.84531  5.9363999999999999  0 0
Triangles
48
0  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 0
23 1   22 0
0  22  1 0
23 17  24 0
1  23  2 0
2  24  5 0
17 23  20 0
17 11  24 0
24 2   23 0
5  11  8 0
11 17  14 0
21 15  18 0
11 5   24 0
0  25 21 0
15 21  25 0
15 9   12 0
25 0    3 0
3  9  25 0
9  15 25 0
9  3   6 0
Tetrahedra
43
25    10    24    16 0
5     4    11    24 0 
16    24    23    17 0 
25     0     4     3 0
5     4     8    11 0
18    15    22    19 0
24    25    16    22 0
11    17    10    14 0
5     2     1    24 0
4     3     7    10 0
23    16    20    19 0
15     9    25    16 0
9     3    10     6 0 
22    16    23    19 0
15    16    22    19 0
25    15    16    22 0
25     9    10    16 0
9     3    25    10 0
16    24    22    23 0
21    15    25    22 0
21    15    22    18 0
23     1     2    24 0
25     3     4    10 0
23     1    24    22 0
3     6     7    10 0
8     4     7    11 0
7     4    10    11 0
23    16    17    20 0
9    15    12    16 0
10     9    13    16 0
9    12    13    16 0
0    22     4     1 0
4     5     1    24 0
4    25    10    24 0
4    10    11    24 0
4    25    24    22 0
1     4    24    22 0
0    25    22    21 0
0    25     4    22 0
14    10    13    17 0
13    10    16    17 0
10    24    16    17 0
11    17    24    10 0
Edges 
0
End
 


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.4587400000000001
2	0  3.7843800000000001  2.4587400000000001
3	1.84531  3.7843800000000001  2.4587400000000001
4	-1.84531  5.9363999999999999  2.4587400000000001
5	0  5.9363999999999999  2.4587400000000001
6	1.84531  5.9363999999999999  2.4587400000000001
7	-1.84531  8.0884300000000007  2.4587400000000001
8	0  8.0884300000000007  2.4587400000000001
9	1.84531  8.0884300000000007  2.4587400000000001
10	-1.84531  8.0884300000000007  0
11	0  8.0884300000000007  0
12	1.84531  8.0884300000000007  0
13	-1.84531  8.0884300000000007  -2.4587400000000001
14	0  8.0884300000000007  -2.4587400000000001
15	1.84531  8.0884300000000007  -2.4587400000000001
16	-1.84531  5.9363999999999999  -2.4587400000000001
17	0  5.9363999999999999  -2.4587400000000001
18	1.84531  5.9363999999999999  -2.4587400000000001
19	-1.84531  3.7843800000000001  -2.4587400000000001
20	0  3.7843800000000001  -2.4587400000000001
21	1.84531  3.7843800000000001  -2.4587400000000001
22	-1.84531  3.7843800000000001  0
23	0  3.7843800000000001  0
24	1.84531  3.7843800000000001  0
25	1.84531  5.9363999999999999  0
26	-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 one
	T(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.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

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.







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值