TM format

Written by Brad Payne

Compiled and source code by Paul Bourke
October 1996


Description

Files with the tm extension are LONI triangle model files. These are used to represent surface models in terms of points and triangles. Points are shared explicitly among triangles. The triangle model format is a stripped down version of movie.byu files from a few years ago. The format for numbers within the file is flexible; where floating point or integer numbers are called for, anything that would be recognized by the C scanf() functions with a "%f" or "%d" format respectively is acceptable. The tm file is an ASCII file representing integers and floating point numbers. It consists of three sections.

Header line

One line header specifying the number of points in the model, then the number of triangles. The numbers are separated by a space.

Point list

The next section, starting on second line of the file, con- tains a list of the points contained in the model. Points are listed with one point per line, three ASCII floating point numbers per point. The three components, x, y, and z, of each point are separated by spaces.

Triangle list

The triangle list consists of one line per triangle. Each line contains three integers specifying the point numbers as indices in the point list. Indices are 1-indexed (apologies to C loyalists, this is an old format), and the last index on each line is negated. So a triangle containing the first three points from the point list could be specified as 1 2 -3.


Discussion

Sharing Points

The sharing of points within the model is significant. If each point is respecified for each triangle in which it occurs, this will incur a significant expense in storage; there will be three points stored for each triangle, as opposed to a more nearly one to one ratio with sharing. This extra expense can be very significant when surface models may be upwards of 500000 triangles. Perhaps more importantly, failure to share points where possible will impair the effectiveness of many renderers, which exploit such information to produce smooth surface appearance.

Ordering Triangles

The order of points within a triangle is significant, although some formulations are equivalent. The order of traversal controls the direction of the surface normal for that triangle, so 1 2 -3 and 2 3 -1 are equivalent, but 1 3 -2 is the reverse of either. Continuous surfaces should have a consistent orientation for all component triangles.


Examples

A model consisting of a single triangle with vertices at the origin and along the x and y axes would be

     3 1
     0.000 0.000 0.000
     1.000 0.000 0.000
     0.000 1.000 0.000
     1 2 -3
a cube of dimension one has 8 vertices and 6 square faces, so 12 triangular faces, thus:
     8 12
     0.000000 0.000000 0.000000
     0.000000 0.000000 1.000000
     0.000000 1.000000 0.000000
     0.000000 1.000000 1.000000
     1.000000 0.000000 0.000000
     1.000000 0.000000 1.000000
     1.000000 1.000000 0.000000
     1.000000 1.000000 1.000000
     1 2 -4
     4 3 -1
     1 5 -6
     6 2 -1
     2 6 -8
     8 4 -2
     3 4 -8
     8 7 -3
     1 3 -7
     7 5 -1
     5 7 -8
     8 6 -5


C source to convert to DXF

#include "stdio.h"
#include "stdlib.h"
#include "math.h"

int main(argc,argv)
int argc;
char **argv;
{
   int i;
   double x[30000],y[30000],z[30000];
   int v1,v2,v3;
   int nv,ne;
   FILE *fptr;

   if ((fptr = fopen(argv[1],"r")) == NULL) {
      fprintf(stderr,"Couldn't open file \"%s\"\n",argv[1]);
      exit(0);
   }

   printf("999\nDXF of UCLA model\n");
   printf("0\nSECTION\n");
   printf("0\nSECTION\n");
   printf("2\nENTITIES\n");
   printf("0\nSECTION\n");
   printf("2\nENTITIES\n");

   fscanf(fptr,"%d %d\n",&nv,&ne);
   fprintf(stderr,"Vertices = %d, facets = %d\n",nv,ne);

   for (i=0;i<nv;i++) {
      if (fscanf(fptr,"%lf %lf %lf",&x[i],&y[i],&z[i]) != 3) {
         fprintf(stderr,"Unexpected end of vertex list\n");
         exit(0);
      }
   }
   for (i=0;i<ne;i++) {
      if (fscanf(fptr,"%d %d %d",&v1,&v2,&v3) != 3) {
         fprintf(stderr,"Unexpected end of facet list\n");
         exit(0);
      }
      printf("0\n3DFACE\n");
      printf("8\n1\n");
      v1--;
      v2--;
      if (v3 < 0)
         v3 = -v3;
      if (v3 < 0)
         v3 = -v3;
      v3--;
      printf("10\n%g\n20\n%g\n30\n%g\n",x[v1],y[v1],z[v1]);
      printf("11\n%g\n21\n%g\n31\n%g\n",x[v2],y[v2],z[v2]);
      printf("12\n%g\n22\n%g\n32\n%g\n",x[v3],y[v3],z[v3]);
      printf("13\n%g\n23\n%g\n33\n%g\n",x[v3],y[v3],z[v3]);
   }

   printf("0\nENDSEC\n");
   printf("0\nEOF\n");
   fclose(fptr);
}