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"
58extern void Elev_Tri (
int vertex_ind,
int this_face,
int A,
int D,
int E,
int NONORMALS,
struct X3D_PolyRep *this_Elev,
struct SFVec3f *facenormals,
int *pointfaces,
int ccw);
59extern void verify_global_IFS_Coords(
int max);
61extern void Extru_check_normal(
struct SFVec3f *facenormals,
int this_face,
int dire,
struct X3D_PolyRep *rep_,
int ccw);
65static int returnIndexedFanStripIndexSize (
struct Multi_Int32 index ) {
72 for (xx=0; xx<index.n; xx++) {
74 if ((index.p[xx] <=-1) || (xx == (index.n-1))) {
78 if ((index.p[xx] > -1) && (xx == (index.n-1))) {
82 IndexSize += (zz-2) *4;
85 printf (
"IndexedTriangle[Fan|Strip]Set, index %d is less than 3\n",zz);
101 if (this_->coord == 0) {
103 printf (
"checkX3DIFS - have an IFS (%d) with no coords...\n",this_);
107 if (this_->coordIndex.n == 0) {
109 printf (
"checkX3DIFS - have an IFS (%d) with no coordIndex, pointer is %d offset is %d\n",this_,
118int checkX3DElevationGridFields (
struct X3D_ElevationGrid *this_,
float **points,
int *npoints) {
120 int nx = (this_->xDimension);
121 float xSp = (this_->xSpacing);
122 int nz = (this_->zDimension);
123 float zSp = (this_->zSpacing);
124 float *height = ((this_->height).p);
125 int ntri = (nx && nz ? 2 * (nx-1) * (nz-1) : 0);
126 int nh = ((this_->height).n);
134 float *tcoord = NULL;
139 printf (
"Elevationgrid: warning: x,y vs. height: %d * %d ne %d:\n", nx,nz,nh);
141 printf (
"Elevationgrid: error: x,y vs. height: %d * %d ne %d:\n", nx,nz,nh);
147 if ((nx < 2) || (nz < 2)) {
148 printf (
"ElevationGrid: xDimension and zDimension less than 2 %d %d\n", nx,nz);
153 if (!(this_->texCoord)) {
155 FREE_IF_NZ(rep->GeneratedTexCoords[0]);
158 tcoord = rep->GeneratedTexCoords[0] = MALLOC (
float *,
sizeof (
float) * nquads * 12);
162 ConsoleMessage (
"even though we have a texCoord node here, we need to generate");
167 newpoints = MALLOC (
float *,
sizeof (
float) * nz * nx * 3);
169 FREE_IF_NZ(rep->actualCoord);
170 rep->actualCoord = (
float *)newpoints;
173 if (this_->_coordIndex.n > 0) {FREE_IF_NZ(this_->_coordIndex.p);}
174 this_->_coordIndex.p = MALLOC (
int *,
sizeof(
int) * nquads * 5);
175 cindexptr = this_->_coordIndex.p;
177 this_->_coordIndex.n = nquads * 5;
180 *npoints = this_->_coordIndex.n;
182 for (j = 0; j < (nz -1); j++) {
183 for (i=0; i < (nx-1) ; i++) {
190 *cindexptr = j*nx+i; cindexptr++;
191 *cindexptr = j*nx+i+nx; cindexptr++;
192 *cindexptr = j*nx+i+nx+1; cindexptr++;
193 *cindexptr = j*nx+i+1; cindexptr++;
194 *cindexptr = -1; cindexptr++;
201 if (!(this_->texCoord)) {
202 for (j = 0; j < (nz -1); j++) {
203 for (i=0; i < (nx-1) ; i++) {
206 *tcoord = ((float) (i+0)/(nx-1)); tcoord++;
207 *tcoord = ((float)(j+0)/(nz-1)); tcoord ++;
209 *tcoord = ((float) (i+0)/(nx-1)); tcoord++;
210 *tcoord = ((float)(j+1)/(nz-1)); tcoord ++;
212 *tcoord = ((float) (i+1)/(nx-1)); tcoord++;
213 *tcoord = ((float)(j+1)/(nz-1)); tcoord ++;
216 *tcoord = ((float) (i+0)/(nx-1)); tcoord++;
217 *tcoord = ((float)(j+0)/(nz-1)); tcoord ++;
219 *tcoord = ((float) (i+1)/(nx-1)); tcoord++;
220 *tcoord = ((float)(j+1)/(nz-1)); tcoord ++;
222 *tcoord = ((float) (i+1)/(nx-1)); tcoord++;
223 *tcoord = ((float)(j+0)/(nz-1)); tcoord ++;
231 for (j=0; j<nz; j++) {
232 for (i=0; i < nx; i++) {
244 newPoint[0] = xSp * i; newPoint[1] = height[i+(j*nx)]; newPoint[2]=zSp*j;
245 memcpy(newpoints,newPoint,
sizeof(
float)*3);
262 IndexSize = returnIndexedFanStripIndexSize(node->index);
263 if (IndexSize == 0) {
268 newIndex = MALLOC (
int *,
sizeof(
int) * IndexSize);
273 while (xx < (node->index.n-1)) {
276 while ((xx<node->index.n) && (node->index.p[xx] > -1)) xx++;
280 if (xx >= IndexSize) {
281 printf (
"ITFS - index size error... IndexSize < index value \n");
287 for (zz=fanVertex; zz<(xx-2); zz++) {
288 if (windingOrder==0) {
289 newIndex[yy] = node->index.p[zz]; yy++;
290 newIndex[yy] = node->index.p[zz+1]; yy++;
291 newIndex[yy] = node->index.p[zz+2]; yy++;
294 newIndex[yy] = node->index.p[zz]; yy++;
295 newIndex[yy] = node->index.p[zz+2]; yy++;
296 newIndex[yy] = node->index.p[zz+1]; yy++;
299 newIndex[yy] = -1; yy++;
303 if (xx < (node->index.n-1)) {
315 node->_coordIndex.p = newIndex;
316 node->_coordIndex.n = IndexSize;
326 IndexSize = returnIndexedFanStripIndexSize(node->index);
327 if (IndexSize == 0) {
332 newIndex = MALLOC (
int *,
sizeof(
int) * IndexSize);
337 while (xx < (node->index.n-1)) {
340 while ((xx<node->index.n) && (node->index.p[xx] > -1)) xx++;
344 if (xx >= IndexSize) {
345 printf (
"ITFS - index size error... IndexSize < index value \n");
349 for (zz=fanVertex+1; zz<(xx-1); zz++) {
351 newIndex[yy] = node->index.p[fanVertex]; yy++;
352 newIndex[yy] = node->index.p[zz]; yy++;
353 newIndex[yy] = node->index.p[zz+1]; yy++;
354 newIndex[yy] = -1; yy++;
358 if (xx < (node->index.n-1)) {
369 node->_coordIndex.p = newIndex;
370 node->_coordIndex.n = IndexSize;
379 IndexSize = ((node->index.n) * 4) / 3;
380 if (IndexSize <= 0) {
385 newIndex = MALLOC (
int *,
sizeof(
int) * IndexSize);
388 for (xx = 0; xx < node->index.n; xx++) {
389 newIndex[zz] = node->index.p[xx];
405 node->_coordIndex.p = newIndex;
406 node->_coordIndex.n = IndexSize;
415 if ((node->fanCount).n < 1) {
416 ConsoleMessage(
"TriangleFanSet, need at least one fanCount element");
417 node->fanCount.n = 0;
421 for (xx=0; xx<(node->fanCount).n; xx++) {
423 IndexSize += ((node->fanCount).p[xx]-2) * 4;
425 if ((node->fanCount).p[xx] < 3) {
426 printf (
"TriangleFanSet, fanCount index %d is less than 3\n", (node->fanCount).p[xx]);
431 node->_coordIndex.p = MALLOC (
int *,
sizeof(
int) * IndexSize);
432 node->_coordIndex.n = IndexSize;
437 for (xx=0; xx<(node->fanCount).n; xx++) {
441 for (yy=0; yy< ((node->fanCount).p[xx]-2); yy++) {
444 node->_coordIndex.p[IndexSize++] = fanVertex;
445 node->_coordIndex.p[IndexSize++] = zz;
446 node->_coordIndex.p[IndexSize++] = zz+1;
447 node->_coordIndex.p[IndexSize++] = -1;
460 IndexSize = ((node->index.n) /4) * 4;
461 if (IndexSize <= 0) {
468 if (IndexSize != node->index.n) ConsoleMessage (
"IndexedQuadSet using %d of %d indexes according to spec",IndexSize,node->index.n);
473 newIndex = MALLOC (
int *,
sizeof(
int) * IndexSize * 5 / 4);
474 newIndexPtr = newIndex;
477 for (xx = 0; xx < IndexSize; xx++) {
478 *newIndexPtr = node->index.p[xx];
495 FREE_IF_NZ (node->index.p);
496 node->_coordIndex.p = newIndex;
497 node->_coordIndex.n = IndexSize * 5 / 4;
500static void checkQuadSetFields(
struct X3D_QuadSet *node) {
507 dtmp = getCoordinate (node->coord,
"QuadSet");
512 if (((npoints/4)*4) != npoints) {
513 ConsoleMessage (
"Warning, in QuadSet, Coordinates not a multiple of 4\n");
514 npoints = ((npoints/4)*4);
521 IndexSize = (npoints * 8) / 4;
523 node->_coordIndex.p = MALLOC (
int *,
sizeof(
int) * IndexSize);
524 node->_coordIndex.n = IndexSize;
529 for (xx=0; xx<npoints; xx+=4) {
531 node->_coordIndex.p[IndexSize++] = xx;
532 node->_coordIndex.p[IndexSize++] = xx+1;
533 node->_coordIndex.p[IndexSize++] = xx+2;
534 node->_coordIndex.p[IndexSize++] = -1;
535 node->_coordIndex.p[IndexSize++] = xx+2;
536 node->_coordIndex.p[IndexSize++] = xx+3;
537 node->_coordIndex.p[IndexSize++] = xx;
538 node->_coordIndex.p[IndexSize++] = -1;
554 if ((node->stripCount).n < 1) {
555 ConsoleMessage (
"TriangleStripSet, need at least one stripCount element");
556 node->stripCount.n=0;
560 for (xx=0; xx<(node->stripCount).n; xx++) {
562 IndexSize += ((node->stripCount).p[xx]-2) * 4;
564 if ((node->stripCount).p[xx] < 3) {
565 printf (
"TriangleStripSet, index %d is less than 3\n",
566 (node->stripCount).p[xx]);
571 node->_coordIndex.p = MALLOC (
int *,
sizeof(
int) * IndexSize);
572 node->_coordIndex.n = IndexSize;
577 for (xx=0; xx<(node->stripCount).n; xx++) {
580 for (yy=0; yy< ((node->stripCount).p[xx]-2); yy++) {
581 if (windingOrder==0) {
583 node->_coordIndex.p[IndexSize++] = zz;
584 node->_coordIndex.p[IndexSize++] = zz+1;
585 node->_coordIndex.p[IndexSize++] = zz+2;
589 node->_coordIndex.p[IndexSize++] = zz+1;
590 node->_coordIndex.p[IndexSize++] = zz;
591 node->_coordIndex.p[IndexSize++] = zz+2;
594 node->_coordIndex.p[IndexSize++] = -1;
610 dtmp = getCoordinate (node->coord,
"TriangleSet");
615 if (((npoints/3)*3) != npoints) {
616 printf (
"Warning, in TriangleSet, Coordinates not a multiple of 3\n");
617 npoints = ((npoints/3)*3);
624 IndexSize = (npoints * 4) / 3;
626 node->_coordIndex.p = MALLOC (
int *,
sizeof(
int) * IndexSize);
627 node->_coordIndex.n = IndexSize;
632 for (xx=0; xx<npoints; xx+=3) {
634 node->_coordIndex.p[IndexSize++] = xx;
635 node->_coordIndex.p[IndexSize++] = xx+1;
636 node->_coordIndex.p[IndexSize++] = xx+2;
637 node->_coordIndex.p[IndexSize++] = -1;
661 float creaseAngle = (float) PI * 2;
670 int calc_normind = 0;
675 float *fogdepths = NULL;
689 int normalArraySize = INT_ID_UNDEFINED;
696 int *pointfaces = NULL;
704 int this_face, this_coord;
711 ttglobal tg = gglobal();
713 if (node->_nodeType == NODE_IndexedFaceSet) {
714 if (!checkX3DIndexedFaceSetFields(node)) {
720 }
else if (node->_nodeType == NODE_ElevationGrid) {
721 if (!checkX3DElevationGridFields(X3D_ELEVATIONGRID(node),
722 (
float **)&points, &npoints)) {
726 }
else if (node->_nodeType == NODE_GeoElevationGrid) {
727 if (!checkX3DGeoElevationGridFields(X3D_GEOELEVATIONGRID(node),
728 (
float **)&points, &npoints)) {
734 switch (node->_nodeType) {
735 case NODE_IndexedFaceSet:
736 convex = node->convex;
738 cpv = node->colorPerVertex;
739 npv = node->normalPerVertex;
741 orig_texCoordIndex = &node->texCoordIndex;
742 orig_colorIndex = &node->colorIndex;
743 orig_normalIndex = &node->normalIndex;
744 creaseAngle = node->creaseAngle;
745 orig_coordIndex = &node->coordIndex;
760 case NODE_ElevationGrid:
761 orig_coordIndex= &X3D_ELEVATIONGRID(node)->_coordIndex;
762 cpv = X3D_ELEVATIONGRID(node)->colorPerVertex;
763 npv = X3D_ELEVATIONGRID(node)->normalPerVertex;
764 creaseAngle = X3D_ELEVATIONGRID(node)->creaseAngle;
765 cc = (
struct X3D_Color *) X3D_ELEVATIONGRID(node)->color;
766 nc = (
struct X3D_Normal *) X3D_ELEVATIONGRID(node)->normal;
776 case NODE_GeoElevationGrid:
777 orig_coordIndex= &X3D_GEOELEVATIONGRID(node)->_coordIndex;
778 cpv = X3D_GEOELEVATIONGRID(node)->colorPerVertex;
779 npv = X3D_GEOELEVATIONGRID(node)->normalPerVertex;
780 creaseAngle = (float) X3D_GEOELEVATIONGRID(node)->creaseAngle;
781 cc = (
struct X3D_Color *) X3D_GEOELEVATIONGRID(node)->color;
782 nc = (
struct X3D_Normal *) X3D_GEOELEVATIONGRID(node)->normal;
789 case NODE_IndexedTriangleFanSet:
790 checkIndexedTriangleFanSetFields(X3D_INDEXEDTRIANGLEFANSET(node));
791 orig_coordIndex= &X3D_INDEXEDTRIANGLEFANSET(node)->_coordIndex;
792 cpv = X3D_INDEXEDTRIANGLEFANSET(node)->colorPerVertex;
793 npv = X3D_INDEXEDTRIANGLEFANSET(node)->normalPerVertex;
794 ccw = X3D_INDEXEDTRIANGLEFANSET(node)->ccw;
795 cc = (
struct X3D_Color *) X3D_INDEXEDTRIANGLEFANSET(node)->color;
796 nc = (
struct X3D_Normal *) X3D_INDEXEDTRIANGLEFANSET(node)->normal;
798 co = (
struct X3D_Coordinate *) X3D_INDEXEDTRIANGLEFANSET(node)->coord;
800 if(!npv) creaseAngle = 0.0;
810 case NODE_IndexedTriangleSet:
811 checkIndexedTriangleSetFields(X3D_INDEXEDTRIANGLESET(node));
812 orig_coordIndex= &X3D_INDEXEDTRIANGLESET(node)->_coordIndex;
813 cpv = X3D_INDEXEDTRIANGLESET(node)->colorPerVertex;
814 npv = X3D_INDEXEDTRIANGLESET(node)->normalPerVertex;
815 ccw = X3D_INDEXEDTRIANGLESET(node)->ccw;
816 cc = (
struct X3D_Color *) X3D_INDEXEDTRIANGLESET(node)->color;
817 nc = (
struct X3D_Normal *) X3D_INDEXEDTRIANGLESET(node)->normal;
819 co = (
struct X3D_Coordinate *) X3D_INDEXEDTRIANGLESET(node)->coord;
821 if(!npv) creaseAngle = 0.0;
831 case NODE_IndexedTriangleStripSet:
832 checkIndexedTriangleStripSetFields(X3D_INDEXEDTRIANGLESTRIPSET(node));
833 orig_coordIndex= &X3D_INDEXEDTRIANGLESTRIPSET(node)->_coordIndex;
834 cpv = X3D_INDEXEDTRIANGLESTRIPSET(node)->colorPerVertex;
835 npv = X3D_INDEXEDTRIANGLESTRIPSET(node)->normalPerVertex;
836 ccw = X3D_INDEXEDTRIANGLESTRIPSET(node)->ccw;
837 cc = (
struct X3D_Color *) X3D_INDEXEDTRIANGLESTRIPSET(node)->color;
838 nc = (
struct X3D_Normal *) X3D_INDEXEDTRIANGLESTRIPSET(node)->normal;
840 co = (
struct X3D_Coordinate *) X3D_INDEXEDTRIANGLESTRIPSET(node)->coord;
842 if(!npv) creaseAngle = 0.0;
852 case NODE_TriangleFanSet:
853 checkTriangleFanSetFields(X3D_TRIANGLEFANSET(node));
854 orig_coordIndex= &X3D_TRIANGLEFANSET(node)->_coordIndex;
855 cpv = X3D_TRIANGLEFANSET(node)->colorPerVertex;
856 npv = X3D_TRIANGLEFANSET(node)->normalPerVertex;
857 ccw = X3D_TRIANGLEFANSET(node)->ccw;
858 cc = (
struct X3D_Color *) X3D_TRIANGLEFANSET(node)->color;
859 nc = (
struct X3D_Normal *) X3D_TRIANGLEFANSET(node)->normal;
863 if(!nc && !npv) creaseAngle = 0.0;
872 case NODE_TriangleSet:
873 checkTriangleSetFields(X3D_TRIANGLESET(node));
874 orig_coordIndex= &X3D_TRIANGLESET(node)->_coordIndex;
875 cpv = X3D_TRIANGLESET(node)->colorPerVertex;
876 npv = X3D_TRIANGLESET(node)->normalPerVertex;
877 ccw = X3D_TRIANGLESET(node)->ccw;
878 cc = (
struct X3D_Color *) X3D_TRIANGLESET(node)->color;
879 nc = (
struct X3D_Normal *) X3D_TRIANGLESET(node)->normal;
883 MARK_EVENT (X3D_NODE(node), offsetof (
struct X3D_TriangleSet, attrib));
886 MARK_EVENT (X3D_NODE(node), offsetof (
struct X3D_TriangleSet, fogCoord));
887 MARK_EVENT (X3D_NODE(node), offsetof (
struct X3D_TriangleSet, metadata));
888 MARK_EVENT (X3D_NODE(node), offsetof (
struct X3D_TriangleSet, normal));
889 MARK_EVENT (X3D_NODE(node), offsetof (
struct X3D_TriangleSet, texCoord));
891 case NODE_TriangleStripSet:
892 checkTriangleStripSetFields(X3D_TRIANGLESTRIPSET(node));
893 orig_coordIndex= &X3D_TRIANGLESTRIPSET(node)->_coordIndex;
894 cpv = X3D_TRIANGLESTRIPSET(node)->colorPerVertex;
895 npv = X3D_TRIANGLESTRIPSET(node)->normalPerVertex;
896 ccw = X3D_TRIANGLESTRIPSET(node)->ccw;
897 cc = (
struct X3D_Color *) X3D_TRIANGLESTRIPSET(node)->color;
898 nc = (
struct X3D_Normal *) X3D_TRIANGLESTRIPSET(node)->normal;
902 if(!nc && !npv) creaseAngle = 0.0;
912 case NODE_IndexedQuadSet:
913 checkIndexedQuadSetFields(X3D_INDEXEDQUADSET(node));
914 orig_coordIndex= &X3D_INDEXEDQUADSET(node)->_coordIndex;
915 cpv = X3D_INDEXEDQUADSET(node)->colorPerVertex;
916 npv = X3D_INDEXEDQUADSET(node)->normalPerVertex;
917 ccw = X3D_INDEXEDQUADSET(node)->ccw;
918 cc = (
struct X3D_Color *) X3D_INDEXEDQUADSET(node)->color;
919 nc = (
struct X3D_Normal *) X3D_INDEXEDQUADSET(node)->normal;
934 checkQuadSetFields(X3D_QUADSET(node));
935 orig_coordIndex= &X3D_QUADSET(node)->_coordIndex;
936 cpv = X3D_QUADSET(node)->colorPerVertex;
937 npv = X3D_QUADSET(node)->normalPerVertex;
938 ccw = X3D_QUADSET(node)->ccw;
939 cc = (
struct X3D_Color *) X3D_QUADSET(node)->color;
940 nc = (
struct X3D_Normal *) X3D_QUADSET(node)->normal;
944 MARK_EVENT (X3D_NODE(node), offsetof (
struct X3D_QuadSet, attrib));
945 MARK_EVENT (X3D_NODE(node), offsetof (
struct X3D_QuadSet, color));
946 MARK_EVENT (X3D_NODE(node), offsetof (
struct X3D_QuadSet, coord));
947 MARK_EVENT (X3D_NODE(node), offsetof (
struct X3D_QuadSet, fogCoord));
948 MARK_EVENT (X3D_NODE(node), offsetof (
struct X3D_QuadSet, metadata));
949 MARK_EVENT (X3D_NODE(node), offsetof (
struct X3D_QuadSet, normal));
950 MARK_EVENT (X3D_NODE(node), offsetof (
struct X3D_QuadSet, texCoord));
954 ConsoleMessage (
"unknown type for make_genericfaceset, %d\n",node->_nodeType);
959 if (orig_coordIndex != NULL) cin= orig_coordIndex->n;
else cin = 0;
960 if (orig_texCoordIndex != NULL) tcin= orig_texCoordIndex->n;
else tcin = 0;
961 if (orig_colorIndex != NULL) colin= orig_colorIndex->n;
else colin = 0;
962 if (orig_normalIndex != NULL) norin= orig_normalIndex->n;
else norin = 0;
965 printf (
"cin %d tcin %d colin %d norin %d\n",cin,tcin,colin,norin);
966 printf (
"start of make_indexedfaceset for node %p, cin %d tcin %d colin %d norin %d\n",node, cin, tcin, colin, norin);
974 printf (
"NOW, the IFS has a cin of %d ca %f\n",cin,creaseAngle);
980 printf (
"Null IFS found, returing ntri0\n");
990 if((orig_coordIndex->p[cin-1]) == -1) { cin--; }
996 dtmp = getCoordinate (X3D_NODE(co),
"make FacedSet");
1006 if(fc2->depth.n < npoints){
1007 fc2->depth.p = REALLOC(fc2->depth.p, npoints *
sizeof(
float));
1008 for(i=fc2->depth.n; i<npoints; i++){
1009 fc2->depth.p[i] = fc2->depth.p[fc->depth.n-1];
1011 fc2->depth.n = npoints;
1013 fogdepths = fc2->depth.p;
1020 if ((cc->_nodeType != NODE_Color) && (cc->_nodeType != NODE_ColorRGBA)) {
1021 printf (
"make_IFS, expected %d got %d\n", NODE_Color, cc->_nodeType);
1023 ncolors = cc->color.n;
1028 if (nc->_nodeType != NODE_Normal) {
1029 printf (
"make_IFS, normal expected %d, got %d\n",NODE_Normal, nc->_nodeType);
1031 nnormals = nc->vector.n;
1039 rep_->tcoordtype=tc->_nodeType;
1045 faceok = MALLOC(
struct facepar *,
sizeof(
struct facepar)*(cin/2+1));
1046 faces = count_IFS_faces (cin,orig_coordIndex,faceok);
1048 printf (
"faces %d, cin %d npoints %d\n",faces,cin,npoints);
1065 facenormals = MALLOC(
struct SFVec3f *,
sizeof(
struct SFVec3f)*faces);
1066 pointfaces = MALLOC(
int *,
sizeof(
int)*npoints*POINT_FACES);
1070 if (!IFS_face_normals (facenormals,faceok,pointfaces,faces,npoints,cin,points,orig_coordIndex,ccw)) {
1072 FREE_IF_NZ (facenormals);
1073 FREE_IF_NZ (faceok);
1074 FREE_IF_NZ (pointfaces);
1093 for(i=0;i<faces;i++){
1094 nvert = faceok[i].end - faceok[i].start +1;
1095 ntri += 2*nvert-2-nvert;
1105 if(!convex) { ntri =ntri*2; }
1110 FREE_IF_NZ(rep_->cindex);
1111 FREE_IF_NZ(rep_->colindex);
1112 FREE_IF_NZ(rep_->norindex);
1113 FREE_IF_NZ(rep_->oindex);
1114 cindex = rep_->cindex = MALLOC(GLuint *,
sizeof(*(rep_->cindex))*3*(ntri));
1115 colindex = rep_->colindex = MALLOC(GLuint *,
sizeof(*(rep_->colindex))*3*(ntri));
1116 norindex = rep_->norindex = MALLOC(GLuint *,
sizeof(*(rep_->norindex))*3*ntri);
1119 bzero (colindex,
sizeof(*(rep_->colindex))*3*(ntri));
1120 bzero (norindex,
sizeof(*(rep_->colindex))*3*(ntri));
1122 FREE_IF_NZ(rep_->normal);
1125 normalArraySize = 3*3*ntri;
1126 rep_->normal = MALLOC(
float *,
sizeof(*(rep_->normal))*normalArraySize * 2 );
1128 rep_->normal = MALLOC(
float *, 1);
1131 FREE_IF_NZ(rep_->tcindex);
1133 tcindex = rep_->tcindex = MALLOC(GLuint*,
sizeof(*(rep_->tcindex))*3*(ntri));
1136 tess_vs=MALLOC(
int *,
sizeof(*(tess_vs))*(ntri)*3);
1140 for (this_face=0; this_face<faces; this_face++) {
1142 int tess_contour_start;
1146 tg->Tess.global_IFS_Coord_count = 0;
1148 tess_contour_start = 0;
1151 if (faceok[this_face].OK) {
1166 printf (
"working on face %d coord %d total coords %d coordIndex %d\n",
1167 this_face,this_coord,cin,(orig_coordIndex->p[ this_coord]));
1181 this_coord = faceok[this_face].start;
1188 gluTessBeginPolygon( tg->Tess.global_tessobj, &cbdata);
1189 gluTessBeginContour( tg->Tess.global_tessobj );
1191 initind = relative_coord++;
1192 lastind = relative_coord++;
1195 i = (orig_coordIndex->p[ relative_coord + this_coord]);
1200 int foundContour = FALSE;
1204 for (ind=tess_contour_start; ind<relative_coord; ind++) {
1211 if ( orig_coordIndex->p[relative_coord + this_coord] ==
1212 orig_coordIndex->p[ind + this_coord]) {
1214 tess_contour_start = relative_coord+1;
1215 FW_GLU_NEXT_CONTOUR(tg->Tess.global_tessobj,GLU_UNKNOWN);
1216 foundContour = TRUE;
1221 if (!foundContour) {
1223 tess_v[0] = c1->c[0];
1224 tess_v[1] = c1->c[1];
1225 tess_v[2] = c1->c[2];
1226 tess_vs[relative_coord] = relative_coord;
1230 FW_GLU_TESS_VERTEX(tg->Tess.global_tessobj,tess_v,&tess_vs[relative_coord]);
1236 tg->Tess.global_IFS_Coords[tg->Tess.global_IFS_Coord_count++] = initind;
1237 tg->Tess.global_IFS_Coords[tg->Tess.global_IFS_Coord_count++] = lastind;
1238 tg->Tess.global_IFS_Coords[tg->Tess.global_IFS_Coord_count++] = relative_coord;
1240 lastind = relative_coord++;
1243 if (relative_coord + this_coord == cin) {
1246 i = (orig_coordIndex->p[ relative_coord + this_coord]);
1252 gluTessEndContour( tg->Tess.global_tessobj );
1253 gluTessEndPolygon( tg->Tess.global_tessobj );
1258 verify_global_IFS_Coords(cin);
1267 for (i=0; i<tg->Tess.global_IFS_Coord_count; i++) {
1269 cindex [vert_ind] = (orig_coordIndex->p[this_coord+tg->Tess.global_IFS_Coords[i]]);
1275 int iwant,ihavei,ihaven;
1279 iwant = this_coord+tg->Tess.global_IFS_Coords[i];
1280 ihavei = min(iwant, orig_normalIndex->n-1);
1281 if(ihavei < iwant) {
1282 static int once = 0;
1283 if(!once) ConsoleMessage(
"not enough normal indexes have %d want %d \n",ihavei,iwant);
1286 iwant = orig_normalIndex->p[ihavei];
1287 ihaven = min(nnormals-1,iwant);
1288 if(ihaven < iwant) {
1289 static int once = 0;
1290 if(!once) ConsoleMessage(
"not enough normals have %d want %d \n",ihaven,iwant);
1293 norindex[vert_ind] = ihaven;
1298 ihavei = min(iwant, orig_normalIndex->n-1);
1299 if(ihavei < iwant) {
1300 static int once = 0;
1301 if(!once) ConsoleMessage(
"not enough normal indexes have %d want %d \n",ihavei,iwant);
1304 norindex[vert_ind] = ihavei;
1310 iwant = this_coord+tg->Tess.global_IFS_Coords[i];
1311 ihavei = min(iwant, norin);
1312 if(ihavei < iwant) {
1313 static int once = 0;
1314 if(!once) ConsoleMessage(
"not enough normal indexes have %d want %d \n",ihavei,iwant);
1318 norindex[vert_ind] = ihavei;
1321 norindex[vert_ind] = this_face;
1327 if (fabs(creaseAngle) > 0.00001) {
1329 if (normalArraySize != INT_ID_UNDEFINED) {
1330 if (calc_normind*3 > normalArraySize) {
1331 printf (
"HMMM _ NORMAL OVERFLOW\n");
1335 normalize_ifs_face (&rep_->normal[calc_normind*3],
1336 facenormals, pointfaces, cindex[vert_ind],
1337 this_face, creaseAngle);
1338 rep_->norindex[vert_ind] = calc_normind++;
1344 veccopy3f(&rep_->normal[vert_ind*3+0],facenormals[this_face].c);
1345 rep_->norindex[vert_ind] = vert_ind;
1358 if (cpv) tmpI = this_coord+tg->Tess.global_IFS_Coords[i];
1359 else tmpI = this_face;
1361 if (tmpI >= orig_colorIndex->n) {
1362 printf (
"faceSet, colorIndex problem, %d >= %d\n", tmpI,orig_colorIndex->n);
1363 colindex[vert_ind] = 0;
1365 colindex[vert_ind] = orig_colorIndex->p[tmpI];
1372 colindex[vert_ind] = (orig_coordIndex->p[this_coord+tg->Tess.global_IFS_Coords[i]]);
1375 colindex[vert_ind] = this_face;
1386 if ((this_coord+tg->Tess.global_IFS_Coords[i]) < tcin) {
1387 tcindex[vert_ind] = orig_texCoordIndex->p[this_coord+tg->Tess.global_IFS_Coords[i]];
1389 tcindex[vert_ind] = 0;
1394 tcindex[vert_ind] = (orig_coordIndex->p[this_coord+tg->Tess.global_IFS_Coords[i]]);
1400 if (vert_ind < (ntri*3-1)) vert_ind++;
1404 this_coord += relative_coord;
1407 if (this_coord < cin)
1408 if ((orig_coordIndex->p[this_coord]) == -1) {this_coord++;}
1413 rep_->ntri = vert_ind/3;
1415 printf (
"make_indededfaceset, end, ntri %d\n",rep_->ntri);
1418 FREE_IF_NZ (tess_vs);
1419 FREE_IF_NZ (facenormals);
1420 FREE_IF_NZ (faceok);
1421 FREE_IF_NZ (pointfaces);
1431double getAlpha(
float ang) {
1432 if (ang >= 0.99999)
return asin(0.9999);
1433 else if (ang <= -0.99999)
return asin(-0.9999);
1434 return asin((
double)ang);
1438double getGamma(
double alpha,
double minor) {
1441 if(APPROX(cos(alpha),0))
1444 gamma=acos(minor / cos(alpha));
1445 if(fabs(sin(gamma)-(-minor/cos(alpha)))>fabs(sin(gamma))) gamma=-gamma;
1462 struct point_XYZ spp1 = {.x=0.0, .y=0.0, .z=0.0};
1471 for(spi=1;spi<nspi;spi++) {
1472 VEC_FROM_CDIFF(spine[spi],spine[0],spp1);
1473 if(!APPROX(VECSQ(spp1),0))
1478 spylen=1/(float) sqrt(VECSQ(spp1)); VECSCALE(spp1,spylen);
1480 printf(
"Reference vector along spine=[%f,%f,%f]\n", spp1.x,spp1.y,spp1.z);
1485 if ((fabs(spp1.x) >= fabs(spp1.y)) && (fabs(spp1.x) >= fabs(spp1.z))) {majorX = TRUE;}
1486 else if ((fabs(spp1.y) >= fabs(spp1.x)) && (fabs(spp1.y) >= fabs(spp1.z))) { }
1488 if ((fabs(spp1.x) <= fabs(spp1.y)) && (fabs(spp1.x) <= fabs(spp1.z))) {minorX = TRUE;}
1489 else if ((fabs(spp1.y) <= fabs(spp1.x)) && (fabs(spp1.y) <= fabs(spp1.z))) minorY = TRUE;
1493 printf (
"major axis %d %d %d\n",majorX, majorY, majorZ);
1494 printf (
"minor axis %d %d %d\n",minorX, minorY, minorZ);
1501 alpha = getAlpha((
float)spp1.x);
1502 gamma = getGamma(alpha,minorY?spp1.y:spp1.z);
1505 printf(
"majorX: alpha=%f gamma=%f\n",alpha,gamma);
1510 spy->y=-(cos(alpha)*(-sin(gamma)));
1511 spy->z=cos(alpha)*cos(gamma);
1513 spz->y=-(sin(alpha)*sin(gamma));
1514 spz->z=(-sin(alpha))*cos(gamma);
1519 alpha = getAlpha((
float)spp1.z);
1520 gamma = getGamma(alpha,minorX?spp1.x:spp1.y);
1523 printf(
"majorZ: alpha=%f gamma=%f\n",alpha,gamma);
1526 spy->y=-(cos(alpha)*(-sin(gamma)));
1527 spy->x=cos(alpha)*cos(gamma);
1529 spz->y=-(sin(alpha)*sin(gamma));
1530 spz->x=(-sin(alpha))*cos(gamma);
1538 VECCP(*spy,spp1,crossp);
1539 if( veclengthd((
double*)&crossp) < .001 )
return;
1541 alpha = getAlpha((
float)spp1.y);
1542 gamma = getGamma(alpha,minorX?spp1.x:spp1.z);
1545 printf(
"majorY: lpha=%f gamma=%f\n",alpha,gamma);
1548 spy->x=-(cos(alpha)*(-sin(gamma)));
1549 spy->z=cos(alpha)*cos(gamma);
1551 spz->x=-(sin(alpha)*sin(gamma));
1552 spz->z=(-sin(alpha))*cos(gamma);
1567void stream_extrusion_texture_coords (
struct X3D_PolyRep *rep_,
1578 rep_->GeneratedTexCoords[0] = MALLOC (
float *,
sizeof(
float) * 2 * 3 * rep_->ntri);
1580 nc = rep_->GeneratedTexCoords[0];
1588 for (count = 0; count < rep_->ntri*3; count++) {
1589 ind = tcindex[count];
1592 *nc = tcoord[ind*3]; nc++; *nc = tcoord[ind*3+2]; nc++;
1605 int beginCap = node->beginCap;
1606 int endCap = node->endCap;
1608 int nspi = node->spine.n;
1609 int nsec = node->crossSection.n;
1613 int nori = node->orientation.n;
1616 int nsca = node->scale.n;
1618 struct SFVec3f *spine =node->spine.p;
1619 struct SFVec2f *curve =node->crossSection.p;
1620 struct SFRotation *orientation=node->orientation.p;
1641 int max_ncoord_add=0;
1645 int ncolinear_at_begin=0;
1648 int ncolinear_at_end=0;
1652 int spi,sec,triind,pos_of_last_zvalue;
1653 int next_spi, prev_spi;
1657 int circular = FALSE;
1659 int spine_is_one_vertex;
1661 float spxlen,spylen,spzlen;
1681 struct SFVec3f *facenormals = NULL;
1682 int *pointfaces = 0;
1683 int *defaultface = 0;
1686 float creaseAngle = node->creaseAngle;
1687 int ccw = node->ccw;
1698 printf (
"VRMLExtrusion.pm start\n");
1710 if (nspi < 1)
return;
1717 int tmp1, temp_indx;
1718 int increment, currentlocn;
1720 crossSection = MALLOC(
struct SFVec2f *,
sizeof(crossSection)*nsec*2);
1724 for (tmp1=0; tmp1<nsec; tmp1++) {
1726 crossSection[currentlocn].c[0] = curve[tmp1].c[0];
1727 crossSection[currentlocn].c[1] = curve[tmp1].c[1];
1732 currentlocn += increment;
1734 if(vecapprox3f(crossSection[0].c,crossSection[nsec-1].c,.001f))
1737 printf (
"we had nsec %d coords, but now we have %d\n",nsec,currentlocn);
1745 ntri = 2 * (nspi-1) * (nsec-1);
1748 printf (
"so, we have ntri %d nspi %d nsec %d\n",ntri,nspi,nsec);
1753 circular = APPROX(spine[0].c[0], spine[nspi-1].c[0]) &&
1754 APPROX(spine[0].c[1], spine[nspi-1].c[1]) &&
1755 APPROX(spine[0].c[2], spine[nspi-1].c[2]);
1758 printf (
"tubular %d circular %d\n",tubular, circular);
1767 if (circular && tubular) {
1771 printf (
"Extrusion, turning off caps \n");
1775 if(beginCap||endCap) {
1776 if(tubular?nsec<4:nsec<3) {
1777 freewrlDie(
"Only two real vertices in crossSection. Caps not possible!");
1780 if(tubular) nctri=nsec-2;
1784 printf (
"nsec = %d, ntri = %d nctri = %d\n",nsec, ntri,nctri);
1790 while(sec+2<=nsec-1 &&
1794 APPROX(0, (crossSection[sec+1].c[0]-crossSection[0].c[0])
1795 *(crossSection[sec+2].c[1]-crossSection[0].c[1])
1796 - (crossSection[sec+1].c[1]-crossSection[0].c[1])
1797 *(crossSection[sec+2].c[0]-crossSection[0].c[0]))
1798 ) ncolinear_at_begin++, sec++;
1803 sec=tubular?(nsec-2):(nsec-1);
1805 APPROX(0, (crossSection[sec ].c[0]-crossSection[0].c[0])
1806 *(crossSection[sec-1].c[1]-crossSection[0].c[1])
1807 - (crossSection[sec ].c[1]-crossSection[0].c[1])
1808 *(crossSection[sec-1].c[0]-crossSection[0].c[0]))
1809 ) ncolinear_at_end++,sec--;
1811 nctri-= ncolinear_at_begin+ncolinear_at_end;
1815 freewrlDie(
"All in crossSection points colinear. Caps not possible!");
1819 nctri= ((beginCap)?nctri:0) + ((endCap)?nctri:0) ;
1826 max_ncoord_add=(nspi-1)*(nsec-1)
1837 rep_->ntri = ntri + nctri;
1841 cindex = rep_->cindex = MALLOC(GLuint *,
sizeof(*(rep_->cindex))*3*(rep_->ntri));
1842 coord = rep_->actualCoord = MALLOC(
float *,
sizeof(*(rep_->actualCoord))*(nspi*nsec+max_ncoord_add)*3);
1843 rep_->normal = MALLOC(
float *,
sizeof(*(rep_->normal))*3*(rep_->ntri)*3);
1844 rep_->norindex = MALLOC(GLuint *,
sizeof(*(rep_->norindex))*3*(rep_->ntri));
1851 facenormals = MALLOC(
struct SFVec3f *,
sizeof(
struct SFVec3f)*(rep_->ntri+1)/2);
1854 pointfaces = MALLOC(
int *,
sizeof(*pointfaces)*POINT_FACES*3*rep_->ntri);
1857 defaultface = MALLOC(
int *,
sizeof(*defaultface)*rep_->ntri);
1861 SCP = MALLOC(
struct SCP *,
sizeof(
struct SCP)*nspi);
1866 tcoordsize = (nctri + (ntri*2))*3;
1869 printf (
"tcoordsize is %d\n",tcoordsize);
1872 FREE_IF_NZ (rep_->GeneratedTexCoords[0]);
1873 FREE_IF_NZ (rep_->tcindex);
1875 tcoord = MALLOC(
float *,
sizeof(*(rep_->GeneratedTexCoords[0]))*tcoordsize);
1877 tcindexsize = rep_->ntri*3;
1879 printf (
"tcindexsize %d\n",tcindexsize);
1882 tcindex = MALLOC(GLuint *,
sizeof(*(rep_->tcindex))*tcindexsize);
1885 beginVals = MALLOC(
float *,
sizeof(
float) * 2 * (nsec+1)*100);
1886 endVals = MALLOC(
float *,
sizeof(
float) * 2 * (nsec+1)*100);
1888 memset((
void *)tcindex,0,tcindexsize*
sizeof(*(rep_->tcindex)));
1893 HAVETOSMOOTH = (fabs(creaseAngle)>0.0001);
1894 for (tmp = 0; tmp < 3*rep_->ntri; tmp++) {
1895 pointfaces[tmp*POINT_FACES]=0;
1903 spine_is_one_vertex=0;
1919 for(spi=0; spi<nspi;spi++){
1920 for(next_spi=spi+1;next_spi<nspi;next_spi++) {
1921 VEC_FROM_CDIFF(spine[spi],spine[next_spi],spp1);
1922 if(!APPROX(VECSQ(spp1),0))
1925 if(next_spi<nspi) SCP[next_spi].prev=next_spi-1;
1928 printf(
"spi=%d next_spi=%d\n",spi,next_spi);
1932 SCP[spi].next=next_spi;
1933 SCP[spi].prev=prev_spi;
1935 while(next_spi>spi+1) {
1937 SCP[spi].next=next_spi;
1938 SCP[spi].prev=prev_spi;
1948 printf (
" SCP[0].next = %d, nspi = %d\n",SCP[0].next,nspi);
1953 if(SCP[0].next==nspi) {
1954 spine_is_one_vertex=1;
1956 printf(
"All spine vertices are the same!\n");
1961 SCP[0].z.x=0; SCP[0].z.y=0; SCP[0].z.z=0;
1963 for(spi=1;spi<nspi;spi++) {
1964 SCP[spi].y=SCP[0].y;
1965 SCP[spi].z=SCP[0].z;
1969 for(spi=0;spi<nspi;spi++) {
1970 printf(
"SCP[%d].next=%d, SCP[%d].prev=%d\n",
1971 spi,SCP[spi].next,spi,SCP[spi].prev);
1977 while(SCP[spi].prev==-1) spi++;
1981 while(SCP[t].next==nspi) t--;
1984 printf (
"now, spi = %d, t = %d\n",spi,t);
1993 VEC_FROM_CDIFF(spine[1],spine[0],SCP[0].y);
1995 VEC_FROM_CDIFF(spine[1],spine[0],spp1);
1997 VEC_FROM_CDIFF(spine[1],spine[0],spm1);
1998 VECCP(spp1,spm1,SCP[1].z);
2012 VECCP(spp1,Yaxis,SCP[1].z);
2015 dlen_cp = veclengthd((
double*)&(SCP[1].z));
2016 if( dlen_cp < .001 )
2024 printf (
"just calculated z for spi 0\n");
2025 printf(
"SCP[0].y=[%f,%f,%f], SCP[1].z=[%f,%f,%f]\n",
2026 SCP[0].y.x,SCP[0].y.y,SCP[0].y.z,
2027 SCP[1].z.x,SCP[1].z.y,SCP[1].z.z);
2032 for(; spi<=t; spi++) {
2034 VEC_FROM_CDIFF(spine[SCP[spi].next],spine[SCP[spi].prev],SCP[spi].y);
2036 VEC_FROM_CDIFF(spine[SCP[spi].next],spine[spi],spp1);
2037 VEC_FROM_CDIFF(spine[SCP[spi].prev],spine[spi],spm1);
2038 VECCP(spp1,spm1,SCP[spi].z);
2040 printf (
"just calculated z for spi %d\n",spi);
2047 printf (
"we are circular\n");
2050 VEC_FROM_CDIFF(spine[SCP[0].next],spine[SCP[nspi-1].prev],SCP[0].y);
2052 SCP[nspi-1].y=SCP[0].y;
2055 VEC_FROM_CDIFF(spine[SCP[0].next],spine[0],spp1);
2056 VEC_FROM_CDIFF(spine[SCP[nspi-1].prev],spine[0],spm1);
2057 VECCP(spp1,spm1,SCP[0].z);
2059 SCP[nspi-1].z=SCP[0].z;
2063 printf (
"we are not circular\n");
2067 VEC_FROM_CDIFF(spine[SCP[0].next],spine[0],SCP[0].y);
2071 VEC_FROM_CDIFF(spine[nspi-1],spine[SCP[nspi-1].prev],SCP[nspi-1].y);
2074 SCP[0].z=SCP[SCP[0].next].z;
2076 SCP[nspi-1].z=SCP[SCP[nspi-1].prev].z;
2079 printf(
"SCP[0].y=[%f,%f,%f], SCP[0].z=[%f,%f,%f]\n",
2080 SCP[0].y.x,SCP[0].y.y,SCP[0].y.z,
2081 SCP[0].z.x,SCP[0].z.y,SCP[0].z.z);
2082 printf(
"SCP[1].y=[%f,%f,%f], SCP[1].z=[%f,%f,%f]\n",
2083 SCP[1].y.x,SCP[1].y.y,SCP[1].y.z,
2084 SCP[1].z.x,SCP[1].z.y,SCP[1].z.z);
2090 while(SCP[spi].prev==-1) {
2091 SCP[spi].y=SCP[0].y;
2092 SCP[spi].z=SCP[0].z;
2097 while(SCP[t].next==nspi) {
2098 SCP[t].y=SCP[nspi-1].y;
2099 SCP[t].z=SCP[nspi-1].z;
2107 pos_of_last_zvalue=-1;
2108 for(spi=0;spi<nspi;spi++) {
2109 if(pos_of_last_zvalue>=0) {
2110 if(APPROX(VECSQ(SCP[spi].z),0))
2111 SCP[spi].z= SCP[pos_of_last_zvalue].z;
2113 pos_of_last_zvalue=spi;
2115 if(!APPROX(VECSQ(SCP[spi].z),0)) {
2118 printf(
"Found z-Value!\n");
2121 for(t=spi-1; t>-1; t--)
2122 SCP[t].z=SCP[spi].z;
2123 pos_of_last_zvalue=spi;
2128 printf(
"pos_of_last_zvalue=%d\n",pos_of_last_zvalue);
2134 for(spi=(circular?2:1);spi<nspi;spi++) {
2135 if(VECPT(SCP[spi].z,SCP[spi-1].z)<0) {
2136 VECSCALE(SCP[spi].z,-1);
2138 printf(
"Extrusion.GenPloyRep: Flipped axis spi=%d\n",spi);
2144 if(pos_of_last_zvalue==-1) {
2147 printf(
"Extrusion.GenPloyRep:Whole spine is colinear!\n");
2151 spy.x=0; spy.y=1; spy.z=0;
2152 spz.x=0; spz.y=0; spz.z=1;
2154 if(!spine_is_one_vertex) {
2155 compute_spy_spz(&spy,&spz,spine,nspi);
2159 printf (
"so, spy [%f %f %f], spz [%f %f %f]\n", spy.x, spy.y,spy.z, spz.x, spz.y, spz.z);
2163 for(spi=0;spi<nspi;spi++) {
2171 for(spi=0;spi<nspi;spi++) {
2172 printf(
"SCP[%d].y=[%f,%f,%f], SCP[%d].z=[%f,%f,%f]\n",
2173 spi,SCP[spi].y.x,SCP[spi].y.y,SCP[spi].y.z,
2174 spi,SCP[spi].z.x,SCP[spi].z.y,SCP[spi].z.z);
2184 if(nsca>1 && nsca <nspi)
2185 printf(
"Extrusion.GenPolyRep: Warning!\n"
2186 "\tNumber of scaling parameters do not match the number of spines!\n"
2187 "\tWill revert to using only the first scale value.\n");
2189 if(nori>1 && nori <nspi)
2190 printf(
"Extrusion.GenPolyRep: Warning!\n"
2191 "\tNumber of orientation parameters "
2192 "do not match the number of spines!\n"
2193 "\tWill revert to using only the first orientation value.\n");
2196 for(spi = 0; spi<nspi; spi++) {
2201 spylen = 1/(float)sqrt(VECSQ(spy)); VECSCALE(spy, spylen);
2202 spzlen = 1/(float)sqrt(VECSQ(spz)); VECSCALE(spz, spzlen);
2203 spxlen = 1/(float)sqrt(VECSQ(spx)); VECSCALE(spx, spxlen);
2207 int ori = (nori==nspi ? spi : 0);
2209 if(IS_ROTATION_VEC_NOT_NORMAL(orientation[ori]))
2210 printf(
"Extrusion.GenPolyRep: Warning!\n"
2211 "\tRotationvector #%d not normal!\n"
2212 "\tWon`t correct it, because it is bad VRML`97.\n",
2215 MATRIX_FROM_ROTATION(orientation[ori],m);
2221 for(sec = 0; sec<nsec; sec++) {
2223 float ptx = crossSection[sec].c[0];
2224 float ptz = crossSection[sec].c[1];
2226 int sca = (nsca==nspi ? spi : 0);
2227 ptx *= node->scale.p[sca].c[0];
2228 ptz *= node->scale.p[sca].c[1];
2241 beginVals[sec*2+0] = ptx;
2242 beginVals[sec*2+1] = ptz;
2243 }
else if (spi == (nspi-1)) {
2245 endVals[(sec*2)+0]=ptx;
2246 endVals[(sec*2)+1]=ptz;
2252 coord[(sec+spi*nsec)*3+0] =
2253 (
float)(spx.x * point.x + spy.x * point.y + spz.x * point.z)
2254 + node->spine.p[spi].c[0];
2255 coord[(sec+spi*nsec)*3+1] =
2256 (
float)(spx.y * point.x + spy.y * point.y + spz.y * point.z)
2257 + node->spine.p[spi].c[1];
2258 coord[(sec+spi*nsec)*3+2] =
2259 (
float)(spx.z * point.x + spy.z * point.y + spz.z * point.z)
2260 + node->spine.p[spi].c[2];
2287 int Atex, Btex, Ctex, Dtex, Etex, Ftex;
2297 printf(
"Coords: \n");
2299 for(x=0; x<nsec; x++) {
2300 for(z=0; z<nspi; z++) {
2301 int xxx = 3*(x+z*nsec);
2302 printf(
"coord: %d [%f %f %f] ",(x+z*nsec),
2303 coord[xxx], coord[xxx+1], coord[xxx+2]);
2314 for(x=0; x<nsec-1; x++) {
2315 for(z=0; z<nspi-1; z++) {
2322 Atex = A; Btex = B; Ctex = C; Dtex = D;
2347 VEC_FROM_COORDDIFF(coord,C,coord,A,ac);
2348 VEC_FROM_COORDDIFF(coord,D,coord,B,bd);
2350 if(sqrt(VECSQ(ac))>sqrt(VECSQ(bd))) {
2351 E=B; F=D; Etex=Btex; Ftex=Dtex;
2353 E=C; F=A; Etex=Ctex; Ftex=Atex;
2359 VEC_FROM_COORDDIFF(coord,B,coord,A,ab);
2360 VEC_FROM_COORDDIFF(coord,D,coord,C,cd);
2363 printf(
"ab=[%f,%f,%f],cd=[%f,%f,%f]\n",
2364 ab.x,ab.y,ab.z,cd.x,cd.y,cd.z);
2365 printf(
"Orig: %d %d [%f %f %f] [%f %f %f] (%d, %d, %d) \n",
2367 coord[D*3], coord[D*3+1], coord[D*3+2],
2368 coord[C*3], coord[C*3+1], coord[C*3+2],
2373 denominator= ab.y*cd.x-ab.x*cd.y;
2374 numerator = (-ac.x)*cd.y-(-ac.y)*cd.x;
2377 if(!APPROX(denominator,0)) {
2378 u=numerator/denominator;
2379 r=((-ac.x)*ab.y-(-ac.y)*ab.x)/denominator;
2382 if(APPROX(numerator,0)) {
2384 denominator=ab.z*cd.x-ab.x*cd.z;
2385 numerator = (-ac.x)*cd.z-(-ac.z)*cd.x;
2386 if(!APPROX(denominator,0)) {
2387 u=numerator/denominator;
2388 r=((-ac.x)*ab.y-(-ac.y)*ab.x)/denominator;
2393 printf(
"u=%f, r=%f\n",u,r);
2396 if(u>=0 && u<=1 && r>=0 && r<=1
2397 && APPROX((-ac.x)+u*ab.x,r*cd.x)
2398 && APPROX((-ac.y)+u*ab.y,r*cd.y)
2399 && APPROX((-ac.z)+u*ab.z,r*cd.z)) {
2402 printf(
"Intersection found at P=[%f,%f,%f]!\n",
2404 coord[A*3+1]+u*ab.y,
2409 coord[(ncoord)*3 ]=coord[A*3 ]+(
float)(u*ab.x);
2410 coord[(ncoord)*3+1]=coord[A*3+1]+(
float)(u*ab.y);
2411 coord[(ncoord)*3+2]=coord[A*3+2]+(
float)(u*ab.z);
2423 Elev_Tri(triind*3, this_face, D,A,E, TRUE , rep_, facenormals, pointfaces,ccw);
2425 tcindex[triind*3] = (GLuint)Dtex;
2426 tcindex[triind*3+2] = (GLuint)Etex;
2427 tcindex[triind*3+1] = (GLuint)Atex;
2429 defaultface[triind] = this_face;
2434 Elev_Tri(triind*3, this_face, B, C, F, TRUE, rep_, facenormals, pointfaces,ccw);
2436 tcindex[triind*3] = (GLuint)Btex;
2437 tcindex[triind*3+1] = (GLuint)Ctex;
2438 tcindex[triind*3+2] = (GLuint)Ftex;
2440 if ((triind*3+2) >= tcindexsize)
2441 printf (
"INTERNAL ERROR: Extrusion - tcindex size too small!\n");
2442 defaultface[triind] = this_face;
2450 for (tmp=0; tmp<(triind*3); tmp++) {
2452 normalize_ifs_face (&rep_->normal[tmp*3],
2453 facenormals, pointfaces, cindex[tmp],
2454 defaultface[tmp/3], creaseAngle);
2456 int iiface = defaultface[tmp/3];
2457 veccopy3f(&rep_->normal[tmp*3+0],facenormals[iiface].c);
2462 rep_->norindex[tmp] = (GLuint)tmp;
2465 end_of_sides = triind*3;
2477 if (tubular) endpoint = nsec-3-ncolinear_at_end;
2478 else endpoint = nsec-2-ncolinear_at_end;
2485 triind_start = triind;
2487 for(x=0+ncolinear_at_begin; x<endpoint; x++) {
2488 Elev_Tri(triind*3, this_face, 0, x+2, x+1, TRUE , rep_, facenormals, pointfaces,ccw);
2489 defaultface[triind] = this_face;
2490 Extru_tex(triind*3, tci_ct, 0 , +x+2, x+1, tcindex ,ccw,tcindexsize);
2494 Extru_ST_map(triind_start,0+ncolinear_at_begin,endpoint,
2495 beginVals,nsec,tcindex, cindex, tcoord, tcoordsize);
2496 tci_ct+=endpoint-(0+ncolinear_at_begin);
2497 triind_start+=endpoint-(0+ncolinear_at_begin);
2502 triind_start = triind;
2504 for(x=0+ncolinear_at_begin; x<endpoint; x++) {
2505 Elev_Tri(triind*3, this_face, 0 +(nspi-1)*nsec,
2506 x+1+(nspi-1)*nsec,x+2+(nspi-1)*nsec,
2507 TRUE , rep_, facenormals, pointfaces,ccw);
2508 defaultface[triind] = this_face;
2509 Extru_tex(triind*3, tci_ct, 0+(nspi-1)*nsec,
2512 tcindex,ccw,tcindexsize);
2516 Extru_ST_map(triind_start,0+ncolinear_at_begin,endpoint,
2517 endVals, nsec, tcindex, cindex, tcoord, tcoordsize);
2522 if(beginCap || endCap) {
2532 ttglobal tg = gglobal();
2533 int max_combiner = 30;
2534 tess_vs=MALLOC(
int *,
sizeof(*(tess_vs)) * (nsec - 3 - ncolinear_at_end + max_combiner) * 3);
2535 int last_vertex = 2*nsec + (nspi-1)*nsec;
2537 if (tubular) endpoint = nsec-1-ncolinear_at_end;
2538 else endpoint = nsec-ncolinear_at_end;
2540 set_tess_callbacks(1);
2541 cbdata.coords = rep_->actualCoord;
2542 cbdata.counter = &last_vertex;
2543 cbdata.ria = tess_vs;
2544 cbdata.riaindex = &x;
2547 tg->Tess.global_IFS_Coord_count = 0;
2548 gluTessNormal(tg->Tess.text_tessobj,0.0,1.0,0.0);
2551 gluTessBeginPolygon( tg->Tess.global_tessobj, &cbdata );
2552 gluTessBeginContour( tg->Tess.global_tessobj );
2554 for(x=0+ncolinear_at_begin; x<endpoint; x++) {
2556 c1 = (
struct SFVec3f *) &rep_->actualCoord[3*x];
2560 tess_v[0] = c1->c[0]; tess_v[1] = c1->c[1]; tess_v[2] = c1->c[2];
2562 FW_GLU_TESS_VERTEX(tg->Tess.global_tessobj,tess_v,&tess_vs[x]);
2565 gluTessEndContour( tg->Tess.global_tessobj );
2566 gluTessEndPolygon( tg->Tess.global_tessobj );
2568 verify_global_IFS_Coords(ntri*3);
2570 for (x=0; x<tg->Tess.global_IFS_Coord_count; x+=3) {
2573 Elev_Tri(triind*3, this_face, tg->Tess.global_IFS_Coords[x],
2574 tg->Tess.global_IFS_Coords[x+2], tg->Tess.global_IFS_Coords[x+1],
2575 TRUE , rep_, facenormals, pointfaces,ccw);
2576 defaultface[triind] = this_face;
2580 Extru_check_normal (facenormals,this_face,-1,rep_,ccw);
2586 tg->Tess.global_IFS_Coord_count = 0;
2588 gluTessNormal(tg->Tess.text_tessobj,0.0,1.0,0.0);
2590 gluTessBeginPolygon( tg->Tess.global_tessobj, &cbdata );
2591 gluTessBeginContour( tg->Tess.global_tessobj );
2593 for(x=0+ncolinear_at_begin; x<endpoint; x++) {
2594 c1 = (
struct SFVec3f *) &rep_->actualCoord[3*(x+(nspi-1)*nsec)];
2595 tess_v[0] = c1->c[0]; tess_v[1] = c1->c[1]; tess_v[2] = c1->c[2];
2596 tess_vs[x] = x+(nspi-1)*nsec;
2597 FW_GLU_TESS_VERTEX(tg->Tess.global_tessobj,tess_v,&tess_vs[x]);
2600 gluTessEndContour( tg->Tess.global_tessobj );
2601 gluTessEndPolygon( tg->Tess.global_tessobj );
2603 verify_global_IFS_Coords(ntri*3);
2605 for (x=0; x<tg->Tess.global_IFS_Coord_count; x+=3) {
2606 Elev_Tri(triind*3, this_face, tg->Tess.global_IFS_Coords[x],
2607 tg->Tess.global_IFS_Coords[x+1], tg->Tess.global_IFS_Coords[x+2],
2608 TRUE , rep_, facenormals, pointfaces,ccw);
2609 defaultface[triind] = this_face;
2613 Extru_check_normal (facenormals,this_face,1,rep_,ccw);
2618 set_tess_callbacks(0);
2621 FREE_IF_NZ (tess_vs);
2631 for (tmp=end_of_sides; tmp<(triind*3); tmp++) {
2632 int iiface = defaultface[tmp/3];
2633 veccopy3f(&rep_->normal[tmp*3+0],facenormals[iiface].c);
2637 rep_->norindex[tmp] = (GLuint)tmp;
2642 if (tcoordsize <= ((nsec-1)+(nspi-1)*(nsec-1)*3+2)) {
2643 printf (
"INTERNAL ERROR: Extrusion side tcoord calcs nspi %d nsec %d tcoordsize %d\n",
2644 nspi,nsec,tcoordsize);
2646 for(sec=0; sec<nsec; sec++) {
2647 for(spi=0; spi<nspi; spi++) {
2651 tcoord[(sec+spi*nsec)*3+0] = (
float) sec/(nsec-1);
2652 tcoord[(sec+spi*nsec)*3+1] = 0;
2653 tcoord[(sec+spi*nsec)*3+2] = (
float) spi/(nspi-1);
2659 printf (
"done, lets free\n");
2663 FREE_IF_NZ (defaultface);
2664 FREE_IF_NZ (pointfaces);
2665 FREE_IF_NZ (facenormals);
2666 FREE_IF_NZ (crossSection);
2668 FREE_IF_NZ (beginVals);
2669 FREE_IF_NZ (endVals);
2673 stream_extrusion_texture_coords (rep_, tcoord, tcindex);
2676 FREE_IF_NZ (tcoord);
2677 FREE_IF_NZ (tcindex);
2681 printf(
"Extrusion.GenPloyRep: triind=%d ntri=%d nctri=%d "
2682 "ncolinear_at_begin=%d ncolinear_at_end=%d\n",
2683 triind,ntri,nctri,ncolinear_at_begin,ncolinear_at_end);
2685 printf (
"end VRMLExtrusion.pm\n");