35 #include <libFreeWRL.h>
37 #include "../vrml_parser/Structs.h"
38 #include "../vrml_parser/CRoutes.h"
39 #include "../main/headers.h"
41 #include "LinearAlgebra.h"
44 #include "Component_Geospatial.h"
57 extern void Elev_Tri (
int vertex_ind,
int this_face,
int A,
int D,
int E,
int NONORMALS,
struct X3D_PolyRep *this_Elev,
struct point_XYZ *facenormals,
int *pointfaces,
int ccw);
58 extern void verify_global_IFS_Coords(
int max);
59 extern void Extru_check_normal(
struct point_XYZ *facenormals,
int this_face,
int dire,
struct X3D_PolyRep *rep_,
int ccw);
60 void register_Polyrep_combiner();
63 static int returnIndexedFanStripIndexSize (
struct Multi_Int32 index ) {
70 for (xx=0; xx<index.n; xx++) {
72 if ((index.p[xx] <=-1) || (xx == (index.n-1))) {
76 if ((index.p[xx] > -1) && (xx == (index.n-1))) {
80 IndexSize += (zz-2) *4;
83 printf (
"IndexedTriangle[Fan|Strip]Set, index %d is less than 3\n",zz);
99 if (this_->coord == 0) {
101 printf (
"checkX3DIFS - have an IFS (%d) with no coords...\n",this_);
105 if (this_->coordIndex.n == 0) {
107 printf (
"checkX3DIFS - have an IFS (%d) with no coordIndex, pointer is %d offset is %d\n",this_,
116 int checkX3DElevationGridFields (
struct X3D_ElevationGrid *this_,
float **points,
int *npoints) {
118 int nx = (this_->xDimension);
119 float xSp = (this_->xSpacing);
120 int nz = (this_->zDimension);
121 float zSp = (this_->zSpacing);
122 float *height = ((this_->height).p);
123 int ntri = (nx && nz ? 2 * (nx-1) * (nz-1) : 0);
124 int nh = ((this_->height).n);
132 float *tcoord = NULL;
137 printf (
"Elevationgrid: warning: x,y vs. height: %d * %d ne %d:\n", nx,nz,nh);
139 printf (
"Elevationgrid: error: x,y vs. height: %d * %d ne %d:\n", nx,nz,nh);
145 if ((nx < 2) || (nz < 2)) {
146 printf (
"ElevationGrid: xDimension and zDimension less than 2 %d %d\n", nx,nz);
151 if (!(this_->texCoord)) {
153 FREE_IF_NZ(rep->GeneratedTexCoords[0]);
156 tcoord = rep->GeneratedTexCoords[0] = MALLOC (
float *,
sizeof (
float) * nquads * 12);
160 ConsoleMessage (
"even though we have a texCoord node here, we need to generate");
165 newpoints = MALLOC (
float *,
sizeof (
float) * nz * nx * 3);
167 FREE_IF_NZ(rep->actualCoord);
168 rep->actualCoord = (
float *)newpoints;
171 if (this_->_coordIndex.n > 0) {FREE_IF_NZ(this_->_coordIndex.p);}
172 this_->_coordIndex.p = MALLOC (
int *,
sizeof(
int) * nquads * 5);
173 cindexptr = this_->_coordIndex.p;
175 this_->_coordIndex.n = nquads * 5;
178 *npoints = this_->_coordIndex.n;
180 for (j = 0; j < (nz -1); j++) {
181 for (i=0; i < (nx-1) ; i++) {
188 *cindexptr = j*nx+i; cindexptr++;
189 *cindexptr = j*nx+i+nx; cindexptr++;
190 *cindexptr = j*nx+i+nx+1; cindexptr++;
191 *cindexptr = j*nx+i+1; cindexptr++;
192 *cindexptr = -1; cindexptr++;
199 if (!(this_->texCoord)) {
200 for (j = 0; j < (nz -1); j++) {
201 for (i=0; i < (nx-1) ; i++) {
204 *tcoord = ((float) (i+0)/(nx-1)); tcoord++;
205 *tcoord = ((float)(j+0)/(nz-1)); tcoord ++;
207 *tcoord = ((float) (i+0)/(nx-1)); tcoord++;
208 *tcoord = ((float)(j+1)/(nz-1)); tcoord ++;
210 *tcoord = ((float) (i+1)/(nx-1)); tcoord++;
211 *tcoord = ((float)(j+1)/(nz-1)); tcoord ++;
214 *tcoord = ((float) (i+0)/(nx-1)); tcoord++;
215 *tcoord = ((float)(j+0)/(nz-1)); tcoord ++;
217 *tcoord = ((float) (i+1)/(nx-1)); tcoord++;
218 *tcoord = ((float)(j+1)/(nz-1)); tcoord ++;
220 *tcoord = ((float) (i+1)/(nx-1)); tcoord++;
221 *tcoord = ((float)(j+0)/(nz-1)); tcoord ++;
229 for (j=0; j<nz; j++) {
230 for (i=0; i < nx; i++) {
242 newPoint[0] = xSp * i; newPoint[1] = height[i+(j*nx)]; newPoint[2]=zSp*j;
243 memcpy(newpoints,newPoint,
sizeof(
float)*3);
260 IndexSize = returnIndexedFanStripIndexSize(node->index);
261 if (IndexSize == 0) {
266 newIndex = MALLOC (
int *,
sizeof(
int) * IndexSize);
271 while (xx < (node->index.n-1)) {
274 while ((xx<node->index.n) && (node->index.p[xx] > -1)) xx++;
278 if (xx >= IndexSize) {
279 printf (
"ITFS - index size error... IndexSize < index value \n");
285 for (zz=fanVertex; zz<(xx-2); zz++) {
286 if (windingOrder==0) {
287 newIndex[yy] = node->index.p[zz]; yy++;
288 newIndex[yy] = node->index.p[zz+1]; yy++;
289 newIndex[yy] = node->index.p[zz+2]; yy++;
292 newIndex[yy] = node->index.p[zz]; yy++;
293 newIndex[yy] = node->index.p[zz+2]; yy++;
294 newIndex[yy] = node->index.p[zz+1]; yy++;
297 newIndex[yy] = -1; yy++;
301 if (xx < (node->index.n-1)) {
313 node->_coordIndex.p = newIndex;
314 node->_coordIndex.n = IndexSize;
324 IndexSize = returnIndexedFanStripIndexSize(node->index);
325 if (IndexSize == 0) {
330 newIndex = MALLOC (
int *,
sizeof(
int) * IndexSize);
335 while (xx < (node->index.n-1)) {
338 while ((xx<node->index.n) && (node->index.p[xx] > -1)) xx++;
342 if (xx >= IndexSize) {
343 printf (
"ITFS - index size error... IndexSize < index value \n");
347 for (zz=fanVertex+1; zz<(xx-1); zz++) {
349 newIndex[yy] = node->index.p[fanVertex]; yy++;
350 newIndex[yy] = node->index.p[zz]; yy++;
351 newIndex[yy] = node->index.p[zz+1]; yy++;
352 newIndex[yy] = -1; yy++;
356 if (xx < (node->index.n-1)) {
367 node->_coordIndex.p = newIndex;
368 node->_coordIndex.n = IndexSize;
377 IndexSize = ((node->index.n) * 4) / 3;
378 if (IndexSize <= 0) {
383 newIndex = MALLOC (
int *,
sizeof(
int) * IndexSize);
386 for (xx = 0; xx < node->index.n; xx++) {
387 newIndex[zz] = node->index.p[xx];
403 node->_coordIndex.p = newIndex;
404 node->_coordIndex.n = IndexSize;
413 if ((node->fanCount).n < 1) {
414 ConsoleMessage(
"TriangleFanSet, need at least one fanCount element");
415 node->fanCount.n = 0;
419 for (xx=0; xx<(node->fanCount).n; xx++) {
421 IndexSize += ((node->fanCount).p[xx]-2) * 4;
423 if ((node->fanCount).p[xx] < 3) {
424 printf (
"TriangleFanSet, fanCount index %d is less than 3\n", (node->fanCount).p[xx]);
429 node->_coordIndex.p = MALLOC (
int *,
sizeof(
int) * IndexSize);
430 node->_coordIndex.n = IndexSize;
435 for (xx=0; xx<(node->fanCount).n; xx++) {
439 for (yy=0; yy< ((node->fanCount).p[xx]-2); yy++) {
442 node->_coordIndex.p[IndexSize++] = fanVertex;
443 node->_coordIndex.p[IndexSize++] = zz;
444 node->_coordIndex.p[IndexSize++] = zz+1;
445 node->_coordIndex.p[IndexSize++] = -1;
458 IndexSize = ((node->index.n) /4) * 4;
459 if (IndexSize <= 0) {
466 if (IndexSize != node->index.n) ConsoleMessage (
"IndexedQuadSet using %d of %d indexes according to spec",IndexSize,node->index.n);
471 newIndex = MALLOC (
int *,
sizeof(
int) * IndexSize * 5 / 4);
472 newIndexPtr = newIndex;
475 for (xx = 0; xx < IndexSize; xx++) {
476 *newIndexPtr = node->index.p[xx];
493 FREE_IF_NZ (node->index.p);
494 node->_coordIndex.p = newIndex;
495 node->_coordIndex.n = IndexSize * 5 / 4;
498 static void checkQuadSetFields(
struct X3D_QuadSet *node) {
505 dtmp = getCoordinate (node->coord,
"QuadSet");
510 if (((npoints/4)*4) != npoints) {
511 ConsoleMessage (
"Warning, in QuadSet, Coordinates not a multiple of 4\n");
512 npoints = ((npoints/4)*4);
519 IndexSize = (npoints * 8) / 4;
521 node->_coordIndex.p = MALLOC (
int *,
sizeof(
int) * IndexSize);
522 node->_coordIndex.n = IndexSize;
527 for (xx=0; xx<npoints; xx+=4) {
529 node->_coordIndex.p[IndexSize++] = xx;
530 node->_coordIndex.p[IndexSize++] = xx+1;
531 node->_coordIndex.p[IndexSize++] = xx+2;
532 node->_coordIndex.p[IndexSize++] = -1;
533 node->_coordIndex.p[IndexSize++] = xx+2;
534 node->_coordIndex.p[IndexSize++] = xx+3;
535 node->_coordIndex.p[IndexSize++] = xx;
536 node->_coordIndex.p[IndexSize++] = -1;
552 if ((node->stripCount).n < 1) {
553 ConsoleMessage (
"TriangleStripSet, need at least one stripCount element");
554 node->stripCount.n=0;
558 for (xx=0; xx<(node->stripCount).n; xx++) {
560 IndexSize += ((node->stripCount).p[xx]-2) * 4;
562 if ((node->stripCount).p[xx] < 3) {
563 printf (
"TriangleStripSet, index %d is less than 3\n",
564 (node->stripCount).p[xx]);
569 node->_coordIndex.p = MALLOC (
int *,
sizeof(
int) * IndexSize);
570 node->_coordIndex.n = IndexSize;
575 for (xx=0; xx<(node->stripCount).n; xx++) {
578 for (yy=0; yy< ((node->stripCount).p[xx]-2); yy++) {
579 if (windingOrder==0) {
581 node->_coordIndex.p[IndexSize++] = zz;
582 node->_coordIndex.p[IndexSize++] = zz+1;
583 node->_coordIndex.p[IndexSize++] = zz+2;
587 node->_coordIndex.p[IndexSize++] = zz+1;
588 node->_coordIndex.p[IndexSize++] = zz;
589 node->_coordIndex.p[IndexSize++] = zz+2;
592 node->_coordIndex.p[IndexSize++] = -1;
608 dtmp = getCoordinate (node->coord,
"TriangleSet");
613 if (((npoints/3)*3) != npoints) {
614 printf (
"Warning, in TriangleSet, Coordinates not a multiple of 3\n");
615 npoints = ((npoints/3)*3);
622 IndexSize = (npoints * 4) / 3;
624 node->_coordIndex.p = MALLOC (
int *,
sizeof(
int) * IndexSize);
625 node->_coordIndex.n = IndexSize;
630 for (xx=0; xx<npoints; xx+=3) {
632 node->_coordIndex.p[IndexSize++] = xx;
633 node->_coordIndex.p[IndexSize++] = xx+1;
634 node->_coordIndex.p[IndexSize++] = xx+2;
635 node->_coordIndex.p[IndexSize++] = -1;
653 float creaseAngle = (float) PI * 2;
662 int calc_normind = 0;
667 float *fogdepths = NULL;
681 int normalArraySize = INT_ID_UNDEFINED;
687 int *pointfaces = NULL;
695 int this_face, this_coord;
704 if (node->_nodeType == NODE_IndexedFaceSet) {
705 if (!checkX3DIndexedFaceSetFields(node)) {
711 }
else if (node->_nodeType == NODE_ElevationGrid) {
712 if (!checkX3DElevationGridFields(X3D_ELEVATIONGRID(node),
713 (
float **)&points, &npoints)) {
717 }
else if (node->_nodeType == NODE_GeoElevationGrid) {
718 if (!checkX3DGeoElevationGridFields(X3D_GEOELEVATIONGRID(node),
719 (
float **)&points, &npoints)) {
725 switch (node->_nodeType) {
726 case NODE_IndexedFaceSet:
727 convex = node->convex;
728 cpv = node->colorPerVertex;
729 npv = node->normalPerVertex;
731 orig_texCoordIndex = &node->texCoordIndex;
732 orig_colorIndex = &node->colorIndex;
733 orig_normalIndex = &node->normalIndex;
734 creaseAngle = node->creaseAngle;
735 orig_coordIndex = &node->coordIndex;
750 case NODE_ElevationGrid:
751 orig_coordIndex= &X3D_ELEVATIONGRID(node)->_coordIndex;
752 cpv = X3D_ELEVATIONGRID(node)->colorPerVertex;
753 npv = X3D_ELEVATIONGRID(node)->normalPerVertex;
754 creaseAngle = X3D_ELEVATIONGRID(node)->creaseAngle;
755 cc = (
struct X3D_Color *) X3D_ELEVATIONGRID(node)->color;
756 nc = (
struct X3D_Normal *) X3D_ELEVATIONGRID(node)->normal;
766 case NODE_GeoElevationGrid:
767 orig_coordIndex= &X3D_GEOELEVATIONGRID(node)->_coordIndex;
768 cpv = X3D_GEOELEVATIONGRID(node)->colorPerVertex;
769 npv = X3D_GEOELEVATIONGRID(node)->normalPerVertex;
770 creaseAngle = (float) X3D_GEOELEVATIONGRID(node)->creaseAngle;
771 cc = (
struct X3D_Color *) X3D_GEOELEVATIONGRID(node)->color;
772 nc = (
struct X3D_Normal *) X3D_GEOELEVATIONGRID(node)->normal;
779 case NODE_IndexedTriangleFanSet:
780 checkIndexedTriangleFanSetFields(X3D_INDEXEDTRIANGLEFANSET(node));
781 orig_coordIndex= &X3D_INDEXEDTRIANGLEFANSET(node)->_coordIndex;
782 cpv = X3D_INDEXEDTRIANGLEFANSET(node)->colorPerVertex;
783 npv = X3D_INDEXEDTRIANGLEFANSET(node)->normalPerVertex;
784 ccw = X3D_INDEXEDTRIANGLEFANSET(node)->ccw;
785 cc = (
struct X3D_Color *) X3D_INDEXEDTRIANGLEFANSET(node)->color;
786 nc = (
struct X3D_Normal *) X3D_INDEXEDTRIANGLEFANSET(node)->normal;
788 co = (
struct X3D_Coordinate *) X3D_INDEXEDTRIANGLEFANSET(node)->coord;
790 if(!npv) creaseAngle = 0.0;
800 case NODE_IndexedTriangleSet:
801 checkIndexedTriangleSetFields(X3D_INDEXEDTRIANGLESET(node));
802 orig_coordIndex= &X3D_INDEXEDTRIANGLESET(node)->_coordIndex;
803 cpv = X3D_INDEXEDTRIANGLESET(node)->colorPerVertex;
804 npv = X3D_INDEXEDTRIANGLESET(node)->normalPerVertex;
805 ccw = X3D_INDEXEDTRIANGLESET(node)->ccw;
806 cc = (
struct X3D_Color *) X3D_INDEXEDTRIANGLESET(node)->color;
807 nc = (
struct X3D_Normal *) X3D_INDEXEDTRIANGLESET(node)->normal;
809 co = (
struct X3D_Coordinate *) X3D_INDEXEDTRIANGLESET(node)->coord;
811 if(!npv) creaseAngle = 0.0;
821 case NODE_IndexedTriangleStripSet:
822 checkIndexedTriangleStripSetFields(X3D_INDEXEDTRIANGLESTRIPSET(node));
823 orig_coordIndex= &X3D_INDEXEDTRIANGLESTRIPSET(node)->_coordIndex;
824 cpv = X3D_INDEXEDTRIANGLESTRIPSET(node)->colorPerVertex;
825 npv = X3D_INDEXEDTRIANGLESTRIPSET(node)->normalPerVertex;
826 ccw = X3D_INDEXEDTRIANGLESTRIPSET(node)->ccw;
827 cc = (
struct X3D_Color *) X3D_INDEXEDTRIANGLESTRIPSET(node)->color;
828 nc = (
struct X3D_Normal *) X3D_INDEXEDTRIANGLESTRIPSET(node)->normal;
830 co = (
struct X3D_Coordinate *) X3D_INDEXEDTRIANGLESTRIPSET(node)->coord;
832 if(!npv) creaseAngle = 0.0;
842 case NODE_TriangleFanSet:
843 checkTriangleFanSetFields(X3D_TRIANGLEFANSET(node));
844 orig_coordIndex= &X3D_TRIANGLEFANSET(node)->_coordIndex;
845 cpv = X3D_TRIANGLEFANSET(node)->colorPerVertex;
846 npv = X3D_TRIANGLEFANSET(node)->normalPerVertex;
847 ccw = X3D_TRIANGLEFANSET(node)->ccw;
848 cc = (
struct X3D_Color *) X3D_TRIANGLEFANSET(node)->color;
849 nc = (
struct X3D_Normal *) X3D_TRIANGLEFANSET(node)->normal;
853 if(!nc && !npv) creaseAngle = 0.0;
862 case NODE_TriangleSet:
863 checkTriangleSetFields(X3D_TRIANGLESET(node));
864 orig_coordIndex= &X3D_TRIANGLESET(node)->_coordIndex;
865 cpv = X3D_TRIANGLESET(node)->colorPerVertex;
866 npv = X3D_TRIANGLESET(node)->normalPerVertex;
867 ccw = X3D_TRIANGLESET(node)->ccw;
868 cc = (
struct X3D_Color *) X3D_TRIANGLESET(node)->color;
869 nc = (
struct X3D_Normal *) X3D_TRIANGLESET(node)->normal;
873 MARK_EVENT (X3D_NODE(node), offsetof (
struct X3D_TriangleSet, attrib));
876 MARK_EVENT (X3D_NODE(node), offsetof (
struct X3D_TriangleSet, fogCoord));
877 MARK_EVENT (X3D_NODE(node), offsetof (
struct X3D_TriangleSet, metadata));
878 MARK_EVENT (X3D_NODE(node), offsetof (
struct X3D_TriangleSet, normal));
879 MARK_EVENT (X3D_NODE(node), offsetof (
struct X3D_TriangleSet, texCoord));
881 case NODE_TriangleStripSet:
882 checkTriangleStripSetFields(X3D_TRIANGLESTRIPSET(node));
883 orig_coordIndex= &X3D_TRIANGLESTRIPSET(node)->_coordIndex;
884 cpv = X3D_TRIANGLESTRIPSET(node)->colorPerVertex;
885 npv = X3D_TRIANGLESTRIPSET(node)->normalPerVertex;
886 ccw = X3D_TRIANGLESTRIPSET(node)->ccw;
887 cc = (
struct X3D_Color *) X3D_TRIANGLESTRIPSET(node)->color;
888 nc = (
struct X3D_Normal *) X3D_TRIANGLESTRIPSET(node)->normal;
892 if(!nc && !npv) creaseAngle = 0.0;
902 case NODE_IndexedQuadSet:
903 checkIndexedQuadSetFields(X3D_INDEXEDQUADSET(node));
904 orig_coordIndex= &X3D_INDEXEDQUADSET(node)->_coordIndex;
905 cpv = X3D_INDEXEDQUADSET(node)->colorPerVertex;
906 npv = X3D_INDEXEDQUADSET(node)->normalPerVertex;
907 ccw = X3D_INDEXEDQUADSET(node)->ccw;
908 cc = (
struct X3D_Color *) X3D_INDEXEDQUADSET(node)->color;
909 nc = (
struct X3D_Normal *) X3D_INDEXEDQUADSET(node)->normal;
924 checkQuadSetFields(X3D_QUADSET(node));
925 orig_coordIndex= &X3D_QUADSET(node)->_coordIndex;
926 cpv = X3D_QUADSET(node)->colorPerVertex;
927 npv = X3D_QUADSET(node)->normalPerVertex;
928 ccw = X3D_QUADSET(node)->ccw;
929 cc = (
struct X3D_Color *) X3D_QUADSET(node)->color;
930 nc = (
struct X3D_Normal *) X3D_QUADSET(node)->normal;
934 MARK_EVENT (X3D_NODE(node), offsetof (
struct X3D_QuadSet, attrib));
935 MARK_EVENT (X3D_NODE(node), offsetof (
struct X3D_QuadSet, color));
936 MARK_EVENT (X3D_NODE(node), offsetof (
struct X3D_QuadSet, coord));
937 MARK_EVENT (X3D_NODE(node), offsetof (
struct X3D_QuadSet, fogCoord));
938 MARK_EVENT (X3D_NODE(node), offsetof (
struct X3D_QuadSet, metadata));
939 MARK_EVENT (X3D_NODE(node), offsetof (
struct X3D_QuadSet, normal));
940 MARK_EVENT (X3D_NODE(node), offsetof (
struct X3D_QuadSet, texCoord));
944 ConsoleMessage (
"unknown type for make_genericfaceset, %d\n",node->_nodeType);
949 if (orig_coordIndex != NULL) cin= orig_coordIndex->n;
else cin = 0;
950 if (orig_texCoordIndex != NULL) tcin= orig_texCoordIndex->n;
else tcin = 0;
951 if (orig_colorIndex != NULL) colin= orig_colorIndex->n;
else colin = 0;
952 if (orig_normalIndex != NULL) norin= orig_normalIndex->n;
else norin = 0;
955 printf (
"cin %d tcin %d colin %d norin %d\n",cin,tcin,colin,norin);
956 printf (
"start of make_indexedfaceset for node %p, cin %d tcin %d colin %d norin %d\n",node, cin, tcin, colin, norin);
964 printf (
"NOW, the IFS has a cin of %d ca %f\n",cin,creaseAngle);
970 printf (
"Null IFS found, returing ntri0\n");
980 if((orig_coordIndex->p[cin-1]) == -1) { cin--; }
986 dtmp = getCoordinate (X3D_NODE(co),
"make FacedSet");
996 if(fc2->depth.n < npoints){
997 fc2->depth.p = REALLOC(fc2->depth.p, npoints *
sizeof(
float));
998 for(i=fc2->depth.n; i<npoints; i++){
999 fc2->depth.p[i] = fc2->depth.p[fc->depth.n-1];
1001 fc2->depth.n = npoints;
1003 fogdepths = fc2->depth.p;
1010 if ((cc->_nodeType != NODE_Color) && (cc->_nodeType != NODE_ColorRGBA)) {
1011 printf (
"make_IFS, expected %d got %d\n", NODE_Color, cc->_nodeType);
1013 ncolors = cc->color.n;
1018 if (nc->_nodeType != NODE_Normal) {
1019 printf (
"make_IFS, normal expected %d, got %d\n",NODE_Normal, nc->_nodeType);
1021 nnormals = nc->vector.n;
1029 rep_->tcoordtype=tc->_nodeType;
1035 faces = count_IFS_faces (cin,orig_coordIndex);
1037 printf (
"faces %d, cin %d npoints %d\n",faces,cin,npoints);
1052 faceok = MALLOC(
int *,
sizeof(
int)*faces);
1053 pointfaces = MALLOC(
int *,
sizeof(
int)*npoints*POINT_FACES);
1057 if (!IFS_face_normals (facenormals,faceok,pointfaces,faces,npoints,cin,points,orig_coordIndex,ccw)) {
1059 FREE_IF_NZ (facenormals);
1060 FREE_IF_NZ (faceok);
1061 FREE_IF_NZ (pointfaces);
1067 for(i=0; i<cin; i++) {
1068 if((orig_coordIndex->p[i]) == -1) {
1075 if(nvert>2) {ntri += nvert-2;}
1079 printf (
"vert %d ntri %d\n",nvert,ntri);
1083 if(!convex) { ntri =ntri*2; }
1088 FREE_IF_NZ(rep_->cindex);
1089 FREE_IF_NZ(rep_->colindex);
1090 FREE_IF_NZ(rep_->norindex);
1092 cindex = rep_->cindex = MALLOC(GLuint *,
sizeof(*(rep_->cindex))*3*(ntri));
1093 colindex = rep_->colindex = MALLOC(GLuint *,
sizeof(*(rep_->colindex))*3*(ntri));
1094 norindex = rep_->norindex = MALLOC(GLuint *,
sizeof(*(rep_->norindex))*3*ntri);
1097 bzero (colindex,
sizeof(*(rep_->colindex))*3*(ntri));
1098 bzero (norindex,
sizeof(*(rep_->colindex))*3*(ntri));
1100 FREE_IF_NZ(rep_->normal);
1103 normalArraySize = 3*3*ntri;
1104 rep_->normal = MALLOC(
float *,
sizeof(*(rep_->normal))*normalArraySize * 2 );
1106 rep_->normal = MALLOC(
float *, 1);
1109 FREE_IF_NZ(rep_->tcindex);
1111 tcindex = rep_->tcindex = MALLOC(GLuint*,
sizeof(*(rep_->tcindex))*3*(ntri));
1114 tess_vs=MALLOC(
int *,
sizeof(*(tess_vs))*(ntri)*3);
1119 for (this_face=0; this_face<faces; this_face++) {
1121 int tess_contour_start;
1125 tg->Tess.global_IFS_Coord_count = 0;
1127 tess_contour_start = 0;
1130 if (!faceok[this_face]) {
1132 printf (
"in generate of faces, face %d is invalid, skipping...\n",this_face);
1138 while ((this_coord < cin) && ((orig_coordIndex->p[this_coord]) != -1)) this_coord++;
1141 if ((this_coord < (cin-1)) && ((orig_coordIndex->p[this_coord]) == -1)) this_coord++;
1145 printf (
"working on face %d coord %d total coords %d coordIndex %d\n",
1146 this_face,this_coord,cin,(orig_coordIndex->p[ this_coord]));
1165 gluTessBeginPolygon( tg->Tess.global_tessobj, &cbdata);
1166 gluTessBeginContour( tg->Tess.global_tessobj );
1168 initind = relative_coord++;
1169 lastind = relative_coord++;
1172 i = (orig_coordIndex->p[ relative_coord + this_coord]);
1177 int foundContour = FALSE;
1181 for (ind=tess_contour_start; ind<relative_coord; ind++) {
1188 if ( orig_coordIndex->p[relative_coord + this_coord] ==
1189 orig_coordIndex->p[ind + this_coord]) {
1191 tess_contour_start = relative_coord+1;
1192 FW_GLU_NEXT_CONTOUR(tg->Tess.global_tessobj,GLU_UNKNOWN);
1193 foundContour = TRUE;
1198 if (!foundContour) {
1200 tess_v[0] = c1->c[0];
1201 tess_v[1] = c1->c[1];
1202 tess_v[2] = c1->c[2];
1203 tess_vs[relative_coord] = relative_coord;
1207 FW_GLU_TESS_VERTEX(tg->Tess.global_tessobj,tess_v,&tess_vs[relative_coord]);
1213 tg->Tess.global_IFS_Coords[tg->Tess.global_IFS_Coord_count++] = initind;
1214 tg->Tess.global_IFS_Coords[tg->Tess.global_IFS_Coord_count++] = lastind;
1215 tg->Tess.global_IFS_Coords[tg->Tess.global_IFS_Coord_count++] = relative_coord;
1217 lastind = relative_coord++;
1220 if (relative_coord + this_coord == cin) {
1223 i = (orig_coordIndex->p[ relative_coord + this_coord]);
1229 gluTessEndContour( tg->Tess.global_tessobj );
1230 gluTessEndPolygon( tg->Tess.global_tessobj );
1235 verify_global_IFS_Coords(cin);
1237 IFS_check_normal (facenormals,this_face,points, this_coord, orig_coordIndex, ccw);
1242 for (i=0; i<tg->Tess.global_IFS_Coord_count; i++) {
1244 cindex [vert_ind] = (orig_coordIndex->p[this_coord+tg->Tess.global_IFS_Coords[i]]);
1253 norindex[vert_ind] = orig_normalIndex->p[this_coord+tg->Tess.global_IFS_Coords[i]];
1256 norindex[vert_ind] = orig_normalIndex->p[this_face];
1262 norindex[vert_ind] = (orig_coordIndex->p[this_coord+tg->Tess.global_IFS_Coords[i]]);
1265 norindex[vert_ind] = this_face;
1271 if (fabs(creaseAngle) > 0.00001) {
1273 if (normalArraySize != INT_ID_UNDEFINED) {
1274 if (calc_normind*3 > normalArraySize) {
1275 printf (
"HMMM _ NORMAL OVERFLOW\n");
1279 normalize_ifs_face (&rep_->normal[calc_normind*3],
1280 facenormals, pointfaces, cindex[vert_ind],
1281 this_face, creaseAngle);
1282 rep_->norindex[vert_ind] = calc_normind++;
1285 rep_->normal[vert_ind*3+0]=(float) facenormals[this_face].x;
1286 rep_->normal[vert_ind*3+1]=(float) facenormals[this_face].y;
1287 rep_->normal[vert_ind*3+2]=(float) facenormals[this_face].z;
1288 rep_->norindex[vert_ind] = vert_ind;
1301 if (cpv) tmpI = this_coord+tg->Tess.global_IFS_Coords[i];
1302 else tmpI = this_face;
1304 if (tmpI >= orig_colorIndex->n) {
1305 printf (
"faceSet, colorIndex problem, %d >= %d\n", tmpI,orig_colorIndex->n);
1306 colindex[vert_ind] = 0;
1308 colindex[vert_ind] = orig_colorIndex->p[tmpI];
1315 colindex[vert_ind] = (orig_coordIndex->p[this_coord+tg->Tess.global_IFS_Coords[i]]);
1318 colindex[vert_ind] = this_face;
1329 if ((this_coord+tg->Tess.global_IFS_Coords[i]) < tcin) {
1330 tcindex[vert_ind] = orig_texCoordIndex->p[this_coord+tg->Tess.global_IFS_Coords[i]];
1332 tcindex[vert_ind] = 0;
1337 tcindex[vert_ind] = (orig_coordIndex->p[this_coord+tg->Tess.global_IFS_Coords[i]]);
1343 if (vert_ind < (ntri*3-1)) vert_ind++;
1347 this_coord += relative_coord;
1350 if (this_coord < cin)
1351 if ((orig_coordIndex->p[this_coord]) == -1) {this_coord++;}
1356 rep_->ntri = vert_ind/3;
1358 printf (
"make_indededfaceset, end, ntri %d\n",rep_->ntri);
1361 FREE_IF_NZ (tess_vs);
1362 FREE_IF_NZ (facenormals);
1363 FREE_IF_NZ (faceok);
1364 FREE_IF_NZ (pointfaces);
1372 double getAlpha(
float ang) {
1373 if (ang >= 0.99999)
return asin(0.9999);
1374 else if (ang <= -0.99999)
return asin(-0.9999);
1375 return asin((
double)ang);
1379 double getGamma(
double alpha,
double minor) {
1382 if(APPROX(cos(alpha),0))
1385 gamma=acos(minor / cos(alpha));
1386 if(fabs(sin(gamma)-(-minor/cos(alpha)))>fabs(sin(gamma))) gamma=-gamma;
1403 struct point_XYZ spp1 = {0.0, 0.0, 0.0};
1412 for(spi=1;spi<nspi;spi++) {
1413 VEC_FROM_CDIFF(spine[spi],spine[0],spp1);
1414 if(!APPROX(VECSQ(spp1),0))
1419 spylen=1/(float) sqrt(VECSQ(spp1)); VECSCALE(spp1,spylen);
1421 printf(
"Reference vector along spine=[%f,%f,%f]\n", spp1.x,spp1.y,spp1.z);
1426 if ((fabs(spp1.x) >= fabs(spp1.y)) && (fabs(spp1.x) >= fabs(spp1.z))) {majorX = TRUE;}
1427 else if ((fabs(spp1.y) >= fabs(spp1.x)) && (fabs(spp1.y) >= fabs(spp1.z))) { }
1429 if ((fabs(spp1.x) <= fabs(spp1.y)) && (fabs(spp1.x) <= fabs(spp1.z))) {minorX = TRUE;}
1430 else if ((fabs(spp1.y) <= fabs(spp1.x)) && (fabs(spp1.y) <= fabs(spp1.z))) minorY = TRUE;
1434 printf (
"major axis %d %d %d\n",majorX, majorY, majorZ);
1435 printf (
"minor axis %d %d %d\n",minorX, minorY, minorZ);
1442 alpha = getAlpha((
float)spp1.x);
1443 gamma = getGamma(alpha,minorY?spp1.y:spp1.z);
1446 printf(
"majorX: alpha=%f gamma=%f\n",alpha,gamma);
1451 spy->y=-(cos(alpha)*(-sin(gamma)));
1452 spy->z=cos(alpha)*cos(gamma);
1454 spz->y=-(sin(alpha)*sin(gamma));
1455 spz->z=(-sin(alpha))*cos(gamma);
1460 alpha = getAlpha((
float)spp1.z);
1461 gamma = getGamma(alpha,minorX?spp1.x:spp1.y);
1464 printf(
"majorZ: alpha=%f gamma=%f\n",alpha,gamma);
1467 spy->y=-(cos(alpha)*(-sin(gamma)));
1468 spy->x=cos(alpha)*cos(gamma);
1470 spz->y=-(sin(alpha)*sin(gamma));
1471 spz->x=(-sin(alpha))*cos(gamma);
1479 VECCP(*spy,spp1,crossp);
1480 if( veclengthd((
double*)&crossp) < .001 )
return;
1482 alpha = getAlpha((
float)spp1.y);
1483 gamma = getGamma(alpha,minorX?spp1.x:spp1.z);
1486 printf(
"majorY: lpha=%f gamma=%f\n",alpha,gamma);
1489 spy->x=-(cos(alpha)*(-sin(gamma)));
1490 spy->z=cos(alpha)*cos(gamma);
1492 spz->x=-(sin(alpha)*sin(gamma));
1493 spz->z=(-sin(alpha))*cos(gamma);
1508 void stream_extrusion_texture_coords (
struct X3D_PolyRep *rep_,
1519 rep_->GeneratedTexCoords[0] = MALLOC (
float *,
sizeof(
float) * 2 * 3 * rep_->ntri);
1521 nc = rep_->GeneratedTexCoords[0];
1529 for (count = 0; count < rep_->ntri*3; count++) {
1530 ind = tcindex[count];
1533 *nc = tcoord[ind*3]; nc++; *nc = tcoord[ind*3+2]; nc++;
1546 int beginCap = node->beginCap;
1547 int endCap = node->endCap;
1549 int nspi = node->spine.n;
1550 int nsec = node->crossSection.n;
1554 int nori = node->orientation.n;
1557 int nsca = node->scale.n;
1559 struct SFVec3f *spine =node->spine.p;
1560 struct SFVec2f *curve =node->crossSection.p;
1561 struct SFRotation *orientation=node->orientation.p;
1582 int max_ncoord_add=0;
1586 int ncolinear_at_begin=0;
1589 int ncolinear_at_end=0;
1593 int spi,sec,triind,pos_of_last_zvalue;
1594 int next_spi, prev_spi;
1598 int circular = FALSE;
1600 int spine_is_one_vertex;
1602 float spxlen,spylen,spzlen;
1622 int *pointfaces = 0;
1623 int *defaultface = 0;
1626 float creaseAngle = node->creaseAngle;
1627 int ccw = node->ccw;
1638 printf (
"VRMLExtrusion.pm start\n");
1651 if (nspi < 1)
return;
1658 int tmp1, temp_indx;
1659 int increment, currentlocn;
1661 crossSection = MALLOC(
struct SFVec2f *,
sizeof(crossSection)*nsec*2);
1665 for (tmp1=0; tmp1<nsec; tmp1++) {
1667 crossSection[currentlocn].c[0] = curve[tmp1].c[0];
1668 crossSection[currentlocn].c[1] = curve[tmp1].c[1];
1673 for (temp_indx=0; temp_indx<currentlocn; temp_indx++) {
1674 if ((APPROX(crossSection[currentlocn].c[0],crossSection[temp_indx].c[0])) &&
1675 (APPROX(crossSection[currentlocn].c[1],crossSection[temp_indx].c[1]))) {
1677 if ((temp_indx != 0) && (tmp1 != (nsec-1))) {
1688 currentlocn += increment;
1692 printf (
"we had nsec %d coords, but now we have %d\n",nsec,currentlocn);
1700 ntri = 2 * (nspi-1) * (nsec-1);
1703 printf (
"so, we have ntri %d nspi %d nsec %d\n",ntri,nspi,nsec);
1708 circular = APPROX(spine[0].c[0], spine[nspi-1].c[0]) &&
1709 APPROX(spine[0].c[1], spine[nspi-1].c[1]) &&
1710 APPROX(spine[0].c[2], spine[nspi-1].c[2]);
1713 printf (
"tubular %d circular %d\n",tubular, circular);
1722 if (circular && tubular) {
1726 printf (
"Extrusion, turning off caps \n");
1730 if(beginCap||endCap) {
1731 if(tubular?nsec<4:nsec<3) {
1732 freewrlDie(
"Only two real vertices in crossSection. Caps not possible!");
1735 if(tubular) nctri=nsec-2;
1739 printf (
"nsec = %d, ntri = %d nctri = %d\n",nsec, ntri,nctri);
1745 while(sec+2<=nsec-1 &&
1749 APPROX(0, (crossSection[sec+1].c[0]-crossSection[0].c[0])
1750 *(crossSection[sec+2].c[1]-crossSection[0].c[1])
1751 - (crossSection[sec+1].c[1]-crossSection[0].c[1])
1752 *(crossSection[sec+2].c[0]-crossSection[0].c[0]))
1753 ) ncolinear_at_begin++, sec++;
1758 sec=tubular?(nsec-2):(nsec-1);
1760 APPROX(0, (crossSection[sec ].c[0]-crossSection[0].c[0])
1761 *(crossSection[sec-1].c[1]-crossSection[0].c[1])
1762 - (crossSection[sec ].c[1]-crossSection[0].c[1])
1763 *(crossSection[sec-1].c[0]-crossSection[0].c[0]))
1764 ) ncolinear_at_end++,sec--;
1766 nctri-= ncolinear_at_begin+ncolinear_at_end;
1770 freewrlDie(
"All in crossSection points colinear. Caps not possible!");
1774 nctri= ((beginCap)?nctri:0) + ((endCap)?nctri:0) ;
1781 max_ncoord_add=(nspi-1)*(nsec-1)
1792 rep_->ntri = ntri + nctri;
1796 cindex = rep_->cindex = MALLOC(GLuint *,
sizeof(*(rep_->cindex))*3*(rep_->ntri));
1797 coord = rep_->actualCoord = MALLOC(
float *,
sizeof(*(rep_->actualCoord))*(nspi*nsec+max_ncoord_add)*3);
1798 rep_->normal = MALLOC(
float *,
sizeof(*(rep_->normal))*3*(rep_->ntri)*3);
1799 rep_->norindex = MALLOC(GLuint *,
sizeof(*(rep_->norindex))*3*(rep_->ntri));
1805 facenormals = MALLOC(
struct point_XYZ *,
sizeof(*facenormals)*(rep_->ntri+1)/2);
1808 pointfaces = MALLOC(
int *,
sizeof(*pointfaces)*POINT_FACES*3*rep_->ntri);
1811 defaultface = MALLOC(
int *,
sizeof(*defaultface)*rep_->ntri);
1815 SCP = MALLOC(
struct SCP *,
sizeof(
struct SCP)*nspi);
1820 tcoordsize = (nctri + (ntri*2))*3;
1823 printf (
"tcoordsize is %d\n",tcoordsize);
1826 FREE_IF_NZ (rep_->GeneratedTexCoords[0]);
1827 FREE_IF_NZ (rep_->tcindex);
1829 tcoord = MALLOC(
float *,
sizeof(*(rep_->GeneratedTexCoords[0]))*tcoordsize);
1831 tcindexsize = rep_->ntri*3;
1833 printf (
"tcindexsize %d\n",tcindexsize);
1836 tcindex = MALLOC(GLuint *,
sizeof(*(rep_->tcindex))*tcindexsize);
1839 beginVals = MALLOC(
float *,
sizeof(
float) * 2 * (nsec+1)*100);
1840 endVals = MALLOC(
float *,
sizeof(
float) * 2 * (nsec+1)*100);
1842 memset((
void *)tcindex,0,tcindexsize*
sizeof(*(rep_->tcindex)));
1847 HAVETOSMOOTH = (fabs(creaseAngle)>0.0001);
1848 for (tmp = 0; tmp < 3*rep_->ntri; tmp++) {
1849 pointfaces[tmp*POINT_FACES]=0;
1857 spine_is_one_vertex=0;
1873 for(spi=0; spi<nspi;spi++){
1874 for(next_spi=spi+1;next_spi<nspi;next_spi++) {
1875 VEC_FROM_CDIFF(spine[spi],spine[next_spi],spp1);
1876 if(!APPROX(VECSQ(spp1),0))
1879 if(next_spi<nspi) SCP[next_spi].prev=next_spi-1;
1882 printf(
"spi=%d next_spi=%d\n",spi,next_spi);
1886 SCP[spi].next=next_spi;
1887 SCP[spi].prev=prev_spi;
1889 while(next_spi>spi+1) {
1891 SCP[spi].next=next_spi;
1892 SCP[spi].prev=prev_spi;
1902 printf (
" SCP[0].next = %d, nspi = %d\n",SCP[0].next,nspi);
1907 if(SCP[0].next==nspi) {
1908 spine_is_one_vertex=1;
1910 printf(
"All spine vertices are the same!\n");
1915 SCP[0].z.x=0; SCP[0].z.y=0; SCP[0].z.z=0;
1917 for(spi=1;spi<nspi;spi++) {
1918 SCP[spi].y=SCP[0].y;
1919 SCP[spi].z=SCP[0].z;
1923 for(spi=0;spi<nspi;spi++) {
1924 printf(
"SCP[%d].next=%d, SCP[%d].prev=%d\n",
1925 spi,SCP[spi].next,spi,SCP[spi].prev);
1931 while(SCP[spi].prev==-1) spi++;
1935 while(SCP[t].next==nspi) t--;
1938 printf (
"now, spi = %d, t = %d\n",spi,t);
1947 VEC_FROM_CDIFF(spine[1],spine[0],SCP[0].y);
1949 VEC_FROM_CDIFF(spine[1],spine[0],spp1);
1951 VEC_FROM_CDIFF(spine[1],spine[0],spm1);
1952 VECCP(spp1,spm1,SCP[1].z);
1966 VECCP(spp1,Yaxis,SCP[1].z);
1969 dlen_cp = veclengthd((
double*)&(SCP[1].z));
1970 if( dlen_cp < .001 )
1978 printf (
"just calculated z for spi 0\n");
1979 printf(
"SCP[0].y=[%f,%f,%f], SCP[1].z=[%f,%f,%f]\n",
1980 SCP[0].y.x,SCP[0].y.y,SCP[0].y.z,
1981 SCP[1].z.x,SCP[1].z.y,SCP[1].z.z);
1986 for(; spi<=t; spi++) {
1988 VEC_FROM_CDIFF(spine[SCP[spi].next],spine[SCP[spi].prev],SCP[spi].y);
1990 VEC_FROM_CDIFF(spine[SCP[spi].next],spine[spi],spp1);
1991 VEC_FROM_CDIFF(spine[SCP[spi].prev],spine[spi],spm1);
1992 VECCP(spp1,spm1,SCP[spi].z);
1994 printf (
"just calculated z for spi %d\n",spi);
2001 printf (
"we are circular\n");
2004 VEC_FROM_CDIFF(spine[SCP[0].next],spine[SCP[nspi-1].prev],SCP[0].y);
2006 SCP[nspi-1].y=SCP[0].y;
2009 VEC_FROM_CDIFF(spine[SCP[0].next],spine[0],spp1);
2010 VEC_FROM_CDIFF(spine[SCP[nspi-1].prev],spine[0],spm1);
2011 VECCP(spp1,spm1,SCP[0].z);
2013 SCP[nspi-1].z=SCP[0].z;
2017 printf (
"we are not circular\n");
2021 VEC_FROM_CDIFF(spine[SCP[0].next],spine[0],SCP[0].y);
2025 VEC_FROM_CDIFF(spine[nspi-1],spine[SCP[nspi-1].prev],SCP[nspi-1].y);
2028 SCP[0].z=SCP[SCP[0].next].z;
2030 SCP[nspi-1].z=SCP[SCP[nspi-1].prev].z;
2033 printf(
"SCP[0].y=[%f,%f,%f], SCP[0].z=[%f,%f,%f]\n",
2034 SCP[0].y.x,SCP[0].y.y,SCP[0].y.z,
2035 SCP[0].z.x,SCP[0].z.y,SCP[0].z.z);
2036 printf(
"SCP[1].y=[%f,%f,%f], SCP[1].z=[%f,%f,%f]\n",
2037 SCP[1].y.x,SCP[1].y.y,SCP[1].y.z,
2038 SCP[1].z.x,SCP[1].z.y,SCP[1].z.z);
2044 while(SCP[spi].prev==-1) {
2045 SCP[spi].y=SCP[0].y;
2046 SCP[spi].z=SCP[0].z;
2051 while(SCP[t].next==nspi) {
2052 SCP[t].y=SCP[nspi-1].y;
2053 SCP[t].z=SCP[nspi-1].z;
2061 pos_of_last_zvalue=-1;
2062 for(spi=0;spi<nspi;spi++) {
2063 if(pos_of_last_zvalue>=0) {
2064 if(APPROX(VECSQ(SCP[spi].z),0))
2065 SCP[spi].z= SCP[pos_of_last_zvalue].z;
2067 pos_of_last_zvalue=spi;
2069 if(!APPROX(VECSQ(SCP[spi].z),0)) {
2072 printf(
"Found z-Value!\n");
2075 for(t=spi-1; t>-1; t--)
2076 SCP[t].z=SCP[spi].z;
2077 pos_of_last_zvalue=spi;
2082 printf(
"pos_of_last_zvalue=%d\n",pos_of_last_zvalue);
2088 for(spi=(circular?2:1);spi<nspi;spi++) {
2089 if(VECPT(SCP[spi].z,SCP[spi-1].z)<0) {
2090 VECSCALE(SCP[spi].z,-1);
2092 printf(
"Extrusion.GenPloyRep: Flipped axis spi=%d\n",spi);
2098 if(pos_of_last_zvalue==-1) {
2101 printf(
"Extrusion.GenPloyRep:Whole spine is colinear!\n");
2105 spy.x=0; spy.y=1; spy.z=0;
2106 spz.x=0; spz.y=0; spz.z=1;
2108 if(!spine_is_one_vertex) {
2109 compute_spy_spz(&spy,&spz,spine,nspi);
2113 printf (
"so, spy [%f %f %f], spz [%f %f %f]\n", spy.x, spy.y,spy.z, spz.x, spz.y, spz.z);
2117 for(spi=0;spi<nspi;spi++) {
2125 for(spi=0;spi<nspi;spi++) {
2126 printf(
"SCP[%d].y=[%f,%f,%f], SCP[%d].z=[%f,%f,%f]\n",
2127 spi,SCP[spi].y.x,SCP[spi].y.y,SCP[spi].y.z,
2128 spi,SCP[spi].z.x,SCP[spi].z.y,SCP[spi].z.z);
2138 if(nsca>1 && nsca <nspi)
2139 printf(
"Extrusion.GenPolyRep: Warning!\n"
2140 "\tNumber of scaling parameters do not match the number of spines!\n"
2141 "\tWill revert to using only the first scale value.\n");
2143 if(nori>1 && nori <nspi)
2144 printf(
"Extrusion.GenPolyRep: Warning!\n"
2145 "\tNumber of orientation parameters "
2146 "do not match the number of spines!\n"
2147 "\tWill revert to using only the first orientation value.\n");
2150 for(spi = 0; spi<nspi; spi++) {
2155 spylen = 1/(float)sqrt(VECSQ(spy)); VECSCALE(spy, spylen);
2156 spzlen = 1/(float)sqrt(VECSQ(spz)); VECSCALE(spz, spzlen);
2157 spxlen = 1/(float)sqrt(VECSQ(spx)); VECSCALE(spx, spxlen);
2161 int ori = (nori==nspi ? spi : 0);
2163 if(IS_ROTATION_VEC_NOT_NORMAL(orientation[ori]))
2164 printf(
"Extrusion.GenPolyRep: Warning!\n"
2165 "\tRotationvector #%d not normal!\n"
2166 "\tWon`t correct it, because it is bad VRML`97.\n",
2169 MATRIX_FROM_ROTATION(orientation[ori],m);
2175 for(sec = 0; sec<nsec; sec++) {
2177 float ptx = crossSection[sec].c[0];
2178 float ptz = crossSection[sec].c[1];
2180 int sca = (nsca==nspi ? spi : 0);
2181 ptx *= node->scale.p[sca].c[0];
2182 ptz *= node->scale.p[sca].c[1];
2195 beginVals[sec*2+0] = ptx;
2196 beginVals[sec*2+1] = ptz;
2197 }
else if (spi == (nspi-1)) {
2199 endVals[(sec*2)+0]=ptx;
2200 endVals[(sec*2)+1]=ptz;
2206 coord[(sec+spi*nsec)*3+0] =
2207 (
float)(spx.x * point.x + spy.x * point.y + spz.x * point.z)
2208 + node->spine.p[spi].c[0];
2209 coord[(sec+spi*nsec)*3+1] =
2210 (float)(spx.y * point.x + spy.y * point.y + spz.y * point.z)
2211 + node->spine.p[spi].c[1];
2212 coord[(sec+spi*nsec)*3+2] =
2213 (
float)(spx.z * point.x + spy.z * point.y + spz.z * point.z)
2214 + node->spine.p[spi].c[2];
2241 int Atex, Btex, Ctex, Dtex, Etex, Ftex;
2251 printf(
"Coords: \n");
2253 for(x=0; x<nsec; x++) {
2254 for(z=0; z<nspi; z++) {
2255 int xxx = 3*(x+z*nsec);
2256 printf(
"coord: %d [%f %f %f] ",(x+z*nsec),
2257 coord[xxx], coord[xxx+1], coord[xxx+2]);
2268 for(x=0; x<nsec-1; x++) {
2269 for(z=0; z<nspi-1; z++) {
2276 Atex = A; Btex = B; Ctex = C; Dtex = D;
2301 VEC_FROM_COORDDIFF(coord,C,coord,A,ac);
2302 VEC_FROM_COORDDIFF(coord,D,coord,B,bd);
2304 if(sqrt(VECSQ(ac))>sqrt(VECSQ(bd))) {
2305 E=B; F=D; Etex=Btex; Ftex=Dtex;
2307 E=C; F=A; Etex=Ctex; Ftex=Atex;
2313 VEC_FROM_COORDDIFF(coord,B,coord,A,ab);
2314 VEC_FROM_COORDDIFF(coord,D,coord,C,cd);
2317 printf(
"ab=[%f,%f,%f],cd=[%f,%f,%f]\n",
2318 ab.x,ab.y,ab.z,cd.x,cd.y,cd.z);
2319 printf(
"Orig: %d %d [%f %f %f] [%f %f %f] (%d, %d, %d) \n",
2321 coord[D*3], coord[D*3+1], coord[D*3+2],
2322 coord[C*3], coord[C*3+1], coord[C*3+2],
2327 denominator= ab.y*cd.x-ab.x*cd.y;
2328 numerator = (-ac.x)*cd.y-(-ac.y)*cd.x;
2331 if(!APPROX(denominator,0)) {
2332 u=numerator/denominator;
2333 r=((-ac.x)*ab.y-(-ac.y)*ab.x)/denominator;
2336 if(APPROX(numerator,0)) {
2338 denominator=ab.z*cd.x-ab.x*cd.z;
2339 numerator = (-ac.x)*cd.z-(-ac.z)*cd.x;
2340 if(!APPROX(denominator,0)) {
2341 u=numerator/denominator;
2342 r=((-ac.x)*ab.y-(-ac.y)*ab.x)/denominator;
2347 printf(
"u=%f, r=%f\n",u,r);
2350 if(u>=0 && u<=1 && r>=0 && r<=1
2351 && APPROX((-ac.x)+u*ab.x,r*cd.x)
2352 && APPROX((-ac.y)+u*ab.y,r*cd.y)
2353 && APPROX((-ac.z)+u*ab.z,r*cd.z)) {
2356 printf(
"Intersection found at P=[%f,%f,%f]!\n",
2358 coord[A*3+1]+u*ab.y,
2363 coord[(ncoord)*3 ]=coord[A*3 ]+(
float)(u*ab.x);
2364 coord[(ncoord)*3+1]=coord[A*3+1]+(
float)(u*ab.y);
2365 coord[(ncoord)*3+2]=coord[A*3+2]+(
float)(u*ab.z);
2377 Elev_Tri(triind*3, this_face, D,A,E, TRUE , rep_, facenormals, pointfaces,ccw);
2379 tcindex[triind*3] = (GLuint)Dtex;
2380 tcindex[triind*3+2] = (GLuint)Etex;
2381 tcindex[triind*3+1] = (GLuint)Atex;
2383 defaultface[triind] = this_face;
2388 Elev_Tri(triind*3, this_face, B, C, F, TRUE, rep_, facenormals, pointfaces,ccw);
2390 tcindex[triind*3] = (GLuint)Btex;
2391 tcindex[triind*3+1] = (GLuint)Ctex;
2392 tcindex[triind*3+2] = (GLuint)Ftex;
2394 if ((triind*3+2) >= tcindexsize)
2395 printf (
"INTERNAL ERROR: Extrusion - tcindex size too small!\n");
2396 defaultface[triind] = this_face;
2404 for (tmp=0; tmp<(triind*3); tmp++) {
2406 normalize_ifs_face (&rep_->normal[tmp*3],
2407 facenormals, pointfaces, cindex[tmp],
2408 defaultface[tmp/3], creaseAngle);
2410 rep_->normal[tmp*3+0] = (float) facenormals[defaultface[tmp/3]].x;
2411 rep_->normal[tmp*3+1] = (float) facenormals[defaultface[tmp/3]].y;
2412 rep_->normal[tmp*3+2] = (float) facenormals[defaultface[tmp/3]].z;
2414 rep_->norindex[tmp] = (GLuint)tmp;
2417 end_of_sides = triind*3;
2429 if (tubular) endpoint = nsec-3-ncolinear_at_end;
2430 else endpoint = nsec-2-ncolinear_at_end;
2437 triind_start = triind;
2439 for(x=0+ncolinear_at_begin; x<endpoint; x++) {
2440 Elev_Tri(triind*3, this_face, 0, x+2, x+1, TRUE , rep_, facenormals, pointfaces,ccw);
2441 defaultface[triind] = this_face;
2442 Extru_tex(triind*3, tci_ct, 0 , +x+2, x+1, tcindex ,ccw,tcindexsize);
2446 Extru_ST_map(triind_start,0+ncolinear_at_begin,endpoint,
2447 beginVals,nsec,tcindex, cindex, tcoord, tcoordsize);
2448 tci_ct+=endpoint-(0+ncolinear_at_begin);
2449 triind_start+=endpoint-(0+ncolinear_at_begin);
2454 triind_start = triind;
2456 for(x=0+ncolinear_at_begin; x<endpoint; x++) {
2457 Elev_Tri(triind*3, this_face, 0 +(nspi-1)*nsec,
2458 x+1+(nspi-1)*nsec,x+2+(nspi-1)*nsec,
2459 TRUE , rep_, facenormals, pointfaces,ccw);
2460 defaultface[triind] = this_face;
2461 Extru_tex(triind*3, tci_ct, 0+(nspi-1)*nsec,
2464 tcindex,ccw,tcindexsize);
2468 Extru_ST_map(triind_start,0+ncolinear_at_begin,endpoint,
2469 endVals, nsec, tcindex, cindex, tcoord, tcoordsize);
2474 if(beginCap || endCap) {
2486 tess_vs=MALLOC(
int *,
sizeof(*(tess_vs)) * (nsec - 3 - ncolinear_at_end) * 3);
2489 if (tubular) endpoint = nsec-1-ncolinear_at_end;
2490 else endpoint = nsec-ncolinear_at_end;
2494 tg->Tess.global_IFS_Coord_count = 0;
2496 gluTessBeginPolygon( tg->Tess.global_tessobj, NULL);
2497 gluTessBeginContour( tg->Tess.global_tessobj );
2499 for(x=0+ncolinear_at_begin; x<endpoint; x++) {
2501 c1 = (
struct SFVec3f *) &rep_->actualCoord[3*x];
2505 tess_v[0] = c1->c[0]; tess_v[1] = c1->c[1]; tess_v[2] = c1->c[2];
2507 FW_GLU_TESS_VERTEX(tg->Tess.global_tessobj,tess_v,&tess_vs[x]);
2510 gluTessEndContour( tg->Tess.global_tessobj );
2511 gluTessEndPolygon( tg->Tess.global_tessobj );
2513 verify_global_IFS_Coords(ntri*3);
2515 for (x=0; x<tg->Tess.global_IFS_Coord_count; x+=3) {
2518 Elev_Tri(triind*3, this_face, tg->Tess.global_IFS_Coords[x],
2519 tg->Tess.global_IFS_Coords[x+2], tg->Tess.global_IFS_Coords[x+1],
2520 TRUE , rep_, facenormals, pointfaces,ccw);
2521 defaultface[triind] = this_face;
2525 Extru_check_normal (facenormals,this_face,-1,rep_,ccw);
2531 tg->Tess.global_IFS_Coord_count = 0;
2533 gluTessBeginPolygon( tg->Tess.global_tessobj, NULL);
2534 gluTessBeginContour( tg->Tess.global_tessobj );
2536 for(x=0+ncolinear_at_begin; x<endpoint; x++) {
2537 c1 = (
struct SFVec3f *) &rep_->actualCoord[3*(x+(nspi-1)*nsec)];
2538 tess_v[0] = c1->c[0]; tess_v[1] = c1->c[1]; tess_v[2] = c1->c[2];
2539 tess_vs[x] = x+(nspi-1)*nsec;
2540 FW_GLU_TESS_VERTEX(tg->Tess.global_tessobj,tess_v,&tess_vs[x]);
2543 gluTessEndContour( tg->Tess.global_tessobj );
2544 gluTessEndPolygon( tg->Tess.global_tessobj );
2546 verify_global_IFS_Coords(ntri*3);
2548 for (x=0; x<tg->Tess.global_IFS_Coord_count; x+=3) {
2549 Elev_Tri(triind*3, this_face, tg->Tess.global_IFS_Coords[x],
2550 tg->Tess.global_IFS_Coords[x+1], tg->Tess.global_IFS_Coords[x+2],
2551 TRUE , rep_, facenormals, pointfaces,ccw);
2552 defaultface[triind] = this_face;
2556 Extru_check_normal (facenormals,this_face,1,rep_,ccw);
2562 FREE_IF_NZ (tess_vs);
2572 for (tmp=end_of_sides; tmp<(triind*3); tmp++) {
2573 rep_->normal[tmp*3+0] = (float) facenormals[defaultface[tmp/3]].x;
2574 rep_->normal[tmp*3+1] = (float) facenormals[defaultface[tmp/3]].y;
2575 rep_->normal[tmp*3+2] = (float) facenormals[defaultface[tmp/3]].z;
2576 rep_->norindex[tmp] = (GLuint)tmp;
2581 if (tcoordsize <= ((nsec-1)+(nspi-1)*(nsec-1)*3+2)) {
2582 printf (
"INTERNAL ERROR: Extrusion side tcoord calcs nspi %d nsec %d tcoordsize %d\n",
2583 nspi,nsec,tcoordsize);
2585 for(sec=0; sec<nsec; sec++) {
2586 for(spi=0; spi<nspi; spi++) {
2590 tcoord[(sec+spi*nsec)*3+0] = (
float) sec/(nsec-1);
2591 tcoord[(sec+spi*nsec)*3+1] = 0;
2592 tcoord[(sec+spi*nsec)*3+2] = (
float) spi/(nspi-1);
2598 printf (
"done, lets free\n");
2602 FREE_IF_NZ (defaultface);
2603 FREE_IF_NZ (pointfaces);
2604 FREE_IF_NZ (facenormals);
2605 FREE_IF_NZ (crossSection);
2607 FREE_IF_NZ (beginVals);
2608 FREE_IF_NZ (endVals);
2612 stream_extrusion_texture_coords (rep_, tcoord, tcindex);
2615 FREE_IF_NZ (tcoord);
2616 FREE_IF_NZ (tcindex);
2620 printf(
"Extrusion.GenPloyRep: triind=%d ntri=%d nctri=%d "
2621 "ncolinear_at_begin=%d ncolinear_at_end=%d\n",
2622 triind,ntri,nctri,ncolinear_at_begin,ncolinear_at_end);
2624 printf (
"end VRMLExtrusion.pm\n");