Skip to content
Snippets Groups Projects
Commit 44aefc87 authored by Christophe Geuzaine's avatar Christophe Geuzaine
Browse files

- don't use unset() (only available in cmake >= 2.6.4)

- make sure we don't package the binary dir in make package_source
- fix GMSH_VERSION in Info.plist
- move last few README to README.txt
- added all remaining un-committed converters from mailing list into utils/
parent 5e284d6d
No related branches found
No related tags found
No related merge requests found
Showing
with 1672 additions and 1 deletion
Compile sources using the following command:
gcc stl.c segtri.c mesh.c main.c -o stlToGmsh
To run application
./stlToGmsh <file.stl> <nx> <ny> <nz>
#define MAX(A,B) ((A)>(B) ? (A):(B))
#define MIN(A,B) ((A)<(B) ? (A):(B))
#define ABS(X) ((X) < 0 ? -(X) : (X))
static const int LOGICAL_TRUE = 1;
static const int LOGICAL_FALSE = 0;
static const int LOGICAL_ERROR = -1;
float C_EPS;
File added
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "globals.h"
#include "stl.h"
#include "mesh.h"
#include "segtri.h"
stl_data stl_in;
msh_data msh_out;
int CreateVoxelMesh(int nx, int ny, int nz)
{
msh_data msh_tmp;
int *conversion_list;
int i, j, k, n;
int ind;
float dx, dy, dz;
float cx, cy, cz;
msh_node v[8];
stl_facet T;
stl_vertex q;
stl_vertex r;
char code;
msh_tmp.stats.number_of_nodes = (nx + 1) * (ny + 1) * (nz + 1);
msh_tmp.stats.number_of_elements = nx * ny * nz;
MshAllocate(&msh_tmp);
dx = (stl_in.stats.max.x - stl_in.stats.min.x) / nx;
dy = (stl_in.stats.max.y - stl_in.stats.min.y) / ny;
dz = (stl_in.stats.max.z - stl_in.stats.min.z) / nz;
ind = 0;
cz = stl_in.stats.min.z;
for(k = 0; k < nz + 1; k++)
{
cy = stl_in.stats.min.y;
for(j = 0; j < ny + 1; j++)
{
cx = stl_in.stats.min.x;
for(i = 0; i < nx + 1; i++)
{
msh_tmp.node_start[ind].x = cx;
msh_tmp.node_start[ind].y = cy;
msh_tmp.node_start[ind].z = cz;
ind++;
cx += dx;
}
cy += dy;
}
cz += dz;
}
ind = 0;
for(k = 0; k < nz; k++)
{
for(j = 0; j < ny; j++)
{
for(i = 0; i < nx; i++)
{
msh_tmp.element_start[ind].node[0] = (i + 0) + (nx + 1) * (j + 0) + (nx + 1) * (ny + 1) * (k + 0);
msh_tmp.element_start[ind].node[1] = (i + 1) + (nx + 1) * (j + 0) + (nx + 1) * (ny + 1) * (k + 0);
msh_tmp.element_start[ind].node[2] = (i + 1) + (nx + 1) * (j + 1) + (nx + 1) * (ny + 1) * (k + 0);
msh_tmp.element_start[ind].node[3] = (i + 0) + (nx + 1) * (j + 1) + (nx + 1) * (ny + 1) * (k + 0);
msh_tmp.element_start[ind].node[4] = (i + 0) + (nx + 1) * (j + 0) + (nx + 1) * (ny + 1) * (k + 1);
msh_tmp.element_start[ind].node[5] = (i + 1) + (nx + 1) * (j + 0) + (nx + 1) * (ny + 1) * (k + 1);
msh_tmp.element_start[ind].node[6] = (i + 1) + (nx + 1) * (j + 1) + (nx + 1) * (ny + 1) * (k + 1);
msh_tmp.element_start[ind].node[7] = (i + 0) + (nx + 1) * (j + 1) + (nx + 1) * (ny + 1) * (k + 1);
ind++;
}
}
}
for (i = 0; i < msh_tmp.stats.number_of_elements; i++)
{
// printf("Processing element: %d of %d...\n", i + 1, msh_tmp.stats.number_of_elements);
// Create a ray from the center of the element to a distant point
q.x = 0;
q.y = 0;
q.z = 0;
for (k = 0; k < 8; k++)
{
v[k] = msh_tmp.node_start[msh_tmp.element_start[i].node[k]];
q.x += v[k].x;
q.y += v[k].y;
q.z += v[k].z;
}
q.x /= 8;
q.y /= 8;
q.z /= 8;
r.x = q.x + 2.91f * stl_in.stats.size.x;
r.y = q.y + 2.21f * stl_in.stats.size.y;
r.z = q.z + 2.45f * stl_in.stats.size.z;
n = 0;
for (j = 0; j < stl_in.stats.number_of_facets; j++)
{
T = stl_in.facet_start[j];
code = StlSegTriInt(T, q, r);
if (code != '0') n++;
}
if (n % 2 != 0)
{
// The element is inside the solid
msh_tmp.element_start[i].inside = LOGICAL_TRUE;
}
else
{
// The element is outside the solid
msh_tmp.element_start[i].inside = LOGICAL_FALSE;
}
}
// Remove elements which are outside the solid
msh_out.stats.number_of_nodes = msh_tmp.stats.number_of_nodes;
msh_out.stats.number_of_elements = msh_tmp.stats.number_of_elements;
MshAllocate(&msh_out);
n = 0;
for (i = 0; i < msh_tmp.stats.number_of_elements; i++)
{
if (msh_tmp.element_start[i].inside == LOGICAL_TRUE)
{
msh_out.element_start[n] = msh_tmp.element_start[i];
n++;
}
}
msh_out.stats.number_of_elements = n;
// Allocate memory for conversion list
conversion_list = calloc(msh_tmp.stats.number_of_nodes, sizeof(int));
// Remove unused nodes
for (i = 0; i < msh_tmp.stats.number_of_nodes; i++)
{
msh_tmp.node_start[i].keep = LOGICAL_FALSE;
}
for (i = 0; i < msh_out.stats.number_of_elements; i++)
{
if (msh_out.element_start[i].inside == LOGICAL_TRUE)
{
for (k = 0; k < 8; k++)
{
msh_tmp.node_start[msh_out.element_start[i].node[k]].keep = LOGICAL_TRUE;
}
}
}
n = 0;
for (i = 0; i < msh_tmp.stats.number_of_nodes; i++)
{
if (msh_tmp.node_start[i].keep == LOGICAL_TRUE)
{
msh_out.node_start[n] = msh_tmp.node_start[i];
conversion_list[i] = n;
n++;
}
}
msh_out.stats.number_of_nodes = n;
// Renumber elements
for (i = 0; i < msh_out.stats.number_of_elements; i++)
{
for (k = 0; k < 8; k++)
{
msh_out.element_start[i].node[k] = conversion_list[msh_out.element_start[i].node[k]];
}
}
// Free memory
if (conversion_list != NULL)
{
free(conversion_list);
conversion_list = NULL;
}
MshReallocate(&msh_out);
// Free memory
MshClose(&msh_tmp);
return LOGICAL_TRUE;
}
void Usage()
{
printf("\nUsage:\n");
printf("stlToGmsh <file.stl> <nx> <ny> <nz>\n");
printf("\n");
printf("nx: number of divisions along x axis\n");
printf("ny: number of divisions along y axis\n");
printf("nz: number of divisions along z axis\n");
printf("\nExample:\n");
printf("stlToGmsh part.stl 20 20 20\n");
printf("\n");
}
int main(int argc, char *argv[])
{
int nx, ny, nz;
if (argc != 5)
{
printf("\nError: %d argument(s) entered when 4 were expected\n", argc - 1);
Usage();
exit(0);
}
StlOpenSTL(&stl_in, argv[1]);
sscanf(argv[2], "%d", &nx);
sscanf(argv[3], "%d", &ny);
sscanf(argv[4], "%d", &nz);
printf("Processing...\n");
CreateVoxelMesh(nx, ny, nz);
strncpy(argv[1] + strlen(argv[1]) - 3, "msh", 3);
MshWriteMSH(&msh_out, argv[1]);
// Free memory
StlClose(&stl_in);
MshClose(&msh_out);
printf("Done.\n");
return 0; /* ANSI C requires main to return int. */
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
//#include <malloc.h>
#include "globals.h"
#include "mesh.h"
int MshAllocate(msh_data *msh)
{
/* Allocate memory */
msh->node_start = calloc(msh->stats.number_of_nodes, sizeof(msh_node));
msh->stats.nodes_malloced = msh->stats.number_of_nodes;
if (msh->node_start == NULL) return LOGICAL_FALSE;
msh->element_start = calloc(msh->stats.number_of_elements, sizeof(msh_element));
msh->stats.elements_malloced = msh->stats.number_of_elements;
if (msh->element_start == NULL) return LOGICAL_FALSE;
return LOGICAL_TRUE;
}
int MshReallocate(msh_data *msh)
{
/* Reallocate more memory */
msh->node_start = realloc(msh->node_start, (msh->stats.number_of_nodes + 1) * sizeof(msh_node));
msh->stats.nodes_malloced = msh->stats.number_of_nodes;
if (msh->node_start == NULL) return LOGICAL_FALSE;
msh->element_start = realloc(msh->element_start, (msh->stats.number_of_elements + 1) * sizeof(msh_element));
msh->stats.elements_malloced = msh->stats.number_of_elements;
if (msh->element_start == NULL) return LOGICAL_FALSE;
return LOGICAL_TRUE;
}
void MshClose(msh_data *msh)
{
msh->stats.number_of_nodes = 0;
msh->stats.number_of_elements = 0;
msh->stats.nodes_malloced = 0;
msh->stats.elements_malloced = 0;
// Free memory
if(msh->node_start != NULL)
{
free(msh->node_start);
msh->node_start = NULL;
}
if(msh->element_start != NULL)
{
free(msh->element_start);
msh->element_start = NULL;
}
}
int MshWriteMSH(msh_data *msh, char *file)
{
int i, j;
FILE *fp;
if (msh->node_start == NULL)
return LOGICAL_FALSE;
if (msh->element_start == NULL)
return LOGICAL_FALSE;
fp = fopen(file, "w");
if (fp == NULL) return LOGICAL_FALSE;
fprintf(fp, "$NOD\n");
fprintf(fp, "%d\n", msh->stats.number_of_nodes);
for (i = 0; i < msh->stats.number_of_nodes; i++)
{
fprintf(fp, "%d %f %f %f", i + 1, msh->node_start[i].x, msh->node_start[i].y, msh->node_start[i].z);
fprintf(fp, "\n");
}
fprintf(fp, "$ENDNOD\n");
fprintf(fp, "$ELM\n");
fprintf(fp, "%d\n", msh->stats.number_of_elements);
for (i = 0; i < msh->stats.number_of_elements; i++)
{
fprintf(fp, "%d", i + 1);
fprintf(fp, " %d", 5);
fprintf(fp, " %d", 1);
fprintf(fp, " %d", 1);
fprintf(fp, " %d", 8);
for (j = 0; j < 8; j++)
{
fprintf(fp, " %d", msh->element_start[i].node[j] + 1);
}
fprintf(fp, "\n");
}
fprintf(fp, "$ENDELM\n");
fclose(fp);
return LOGICAL_TRUE;
}
typedef struct
{
float x, y, z;
int keep;
}msh_node;
typedef struct
{
int node[8];
int inside;
}msh_element;
typedef struct
{
int number_of_nodes;
int number_of_elements;
int nodes_malloced;
int elements_malloced;
}msh_stats;
typedef struct
{
FILE *fp;
msh_node *node_start;
msh_element *element_start;
msh_stats stats;
}msh_data;
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "globals.h"
#include "stl.h"
#include "segtri.h"
/*------------Function prototypes. ----------------------------*/
int StlFindLargestValue(stl_vertex v);
float StlDot(stl_vertex a, stl_vertex b);
void StlSubVec(stl_vertex a, stl_vertex b, stl_vertex *c);
char StlInTri3D(stl_facet T, int m, stl_vertex r );
char StlInTri2D(stl_vertex Tp[3], stl_vertex pp );
float StlArea(stl_vertex q, stl_vertex b, stl_vertex c );
char StlInPlane(stl_facet T, int m, stl_vertex q, stl_vertex r);
char StlSegTriCross(stl_facet T, stl_vertex q, stl_vertex r );
float StlVolume(stl_vertex a, stl_vertex b, stl_vertex c, stl_vertex d );
/*-------------------------------------------------------------------*/
/*---------------------------------------------------------------------
'p': The segment lies wholly within the plane.
'q': The q endpoint is on the plane (but not 'p').
'r': The r endpoint is on the plane (but not 'p').
'0': The segment lies strictly to one side or the other of the plane.
'1': The segement intersects the plane, and 'p' does not hold.
---------------------------------------------------------------------*/
char StlSegPlaneInt(stl_plane P, stl_vertex q, stl_vertex r, stl_vertex *p, int *m)
{
stl_vertex rq;
float num, denom, t;
num = P.D - StlDot(q, P.normal);
StlSubVec(r, q, &rq);
denom = StlDot(P.normal, rq);
if ( ABS(denom) < C_EPS )
{
/* Segment is parallel to plane. */
if ( ABS(num) < C_EPS)
{
/* q is on plane. */
*m = StlFindLargestValue(P.normal);
return 'p';
}
else
return '0';
}
else
t = num / denom;
if (t < -C_EPS || t > 1 + C_EPS)
return '0';
if ( (C_EPS < t) && (t < 1 - C_EPS) )
{
*m = StlFindLargestValue(P.normal);
p->x = q.x + t * (r.x - q.x);
p->y = q.y + t * (r.y - q.y);
p->z = q.z + t * (r.z - q.z);
return '1';
}
else if ( t <= C_EPS ) /* t == 0 */
{
*m = StlFindLargestValue(P.normal);
return 'q';
}
else if ( t >= 1 - C_EPS ) /* t == 1 */
{
*m = StlFindLargestValue(P.normal);
return 'r';
}
return '0';
}
int StlFindLargestValue(stl_vertex nv)
{
int m;
int j;
float tcur; /*temporary storage */
float biggest = 0; /* Largest component of normal vector. */
float v[3];
v[0] = nv.x;
v[1] = nv.y;
v[2] = nv.z;
for (j = 0; j < 3; j++)
{
tcur = ABS(v[j]);
if ( tcur > biggest)
{
biggest = tcur;
m = j;
}
}
return m;
}
/*---------------------------------------------------------------------
a - b ==> c.
---------------------------------------------------------------------*/
void StlSubVec(stl_vertex a, stl_vertex b, stl_vertex *c)
{
c->x = a.x - b.x;
c->y = a.y - b.y;
c->z = a.z - b.z;
}
/*---------------------------------------------------------------------
Returns the dot product of the two input vectors.
---------------------------------------------------------------------*/
float StlDot(stl_vertex a, stl_vertex b)
{
float sum = 0;
sum = a.x * b.x + a.y * b.y + a.z * b.z;
return sum;
}
/* Assumption: p lies in the plane containing T.
Returns a char:
'V': the query point p coincides with a Vertex of triangle T.
'E': the query point p is in the relative interior of an Edge of triangle T.
'F': the query point p is in the relative interior of a Face of triangle T.
'0': the query point p does not intersect (misses) triangle T.
*/
char StlInTri3D( stl_facet T, int m, stl_vertex r )
{
int j;
stl_vertex pp; /* projected p */
stl_vertex Tp[3]; /* projected T: three new vertices */
/* Project out coordinate m in both p and the triangular face */
for ( j = 0; j < 3; j++ )
{
if ( m == 0 )
{
pp.x = r.y;
pp.y = r.z;
Tp[j].x = T.vertex[j].y;
Tp[j].y = T.vertex[j].z;
}
if ( m == 1 )
{
pp.x = r.x;
pp.y = r.z;
Tp[j].x = T.vertex[j].x;
Tp[j].y = T.vertex[j].z;
}
if ( m == 2 )
{
pp.x = r.x;
pp.y = r.y;
Tp[j].x = T.vertex[j].x;
Tp[j].y = T.vertex[j].y;
}
}
return (StlInTri2D(Tp, pp));
}
char StlInTri2D(stl_vertex Tp[3], stl_vertex pp )
{
float area0, area1, area2;
/* compute three AreaSign() values for pp w.r.t. each edge of the face in 2D */
area0 = StlArea( pp, Tp[0], Tp[1] );
area1 = StlArea( pp, Tp[1], Tp[2] );
area2 = StlArea( pp, Tp[2], Tp[0] );
if ( ( ABS(area0) < C_EPS ) && ( area1 > 0 ) && ( area2 > 0 ) ||
( ABS(area1) < C_EPS ) && ( area0 > 0 ) && ( area2 > 0 ) ||
( ABS(area2) < C_EPS ) && ( area0 > 0 ) && ( area1 > 0 ) )
return 'E';
if ( ( ABS(area0) < C_EPS ) && ( area1 < 0 ) && ( area2 < 0 ) ||
( ABS(area1) < C_EPS ) && ( area0 < 0 ) && ( area2 < 0 ) ||
( ABS(area2) < C_EPS ) && ( area0 < 0 ) && ( area1 < 0 ) )
return 'E';
if ( ( area0 > 0 ) && ( area1 > 0 ) && ( area2 > 0 ) ||
( area0 < 0 ) && ( area1 < 0 ) && ( area2 < 0 ) )
return 'F';
if ( ( ABS(area0) < C_EPS ) && ( ABS(area1) < C_EPS ) ||
( ABS(area0) < C_EPS ) && ( ABS(area2) < C_EPS ) ||
( ABS(area1) < C_EPS ) && ( ABS(area2) < C_EPS ) )
return 'V';
return '0';
}
float StlArea( stl_vertex a, stl_vertex b, stl_vertex c )
{
float area2;
area2 = ( b.x - a.x ) * ( c.y - a.y ) -
( c.x - a.x ) * ( b.y - a.y );
return area2;
}
char StlTriPlaneCross(stl_facet T, stl_plane P, int *v)
{
int code = '?';
float d0, d1, d2;
d0 = T.vertex[0].x * P.normal.x +
T.vertex[0].y * P.normal.y +
T.vertex[0].z * P.normal.z - P.D;
d1 = T.vertex[1].x * P.normal.x +
T.vertex[1].y * P.normal.y +
T.vertex[1].z * P.normal.z - P.D;
d2 = T.vertex[2].x * P.normal.x +
T.vertex[2].y * P.normal.y +
T.vertex[2].z * P.normal.z - P.D;
if ((d0 > 0) && (d1 > 0) && (d2 > 0) ||
(d0 < 0) && (d1 < 0) && (d2 < 0))
return '0';
// The triangle is completly on the plane
// This will result in bad contours.
// Another section should be chosen.
if (d0 == 0 && d1 == 0 && d2 == 0)
{
return '?';
}
if (d0 == 0 && d1 == 0)
{
*v = 2;
return '1';
}
if (d0 == 0 && d2 == 0)
{
*v = 1;
return '1';
}
if (d1 == 0 && d2 == 0)
{
*v = 2;
return '1';
}
if ((d0 <= 0) && (d1 > 0) && (d2 > 0) ||
(d0 >= 0) && (d1 < 0) && (d2 < 0))
{
*v = 0;
return '1';
}
if ((d0 > 0) && (d1 <= 0) && (d2 > 0) ||
(d0 < 0) && (d1 >= 0) && (d2 < 0))
{
*v = 1;
return '1';
}
if ((d0 > 0) && (d1 > 0) && (d2 <= 0) ||
(d0 < 0) && (d1 < 0) && (d2 >= 0))
{
*v = 2;
return '1';
}
return code;
}
char StlTriTriCross(stl_facet T0, stl_facet T1)
{
int code = '?';
float vol0, vol1, vol2;
vol0 = StlVolume(T0.vertex[0], T0.vertex[1], T0.vertex[2], T1.vertex[0]);
vol1 = StlVolume(T0.vertex[0], T0.vertex[1], T0.vertex[2], T1.vertex[1]);
vol2 = StlVolume(T0.vertex[0], T0.vertex[1], T0.vertex[2], T1.vertex[2]);
/* Opposite sign: no intersection between triangle 1 and triangle 2 */
if ( ( ( vol0 > 0 ) && ( vol1 > 0 ) && ( vol2 > 0 ) ) ||
( ( vol0 < 0 ) && ( vol1 < 0 ) && ( vol2 < 0 ) ) )
return '0';
return code;
}
char StlSegTriInt(stl_facet T, stl_vertex q, stl_vertex r)
{
int code = '?';
int m = -1;
stl_vertex p;
stl_plane P;
P.D = StlDot(T.vertex[0], T.normal);
P.normal = T.normal;
code = StlSegPlaneInt(P, q, r, &p, &m );
if ( code == '0')
return '0';
else if ( code == 'q')
return StlInTri3D( T, m, q );
else if ( code == 'r')
return StlInTri3D( T, m, r );
else if ( code == 'p' )
return 'p';
else if ( code == '1' )
return StlSegTriCross( T, q, r );
else
return code;
}
/*---------------------------------------------------------------------
The signed volumes of three tetrahedra are computed, determined
by the segment qr, and each edge of the triangle.
Returns a char:
'v': the open segment includes a vertex of T.
'e': the open segment includes a point in the relative interior of an edge
of T.
'f': the open segment includes a point in the relative interior of a face
of T.
'0': the open segment does not intersect triangle T.
---------------------------------------------------------------------*/
char StlSegTriCross(stl_facet T, stl_vertex q, stl_vertex r)
{
float vol0, vol1, vol2;
vol0 = StlVolume( q, T.vertex[0], T.vertex[1], r );
vol1 = StlVolume( q, T.vertex[1], T.vertex[2], r );
vol2 = StlVolume( q, T.vertex[2], T.vertex[0], r );
/* Same sign: segment intersects interior of triangle. */
if ( ( ( vol0 > C_EPS ) && ( vol1 > C_EPS ) && ( vol2 > C_EPS ) ) ||
( ( vol0 < -C_EPS ) && ( vol1 < -C_EPS ) && ( vol2 < -C_EPS ) ) )
return 'f';
/* Opposite sign: no intersection between segment and triangle */
if ( ( ( vol0 > 0 ) || ( vol1 > 0 ) || ( vol2 > 0 ) ) &&
( ( vol0 < 0 ) || ( vol1 < 0 ) || ( vol2 < 0 ) ) )
return '0';
/* Two zeros: segment intersects vertex. */
else if ( ( ( ABS(vol0) < C_EPS ) && ( ABS(vol1) < C_EPS ) ) ||
( ( ABS(vol0) < C_EPS ) && ( ABS(vol2) < C_EPS ) ) ||
( ( ABS(vol1) < C_EPS ) && ( ABS(vol2) < C_EPS ) ) )
return 'v';
/* One zero: segment intersects edge. */
else if ( ( ABS(vol0) < C_EPS ) || ( ABS(vol1) < C_EPS ) || ( ABS(vol2) < C_EPS ) )
return 'e';
else
return '0';
}
float StlVolume( stl_vertex a, stl_vertex b, stl_vertex c, stl_vertex d )
{
float vol;
float bxdx, bydy, bzdz, cxdx, cydy, czdz;
bxdx = b.x - d.x;
bydy = b.y - d.y;
bzdz = b.z - d.z;
cxdx = c.x - d.x;
cydy = c.y - d.y;
czdz = c.z - d.z;
vol = (a.z - d.z) * (bxdx * cydy - bydy * cxdx)
+ (a.y - d.y) * (bzdz * cxdx - bxdx * czdz)
+ (a.x - d.x) * (bydy * czdz - bzdz * cydy);
return vol;
}
char StlTriTriCross(stl_facet T0, stl_facet T1);
char StlSegTriInt( stl_facet T, stl_vertex q, stl_vertex r);
char StlSegPlaneInt(stl_plane P, stl_vertex q, stl_vertex r, stl_vertex *p, int *m );
char StlTriPlaneCross(stl_facet T, stl_plane P, int *v);
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
//#include <malloc.h>
#include "globals.h"
#include "stl.h"
#if !defined(SEEK_SET)
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
#endif
int StlGetLittleInt(FILE *fp)
{
int value;
value = fgetc(fp) & 0xFF;
value |= (fgetc(fp) & 0xFF) << 0x08;
value |= (fgetc(fp) & 0xFF) << 0x10;
value |= (fgetc(fp) & 0xFF) << 0x18;
return(value);
}
float StlGetLittleFloat(FILE *fp)
{
union
{
int int_value;
float float_value;
} value;
value.int_value = fgetc(fp) & 0xFF;
value.int_value |= (fgetc(fp) & 0xFF) << 0x08;
value.int_value |= (fgetc(fp) & 0xFF) << 0x10;
value.int_value |= (fgetc(fp) & 0xFF) << 0x18;
return(value.float_value);
}
void StlPutLittleInt(FILE *fp, int value_in)
{
int new_value;
union
{
int int_value;
char char_value[4];
} value;
value.int_value = value_in;
new_value = value.char_value[0] & 0xFF;
new_value |= (value.char_value[1] & 0xFF) << 0x08;
new_value |= (value.char_value[2] & 0xFF) << 0x10;
new_value |= (value.char_value[3] & 0xFF) << 0x18;
fwrite(&new_value, sizeof(int), 1, fp);
}
void StlPutLittleFloat(FILE *fp, float value_in)
{
int new_value;
union
{
float float_value;
char char_value[4];
} value;
value.float_value = value_in;
new_value = value.char_value[0] & 0xFF;
new_value |= (value.char_value[1] & 0xFF) << 0x08;
new_value |= (value.char_value[2] & 0xFF) << 0x10;
new_value |= (value.char_value[3] & 0xFF) << 0x18;
fwrite(&new_value, sizeof(int), 1, fp);
}
int StlCheckIfFileExists(char *file)
{
FILE *fp;
fp = fopen(file, "rb");
if(fp == NULL)
{
return LOGICAL_FALSE;
}
else
{
fclose(fp);
return LOGICAL_TRUE;
}
}
int StlInitialize(stl_data *stl, char *file)
{
long file_size;
int header_num_facets;
int num_facets;
int i, j;
unsigned char chtest[128];
unsigned char fhtest[5];
int num_lines = 1;
stl->stats.volume = -1.0;
/* Open the file */
stl->fp = fopen(file, "rb");
if(stl->fp == NULL)
return LOGICAL_FALSE;
/* Find size of file */
fseek(stl->fp, 0, SEEK_END);
file_size = ftell(stl->fp);
stl->stats.file_size = file_size;
/* Check for binary or ASCII file */
fseek(stl->fp, HEADER_SIZE, SEEK_SET);
fread(chtest, sizeof(chtest), 1, stl->fp);
stl->stats.type = ASCII;
for(i = 0; i < sizeof(chtest); i++)
{
if(chtest[i] > 127)
{
stl->stats.type = BINARY;
break;
}
}
rewind(stl->fp);
/* Get the header and the number of facets in the .STL file */
/* If the .STL file is binary, then do the following */
if(stl->stats.type == BINARY)
{
/* Test if the STL file has the right size */
if(((file_size - HEADER_SIZE) % SIZEOF_STL_FACET != 0)
|| (file_size < STL_MIN_FILE_SIZE))
return LOGICAL_FALSE;
num_facets = (file_size - HEADER_SIZE) / SIZEOF_STL_FACET;
/* Read the header */
strcpy(stl->stats.header, "");
fread(stl->stats.header, LABEL_SIZE, 1, stl->fp);
stl->stats.header[80] = '\0';
/* Read the int following the header. This should contain # of facets */
header_num_facets = StlGetLittleInt(stl->fp);
//if(num_facets != header_num_facets)
//"Warning: File size doesn't match number of facets in the header"
}
/* Otherwise, if the .STL file is ASCII, then do the following */
else
{
/* Get the header */
for(i = 0; (i < 80) && (chtest[i] = getc(stl->fp)) != '\n'; i++);
fscanf(stl->fp, "%s", &fhtest);
if (strcmp(fhtest, "facet") != 0)
return LOGICAL_FALSE;
rewind(stl->fp);
/* Find the number of facets */
j = 0;
for(i = 0; i < file_size ; i++)
{
j++;
if(getc(stl->fp) == '\n')
{
if(j > 4) /* don't count short lines */
{
num_lines++;
}
j = 0;
}
}
rewind(stl->fp);
/* Get the header */
strcpy(stl->stats.header, "");
for(i = 0; (i < 80) && (stl->stats.header[i] = getc(stl->fp)) != '\n'; i++);
num_facets = num_lines / ASCII_LINES_PER_FACET;
}
stl->stats.number_of_facets += num_facets;
/* Successful exit */
return LOGICAL_TRUE;
}
int StlOpenSTL(stl_data *stl, char *file)
{
StlClose(stl);
if (StlInitialize(stl, file) == LOGICAL_TRUE)
{
if (StlAllocate(stl) == LOGICAL_TRUE)
StlReadStl(stl, 0, 1);
else
return LOGICAL_FALSE;
}
else
return LOGICAL_FALSE;
return LOGICAL_TRUE;
}
void StlClose(stl_data *stl)
{
stl_index = 0;
stl->stats.number_of_facets = 0;
stl->stats.malloced = 0;
stl->stats.freed = 0;
stl->stats.facets_malloced = 0;
stl->stats.file_size = 0;
strcpy(stl->stats.header, "");
stl->stats.shortest_edge = 0;
stl->stats.tolerance = 0;
stl->stats.type = 0;
stl->stats.area = 0;
stl->stats.volume = 0;
stl->stats.min.x = 0;
stl->stats.min.y = 0;
stl->stats.min.z = 0;
stl->stats.max.x = 0;
stl->stats.max.y = 0;
stl->stats.max.z = 0;
stl->stats.center.x = 0;
stl->stats.center.y = 0;
stl->stats.center.z = 0;
stl->stats.size.x = 0;
stl->stats.size.y = 0;
stl->stats.size.z = 0;
stl->stats.bounding_diameter = 0;
// Free memory
if(stl->facet_start != NULL)
{
free(stl->facet_start);
stl->facet_start = NULL;
}
}
int StlAllocate(stl_data *stl)
{
/* Allocate memory for the entire .STL file */
stl->facet_start = calloc(stl->stats.number_of_facets, sizeof(stl_facet));
stl->stats.facets_malloced = stl->stats.number_of_facets;
if (stl->facet_start == NULL) return LOGICAL_FALSE;
return LOGICAL_TRUE;
}
int StlAddSTL(stl_data *stl, char *file)
{
int first_facet;
first_facet = stl->stats.number_of_facets;
if (StlInitialize(stl, file) == LOGICAL_TRUE)
{
if (StlReallocate(stl) == LOGICAL_TRUE)
StlReadStl(stl, first_facet, 1);
else
return LOGICAL_FALSE;
}
else
return LOGICAL_FALSE;
return LOGICAL_TRUE;
}
int StlReallocate(stl_data *stl)
{
/* Reallocate more memory for the .STL file(s) */
stl->facet_start = realloc(stl->facet_start, (stl->stats.number_of_facets + 1) * sizeof(stl_facet));
stl->stats.facets_malloced = stl->stats.number_of_facets;
if (stl->facet_start == NULL) return LOGICAL_FALSE;
return LOGICAL_TRUE;
}
void StlReadStl(stl_data *stl, int first_facet, int first)
{
stl_facet facet;
int i;
float diff_x;
float diff_y;
float diff_z;
float max_diff;
if (stl->facet_start == NULL)
return;
if(stl->stats.type == BINARY)
{
fseek(stl->fp, HEADER_SIZE, SEEK_SET);
}
else
{
rewind(stl->fp);
/* Skip the first line of the file */
while(getc(stl->fp) != '\n');
}
for(i = first_facet; i < stl->stats.number_of_facets; i++)
{
if(stl->stats.type == BINARY)
/* Read a single facet from a binary .STL file */
{
facet.normal.x = StlGetLittleFloat(stl->fp);
facet.normal.y = StlGetLittleFloat(stl->fp);
facet.normal.z = StlGetLittleFloat(stl->fp);
facet.vertex[0].x = StlGetLittleFloat(stl->fp);
facet.vertex[0].y = StlGetLittleFloat(stl->fp);
facet.vertex[0].z = StlGetLittleFloat(stl->fp);
facet.vertex[1].x = StlGetLittleFloat(stl->fp);
facet.vertex[1].y = StlGetLittleFloat(stl->fp);
facet.vertex[1].z = StlGetLittleFloat(stl->fp);
facet.vertex[2].x = StlGetLittleFloat(stl->fp);
facet.vertex[2].y = StlGetLittleFloat(stl->fp);
facet.vertex[2].z = StlGetLittleFloat(stl->fp);
facet.extra[0] = fgetc(stl->fp);
facet.extra[1] = fgetc(stl->fp);
}
else
/* Read a single facet from an ASCII .STL file */
{
fscanf(stl->fp, "%*s %*s %f %f %f\n", &facet.normal.x,
&facet.normal.y, &facet.normal.z);
fscanf(stl->fp, "%*s %*s");
fscanf(stl->fp, "%*s %f %f %f\n", &facet.vertex[0].x,
&facet.vertex[0].y, &facet.vertex[0].z);
fscanf(stl->fp, "%*s %f %f %f\n", &facet.vertex[1].x,
&facet.vertex[1].y, &facet.vertex[1].z);
fscanf(stl->fp, "%*s %f %f %f\n", &facet.vertex[2].x,
&facet.vertex[2].y, &facet.vertex[2].z);
fscanf(stl->fp, "%*s");
fscanf(stl->fp, "%*s");
}
/* Write the facet into memory. */
stl->facet_start[i] = facet;
/* while we are going through all of the facets, let's find the */
/* maximum and minimum values for x, y, and z */
/* Initialize the max and min values the first time through*/
if(first)
{
stl->stats.max.x = facet.vertex[0].x;
stl->stats.min.x = facet.vertex[0].x;
stl->stats.max.y = facet.vertex[0].y;
stl->stats.min.y = facet.vertex[0].y;
stl->stats.max.z = facet.vertex[0].z;
stl->stats.min.z = facet.vertex[0].z;
diff_x = ABS(facet.vertex[0].x - facet.vertex[1].x);
diff_y = ABS(facet.vertex[0].y - facet.vertex[1].y);
diff_z = ABS(facet.vertex[0].z - facet.vertex[1].z);
max_diff = MAX(diff_x, diff_y);
max_diff = MAX(diff_z, max_diff);
stl->stats.shortest_edge = max_diff;
first = 0;
}
/* now find the max and min values */
stl->stats.max.x = MAX(stl->stats.max.x, facet.vertex[0].x);
stl->stats.min.x = MIN(stl->stats.min.x, facet.vertex[0].x);
stl->stats.max.y = MAX(stl->stats.max.y, facet.vertex[0].y);
stl->stats.min.y = MIN(stl->stats.min.y, facet.vertex[0].y);
stl->stats.max.z = MAX(stl->stats.max.z, facet.vertex[0].z);
stl->stats.min.z = MIN(stl->stats.min.z, facet.vertex[0].z);
stl->stats.max.x = MAX(stl->stats.max.x, facet.vertex[1].x);
stl->stats.min.x = MIN(stl->stats.min.x, facet.vertex[1].x);
stl->stats.max.y = MAX(stl->stats.max.y, facet.vertex[1].y);
stl->stats.min.y = MIN(stl->stats.min.y, facet.vertex[1].y);
stl->stats.max.z = MAX(stl->stats.max.z, facet.vertex[1].z);
stl->stats.min.z = MIN(stl->stats.min.z, facet.vertex[1].z);
stl->stats.max.x = MAX(stl->stats.max.x, facet.vertex[2].x);
stl->stats.min.x = MIN(stl->stats.min.x, facet.vertex[2].x);
stl->stats.max.y = MAX(stl->stats.max.y, facet.vertex[2].y);
stl->stats.min.y = MIN(stl->stats.min.y, facet.vertex[2].y);
stl->stats.max.z = MAX(stl->stats.max.z, facet.vertex[2].z);
stl->stats.min.z = MIN(stl->stats.min.z, facet.vertex[2].z);
}
stl->stats.size.x = stl->stats.max.x - stl->stats.min.x;
stl->stats.size.y = stl->stats.max.y - stl->stats.min.y;
stl->stats.size.z = stl->stats.max.z - stl->stats.min.z;
/*
stl->stats.bounding_diameter = sqrt(stl->stats.size.x * stl->stats.size.x + stl->stats.size.y * stl->stats.size.y + stl->stats.size.z * stl->stats.size.z);
C_EPS = stl->stats.bounding_diameter / 10000;
C_EPS *= C_EPS;
*/
C_EPS = 1E-6f;
StlReallocate(stl);
}
int StlWriteAscii(stl_data *stl, char *file, char *label)
{
int i;
FILE *fp;
/* Open the file */
fp = fopen(file, "w");
if(fp == NULL)
{
return LOGICAL_FALSE;
}
fprintf(fp, "solid %s\n", label);
for(i = 0; i < stl->stats.number_of_facets; i++)
{
fprintf(fp, "facet normal %.8E %.8E %.8E\n",
stl->facet_start[i].normal.x, stl->facet_start[i].normal.y,
stl->facet_start[i].normal.z);
fprintf(fp, "outer loop\n");
fprintf(fp, "vertex %.8E %.8E %.8E\n",
stl->facet_start[i].vertex[0].x, stl->facet_start[i].vertex[0].y,
stl->facet_start[i].vertex[0].z);
fprintf(fp, "vertex %.8E %.8E %.8E\n",
stl->facet_start[i].vertex[1].x, stl->facet_start[i].vertex[1].y,
stl->facet_start[i].vertex[1].z);
fprintf(fp, "vertex %.8E %.8E %.8E\n",
stl->facet_start[i].vertex[2].x, stl->facet_start[i].vertex[2].y,
stl->facet_start[i].vertex[2].z);
fprintf(fp, "endloop\n");
fprintf(fp, "endfacet\n");
}
fprintf(fp, "endsolid %s\n", label);
fclose(fp);
return LOGICAL_TRUE;
}
int StlWriteBinary(stl_data *stl, char *file, char *label)
{
FILE *fp;
int i;
if (stl->facet_start == NULL)
return LOGICAL_FALSE;
/* Open the file */
fp = fopen(file, "wb");
if(fp == NULL)
{
return LOGICAL_FALSE;
}
fprintf(fp, "%s", label);
for(i = strlen(label); i < LABEL_SIZE; i++) putc(0, fp);
fseek(fp, LABEL_SIZE, SEEK_SET);
StlPutLittleInt(fp, stl->stats.number_of_facets);
for(i = 0; i < stl->stats.number_of_facets; i++)
{
StlPutLittleFloat(fp, stl->facet_start[i].normal.x);
StlPutLittleFloat(fp, stl->facet_start[i].normal.y);
StlPutLittleFloat(fp, stl->facet_start[i].normal.z);
StlPutLittleFloat(fp, stl->facet_start[i].vertex[0].x);
StlPutLittleFloat(fp, stl->facet_start[i].vertex[0].y);
StlPutLittleFloat(fp, stl->facet_start[i].vertex[0].z);
StlPutLittleFloat(fp, stl->facet_start[i].vertex[1].x);
StlPutLittleFloat(fp, stl->facet_start[i].vertex[1].y);
StlPutLittleFloat(fp, stl->facet_start[i].vertex[1].z);
StlPutLittleFloat(fp, stl->facet_start[i].vertex[2].x);
StlPutLittleFloat(fp, stl->facet_start[i].vertex[2].y);
StlPutLittleFloat(fp, stl->facet_start[i].vertex[2].z);
fputc(stl->facet_start[i].extra[0], fp);
fputc(stl->facet_start[i].extra[1], fp);
}
fclose(fp);
return LOGICAL_TRUE;
}
#define LABEL_SIZE 80
#define NUM_FACET_SIZE 4
#define HEADER_SIZE 84
#define STL_MIN_FILE_SIZE 134
#define ASCII_LINES_PER_FACET 7
#define SIZEOF_EDGE_SORT 24
typedef struct
{
float x, y, z;
}stl_vertex;
typedef char stl_extra[2];
typedef struct
{
stl_vertex normal;
stl_vertex vertex[3];
stl_extra extra;
}stl_facet;
#define SIZEOF_STL_FACET 50
typedef enum {BINARY, ASCII} stl_type;
typedef struct
{
long file_size;
char header[81];
stl_type type;
int number_of_facets;
stl_vertex max;
stl_vertex min;
stl_vertex center;
stl_vertex size;
float bounding_diameter;
float shortest_edge;
float tolerance;
float volume;
float area;
int malloced;
int freed;
int facets_malloced;
}stl_stats;
typedef struct
{
FILE *fp;
stl_facet *facet_start;
stl_stats stats;
}stl_data;
typedef struct
{
stl_vertex normal;
float D;
}stl_plane;
int stl_index;
int StlGetLittleInt(FILE *fp);
float StlGetLittleFloat(FILE *fp);
void StlPutLittleInt(FILE *fp, int value_in);
void StlPutLittleFloat(FILE *fp, float value_in);
int StlCheckIfFileExists(char *file);
int StlOpenStl(stl_data *stl, char *file);
int StlAddStl(stl_data *stl, char *file);
void StlReadStl(stl_data *stl, int first_facet, int first);
void StlClose(stl_data *stl);
int StlReallocate(stl_data *stl);
int StlAllocate(stl_data *stl);
#!/usr/bin/python
#tetgentogmsh.py
#Petit convertiseur de fichier tetgen en gmsh .msh
#car le fichier .mesh cree par tetgen ne conserve pas les marqueurs de surface
#Ecrit par frederic Renou frederic.renou@gmail.com 2009
#Base sur la bibliotheque de Ondrej Certik <ondrej@certik.cz>
#homepage: http://code.google.com/p/femgeom/
import sys
verbose=False
if sys.argv[1] in ('h','-h','-help'):
print '-v for verbose mode'
print 'l argument doit etre le fichier tetgen sans le .node'
raise 'fin du fichier'
else:
if sys.argv[1] in ('v','-v'):
print '-v for verbose mode'
fname=sys.argv[2]
verbose=True
else:
fname=sys.argv[1]
#ouverture des fichiers
fo=file(fname+'.msh',"w")
fn=file(fname+'.node',"r")
ff=file(fname+'.face',"r")
fe=file(fname+'.ele',"r")
#lecture du fichier .node
l=[int(x) for x in fn.readline().split()]
npoints,dim,nattrib,nbound=l
assert dim==3
if npoints < 3:
raise "tetgen file empty"
l=fo.write("$NOD\n")
l=fo.write("%d\n"%npoints)
npointlu=0
for line in fn:
if line[0]=="#": continue
l=[float(x) for x in line.split()]
npointlu=npointlu + 1
l[0]=int(l[0])
fo.write("%d "%l[0]+"%f "%l[1]+"%f "%l[2]+"%f\n"%l[3])
if verbose: print "nombre de point lut %d nombre de point par tetgen %d"%(npointlu,npoints)
assert npoints==npointlu
#lecture des fichiers elements
l=[int(x) for x in fe.readline().split()]
ntetra,nnod,nattribe=l
if nnod!=4:
raise "tetgen element are not linear not supported"
#if nattribe!=0:
# raise "tetgen did assign an entity number to each element"
l=[int(x) for x in ff.readline().split()]
nfaces,nattribf=l
if nattribf!=1:
raise "tetgen didn't assign an entity number to each face"
#fin de l ecriture des noeud
l=fo.write("$ENDNOD\n")
l=fo.write("$ELM\n")
l=fo.write("%d\n"%(ntetra+nfaces))
#lecture du fichier face
nfacelu=0
for line in ff:
if line[0]=="#": continue
l=[int(x) for x in line.split()]
nfacelu=nfacelu+1
assert len(l)==5
n=[ #elm-number
l[0],
#elm-type
2,
#reg-phys
l[4],
#reg-elem
l[4],
#number-of-nodes
3,
#coord1
l[1],
#coord
l[2],
#coord
l[3]
]
l=fo.write("%d %d %d %d %d %d %d %d\n"%tuple(n))
if verbose: print "nombre de face lut %d nombre de face par tetgen %d"%(nfacelu,nfaces)
assert nfaces==nfacelu
ntetralu=0
for line in fe:
if line[0]=="#": continue
l=[int(x) for x in line.split()]
ntetralu=ntetralu+1
if nattribe==1: regnumber=l[5]
else: regnumber=3
assert len(l)==(nattrib+5)
n=[ #elm-number
l[0],
#elm-type
4,
#reg-phys
regnumber,
#reg-elem
regnumber,
#number-of-nodes
4,
#coord
l[1],
#coord
l[2],
#coord
l[3],
#coord
l[4]
]
l=fo.write("%d %d %d %d %d %d %d %d %d\n"%tuple(n))
if verbose: print "nombre de tetra lut %d nombre de tetra par tetgen %d"%(nfacelu,nfaces)
assert ntetra==ntetralu
\ No newline at end of file
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
<key>CFBundleShortVersionString</key><string>GMSH_VERSION</string> <key>CFBundleShortVersionString</key><string>GMSH_VERSION</string>
<key>CFBundleIconFile</key><string>Gmsh.icns</string> <key>CFBundleIconFile</key><string>Gmsh.icns</string>
<key>CFBundleSignature</key><string>GMSH</string> <key>CFBundleSignature</key><string>GMSH</string>
<key>CFBundleGetInfoString</key><string>GMSH_VERSION, Copyright 1997-2009 C. Geuzaine and J.-F. Remacle</string> <key>CFBundleGetInfoString</key><string>Gmsh GMSH_VERSION, Copyright 1997-2009 C. Geuzaine and J.-F. Remacle</string>
<key>CFBundleIdentifier</key><string>org.geuz.Gmsh</string> <key>CFBundleIdentifier</key><string>org.geuz.Gmsh</string>
<key>CFBundleDocumentTypes</key> <key>CFBundleDocumentTypes</key>
<array> <array>
......
File moved
File moved
### FIXME TODO ###
# rm -rf Gmsh.framework
# mkdir -p Gmsh.framework
# mkdir -p Gmsh.framework/Versions
# mkdir -p Gmsh.framework/Versions/A
# mkdir -p Gmsh.framework/Versions/A/Headers
# mkdir -p Gmsh.framework/Versions/A/Resources
# cp libGmshLib.a Gmsh.framework/Versions/A/Gmsh
# cp ${GMSH_API} Gmsh.framework/Versions/A/Headers/
# sed -e "s/GMSH_VERSION/${GMSH_VERSION}/g" utils/misc/Info_framework.plist\
# > Gmsh.framework/Versions/A/Resources/Info.plist
# cd Gmsh.framework/Versions && ln -s A Current
# cd Gmsh.framework && ln -s Versions/Current/Gmsh
# cd Gmsh.framework && ln -s Versions/Current/Headers
# cd Gmsh.framework && ln -s Versions/Current/Resources
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment