HyPar  1.0
Finite-Difference Hyperbolic-Parabolic PDE Solver on Cartesian Grids
IBReadBodySTL.c File Reference

Reads 3D body surface from STL file. More...

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <basic.h>
#include <mpivars.h>
#include <immersedboundaries.h>

Go to the source code of this file.

Functions

int IBReadBodySTL (Body3D **body, char *filename, void *m, int *stat)
 

Detailed Description

Reads 3D body surface from STL file.

Author
Debojyoti Ghosh

Definition in file IBReadBodySTL.c.

Function Documentation

◆ IBReadBodySTL()

int IBReadBodySTL ( Body3D **  body,
char *  filename,
void *  m,
int *  stat 
)

Function to read a 3D surface from a STL file. See https://en.wikipedia.org/wiki/STL_(file_format) for details of the STL file format. Notes:

  • This function only reads ASCII STL files.
  • The body read from this file is distributed to all MPI ranks.
Parameters
body3D body to be allocated and read from file
filenameFilename
mMPI object of type MPIVariables
statStatus (0: success; non-0: failure)

Definition at line 21 of file IBReadBodySTL.c.

27 {
28  MPIVariables *mpi = (MPIVariables*) m;
29  int n, ierr;
30  *stat = 0;
31 
32  if ((*body) != NULL) {
33  if (!mpi->rank) {
34  fprintf(stderr,"Error in IBReadBodySTL(): pointer to immersed body not NULL.\n");
35  }
36  *stat = -1;
37  return(0);
38  }
39 
40  /* Rank 0 reads in file */
41  if (!mpi->rank) {
42 
43  FILE *in;
44  in = fopen(filename,"r");
45  if (!in) {
46  fprintf(stderr,"Error in IBReadBodySTL(): file %s not found or cannot be opened.\n",
47  filename);
48  *stat = 1;
49  }
50  else {
51 
52  int nfacets = 0;
53  char word[_MAX_STRING_SIZE_];
54  /* Count number of facets in STL file */
55  ierr = fscanf(in,"%s",word);
56  if (!strcmp(word, "solid")) {
57  nfacets = 0;
58  while (strcmp(word, "endsolid")) {
59  ierr = fscanf(in,"%s",word);
60  if (!strcmp(word, "facet")) nfacets++;
61  }
62  }
63  fclose(in);
64 
65  if (nfacets > 0) {
66  (*body) = (Body3D*) calloc (1,sizeof(Body3D));
67  (*body)->nfacets = nfacets;
68  (*body)->surface = (Facet3D*) calloc (nfacets,sizeof(Facet3D));
69 
70  /* Read in STL data */
71  in = fopen(filename,"r");
72  ierr = fscanf(in,"%s",word);
73  n = 0;
74  while (strcmp(word, "endsolid")) {
75  double t1, t2, t3;
76  ierr = fscanf(in,"%s",word);
77  if (!strcmp(word, "facet")) {
78  ierr = fscanf(in,"%s",word);
79  if (strcmp(word, "normal")) {
80  fprintf(stderr,"Error in IBReadBodySTL(): Illegal keyword read in %s.\n",filename);
81  } else {
82  ierr = fscanf(in,"%lf",&t1);
83  ierr = fscanf(in,"%lf",&t2);
84  ierr = fscanf(in,"%lf",&t3);
85  (*body)->surface[n].nx = t1;
86  (*body)->surface[n].ny = t2;
87  (*body)->surface[n].nz = t3;
88  }
89  ierr = fscanf(in,"%s",word);
90  if (strcmp(word, "outer")) {
91  fprintf(stderr,"Error in IBReadBodySTL(): Illegal keyword read in %s.\n",filename);
92  *stat = 1;
93  } else {
94  ierr = fscanf(in,"%s",word);
95  if (strcmp(word, "loop")) {
96  fprintf(stderr,"Error in IBReadBodySTL(): Illegal keyword read in %s.\n",filename);
97  *stat = 1;
98  } else {
99  ierr = fscanf(in,"%s",word);
100  if (strcmp(word, "vertex")) {
101  fprintf(stderr,"Error in IBReadBodySTL(): Illegal keyword read in %s.\n",filename);
102  *stat = 1;
103  } else {
104  ierr = fscanf(in,"%lf",&t1);
105  ierr = fscanf(in,"%lf",&t2);
106  ierr = fscanf(in,"%lf",&t3);
107  (*body)->surface[n].x1 = t1;
108  (*body)->surface[n].y1 = t2;
109  (*body)->surface[n].z1 = t3;
110  }
111  ierr = fscanf(in,"%s",word);
112  if (strcmp(word, "vertex")) {
113  fprintf(stderr,"Error in IBReadBodySTL(): Illegal keyword read in %s.\n",filename);
114  *stat = 1;
115  } else {
116  ierr = fscanf(in,"%lf",&t1);
117  ierr = fscanf(in,"%lf",&t2);
118  ierr = fscanf(in,"%lf",&t3);
119  (*body)->surface[n].x2 = t1;
120  (*body)->surface[n].y2 = t2;
121  (*body)->surface[n].z2 = t3;
122  }
123  ierr = fscanf(in,"%s",word);
124  if (strcmp(word, "vertex")) {
125  fprintf(stderr,"Error in IBReadBodySTL(): Illegal keyword read in %s.\n",filename);
126  *stat = 1;
127  } else {
128  ierr = fscanf(in,"%lf",&t1);
129  ierr = fscanf(in,"%lf",&t2);
130  ierr = fscanf(in,"%lf",&t3);
131  (*body)->surface[n].x3 = t1;
132  (*body)->surface[n].y3 = t2;
133  (*body)->surface[n].z3 = t3;
134  }
135  }
136  }
137  n++;
138  }
139  }
140  fclose(in);
141  /* done reading STL file */
142  if (n != nfacets) {
143  fprintf(stderr,"Error in IBReadBodySTL(): Inconsistency in number of facets read.\n");
144  free((*body)->surface);
145  free(*body);
146  *stat = 1;
147  }
148  } else {
149  fprintf(stderr,"Error in IBReadBodySTL(): nfacets = 0!!\n");
150  *stat = 1;
151  }
152 
153  }
154  }
155  MPIBroadcast_integer(stat,1,0,&mpi->world);
156 
157  if ((*stat)) return(0);
158 
159  /* Distribute the body to all MPI ranks */
160  int nfacets;
161  if (!mpi->rank) nfacets = (*body)->nfacets;
162  MPIBroadcast_integer(&nfacets,1,0,&mpi->world);
163 
164  if (mpi->rank) {
165  (*body) = (Body3D*) calloc (1,sizeof(Body3D));
166  (*body)->nfacets = nfacets;
167  (*body)->surface = (Facet3D*) calloc (nfacets,sizeof(Facet3D));
168  }
169 
170  int bufdim = 12;
171  double *buffer = (double*) calloc (bufdim*nfacets,sizeof(double));
172  if (!mpi->rank) {
173  for (n=0; n<nfacets; n++) {
174  buffer[n*bufdim+ 0] = (*body)->surface[n].x1;
175  buffer[n*bufdim+ 1] = (*body)->surface[n].x2;
176  buffer[n*bufdim+ 2] = (*body)->surface[n].x3;
177  buffer[n*bufdim+ 3] = (*body)->surface[n].y1;
178  buffer[n*bufdim+ 4] = (*body)->surface[n].y2;
179  buffer[n*bufdim+ 5] = (*body)->surface[n].y3;
180  buffer[n*bufdim+ 6] = (*body)->surface[n].z1;
181  buffer[n*bufdim+ 7] = (*body)->surface[n].z2;
182  buffer[n*bufdim+ 8] = (*body)->surface[n].z3;
183  buffer[n*bufdim+ 9] = (*body)->surface[n].nx;
184  buffer[n*bufdim+10] = (*body)->surface[n].ny;
185  buffer[n*bufdim+11] = (*body)->surface[n].nz;
186  }
187  }
188  MPIBroadcast_double(buffer,(nfacets*bufdim),0,&mpi->world);
189  if (mpi->rank) {
190  for (n=0; n<nfacets; n++) {
191  (*body)->surface[n].x1 = buffer[n*bufdim+ 0];
192  (*body)->surface[n].x2 = buffer[n*bufdim+ 1];
193  (*body)->surface[n].x3 = buffer[n*bufdim+ 2];
194  (*body)->surface[n].y1 = buffer[n*bufdim+ 3];
195  (*body)->surface[n].y2 = buffer[n*bufdim+ 4];
196  (*body)->surface[n].y3 = buffer[n*bufdim+ 5];
197  (*body)->surface[n].z1 = buffer[n*bufdim+ 6];
198  (*body)->surface[n].z2 = buffer[n*bufdim+ 7];
199  (*body)->surface[n].z3 = buffer[n*bufdim+ 8];
200  (*body)->surface[n].nx = buffer[n*bufdim+ 9];
201  (*body)->surface[n].ny = buffer[n*bufdim+10];
202  (*body)->surface[n].nz = buffer[n*bufdim+11];
203  }
204  }
205  free(buffer);
206 
207  return(0);
208 }
Structure defining a facet.
Structure defining a body.
int MPIBroadcast_integer(int *, int, int, void *)
Definition: MPIBroadcast.c:23
int MPIBroadcast_double(double *, int, int, void *)
Definition: MPIBroadcast.c:9
#define _MAX_STRING_SIZE_
Definition: basic.h:14
MPI_Comm world
Structure of MPI-related variables.