30 #include <libFreeWRL.h>
32 #include "input/convertSTL.h"
34 #if defined (INCLUDE_STL_FILES)
41 #define STL_FLOAT_TOLERANCE_USUAL 0.00001
44 static double stl_vertex_tolerance = STL_FLOAT_TOLERANCE_USUAL;
52 #define STL_ASCII_HEADER "solid "
53 #define STL_BINARY_HEADER_LEN 84 // header + uint32
54 #define STL_BINARY_VERTEX_SIZE 50 // 12 * 4 + uint16
56 #define tmpFile "/vrmlSTLFile.wrl"
59 struct tbinarySTLvertexIn {
64 unsigned char attrib1;
65 unsigned char attrib2;
68 struct tstlVertexStruct {
70 int replacementVertex;
71 int condensedVertexNo;
77 typedef struct pSTLHandler{
81 int finalCoordsWritten;
90 int checkSTL_for_3Dprinting;
92 unsigned char *vectorArray;
96 void *STLHandler_constructor(){
97 void *v = malloc(
sizeof(
struct pSTLHandler));
98 memset(v,0,
sizeof(
struct pSTLHandler));
102 void STL_Handler_init(
struct tSTLHandler *t){
105 t->prv = STLHandler_constructor();
107 ppSTLHandler p = (ppSTLHandler)t->prv;
109 p->analyzeSTL = TRUE;
110 p->checkSTL_for_3Dprinting = FALSE;
118 static void recordVector(
int a,
int b, ppSTLHandler p) {
121 if (a>b) {
int x; x=a; a=b; b=x;}
123 ind = a*p->finalCoordsWritten +b;
124 box = ind/4, bits = ind %4;
128 case 0: {
int z = p->vectorArray[box] & 0x03;
129 if (z !=0x03) p->vectorArray[box]+= 0x01;
132 int z = p->vectorArray[box] & 0x0C;
133 if (z !=0x0C) p->vectorArray[box]+=0x04;
136 int z= p->vectorArray[box] & 0x30;
137 if (z !=0x30) p->vectorArray[box]+= 0x10;
140 int z= p->vectorArray[box] & 0xC0;
141 if (z !=0xC0) p->vectorArray[box]+= 0x40;
148 static char returnIndex (
int size,
int a,
int b, ppSTLHandler p) {
151 if (a>b) {
int x; x=a; a=b; b=x;}
153 box = ind/4, bits = ind %4;
156 case 0:
return p->vectorArray[box] & 0x03;
break;
157 case 1:
return (p->vectorArray[box] & 0x0C) >> 2;
break;
158 case 2:
return (p->vectorArray[box] & 0x30) >> 4;
break;
159 case 3:
return (p->vectorArray[box] & 0xC0) >> 6;
break;
168 int SAPPROX(
double a,
double b) {
176 return (fabs(a-b) < stl_vertex_tolerance);
180 int stlDTFT(
const unsigned char* buffer,
int len)
184 unsigned char *tmp = (
unsigned char *)buffer;
185 while ((tmp != NULL) && (*tmp<=
' ')) tmp++;
188 ConsoleMessage (
"stldtft, file len %x\n",len);
190 stllen = offsetPointer_deref(int32_t *, buffer, 80);
191 ConsoleMessage (
"triangle count %x\n",*stllen);
193 ConsoleMessage (
"sizeof struct binarySTLvertexIn %d\n",
sizeof(binarySTLvertexIn));
194 ConsoleMessage (
"binarySTLvertexIn * triangles + 80 + 1 + 4 = %x\n" , 50 * (*stllen) + 80 + 4);
195 ConsoleMessage (
"and, passed in length is %x\n",len);
196 ConsoleMessage (
"last two bytes %x %x\n",buffer[len-2],buffer[len-1]);
199 if (len==((*stllen)*50+STL_BINARY_HEADER_LEN))
return IS_TYPE_BINARY_STL;
203 if (len==((*stllen)*50+STL_BINARY_HEADER_LEN+1))
return IS_TYPE_BINARY_STL;
207 if (strncmp((
const char*)tmp,STL_ASCII_HEADER,strlen(STL_ASCII_HEADER)) == 0) {
208 ConsoleMessage (
"is ASCII stl");
209 return IS_TYPE_ASCII_STL;
212 return IS_TYPE_UNKNOWN;
215 static void calcExtent_dist(
float *_extent,
struct tstlVertexStruct *me) {
216 if (me->vertex.c[0] > EXTENT_MAX_X) EXTENT_MAX_X = me->vertex.c[0];
217 if (me->vertex.c[0] < EXTENT_MIN_X) EXTENT_MIN_X = me->vertex.c[0];
218 if (me->vertex.c[1] > EXTENT_MAX_Y) EXTENT_MAX_Y = me->vertex.c[1];
219 if (me->vertex.c[1] < EXTENT_MIN_Y) EXTENT_MIN_Y = me->vertex.c[1];
220 if (me->vertex.c[2] > EXTENT_MAX_Z) EXTENT_MAX_Z = me->vertex.c[2];
221 if (me->vertex.c[2] < EXTENT_MIN_Z) EXTENT_MIN_Z = me->vertex.c[2];
223 me->dist = me->vertex.c[0]*me->vertex.c[0] +
224 me->vertex.c[1]*me->vertex.c[1] +
225 me->vertex.c[2]*me->vertex.c[2];
231 static void quickSort(
struct Vector* vertices,
int *newVertexIndex,
int left,
int right) {
233 int i = left, j = right;
235 struct tstlVertexStruct *a, *pivot;
237 pivot= vector_get(
struct tstlVertexStruct*, vertices, newVertexIndex[(left+right)/2]);
240 a = vector_get(
struct tstlVertexStruct*, vertices, newVertexIndex[i]);
241 while (a->dist < pivot->dist) {
243 a = vector_get(
struct tstlVertexStruct*, vertices, newVertexIndex[i]);
245 a = vector_get(
struct tstlVertexStruct*, vertices, newVertexIndex[j]);
246 while (a->dist > pivot->dist) {
248 a = vector_get(
struct tstlVertexStruct*, vertices, newVertexIndex[j]);
251 tmp = newVertexIndex[i];
252 newVertexIndex[i] = newVertexIndex[j];
253 newVertexIndex[j] = tmp;
261 quickSort(vertices,newVertexIndex, left, j);
263 quickSort(vertices,newVertexIndex, i, right);
269 static void bubbleSort(
struct Vector* vertices,
int *newVertexIndex) {
271 int totIn = vectorSize(vertices);
278 for(i=0; i<totIn; i++) {
280 for (j=(totIn-1); j>i; j--) {
281 struct tstlVertexStruct *a, *b;
284 a = vector_get(
struct tstlVertexStruct*, vertices, newVertexIndex[j-1]);
285 b = vector_get(
struct tstlVertexStruct*, vertices, newVertexIndex[j]);
289 if (a->dist > b->dist) {
290 k = newVertexIndex[j-1];
291 newVertexIndex[j-1] = newVertexIndex[j];
292 newVertexIndex[j] = k;
304 #endif //DO_QUICKSORT
310 void analyzeSTLdata(
struct Vector* vertices) {
312 int totIn = vectorSize(vertices);
314 int replacedVertexCount=0;
315 int newVertexNumber=0;
317 int* newVertexIndex = MALLOC(
int*,
sizeof (
int)*totIn+1);
326 #include <sys/time.h>
330 gettimeofday(&tv, NULL);
333 for (i=0; i<totIn; i++) newVertexIndex[i] = i;
336 quickSort(vertices,newVertexIndex,0,totIn-1);
338 bubbleSort(vertices,newVertexIndex);
341 gettimeofday(&tve,NULL);
343 gettimeofday(&tv, NULL);
346 for (i=0; i<totIn-1; i++) {
347 struct tstlVertexStruct *startVertex = vector_get(
struct tstlVertexStruct *,vertices,newVertexIndex[i]);
351 if (startVertex->replacementVertex == -1) {
353 struct tstlVertexStruct *runVertex = vector_get(
struct tstlVertexStruct *,
354 vertices,newVertexIndex[j]);
356 while (SAPPROX(startVertex->dist,runVertex->dist) && (j<totIn)) {
358 if ((SAPPROX(startVertex->vertex.c[0],runVertex->vertex.c[0]) &&
359 SAPPROX(startVertex->vertex.c[1],runVertex->vertex.c[1]) &&
360 SAPPROX(startVertex->vertex.c[2],runVertex->vertex.c[2]))) {
363 runVertex->replacementVertex = newVertexIndex[i];
365 replacedVertexCount++;
369 runVertex=vector_get(
struct tstlVertexStruct *, vertices, newVertexIndex[j]);
376 for (i=0; i<totIn; i++) {
378 struct tstlVertexStruct *thisVertex = vector_get(
struct tstlVertexStruct *,vertices,i);
379 if (thisVertex->replacementVertex== -1) {
380 thisVertex->condensedVertexNo = newVertexNumber;
394 gettimeofday(&tve,NULL);
397 FREE_IF_NZ(newVertexIndex);
403 static char *finishThisX3DFile (FILE *fp,
int cp,
char *tfn,
float* _extent,
int vertexCount,
int coordCount, ppSTLHandler p) {
406 float extentX = EXTENT_MAX_X - EXTENT_MIN_X;
407 float extentY = EXTENT_MAX_Y - EXTENT_MIN_Y;
408 float extentZ = EXTENT_MAX_Z - EXTENT_MIN_Z;
409 p->scaleFactor = -1000.0f;
415 if (vertexCount == 0) {
417 for (i=0; i<6; i++) _extent[i]=0.0f;
418 ConsoleMessage (
"No vertices found in STL file");
420 float midX, midY, midZ;
423 if (extentX > p->scaleFactor) p->scaleFactor = extentX;
424 if (extentY > p->scaleFactor) p->scaleFactor = extentY;
425 if (extentZ > p->scaleFactor) p->scaleFactor = extentZ;
429 midX = -EXTENT_MIN_X - (extentX/2.0f);
430 midY = -EXTENT_MIN_Y - (extentY/2.0f);
431 midZ = -EXTENT_MIN_Z - (extentZ/2.0f);
435 cp += fprintf (fp,
"}} \n");
437 if (p->checkSTL_for_3Dprinting && (coordCount>0) && (p->vectorArray)) {
439 int edgesFound = 0;
int manifoldErrorsFound = 0;
440 bool issuesFound =
false;
443 for (x=0; x<(coordCount * coordCount/4);x++) {
444 if ((p->vectorArray[x]& 0x55) != 0x00) {
455 cp += fprintf (fp,
"Shape{appearance Appearance{\n");
456 cp += fprintf (fp,
"lineProperties LineProperties {linewidthScaleFactor 4.0}\n");
457 cp += fprintf (fp,
"material Material{emissiveColor 1 0 0}}geometry IndexedLineSet {\n");
458 cp += fprintf (fp,
" coord USE STL_COORDS\n");
459 cp += fprintf (fp,
" coordIndex [\n");
468 for (a=0; a<coordCount; a++) {
469 for (b=a; b<coordCount; b++) {
470 unsigned char vc = returnIndex(coordCount,a,b,p);
472 if ((vc & 0x01) == 0x01) {
473 cp += fprintf (fp,
"%d, %d, -1,\n",a,b);
474 if (vc == 0x01) edgesFound++;
else manifoldErrorsFound++;
481 cp += fprintf (fp,
"]\n");
482 cp += fprintf (fp,
"}}\n");
483 ConsoleMessage(
"Checking STL file - %d edges %d manifold issues",edgesFound,manifoldErrorsFound);
488 cp += fprintf (fp,
" ] translation %f %f %f}] scale %f %f %f}\n",midX, midY, midZ,10.0f/p->scaleFactor,
489 10.0f/p->scaleFactor, 10.0f/p->scaleFactor);
491 midX = EXTENT_MAX_X-EXTENT_MIN_X;
492 midY = EXTENT_MAX_Y-EXTENT_MIN_Y;
495 if (midX<midY)midX=midY;
497 cp += fprintf (fp,
"Viewpoint {jump FALSE position 0 0 20} \n");
498 cp += fprintf (fp,
"Viewpoint {jump FALSE position 0 0 25} \n");
499 cp += fprintf (fp,
"Viewpoint {jump FALSE position 0 0 40} \n");
501 cp += fprintf (fp,
"Viewpoint {jump FALSE orientation 0.0 -1.0 0.0 -1.57 position 20.0 0.0 0.0} \n");
502 cp += fprintf (fp,
"Viewpoint {jump FALSE orientation 0.0 -1.0 0.0 -3.14 position 0.0 0.0 -20.0} \n");
503 cp += fprintf (fp,
"Viewpoint {jump FALSE orientation 0.0 -1.0 0.0 -4.748 position -20.0 0 0} \n");
505 cp += fprintf (fp,
"Viewpoint {jump FALSE orientation -1.0 0.0 0.0 -1.57 position 0 -20.0 0} \n");
511 cp += fprintf (fp,
"Viewpoint {jump FALSE orientation -0.5888, -0.5688, -0.5743, -2.125 position 20.0 0 0} \n");
513 cp += fprintf (fp,
"Viewpoint {jump FALSE orientation -0.04558, -0.4841, -0.8739, 3.108 position 1.928, 16.93, 11.01} \n");
519 ConsoleMessage (
"STL size: (%4.2f,%4.2f), (%4.2f,%4.2f) (%4.2f,%4.2f)",EXTENT_MIN_X,EXTENT_MAX_X,
520 EXTENT_MIN_Y,EXTENT_MAX_Y, EXTENT_MIN_Z,EXTENT_MAX_Z);
524 retval = MALLOC (
char *, cp+10);
526 fread_val = fread(retval,cp,1,fp);
527 ConsoleMessage (
"fread is %d\n",fread_val);
533 FREE_IF_NZ(p->vectorArray);
540 static char *makeX3D_orig_STL_File(
struct Vector* vertices,
550 ppSTLHandler p = tg->STLHandler.prv;
552 tfn=MALLOC(
char *,strlen(tg->Mainloop.tmpFileLocation) +strlen (tmpFile) + 10);
553 strcpy(tfn,tg->Mainloop.tmpFileLocation);
559 #if !defined (_ANDROID)
560 ConsoleMessage (
"starting makeX3D_analyzed_STL_File; tmpFileLocation is :%s:\n",tg->Mainloop.tmpFileLocation);
561 tfn = TEMPNAM(tg->Mainloop.tmpFileLocation,
"/freewrl_tmp");
565 cp += fprintf (fp,
"#VRML V2.0 utf8\n");
566 cp += fprintf (fp,
"Background {skyColor [ 0.7 0.7 1.0 ]}\n");
567 cp += fprintf (fp,
"Transform { children [Transform { children [Shape{\n");
568 cp += fprintf (fp,
"appearance Appearance{material TwoSidedMaterial{separateBackColor TRUE diffuseColor 0.8 0.8 0.8 backDiffuseColor 0.8 0 0}}\n");
569 cp += fprintf (fp,
"geometry TriangleSet {\n");
570 cp += fprintf (fp,
"normalPerVertex FALSE\n");
571 cp += fprintf (fp,
"solid FALSE\n");
572 cp += fprintf (fp,
"coord DEF STL_COORDS Coordinate { point [\n");
574 for (i=0; i<vectorSize(vertices); i++) {
575 struct tstlVertexStruct *thisVertex = vector_get(
struct tstlVertexStruct *,vertices,i);
577 cp += fprintf (fp,
"%f %f %f,\n",thisVertex->vertex.c[0],thisVertex->vertex.c[1],thisVertex->vertex.c[2]);
580 cp += fprintf (fp,
"]}\n");
585 cp += fprintf (fp,
"normal Normal { vector [\n");
586 for (i=0; i<vectorSize(normals); i++) {
587 struct SFVec3f *thisVertex = vector_get(
struct SFVec3f *,normals,i);
588 cp += fprintf (fp,
"%f %f %f,\n",thisVertex->c[0],thisVertex->c[1],thisVertex->c[2]);
591 cp += fprintf (fp,
"]}\n");
596 p->finalCoordsWritten = vectorSize(vertices);
598 return finishThisX3DFile (fp, cp, tfn, _extent,vectorSize(vertices),0,p);
602 static char *makeX3D_analyzed_STL_File(
struct Vector* vertices,
612 ppSTLHandler p = tg->STLHandler.prv;
615 tfn=MALLOC(
char *,strlen(tg->Mainloop.tmpFileLocation) +strlen (tmpFile) + 10);
616 strcpy(tfn,tg->Mainloop.tmpFileLocation);
622 #if !defined (_ANDROID)
623 ConsoleMessage (
"starting makeX3D_analyzed_STL_File; tmpFileLocation is :%s:\n",tg->Mainloop.tmpFileLocation);
624 tfn = TEMPNAM(tg->Mainloop.tmpFileLocation,
"/freewrl_tmp");
629 cp += fprintf (fp,
"#VRML V2.0 utf8\n");
630 cp += fprintf (fp,
"Background {skyColor [ 0.7 0.7 1.0 ]}\n");
631 cp += fprintf (fp,
"Transform {children [Transform { children [Shape{\n");
632 cp += fprintf (fp,
"appearance Appearance{material Material{}}\n");
633 cp += fprintf (fp,
"geometry IndexedFaceSet {\n");
634 cp += fprintf (fp,
"normalPerVertex FALSE\n");
635 cp += fprintf (fp,
"solid FALSE\n");
636 cp += fprintf (fp,
"creaseAngle 0.75\n");
637 cp += fprintf (fp,
"coord DEF STL_COORDS Coordinate { point [\n");
639 for (i=0; i<vectorSize(vertices); i++) {
640 struct tstlVertexStruct *thisVertex = vector_get(
struct tstlVertexStruct *,vertices,i);
641 if (thisVertex->replacementVertex == -1) {
644 p->finalCoordsWritten++;
645 cp += fprintf (fp,
"%f %f %f, #%d\n",thisVertex->vertex.c[0],thisVertex->vertex.c[1],thisVertex->vertex.c[2],
646 thisVertex->condensedVertexNo);
651 cp += fprintf (fp,
"]}\n");
655 int size=p->finalCoordsWritten;
656 if (p->checkSTL_for_3Dprinting) {
661 p->vectorArray = MALLOC(
unsigned char *,(size*size/4));
662 if (p->vectorArray) bzero(p->vectorArray,(
size_t)size*size/4);
672 cp += fprintf (fp,
"coordIndex [\n");
673 for (i=0; i<vectorSize(vertices); i++) {
675 struct tstlVertexStruct *thisVertex = vector_get(
struct tstlVertexStruct *,vertices,i);
678 if (thisVertex->replacementVertex == -1) {
679 curVertex = thisVertex->condensedVertexNo;
681 struct tstlVertexStruct *rpv = vector_get(
struct tstlVertexStruct *,vertices,
682 thisVertex->replacementVertex);
683 curVertex = rpv->condensedVertexNo;
685 cp += fprintf (fp,
"%d, ",curVertex);
690 cp += fprintf (fp,
"-1, #face %d\n",face);
691 if (p->vectorArray) {
692 recordVector(tv[1],tv[2],p);
693 recordVector(tv[1],tv[3],p);
694 recordVector(tv[2],tv[3],p);
701 cp += fprintf (fp,
"]\n");
704 return finishThisX3DFile (fp, cp, tfn, _extent,vectorSize(vertices),p->finalCoordsWritten,p);
707 #define calc_vector_length(pt) veclength(pt)
708 static float veclength(
struct point_XYZ p )
710 return (
float) sqrt(p.x*p.x + p.y*p.y + p.z*p.z);
717 float a[3];
float b[3];
720 a[0] = c2->c[0] - c1->c[0];
721 a[1] = c2->c[1] - c1->c[1];
722 a[2] = c2->c[2] - c1->c[2];
723 b[0] = c3->c[0] - c1->c[0];
724 b[1] = c3->c[1] - c1->c[1];
725 b[2] = c3->c[2] - c1->c[2];
729 thisfaceNorms.x = a[1]*b[2] - b[1]*a[2];
730 thisfaceNorms.y = -(a[0]*b[2] - b[0]*a[2]);
731 thisfaceNorms.z = a[0]*b[1] - b[0]*a[1];
735 return calc_vector_length(thisfaceNorms) > stl_vertex_tolerance;
739 void fwl_stl_set_rendering_type(
int nv) {
740 ppSTLHandler p = gglobal()->STLHandler.prv;
745 p->analyzeSTL = FALSE;
746 p->checkSTL_for_3Dprinting = FALSE;
750 p->analyzeSTL = TRUE;
751 p->checkSTL_for_3Dprinting = TRUE;
755 p->analyzeSTL = TRUE;
756 p->checkSTL_for_3Dprinting = FALSE;
766 static char *analyzeAndGenerate (
float *_extent,
struct Vector *vertices,
struct Vector *normals,ppSTLHandler p) {
773 if (normals == NULL) {
775 analyzeSTLdata(vertices);
780 retval = makeX3D_analyzed_STL_File (vertices,normals,NULL,_extent);
782 retval = makeX3D_orig_STL_File(vertices,normals,NULL,_extent);
786 ConsoleMessage (
"generating - degenerateTriangleCount %d, Triangles In %d Vertices out %d\n",
787 p->degenerateCount,p->triangleInCount,p->finalCoordsWritten);
792 float fcw = (float) p->finalCoordsWritten;
793 float fcin = (
float) p->triangleInCount * 3;
794 if (fcin < 0.5) fcin = 1;
796 ConsoleMessage (
"Vertex memory savings %4.1f %% \n", (1-(fcw/fcin))*100.0);
800 for (i=0; i<vectorSize(vertices); i++) {
801 FREE_IF_NZ(vector_get(
struct tstlVertexStruct *,vertices,i));
803 deleteVector(
struct Vector*, vertices);
807 for (i=0; i<vectorSize(normals); i++) {
808 FREE_IF_NZ(vector_get(
struct SFVec3f *,normals,i));
810 deleteVector(
struct Vector*, normals);
822 char *convertAsciiSTL (
const char *inp) {
826 struct Vector *vertices = NULL;
827 struct Vector *normals = NULL;
829 char *normalPtr = NULL;
830 char *vertexPtr = NULL;
832 int haveNormalHere =
false;
833 int haveValidNormals =
true;
838 struct tstlVertexStruct *thisVertex[3];
840 #include <sys/time.h>
844 gettimeofday(&tv, NULL);
846 char *tptr = (
char *)inp;
850 ppSTLHandler p = gglobal()->STLHandler.prv;
852 ConsoleMessage (
"start reading AsciiSTL - this can take a while");
855 p->degenerateCount=0;
856 p->triangleInCount = 0;
857 p->finalCoordsWritten = 0;
861 NX=0.0; NY=0.0; NZ=1.0;
864 vertices = newVector(
sizeof (stlVertexStruct),1024);
865 EXTENT_MAX_X = -FLT_MAX; EXTENT_MAX_Y = -FLT_MAX; EXTENT_MAX_Z = -FLT_MAX;
866 EXTENT_MIN_X = FLT_MAX; EXTENT_MIN_Y = FLT_MAX; EXTENT_MIN_Z = FLT_MAX;
869 if (!p->analyzeSTL) {
871 normals = newVector(
sizeof(
struct SFVec3f), 1024);
874 #define USE_STRING_BUILTINS
875 #ifdef USE_STRING_BUILTINS
877 normalPtr = strcasestr(tptr,
"normal ");
878 vertexPtr = strcasestr(tptr,
"vertex ");
879 if ((normalPtr != NULL) &&(normalPtr < vertexPtr)) {
881 haveNormalHere =
true;
885 if (tptr!=NULL) tptr += strlen(
"vertex ");
888 while ((*tptr !=
'\0') && (*tptr !=
'm') && (*tptr !=
'x')) tptr++;
892 }
else if (*tptr ==
'm') {
898 haveNormalHere =
true;
905 #endif// USE_STRING_BUILTINS
910 while (tptr != NULL) {
912 if (haveNormalHere) {
918 NX = strtof(tptr,&tptr);
919 NY = strtof(tptr,&tptr);
920 NZ = strtof(tptr,&tptr);
923 if (3!=sscanf (tptr,
"%f %f %f", &NX,&NY,&NZ)) {
925 if (haveValidNormals) {
927 ConsoleMessage (
"expected normal, did not get it...");
928 strncpy(mys,tptr,40); mys[40] =
'\0';
929 ConsoleMessage (
"got %s",mys);
930 NX=0.0; NY=0.0; NZ=1.0;
931 haveValidNormals =
false;
937 X=strtof(tptr,&tptr);
938 Y=strtof(tptr,&tptr);
939 Z=strtof(tptr,&tptr);
942 if (3==sscanf (tptr,
"%f %f %f", &X,&Y,&Z)) {
944 thisVertex[i] = MALLOC (
struct tstlVertexStruct *,
sizeof (stlVertexStruct));
946 thisVertex[i]->vertex.c[0] = X;
947 thisVertex[i]->vertex.c[1] = Y;
948 thisVertex[i]->vertex.c[2] = Z;
949 thisVertex[i]->replacementVertex = -1;
950 thisVertex[i]->condensedVertexNo = -1;
956 p->triangleInCount++;
959 if (degenerate(&thisVertex[0]->vertex,
960 &thisVertex[1]->vertex, &thisVertex[2]->vertex)) {
963 calcExtent_dist(_extent,thisVertex[0]);
964 calcExtent_dist(_extent,thisVertex[1]);
965 calcExtent_dist(_extent,thisVertex[2]);
966 vector_pushBack(
struct tstlVertexStruct *,vertices,thisVertex[0]);
967 vector_pushBack(
struct tstlVertexStruct *,vertices,thisVertex[1]);
968 vector_pushBack(
struct tstlVertexStruct *,vertices,thisVertex[2]);
973 norm->c[0] = NX; norm->c[1]=NY; norm->c[2]=NZ;
974 vector_pushBack(
struct SFVec3f *,normals,norm);
975 NX = 0.0; NY = 0.0, NZ = 1.0;
980 p->degenerateCount++;
989 #ifdef USE_STRING_BUILTINS
990 normalPtr = strcasestr(tptr,
"normal ");
991 vertexPtr = strcasestr(tptr,
"vertex ");
992 if ((normalPtr != NULL) &&(normalPtr < vertexPtr)) {
995 haveNormalHere =
true;
998 haveNormalHere =
false;
1001 if (messCount >750) {
1002 ConsoleMessage(
"still parsing ASCII STL file... %d triangles, %d degenerates",p->triangleInCount,p->degenerateCount);
1007 if (tptr!=NULL) tptr += strlen(
"vertex ");
1010 haveNormalHere =
false;
1011 while ((*tptr !=
'\0') && (*tptr !=
'm') && (*tptr !=
'x')) tptr++;
1014 if (messCount >750) {
1015 ConsoleMessage(
"still parsing ASCII STL file... %d triangles, %d degenerates",p->triangleInCount,p->degenerateCount);
1020 }
else if (*tptr ==
'm') {
1026 haveNormalHere =
true;
1038 gettimeofday(&tve,NULL);
1039 ConsoleMessage (
"AsciiSTL - took %ld seconds to parse",tve.tv_sec-tv.tv_sec);
1044 return analyzeAndGenerate(_extent,vertices,normals,p);
1047 char *convertBinarySTL (
const unsigned char *buffer) {
1049 struct Vector *vertices = NULL;
1050 struct Vector *normals = NULL;
1053 bool haveAttributeInfo =
false;
1055 unsigned char *tmp = (
unsigned char *)buffer;
1057 ppSTLHandler p = gglobal()->STLHandler.prv;
1060 p->degenerateCount=0;
1061 p->triangleInCount = 0;
1062 p->finalCoordsWritten = 0;
1066 stllen = offsetPointer_deref(int32_t *, buffer, 80);
1067 tmp = offsetPointer_deref(
unsigned char*, buffer, STL_BINARY_HEADER_LEN);
1077 vertices = newVector(
sizeof (stlVertexStruct),(*stllen)*3);
1080 if (!p->analyzeSTL) {
1082 normals = newVector(
sizeof(
struct SFVec3f), (*stllen));
1084 if (
sizeof (
struct SFVec3f) != 12) {
1085 ConsoleMessage (
"binary reading of STL - SFVec3f wrong size");
1091 EXTENT_MAX_X = -FLT_MAX; EXTENT_MAX_Y = -FLT_MAX; EXTENT_MAX_Z = -FLT_MAX;
1092 EXTENT_MIN_X = FLT_MAX; EXTENT_MIN_Y = FLT_MAX; EXTENT_MIN_Z = FLT_MAX;
1094 for (i=0; i<*stllen; i++) {
1096 p->triangleInCount++;
1098 struct tstlVertexStruct *vertex1 = MALLOC (
struct tstlVertexStruct *,
sizeof (stlVertexStruct));
1099 struct tstlVertexStruct *vertex2 = MALLOC (
struct tstlVertexStruct *,
sizeof (stlVertexStruct));
1100 struct tstlVertexStruct *vertex3 = MALLOC (
struct tstlVertexStruct *,
sizeof (stlVertexStruct));
1104 memcpy (vertex1->vertex.c,&tmp[12],12);
1105 vertex1->replacementVertex = -1;
1106 vertex1->condensedVertexNo = -1;
1109 vertex2 = MALLOC (
struct tstlVertexStruct *,
sizeof (stlVertexStruct));
1110 memcpy (vertex2->vertex.c,&(tmp[24]),12);
1111 vertex2->replacementVertex = -1;
1112 vertex2->condensedVertexNo = -1;
1115 vertex3 = MALLOC (
struct tstlVertexStruct *,
sizeof (stlVertexStruct));
1116 memcpy (vertex3->vertex.c,&(tmp[36]),12);
1117 vertex3->replacementVertex = -1;
1118 vertex3->condensedVertexNo = -1;
1121 if (degenerate(&vertex1->vertex, &vertex2->vertex, &vertex3->vertex)) {
1122 calcExtent_dist(_extent,vertex1);
1123 calcExtent_dist(_extent,vertex2);
1124 calcExtent_dist(_extent,vertex3);
1125 vector_pushBack(
struct tstlVertexStruct *,vertices,vertex1);
1126 vector_pushBack(
struct tstlVertexStruct *,vertices,vertex2);
1127 vector_pushBack(
struct tstlVertexStruct *,vertices,vertex3);
1130 if (normals != NULL) {
1133 memcpy(norm, tmp, 12);
1134 vector_pushBack(
struct SFVec3f *,normals,norm);
1137 if ((tmp[48] != 0) || (tmp[49]!=0)) {
1139 haveAttributeInfo =
true;
1143 p->degenerateCount++;
1146 tmp = offsetPointer_deref(
unsigned char*, tmp, STL_BINARY_VERTEX_SIZE);
1149 if (haveAttributeInfo) {
1154 return analyzeAndGenerate(_extent,vertices,normals,p);
1159 float getLastSTLScale(
void) {
1162 ppSTLHandler p = gglobal()->STLHandler.prv;
1164 if (p->scaleFactor < 0.0)
return 1.0;
1165 return p->scaleFactor/10.0;
1168 #endif //INCLUDE_STL_FILES