33#include <libFreeWRL.h>
35#include "../vrml_parser/Structs.h"
36#include "../main/headers.h"
39#include "LinearAlgebra.h"
40#include "../opengl/Frustum.h"
41#include "../opengl/Material.h"
42#include "Component_Geometry3D.h"
43#include "../opengl/OpenGL_Utils.h"
44#include "../opengl/Textures.h"
46#include "Component_Shape.h"
47#include "../scenegraph/RenderFuncs.h"
48#include "../vrml_parser/CRoutes.h"
51#if defined(_MSC_VER) && _MSC_VER < 1500
60void *Component_NURBS_constructor(){
65void Component_NURBS_init(
struct tComponent_NURBS *t){
68 t->prv = Component_NURBS_constructor();
182 rep->transparency = 0;
184 glDeleteBuffers(VBO_COUNT, rep->VBO_buffers);
185 FREE_IF_NZ(rep->actualCoord);
186 FREE_IF_NZ(rep->cindex);
187 FREE_IF_NZ(rep->colindex);
188 FREE_IF_NZ(rep->GeneratedTexCoords[0]);
189 FREE_IF_NZ(rep->norindex);
190 FREE_IF_NZ(rep->normal);
191 FREE_IF_NZ(rep->tcindex);
208 polyrep->streamed = FALSE;
211 polyrep->minVals[0] = 999999.9f;
212 polyrep->minVals[1] = 999999.9f;
213 polyrep->minVals[2] = 999999.9f;
214 polyrep->maxVals[0] = -999999.9f;
215 polyrep->maxVals[1] = -999999.9f;
216 polyrep->maxVals[2] = -999999.9f;
218 for (i=0; i<VBO_COUNT; i++)
219 polyrep->VBO_buffers[i] = 0;
222 glGenBuffers(1,&polyrep->VBO_buffers[VERTEX_VBO]);
223 glGenBuffers(1,&polyrep->VBO_buffers[INDEX_VBO]);
238int uniformKnot(
int n,
int p,
float *U){
243 uniform = 1.0f/(float)(n-p);
244 for(j=0;j<p;k++,j++){
248 for(j=0;j<mm;j++,k++){
251 for(j=0;j<p;j++,k++){
257 printf(
" U[%d]=%f",j,U[j]);
263int FindSpan(
int n,
int p,
float u,
float *U)
291 int i, span, m, order;
297 if(u >= U[i] && u < U[i+1])
304 if(u == U[n])
return n-1;
305 low = p; high = n+1; mid = (low+high)/2;
306 while(u < U[mid] || u >= U[mid+1]){
307 if(u < U[mid]) high = mid;
309 mid = (low + high)/2;
315int BasisFuns(
int span,
float u,
int p,
float *U,
float *N){
328 float left[5], right[5], saved, temp;
332 left[j] = u - U[span+1 - j];
333 right[j] = U[span+j] - u;
339 temp = N[r]/(right[r+1]+left[j-r]);
340 N[r] = saved + right[r+1]*temp;
341 saved = left[j-r]*temp;
349int CurvePoint(
int n,
int p,
float* U,
float *Pw,
float u,
float *C )
370 span = FindSpan(n,p,u,U);
371 BasisFuns(span,u,p,U,N);
373 for(i=0;i<4;i++) Cw[i] = 0.0f;
377 Cw[i] += N[j]*Pw[(span-p+j)*4 + i];
396int SurfacePoint(
int n,
int p,
float *U,
397 int m,
int q,
float *V,
398 float *Pw,
float u,
float v,
float *S)
417 int uspan, vspan, i, l, k;
418 float Nu[100], Nv[100], temp[6][4], Sw[4];
420 uspan = FindSpan(n,p,u,U);
421 BasisFuns(uspan,u,p,U,Nu);
422 vspan = FindSpan(m,q,v,V);
423 BasisFuns(vspan,v,q,V,Nv);
430 temp[l][i] += Nu[k]*Pw[((uspan-p+k)*n + (vspan-q+l))*4 + i];
434 for(i=0;i<4;i++) Sw[i] = 0.0f;
437 Sw[i] += Nv[l]*temp[l][i];
445#include <OpenGL/gl.h>
446#include <OpenGL/glu.h>
449#include <libnurbs2.h>
458#define NNC(A) NNC0(X3D_NODE(A))
459#define MNC(A) MNC0(X3D_NODE(A))
460#define MNX(A) MNX0(X3D_NODE(A))
461#define PPX(A) getTypeNode(X3D_NODE(A))
463void CALLBACK nurbsError(GLenum errorCode)
469 printf(
"ouch from nurbsError\n");
474void CALLBACK nurbscurveBegincb(GLenum type,
void *ud)
477 if(DEBGC) printf(
"nurbscurveBegin\n");
479void CALLBACK nurbscurveVertexcb(GLfloat *vertex,
void *ud)
484 ns = node->__points.n;
485 np = node->__numPoints;
488 node->__points.p = REALLOC(node->__points.p,ns *
sizeof(
struct SFVec3f));
489 node->__points.n = ns;
491 pp = &node->__points.p[np];
493 pp->c[i] = vertex[i];
494 node->__numPoints ++;
496 if(DEBGC) printf(
"nurbscurveVertex\n");
498void CALLBACK nurbscurveNormalcb(GLfloat *nml,
void *ud)
501 if(DEBGC) printf(
"nurbscurveNormal\n");
503void CALLBACK nurbscurveEndcb(
void *ud)
507 if(DEBGC) printf(
"nurbscurveEnd\n");
512int generateUniformKnotVector(
int order,
int ncontrol,
float *knots){
528 m = ncontrol - order;
530 uniform = 1.0f/(float)(m + 1);
531 for(j=0;j<order;k++,j++){
534 for(j=0;j<m;j++,k++){
535 knots[k] =uniform*(float)(j+1);
537 for(j=0;j<order;j++,k++){
542int knotsOK(
int order,
int ncontrol,
int nknots,
double *knots){
545 if(nknots < 2 || nknots != ncontrol + order )
549 double lastval = knots[0];
550 for(i=1;i<nknots;i++){
551 if(lastval == knots[i]) nconsec++;
555 if(knots[i] < lastval)
563int knotsOKf(
int order,
int ncontrol,
int nknots,
float *knots){
566 if(nknots < 2 || nknots != ncontrol + order )
570 double lastval = knots[0];
571 for(i=1;i<nknots;i++){
572 if(lastval == knots[i]) nconsec++;
576 if(knots[i] < lastval)
586 if(node->point.n && !node->controlPoint.n){
589 node->controlPoint.p = MALLOC(
struct SFVec2d*,node->point.n *
sizeof(
struct SFVec2d));
590 for(i=0;i<node->point.n;i++)
591 float2double(node->controlPoint.p[i].c,node->point.p[i].c,2);
599 GLfloat *xyzw, *knots;
602 if(node->controlPoint){
603 if(node->controlPoint->_nodeType == NODE_CoordinateDouble){
607 xyzw = MALLOC(
void *, n * 4 *
sizeof(GLfloat));
608 for(i=0;i<mfd->n;i++){
610 xyzw[i*4 + j] = (float) mfd->p[i].c[j];
613 }
else if(node->controlPoint->_nodeType == NODE_Coordinate){
617 xyzw = MALLOC(
void *, n * 4 *
sizeof(GLfloat));
618 for(i=0;i<mff->n;i++){
620 xyzw[i*4 + j] = mff->p[i].c[j];
627 if(node->weight.n && node->weight.n == n){
630 m = min(node->weight.n, n);
632 im = i < m ? i : m-1;
633 w = node->weight.p[im];
634 xyzw[i*4 + 3] = (float)w;
637 for(i=0;i<n;i++) xyzw[i*4 + 3] = 1.0;
640 if(knotsOK(node->order,n,node->knot.n,node->knot.p)){
643 knots = MALLOC(
void *, nk *
sizeof(GLfloat));
645 knots[i] = (GLfloat)node->knot.p[i];
654 nk = n + node->order ;
656 knots = MALLOC(
void *, nk *
sizeof(GLfloat));
657 generateUniformKnotVector(node->order,n, knots);
660 printf(
"bad knot vector, replacing with:\n");
662 printf(
"[%d]=%f \n",ii,knots[ii]);
668 if(n && nk && nk >= n){
671 mtess = node->order + 1;
672 ntess = node->tessellation;
673 theNurb = gluNewNurbsRenderer();
674 gluNurbsProperty(theNurb, GLU_NURBS_MODE, GLU_NURBS_TESSELLATOR);
675 gluNurbsCallbackData(theNurb,(GLvoid*)node);
681 double model[16], proj[16];
682 float modelf[16], projf[16];
688 node->__points.p = MALLOC(
void *,
sizeof(
struct SFVec3f)*n*10);
689 node->__points.n = n*10;
691 gluNurbsProperty(theNurb, GLU_SAMPLING_TOLERANCE, (
float)(mtess));
693 gluNurbsProperty(theNurb,GLU_SAMPLING_METHOD,GLU_PATH_LENGTH);
695 gluNurbsProperty(theNurb,GLU_SAMPLING_METHOD,GLU_PARAMETRIC_TOLERANCE);
696 gluNurbsProperty(theNurb, GLU_AUTO_LOAD_MATRIX,GL_FALSE);
698 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, model);
699 FW_GL_GETDOUBLEV(GL_PROJECTION_MATRIX, proj);
700 FW_GL_GETINTEGERV(GL_VIEWPORT, viewPort);
702 modelf[i] = (float)model[i];
703 projf[i] = (float)proj[i];
705 gluLoadSamplingMatrices(theNurb,modelf,projf,viewPort);
712 mtess = max(mtess,ntess+1);
714 mtess = max(mtess,(-ntess * n) + 1);
716 mtess = max(mtess,2*n + 1);
717 mtess = (int)((
float)mtess * node->_tscale);
718 node->__points.p = MALLOC(
void *,
sizeof(
struct SFVec3f)*mtess+1);
719 node->__points.n = mtess;
720 gluNurbsProperty(theNurb,GLU_SAMPLING_METHOD,GLU_DOMAIN_DISTANCE);
721 gluNurbsProperty(theNurb,GLU_U_STEP,(GLfloat)mtess);
723 gluNurbsProperty(theNurb, GLU_DISPLAY_MODE, GLU_FILL);
724 gluNurbsCallback(theNurb, GLU_ERROR, nurbsError);
725 gluNurbsCallback(theNurb, GLU_NURBS_BEGIN_DATA, nurbscurveBegincb);
726 gluNurbsCallback(theNurb, GLU_NURBS_VERTEX_DATA, nurbscurveVertexcb);
727 gluNurbsCallback(theNurb, GLU_NURBS_NORMAL_DATA, nurbscurveNormalcb);
728 gluNurbsCallback(theNurb, GLU_NURBS_END_DATA, nurbscurveEndcb);
729 gluBeginCurve(theNurb);
730 node->__numPoints = 0;
731 gluNurbsCurve(theNurb,nk,knots,4,xyzw,node->order,GL_MAP1_VERTEX_4);
732 gluEndCurve(theNurb);
733 gluDeleteNurbsRenderer(theNurb);
734 node->__points.n = node->__numPoints;
743 if (node->__numPoints>0) {
745 setExtent( node->EXTENT_MAX_X, node->EXTENT_MIN_X,
746 node->EXTENT_MAX_Y, node->EXTENT_MIN_Y, 0.0f,0.0f,X3D_NODE(node));
753 FW_GL_VERTEX_POINTER (3,GL_FLOAT,0,(GLfloat *)node->__points.p);
754 sendArraysToGPU (GL_LINE_STRIP, 0, node->__numPoints);
755 tg->Mainloop.trisThisLoop += node->__numPoints;
761 int nc, nu, nku, nkv, nv, i,j;
762 float *knotsu, *knotsv, *xyzw;
765 mff = &node->controlPoint;
767 xyzw = MALLOC(
void *, nc * 4 *
sizeof(GLfloat));
768 for(i=0;i<mff->n;i++){
770 xyzw[i*4 + j] = mff->p[i].c[j];
772 xyzw[i*4 + 2] = 0.0f;
773 xyzw[i*4 + 3] = 1.0f;
775 nu = node->uDimension;
776 nv = node->vDimension;
777 if(node->weight.n && node->weight.n == nc){
780 m = min(node->weight.n, nc);
782 im = i < m ? i : m-1;
783 w = node->weight.p[im];
784 xyzw[i*4 + 3] = (float) w;
787 for(i=0;i<nc;i++) xyzw[i*4 + 3] = 1.0;
789 nu = node->uDimension;
790 nv = node->vDimension;
793 if(knotsOK(node->uOrder,nu,node->uKnot.n,node->uKnot.p)){
797 knotsu = MALLOC(
void *, nku *
sizeof(GLfloat));
799 knotsu[i] = (GLfloat)node->uKnot.p[i];
803 printf(
"good u knot vector nk=%d\n",nku);
804 for(ii=0;ii<nku;ii++)
805 printf(
"[%d]=%f \n",ii,knotsu[ii]);
811 nku = nu + node->uOrder ;
813 knotsu = MALLOC(
void *, nku *
sizeof(GLfloat));
814 generateUniformKnotVector(node->uOrder,nu, knotsu);
817 printf(
"bad u knot vector given, replacing with:\n");
818 for(ii=0;ii<nku;ii++)
819 printf(
"[%d]=%f \n",ii,knotsu[ii]);
825 if(knotsOK(node->vOrder,nv,node->vKnot.n,node->vKnot.p)){
828 knotsv = MALLOC(
void *, nkv *
sizeof(GLfloat));
830 knotsv[i] = (GLfloat)node->vKnot.p[i];
834 printf(
"good v knot vector nk=%d\n",nkv);
835 for(ii=0;ii<nkv;ii++)
836 printf(
"[%d]=%f \n",ii,knotsv[ii]);
842 nkv = nv + node->vOrder ;
844 knotsv = MALLOC(
void *, nkv *
sizeof(GLfloat));
845 generateUniformKnotVector(node->vOrder,nv, knotsv);
848 printf(
"bad v knot vector given, replacing with:\n");
849 for(ii=0;ii<nkv;ii++)
850 printf(
"[%d]=%f \n",ii,knotsv[ii]);
853 if(!knotsOKf(node->vOrder,nv,nkv,knotsv))
854 printf(
"ouch still not right knot vector\n");
857 node->_uKnot.p = knotsu;
858 node->_uKnot.n = nku;
859 node->_vKnot.p = knotsv;
860 node->_vKnot.n = nkv;
861 node->_controlPoint.p = (
struct SFVec4f*)xyzw;
862 node->_controlPoint.n = nc;
866int getNurbsSurfacePoint(
struct X3D_Node *nurbsSurfaceNode,
float *uv,
float *xyz){
868 if(nurbsSurfaceNode){
869 switch(nurbsSurfaceNode->_nodeType){
870 case NODE_NurbsTextureCoordinate:
873 if(NNC(node)) compile_NurbsTextureCoordinate(node);
874 ret = SurfacePoint( node->uDimension,node->uOrder-1,node->_uKnot.p,
875 node->vDimension,node->vOrder-1,node->_vKnot.p,
876 (
float *)node->_controlPoint.p,uv[0],uv[1],xyz);
879 case NODE_NurbsPatchSurface:
881 case NODE_NurbsTrimmedSurface:
921void CALLBACK nurbssurfBegincb(GLenum type,
void *ud)
923 struct stripState ss;
925 if(0)
if(DEBG) printf(
"callback nurbsSurfaceBegin\n");
927 printf(
"nurbssurfBegin type = ");
929 case GL_QUAD_STRIP: printf(
"QUAD_STRIP");
break;
930 case GL_TRIANGLE_STRIP: printf(
"TRIANGLE_STRIP");
break;
931 case GL_TRIANGLE_FAN: printf(
"TRIANGLE_FAN");
break;
932 case GL_TRIANGLES: printf(
"TRIANGLES");
break;
934 printf(
"not sure %x %d",type,type);
948 vector_pushBack(
struct stripState,strips,ss);
950void CALLBACK nurbssurfVertexcb(GLfloat *vertex,
void *ud)
952 struct stripState *ss;
955 ss = vector_get_ptr(
struct stripState,strips,strips->n -1);
956 memcpy(&pp,vertex,
sizeof(
struct SFVec3f));
957 vector_pushBack(
struct SFVec3f,&ss->pv,pp);
960 if(0) printf(
"callback nurbssurfVertex %f %f %f\n",vertex[0],vertex[1],vertex[2]);
962void CALLBACK nurbssurfNormalcb(GLfloat *nml,
void *ud)
964 struct stripState *ss;
967 ss = vector_get_ptr(
struct stripState,strips,strips->n -1);
968 memcpy(&pp,nml,
sizeof(
struct SFVec3f));
969 vector_pushBack(
struct SFVec3f,&ss->nv,pp);
972 if(0) printf(
"callback nurbssurfNormal\n");
974void CALLBACK nurbssurfEndcb(
void *ud)
976 struct stripState *ss;
978 ss = vector_get_ptr(
struct stripState,strips,strips->n -1);
981 printf(
"nurbssurfEnd #p %d #n %d\n",ss->pv.n, ss->nv.n);
982 for(i=0;i<ss->pv.n;i++){
984 printf(
"%f %f %f\n",pp.c[0],pp.c[1],pp.c[2]);
987 if(0)
if(DEBG) printf(
"callback nurbsSurfaceEnd\n");
990void CALLBACK nurbssurfTexcoordcb(GLfloat *tCrd,
void *ud){
991 static int count = 0;
992 struct stripState *ss;
995 ss = vector_get_ptr(
struct stripState,strips,strips->n -1);
996 memcpy(&tp,tCrd,
sizeof(
struct SFVec2f));
997 vector_pushBack(
struct SFVec2f,&ss->tv,tp);
1004 printf(
"callback nurbssufTexcoordcb\n");
1009#define GL_QUAD_STRIP 0x0008
1011static int USETXCOORD = 1;
1015 int i, j, npoints, np, ni, ntri, nindex, ntc;
1016 struct stripState *ss;
1019 GLuint *cindex, *norindex, *tcindex;
1020 float *tcoord = NULL;
1028 polyrep = node->_intern;
1029 FREE_IF_NZ(polyrep->cindex);
1030 FREE_IF_NZ(polyrep->actualCoord);
1031 FREE_IF_NZ(polyrep->GeneratedTexCoords[0]);
1032 FREE_IF_NZ(polyrep->colindex);
1033 FREE_IF_NZ(polyrep->color);
1034 FREE_IF_NZ(polyrep->norindex);
1035 FREE_IF_NZ(polyrep->normal);
1036 FREE_IF_NZ(polyrep->flat_normal);
1037 FREE_IF_NZ(polyrep->tcindex);
1038 FREE_IF_NZ(polyrep->wire_indices);
1042 node->_intern = create_polyrep();
1044 rep_ = polyrep = node->_intern;
1055 rep_->ntexdim[0] = 2;
1056 rep_->tcoordtype = NODE_TextureCoordinate;
1061 npoints = nindex = ntc = 0;
1062 for(i=0;i<strips->n;i++){
1063 ss = vector_get_ptr(
struct stripState,strips,i);
1064 npoints += ss->pv.n;
1067 case GL_QUAD_STRIP: nindex += (ss->pv.n -2)/2 * 5;
break;
1068 case GL_TRIANGLE_STRIP: nindex += (ss->pv.n -2);
break;
1069 case GL_TRIANGLE_FAN: nindex += (ss->pv.n -2);
break;
1070 case GL_TRIANGLES: nindex += (ss->pv.n -2);
break;
1072 nindex += (ss->pv.n -2);
1078 rep_->actualCoord = MALLOC(
void *, npoints * 3 *
sizeof(
float));
1079 rep_->normal = MALLOC(
void *, npoints * 3 *
sizeof(
float));
1087 rep_->ntri = ntri = nindex;
1091 cindex = rep_->cindex = MALLOC(GLuint *,
sizeof(GLuint)*3*(ntri));
1092 norindex = rep_->norindex = MALLOC(GLuint *,
sizeof(GLuint)*3*ntri);
1094 tcindex = rep_->tcindex = MALLOC(GLuint*,
sizeof(GLuint)*3*(ntri));
1099 tcoord = MALLOC (
float *,
sizeof (
float) * ntri * 2 * 3);
1106 for(i=0;i<strips->n;i++){
1107 ss = vector_get_ptr(
struct stripState,strips,i);
1109 memcpy(&rep_->actualCoord[np*3],ss->pv.data,ss->pv.n * 3 *
sizeof(
float));
1110 memcpy(&rep_->normal[np*3],ss->nv.data,ss->nv.n * 3 *
sizeof(
float));
1111 if(USETXCOORD && tcoord) memcpy(&tcoord[np*2],ss->tv.data,ss->tv.n * 2 *
sizeof(
float));
1114 for(j=0;j<ss->pv.n -2;j+=2){
1115 rep_->cindex[ni++] = np+j;
1116 rep_->cindex[ni++] = np+j+1;
1117 rep_->cindex[ni++] = np+j+3;
1119 rep_->cindex[ni++] = np+j+3;
1120 rep_->cindex[ni++] = np+j+2;
1121 rep_->cindex[ni++] = np+j;
1124 memcpy(&rep_->norindex[ntri*3],&rep_->cindex[ntri*3],2*3*
sizeof(
int));
1125 if(USETXCOORD) memcpy(&rep_->tcindex[ntri*3],&rep_->cindex[ntri*3],2*3*
sizeof(
int));
1129 case GL_TRIANGLE_STRIP:
1130 nindex += (ss->pv.n -2);
1132 case GL_TRIANGLE_FAN:
1134 for(j=0;j<ss->pv.n -2;j+=1){
1135 rep_->cindex[ni++] = np;
1136 rep_->cindex[ni++] = np+j+1;
1137 rep_->cindex[ni++] = np+j+2;
1138 memcpy(&rep_->norindex[ntri*3],&rep_->cindex[ntri*3],3*
sizeof(
int));
1139 if(USETXCOORD) memcpy(&rep_->tcindex[ntri*3],&rep_->cindex[ntri*3],3*
sizeof(
int));
1144 nindex += (ss->pv.n -2);
1147 nindex += (ss->pv.n -2);
1152 if(node->texCoord && node->texCoord->_nodeType == NODE_NurbsTextureCoordinate){
1153 static FILE *fp = NULL;
1159 xyz[0] = tcoord[i*2 + 1];
1160 xyz[1] = tcoord[i*2 + 0];
1162 xyz[3] = tcoord[i*2 + 3];
1163 getNurbsSurfacePoint(node->texCoord, xyz, stru);
1165 tcoord[i*2 + 0] = stru[0];
1166 tcoord[i*2 + 1] = stru[1];
1176 tcnode->point.p = (
struct SFVec2f*)tcoord;
1177 tcnode->point.n = np;
1178 if(0)
for(i=0;i<tcnode->point.n;i++){
1179 printf(
"%d %f %f\n",i,tcnode->point.p[i].c[0],tcnode->point.p[i].c[1]);
1187 if (polyrep->ntri != 0) {
1189 stream_polyrep(node, NULL,NULL,NULL,NULL, tcnode);
1192 FREE_IF_NZ(tcnode->point.p);
1195 polyrep->irep_change = node->_change;
1220 int i,j, n, nu, nv, nku, nkv;
1221 GLfloat *xyzw, *knotsu, *knotsv;
1224 nku = nkv = nu = nv = n = 0;
1225 xyzw = knotsu = knotsv = NULL;
1232 if(node->controlPoint){
1233 if(node->controlPoint->_nodeType == NODE_CoordinateDouble){
1237 xyzw = MALLOC(
void *, n * 4 *
sizeof(GLfloat));
1238 for(i=0;i<mfd->n;i++){
1240 xyzw[i*4 + j] = (float)mfd->p[i].c[j];
1243 }
else if(node->controlPoint->_nodeType == NODE_Coordinate){
1247 xyzw = MALLOC(
void *, n * 4 *
sizeof(GLfloat));
1248 for(i=0;i<mff->n;i++){
1250 xyzw[i*4 + j] = mff->p[i].c[j];
1257 if(node->weight.n && node->weight.n == n){
1260 m = min(node->weight.n, n);
1262 im = i < m ? i : m-1;
1263 w = node->weight.p[im];
1264 xyzw[i*4 + 3] = (float)w;
1267 for(i=0;i<n;i++) xyzw[i*4 + 3] = 1.0;
1269 nu = node->uDimension;
1270 nv = node->vDimension;
1273 if(knotsOK(node->uOrder,nu,node->uKnot.n,node->uKnot.p)){
1276 nku = node->uKnot.n;
1277 knotsu = MALLOC(
void *, nku *
sizeof(GLfloat));
1279 knotsu[i] = (GLfloat)node->uKnot.p[i];
1283 printf(
"good u knot vector nk=%d\n",nku);
1284 for(ii=0;ii<nku;ii++)
1285 printf(
"[%d]=%f \n",ii,knotsu[ii]);
1290 static int once = 0;
1291 nku = nu + node->uOrder ;
1293 knotsu = MALLOC(
void *, nku *
sizeof(GLfloat));
1294 generateUniformKnotVector(node->uOrder,nu, knotsu);
1297 printf(
"bad u knot vector given, replacing with:\n");
1298 for(ii=0;ii<nku;ii++)
1299 printf(
"[%d]=%f \n",ii,knotsu[ii]);
1305 if(knotsOK(node->vOrder,nv,node->vKnot.n,node->vKnot.p)){
1307 nkv = node->vKnot.n;
1308 knotsv = MALLOC(
void *, nkv *
sizeof(GLfloat));
1310 knotsv[i] = (GLfloat)node->vKnot.p[i];
1314 printf(
"good v knot vector nk=%d\n",nkv);
1315 for(ii=0;ii<nkv;ii++)
1316 printf(
"[%d]=%f \n",ii,knotsv[ii]);
1320 static int once = 0;
1322 nkv = nv + node->vOrder ;
1324 knotsv = MALLOC(
void *, nkv *
sizeof(GLfloat));
1325 generateUniformKnotVector(node->vOrder,nv, knotsv);
1328 printf(
"bad v knot vector given, replacing with:\n");
1329 for(ii=0;ii<nkv;ii++)
1330 printf(
"[%d]=%f \n",ii,knotsv[ii]);
1336 if(n && nku && nkv){
1338 int ntessu, ntessv, mtessu, mtessv;
1341 int texcoordnodeIsGenerated;
1343 mtessu = node->uOrder + 1;
1344 ntessu = node->uTessellation;
1345 mtessv = node->vOrder + 1;
1346 ntessv = node->vTessellation;
1348 if(DEBG) printf(
"gluNewNurbsRenderer\n");
1350 theNurb = gluNewNurbsRenderer();
1351 gluNurbsProperty(theNurb, GLU_NURBS_MODE, GLU_NURBS_TESSELLATOR);
1357 double model[16], proj[16];
1358 float modelf[16], projf[16];
1365 gluNurbsProperty(theNurb, GLU_SAMPLING_TOLERANCE, (
float)(mtessu));
1367 gluNurbsProperty(theNurb,GLU_SAMPLING_METHOD,GLU_PATH_LENGTH);
1369 gluNurbsProperty(theNurb,GLU_SAMPLING_METHOD,GLU_PARAMETRIC_TOLERANCE);
1370 gluNurbsProperty(theNurb, GLU_AUTO_LOAD_MATRIX,GL_FALSE);
1372 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, model);
1373 FW_GL_GETDOUBLEV(GL_PROJECTION_MATRIX, proj);
1374 FW_GL_GETINTEGERV(GL_VIEWPORT, viewPort);
1376 modelf[i] = (float)model[i];
1377 projf[i] = (float)proj[i];
1379 gluLoadSamplingMatrices(theNurb,modelf,projf,viewPort);
1386 mtessu = max(mtessu,ntessu+1);
1388 mtessu = max(mtessu,(-ntessu * nu) + 1);
1390 mtessu = max(mtessu,2*nu + 1);
1393 mtessv = max(mtessv,ntessv+1);
1395 mtessv = max(mtessv,(-ntessv * nv) + 1);
1397 mtessv = max(mtessv,2*nv + 1);
1398 mtessu = (int)((
float)mtessu * node->_tscale);
1399 mtessv = (int)((
float)mtessv * node->_tscale);
1401 gluNurbsProperty(theNurb,GLU_SAMPLING_METHOD,GLU_DOMAIN_DISTANCE);
1402 gluNurbsProperty(theNurb,GLU_U_STEP,(GLfloat)mtessu);
1403 gluNurbsProperty(theNurb,GLU_V_STEP,(GLfloat)mtessv);
1405 gluNurbsProperty(theNurb, GLU_DISPLAY_MODE, GLU_FILL);
1407 gluNurbsCallback(theNurb, GLU_ERROR, nurbsError);
1408 gluNurbsCallback(theNurb, GLU_NURBS_BEGIN_DATA, nurbssurfBegincb);
1409 gluNurbsCallback(theNurb, GLU_NURBS_VERTEX_DATA, nurbssurfVertexcb);
1410 gluNurbsCallback(theNurb, GLU_NURBS_NORMAL_DATA, nurbssurfNormalcb);
1411 gluNurbsCallback(theNurb, GLU_NURBS_END_DATA, nurbssurfEndcb);
1412 gluNurbsCallback(theNurb, GLU_NURBS_TEXTURE_COORD_DATA, nurbssurfTexcoordcb);
1414 strips = newVector(
struct stripState,20);
1415 gluNurbsCallbackData(theNurb,(GLvoid*)strips);
1417 if(DEBG) printf(
"gluBeginSurface \n");
1418 gluBeginSurface(theNurb);
1419 gluNurbsSurface(theNurb,nku,knotsu,nkv,knotsv,4,4*nu,xyzw,node->uOrder,node->vOrder,GL_MAP2_VERTEX_4);
1453 texcoordnodeIsGenerated = FALSE;
1454 texCoordNode = node->texCoord;
1464 float du, dv, uu, vv;
1467 texcoordnodeIsGenerated = TRUE;
1468 texCoord->point.p = MALLOC(
struct SFVec2f*,nu * nv *
sizeof(
struct SFVec2f));
1469 du = 1.0f / (float)max(1,(nu -1));
1470 dv = 1.0f / (float)max(1,(nv -1));
1474 if(k == nv-1) vv = 1.0f;
1477 if(j == nu-1) uu = 1.0f;
1478 texCoord->point.p[jj].c[0] = uu;
1479 texCoord->point.p[jj].c[1] = vv;
1485 texCoord->point.n = jj;
1486 texCoordNode = X3D_NODE(texCoord);
1496 if(texCoordNode->_nodeType == NODE_TextureCoordinate){
1499 float *control2D = (
float*)texCoord->point.p;
1500 int nctrl = texCoord->point.n;
1505 gluNurbsSurface(theNurb,nku,knotsu,nkv,knotsv,2,2*nu,control2D,node->uOrder,node->vOrder,GL_MAP2_TEXTURE_COORD_2);
1509 float *tknotsu, *tknotsv;
1512 tknotsu = MALLOC(
float *, (nu+2) *
sizeof(GLfloat));
1513 tknotsv = MALLOC(
float *, (nv+2) *
sizeof(GLfloat));
1514 generateUniformKnotVector(2,nu,tknotsu);
1515 generateUniformKnotVector(2,nv,tknotsv);
1516 printf(
"tknotsu = [");
1517 for(k=0;k<nu+2;k++) printf(
"%f ",tknotsu[k]);
1518 printf(
"]\ntknotsv = [");
1519 for(k=0;k<nv+2;k++) printf(
"%f ",tknotsv[k]);
1521 gluNurbsSurface(theNurb,nu+2,knotsu,nv+2,knotsv,4,4*nu,control2D,2,2,GL_MAP2_TEXTURE_COORD_2);
1523 }
else if(texCoordNode->_nodeType == NODE_NurbsTextureCoordinate){
1530 float tknots[4] = {0.0f, 0.0f, 1.0f, 1.0f};
1531 float unit_control2D [8] = {0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f};
1533 gluNurbsSurface(theNurb,4,tknots,4,tknots,2,2*2,unit_control2D,2,2,GL_MAP2_TEXTURE_COORD_2);
1538 float du, dv, uu, vv;
1542 texcoordnodeIsGenerated = TRUE;
1543 FREE_IF_NZ(texCoord->point.p);
1544 texCoord->point.p = MALLOC(
struct SFVec2f*,nu * nv *
sizeof(
struct SFVec2f));
1545 du = 1.0f / (float)max(1,(nu -1));
1546 dv = 1.0f / (float)max(1,(nv -1));
1550 if(k == nv-1) vv = 1.0f;
1553 if(j == nu-1) uu = 1.0f;
1554 texCoord->point.p[jj].c[0] = uu;
1555 texCoord->point.p[jj].c[1] = vv;
1561 texCoord->point.n = jj;
1562 texCoordNode = X3D_NODE(texCoord);
1566 control2D = (
float*)texCoord->point.p;
1567 gluNurbsSurface(theNurb,nku,knotsu,nkv,knotsv,2,2*nu,control2D,node->uOrder,node->vOrder,GL_MAP2_TEXTURE_COORD_2);
1579 if(DEBG) printf(
"gluBeginTrim \n");
1580 gluBeginTrim (theNurb);
1584 GLfloat edgePt[5][2] = {{0.0, 0.0}, {1.0, 0.0}, {1.0, 1.0}, {0.0, 1.0}, {0.0, 0.0}};
1585 if(DEBG) printf(
"gluPwlCurve 0\n");
1586 gluPwlCurve (theNurb, 5, &edgePt[0][0], 2, GLU_MAP1_TRIM_2);
1590 GLfloat *edges = MALLOC(
void *, (2 * ntessu + 2 * ntessv) *2*
sizeof(GLfloat));
1591 GLfloat uspan, vspan;
1592 uspan = 1.0f/(float)(ntessu -1);
1593 vspan = 1.0f/(float)(ntessv -1);
1594 for(i=0;i<ntessu-1;i++){
1595 edges[i*2 +0] = (float)(i)*uspan;
1596 edges[i*2 +1] = 0.0;
1597 edges[(ntessu+ntessv+i)*2 + 0] = (
float)(ntessu - 1 - i)*uspan;
1598 edges[(ntessu+ntessv+i)*2 + 1] = 1.0;
1600 for(i=0;i<ntessv;i++){
1601 edges[(ntessu+i)*2 + 0] = 1.0;
1602 edges[(ntessu+i)*2 + 1] = (
float)(i)*vspan;
1603 edges[(ntessu+ntessv+ntessu+i)*2 + 0] = 0.0;
1604 edges[(ntessu+ntessv+ntessu+i)*2 + 1] = (
float)(ntessv - 1 - i)*vspan;
1607 edges[((ntessu -1)*2 + (ntessv -1)*2)*2 + 0] = 0.0;
1608 edges[((ntessu -1)*2 + (ntessv -1)*2)*2 + 1] = 0.0;
1609 if(DEBG) printf(
"gluPwlCurve 1\n");
1610 gluPwlCurve (theNurb, 2*(ntessu -1 + ntessv -1) +1, edges, 2, GLU_MAP1_TRIM_2);
1612 if(DEBG) printf(
"gluEndTrim\n");
1613 gluEndTrim (theNurb);
1619 GLfloat curvePt[4][2] =
1620 {{0.25, 0.5}, {0.25, 0.75}, {0.75, 0.75}, {0.75, 0.5}};
1621 GLfloat curveKnots[8] =
1622 {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0};
1623 GLfloat pwlPt[4][2] =
1624 {{0.75, 0.5}, {0.5, 0.25}, {0.25, 0.5}};
1626 if(DEBG) printf(
"gluBeginTrim A\n");
1627 gluBeginTrim (theNurb);
1628 if(DEBG) printf(
"gluNurbsCurve A\n");
1629 gluNurbsCurve (theNurb, 8, curveKnots, 2,
1630 &curvePt[0][0], 4, GLU_MAP1_TRIM_2);
1631 if(DEBG) printf(
"gluPwlCurve A\n");
1632 gluPwlCurve (theNurb, 3, &pwlPt[0][0], 2, GLU_MAP1_TRIM_2);
1633 if(DEBG) printf(
"gluEndTrim A\n");
1634 gluEndTrim (theNurb);
1637 for(i=0;i<trim->n;i++){
1640 if(DEBG) printf(
"gluBeginTrim B\n");
1641 gluBeginTrim (theNurb);
1642 for(m=0;m<tc->children.n;m++)
1647 struct X3D_Node *ctr = tc->children.p[m];
1648 GLfloat *cknot, *ctrl, *cweight;
1649 cknot = ctrl = cweight = NULL;
1650 switch(ctr->_nodeType){
1651 case NODE_ContourPolyline2D:
1653 ctrl = MALLOC(
void *, cp2d->controlPoint.n * 2*
sizeof(GLfloat));
1654 for(j=0;j<cp2d->controlPoint.n;j++) {
1656 ctrl[j*2 + k] = (
float)cp2d->controlPoint.p[j].c[k];
1658 if(DEBG) printf(
"gluPwlCurve B\n");
1659 gluPwlCurve (theNurb, cp2d->controlPoint.n, ctrl, 2, GLU_MAP1_TRIM_2);
1662 case NODE_NurbsCurve2D:
1665 nk = nc2d->controlPoint.n + nc2d->order;
1666 if(nk == nc2d->knot.n)
1668 cknot = MALLOC(
void *, nk *
sizeof(GLfloat));
1671 cweight = MALLOC(
void *, nc2d->controlPoint.n *
sizeof(GLfloat));
1672 if(nc2d->weight.n == nc2d->controlPoint.n){
1673 for(j=0;j<nc2d->weight.n;j++) cweight[j] = (
float)nc2d->weight.p[j];
1675 for(j=0;j<nc2d->controlPoint.n;j++) cweight[j] = 1.0f;
1678 ctrl = MALLOC(
void *, nc2d->controlPoint.n * dim*
sizeof(GLfloat));
1679 for(j=0;j<nc2d->controlPoint.n;j++) {
1681 ctrl[j*dim + k] = (float)nc2d->controlPoint.p[j].c[k];
1682 if(dim == 3) ctrl[j*dim + k] *= cweight[j];
1684 if(dim == 3) ctrl[j*dim + dim-1] = (float)cweight[j];
1686 if(knotsOK(nc2d->order,nc2d->controlPoint.n,nc2d->knot.n,nc2d->knot.p)){
1688 for(j=0;j<nc2d->knot.n;j++)
1689 cknot[j] = (
float)nc2d->knot.p[j];
1691 generateUniformKnotVector(nc2d->order,nc2d->controlPoint.n,cknot);
1692 printf(
"replacing nurbscurve2D knotvector with:\n");
1694 printf(
"%f ",cknot[j]);
1700 printf(
"knot %d ={",nc2d->knot.n);
1701 for(j=0;j<nc2d->knot.n;j++){
1702 printf(
"%f ",cknot[j]);
1705 printf(
"control %d = {\n",nc2d->controlPoint.n);
1706 for(j=0;j<nc2d->controlPoint.n;j++) {
1707 for(k=0;k<dim;k++) printf(
"%f \n",ctrl[j*dim +k]);
1712 if(DEBG) printf(
"gluNurbsCurve B\n");
1715 mtess = nc2d->order + 1;
1716 ntess = nc2d->tessellation;
1722 double model[16], proj[16];
1723 float modelf[16], projf[16];
1730 gluNurbsProperty(theNurb, GLU_SAMPLING_TOLERANCE, (
float)(mtess));
1732 gluNurbsProperty(theNurb,GLU_SAMPLING_METHOD,GLU_PATH_LENGTH);
1734 gluNurbsProperty(theNurb,GLU_SAMPLING_METHOD,GLU_PARAMETRIC_TOLERANCE);
1735 gluNurbsProperty(theNurb, GLU_AUTO_LOAD_MATRIX,GL_FALSE);
1737 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, model);
1738 FW_GL_GETDOUBLEV(GL_PROJECTION_MATRIX, proj);
1739 FW_GL_GETINTEGERV(GL_VIEWPORT, viewPort);
1741 modelf[i] = (float)model[i];
1742 projf[i] = (float)proj[i];
1744 gluLoadSamplingMatrices(theNurb,modelf,projf,viewPort);
1751 mtess = max(mtess,ntess+1);
1753 mtess = max(mtess,(-ntess * n) + 1);
1755 mtess = max(mtess,2*n + 1);
1756 gluNurbsProperty(theNurb,GLU_SAMPLING_METHOD,GLU_DOMAIN_DISTANCE);
1757 gluNurbsProperty(theNurb,GLU_U_STEP,(GLfloat)mtess);
1760 gluNurbsCurve (theNurb, nk, cknot, dim, ctrl, nc2d->order, GLU_MAP1_TRIM_2);
1763 ConsoleMessage(
"%s %d",
"unknown trimming contour node",ctr->_nodeType);
1767 FREE_IF_NZ(cweight);
1769 if(DEBG) printf(
"gluEndTrim B\n");
1770 gluEndTrim (theNurb);
1773 if(DEBG) printf(
"gluEndSurface \n");
1774 gluEndSurface(theNurb);
1775 if(DEBG) printf(
"gluDeleteNurbsRenderer \n");
1776 if(0) gluDeleteNurbsRenderer(theNurb);
1781 if(texcoordnodeIsGenerated){
1783 FREE_IF_NZ(texCoord->point.p);
1784 FREE_IF_NZ(texCoordNode);
1788 for(i=0;i<vectorSize(strips);i++){
1789 struct stripState *ss = vector_get_ptr(
struct stripState,strips,i);
1790 FREE_IF_NZ(ss->pv.data); ss->pv.allocn = 0; ss->pv.n = 0;
1791 FREE_IF_NZ(ss->nv.data); ss->nv.allocn = 0; ss->nv.n = 0;
1792 FREE_IF_NZ(ss->tv.data); ss->tv.allocn = 0; ss->tv.n = 0;
1794 FREE_IF_NZ(strips->data); strips->allocn = 0; strips->n = 0;
1805void render_ray_polyrep(
void *node);
1806void render_polyrep(
void *node);
1810 compile_NurbsSurface(node, NULL);
1814 if (!node->_intern)
return;
1815 render_ray_polyrep(node);
1820 if (!node->_intern)
return;
1821 collide_genericfaceset(X3D_INDEXEDFACESET(node));
1826 if (!node->_intern)
return;
1827 CULL_FACE(node->solid)
1828 render_polyrep(node);
1838 if (!node->_intern)
return;
1839 render_ray_polyrep(node);
1844 if (!node->_intern)
return;
1845 collide_genericfaceset(X3D_INDEXEDFACESET(node));
1850 if (!node->_intern)
return;
1851 CULL_FACE(node->solid)
1852 render_polyrep(node);
1855void do_NurbsPositionInterpolator (
void *node) {
1869 if(!px->_OK == TRUE){
1871 if(!(px->knot.n > 1))
1873 if(!px->controlPoint )
1875 if(px->controlPoint->_nodeType != NODE_Coordinate)
1878 if(control->point.n < 2)
1880 n = control->point.n;
1882 if(px->weight.n == n)
1883 weight = px->weight.p;
1884 px->_xyzw.p = MALLOC(
struct SFVec4f*,control->point.n *
sizeof(
struct SFVec4f));
1886 for(i=0;i<control->point.n;i++){
1888 wt = weight ? (float)weight[i] : 1.0f;
1889 veccopy3f(xyzw,control->point.p[i].c);
1890 vecscale3f(xyzw,xyzw,wt);
1892 veccopy4f(px->_xyzw.p[i].c,xyzw);
1894 if(knotsOK(px->order,px->_xyzw.n,px->knot.n,px->knot.p)){
1897 knots = MALLOC(
void *, nk *
sizeof(GLfloat));
1899 knots[i] = (GLfloat)px->knot.p[i];
1906 static int once = 0;
1908 nk = n + px->order ;
1910 knots = MALLOC(
void *, nk *
sizeof(GLfloat));
1911 generateUniformKnotVector(px->order,n, knots);
1914 printf(
"bad knot vector, replacing with:\n");
1915 for(ii=0;ii<nk;ii++)
1916 printf(
"[%d]=%f \n",ii,knots[ii]);
1921 px->_knot.p = knots;
1923 px->_knotrange.c[0] = px->_knot.p[0];
1924 px->_knotrange.c[1] = px->_knot.p[px->_knot.n-1];
1932 fraction = max(px->_knotrange.c[0],px->set_fraction);
1933 fraction = min(px->_knotrange.c[1],px->set_fraction);
1934 CurvePoint(px->_xyzw.n, px->order-1, px->_knot.p, (
float*)px->_xyzw.p, fraction, cw );
1935 veccopy3f(px->value_changed.c,cw);
1939 printf(
"do_PositionInt: Position/Vec3f interp, node %u kin %d kvin %d set_fraction %f\n",
1940 node, kin, kvin, px->set_fraction);
1952void do_NurbsOrientationInterpolator (
void *node) {
1966 if(!px->_OK == TRUE){
1968 if(!(px->knot.n > 1))
1970 if(!px->controlPoint )
1972 if(px->controlPoint->_nodeType != NODE_Coordinate)
1975 if(control->point.n < 2)
1977 n = control->point.n;
1979 if(px->weight.n == n)
1980 weight = px->weight.p;
1981 px->_xyzw.p = MALLOC(
struct SFVec4f*,control->point.n *
sizeof(
struct SFVec4f));
1983 for(i=0;i<control->point.n;i++){
1985 wt = weight ? (float)weight[i] : 1.0f;
1986 veccopy3f(xyzw,control->point.p[i].c);
1987 vecscale3f(xyzw,xyzw,wt);
1989 veccopy4f(px->_xyzw.p[i].c,xyzw);
1991 if(knotsOK(px->order,px->_xyzw.n,px->knot.n,px->knot.p)){
1994 knots = MALLOC(
void *, nk *
sizeof(GLfloat));
1996 knots[i] = (GLfloat)px->knot.p[i];
2003 static int once = 0;
2005 nk = n + px->order ;
2007 knots = MALLOC(
void *, nk *
sizeof(GLfloat));
2008 generateUniformKnotVector(px->order,n, knots);
2011 printf(
"bad knot vector, replacing with:\n");
2012 for(ii=0;ii<nk;ii++)
2013 printf(
"[%d]=%f \n",ii,knots[ii]);
2018 px->_knot.p = knots;
2020 px->_knotrange.c[0] = px->_knot.p[0];
2021 px->_knotrange.c[1] = px->_knot.p[px->_knot.n-1];
2029 fraction = max(px->_knotrange.c[0],px->set_fraction);
2030 fraction = min(px->_knotrange.c[1],px->set_fraction);
2035 float f1, f2, cw1[4], cw2[4], dir[3], rot[4];
2039 f2 = fraction + .01f;
2041 f1 = fraction - .01f;
2045 CurvePoint(px->_xyzw.n, px->order-1, px->_knot.p, (
float*)px->_xyzw.p, f1, cw1 );
2046 CurvePoint(px->_xyzw.n, px->order-1, px->_knot.p, (
float*)px->_xyzw.p, f2, cw2 );
2047 vecdif3f(dir,cw2,cw1);
2048 vecnormalize3f(dir,dir);
2054 float perp[3], dirx[3], sine;
2055 memset(dirx,0,3*
sizeof(
float));
2057 veccross3f(perp,dirx,dir);
2058 sine = veclength3f(perp);
2061 float default_direction [4] = {1.0f, 0.0f, 0.0f, 0.0f};
2062 veccopy4f(rot,default_direction);
2064 float cosine, angle;
2065 vecnormalize3f(perp,perp);
2066 cosine = vecdot3f(dir,dirx);
2067 angle = atan2f(sine,cosine);
2068 veccopy3f(rot,perp);
2075 float perp[3],dir0[3];
2077 CurvePoint(px->_xyzw.n, px->order-1, px->_knot.p, (
float*)px->_xyzw.p, 0.0f, cw1 );
2078 CurvePoint(px->_xyzw.n, px->order-1, px->_knot.p, (
float*)px->_xyzw.p, .001f, cw2 );
2079 vecdif3f(dir0,cw2,cw1);
2080 vecnormalize3f(dir0,dir0);
2082 veccross3f(perp,dir,dir0);
2083 if(veclength3f(perp) == 0.0f){
2085 float default_direction [4] = {1.0f, 0.0f, 0.0f, 0.0f};
2086 veccopy4f(rot,default_direction);
2090 vecnormalize3f(perp,perp);
2091 cosine = vecdot3f(dir0,dir);
2092 angle = acosf(cosine);
2093 veccopy3f(rot,perp);
2097 veccopy4f(px->value_changed.c,rot);
2099 float default_direction [4] = {1.0f, 0.0f, 0.0f, 0.0f};
2100 veccopy4f(px->value_changed.c,default_direction);
2105 printf(
"do_NurbsOrientInt: set_fraction %f value_changed %f %f %f %f\n",fraction,
2106 px->value_changed.c[0],px->value_changed.c[1],px->value_changed.c[2],px->value_changed.c[3] );
2111void do_NurbsSurfaceInterpolator (
void *_node) {
2112 float uv[2], xyzw[4];
2118 if(node->_nodeType != NODE_NurbsSurfaceInterpolator)
return;
2122 if(node->_OK != TRUE){
2123 int i,j, n, nu, nv, nku, nkv;
2124 GLfloat *xyzw, *knotsu, *knotsv;
2126 nku = nkv = nu = nv = n = 0;
2127 xyzw = knotsu = knotsv = NULL;
2128 if(node->controlPoint){
2129 if(node->controlPoint->_nodeType == NODE_CoordinateDouble){
2133 xyzw = MALLOC(
void *, n * 4 *
sizeof(GLfloat));
2134 for(i=0;i<mfd->n;i++){
2136 xyzw[i*4 + j] = (float)mfd->p[i].c[j];
2139 }
else if(node->controlPoint->_nodeType == NODE_Coordinate){
2143 xyzw = MALLOC(
void *, n * 4 *
sizeof(GLfloat));
2144 for(i=0;i<mff->n;i++){
2146 xyzw[i*4 + j] = mff->p[i].c[j];
2154 if(node->weight.n && node->weight.n == n){
2157 m = min(node->weight.n, n);
2159 im = i < m ? i : m-1;
2160 w = node->weight.p[im];
2161 xyzw[i*4 + 3] = (float)w;
2164 for(i=0;i<n;i++) xyzw[i*4 + 3] = 1.0;
2166 nu = node->uDimension;
2167 nv = node->vDimension;
2168 if(nu * nv != n)
return;
2169 if(nu < node->uOrder)
return;
2170 if(nv < node->vOrder)
return;
2173 if(knotsOK(node->uOrder,nu,node->uKnot.n,node->uKnot.p)){
2176 nku = node->uKnot.n;
2177 knotsu = MALLOC(
void *, nku *
sizeof(GLfloat));
2179 knotsu[i] = (GLfloat)node->uKnot.p[i];
2183 printf(
"good u knot vector nk=%d\n",nku);
2184 for(ii=0;ii<nku;ii++)
2185 printf(
"[%d]=%f \n",ii,knotsu[ii]);
2190 static int once = 0;
2191 nku = nu + node->uOrder ;
2193 knotsu = MALLOC(
void *, nku *
sizeof(GLfloat));
2194 generateUniformKnotVector(node->uOrder,nu, knotsu);
2197 printf(
"bad u knot vector given, replacing with:\n");
2198 for(ii=0;ii<nku;ii++)
2199 printf(
"[%d]=%f \n",ii,knotsu[ii]);
2205 if(knotsOK(node->vOrder,nv,node->vKnot.n,node->vKnot.p)){
2207 nkv = node->vKnot.n;
2208 knotsv = MALLOC(
void *, nkv *
sizeof(GLfloat));
2210 knotsv[i] = (GLfloat)node->vKnot.p[i];
2214 printf(
"good v knot vector nk=%d\n",nkv);
2215 for(ii=0;ii<nkv;ii++)
2216 printf(
"[%d]=%f \n",ii,knotsv[ii]);
2220 static int once = 0;
2222 nkv = nv + node->vOrder ;
2224 knotsv = MALLOC(
void *, nkv *
sizeof(GLfloat));
2225 generateUniformKnotVector(node->vOrder,nv, knotsv);
2228 printf(
"bad v knot vector given, replacing with:\n");
2229 for(ii=0;ii<nkv;ii++)
2230 printf(
"[%d]=%f \n",ii,knotsv[ii]);
2235 node->_controlPoint.p = (
struct SFVec4f*)xyzw;
2236 node->_controlPoint.n = n;
2237 node->_uKnot.p = knotsu;
2238 node->_uKnot.n = nku;
2239 node->_vKnot.p = knotsv;
2240 node->_vKnot.n = nkv;
2246 if(!node->_OK)
return;
2248 veccopy2f(uv,node->set_fraction.c);
2250 ok = SurfacePoint(node->uDimension,node->uOrder-1,node->_uKnot.p,
2251 node->vDimension,node->vOrder-1,node->_vKnot.p,
2252 (
float *)node->_controlPoint.p,uv[1],uv[0],xyzw);
2254 veccopy3f(node->position_changed.c,xyzw);
2258 float udir[3], vdir[3], normal[3], xyz1[4];
2259 ok = SurfacePoint(node->uDimension,node->uOrder-1,node->_uKnot.p,
2260 node->vDimension,node->vOrder-1,node->_vKnot.p,
2261 (
float *)node->_controlPoint.p,uv[1],uv[0]+.01f,xyz1);
2262 vecdif3f(udir,xyz1,xyzw);
2263 ok = SurfacePoint(node->uDimension,node->uOrder-1,node->_uKnot.p,
2264 node->vDimension,node->vOrder-1,node->_vKnot.p,
2265 (
float *)node->_controlPoint.p,uv[1]+.01f,uv[0],xyz1);
2266 vecdif3f(vdir,xyz1,xyzw);
2267 veccross3f(normal,udir,vdir);
2268 vecnormalize3f(normal,normal);
2269 veccopy3f(node->normal_changed.c,normal);
2278 printf (
"Pos/Col, new value (%f %f %f)\n",
2279 px->value_changed.c[0],px->value_changed.c[1],px->value_changed.c[2]);
2291 int nt, np,ic,j,i,k;
2292 double *xyzp, *xyzt;
2302 controlPoint = (
struct X3D_Coordinate*)createNewX3DNode(NODE_Coordinate);
2303 node->_patch = X3D_NODE(patch);
2304 patch->controlPoint = X3D_NODE(controlPoint);
2312 nt = trajectoryxz->controlPoint.n;
2313 np = profileyz->controlPoint.n;
2314 xyzp = (
double*)profileyz->controlPoint.p;
2315 xyzt = (
double*)trajectoryxz->controlPoint.p;
2316 xyz = MALLOC(
float*,nt * np * 3 *
sizeof(
float));
2317 controlPoint->point.p = (
struct SFVec3f*)xyz;
2318 controlPoint->point.n = nt * np;
2322 double2float(pt,&xyzt[j*2],2);
2325 float cosine, sine, swingangle;
2326 double2float(pp,&xyzp[2*i],2);
2327 swingangle = atan2f(pt[1],pt[0]);
2328 cosine = cosf(swingangle);
2329 sine = sinf(swingangle);
2330 xyz[ic*3 + 0] = pt[0] + cosine * pp[0];
2331 xyz[ic*3 + 1] = pp[1];
2332 xyz[ic*3 + 2] = pt[1] + sine * pp[0];
2336 patch->solid = node->solid;
2338 patch->uDimension = np;
2339 patch->uKnot.p = malloc(profileyz->knot.n *
sizeof(
double));
2340 memcpy(patch->uKnot.p,profileyz->knot.p,profileyz->knot.n *
sizeof(
double));
2341 patch->uKnot.n = profileyz->knot.n;
2342 patch->uOrder = profileyz->order;
2343 patch->uTessellation = (int)((
float)profileyz->tessellation * profileyz->_tscale);
2345 patch->vDimension = nt;
2346 patch->vKnot.p = malloc(trajectoryxz->knot.n *
sizeof(
double));
2347 memcpy(patch->vKnot.p,trajectoryxz->knot.p,trajectoryxz->knot.n *
sizeof(
double));
2348 patch->vKnot.n = trajectoryxz->knot.n;
2349 patch->vOrder = trajectoryxz->order;
2350 patch->vTessellation = (int)((
float)trajectoryxz->tessellation * profileyz->_tscale);
2355 printf(
"%f %f %f,",xyz[ic*3 + 0], xyz[ic*3 +1], xyz[ic*3 +2]);
2360 printf(
"uDimension=%d vDimension=%d nc=%d\n",np,nt,ic);
2366 if (!node->_intern)
return;
2367 render_ray_polyrep(node->_patch);
2372 if (!node->_intern)
return;
2373 collide_genericfaceset(X3D_INDEXEDFACESET(node->_patch));
2379 if (!node->_patch->_intern)
2382 CULL_FACE(patch->solid)
2383 render_polyrep(X3D_NODE(patch));
2388int compute_tessellation(
int tessellation,
int order,
int ncontrol ){
2395 ntessu = tessellation;
2398 mtessu = max(mtessu,ntessu+1);
2400 mtessu = max(mtessu,(-ntessu * ncontrol) + 1);
2402 mtessu = max(mtessu,2*ncontrol + 1);
2405void compute_knotvector(
int order,
int ncontrol,
int nknots,
double *knots,
int *newnknots,
float **newknots,
float *range){
2411 if(knotsOK(order,ncontrol,nknots,knots)){
2415 knotsu = MALLOC(
void *, nku *
sizeof(GLfloat));
2417 knotsu[i] = (GLfloat)knots[i];
2420 printf(
"good u knot vector nk=%d\n",nku);
2421 for(ii=0;ii<nku;ii++)
2422 printf(
"[%d]=%f \n",ii,knotsu[ii]);
2428 static int once = 0;
2429 nku = ncontrol + order ;
2431 knotsu = MALLOC(
void *, nku *
sizeof(GLfloat));
2432 generateUniformKnotVector(order,ncontrol, knotsu);
2434 printf(
"bad u knot vector given, replacing with:\n");
2435 for(ii=0;ii<nku;ii++)
2436 printf(
"[%d]=%f \n",ii,knotsu[ii]);
2443 range[0] = knotsu[0];
2444 range[1] = knotsu[nku-1];
2446void compute_weightedcontrol(
double *xyz,
int dim,
int nc,
int nweight,
double *weights,
float **cxyzw){
2456 xyzw = MALLOC(
float *, nc * 4 *
sizeof(GLfloat));
2458 xyzw[i*4 +0] = xyzw[i*4 +1] =xyzw[i*4 +2] =xyzw[i*4 +3] = 0.0f;
2461 xyzw[i*4 + j] = (float)xyz[i*dim + j];
2463 xyzw[i*4 + 3] = 1.0f;
2465 if(nweight && nweight == nc ){
2467 float wt = (float)weights[i];
2469 vecscale3f(&xyzw[i*4],&xyzw[i*4],wt);
2474void compute_doublecontrol(
struct X3D_Node *controlPoint,
int *nc,
double** xyz ){
2479 double *xyzd = NULL;
2481 switch(controlPoint->_nodeType){
2482 case NODE_Coordinate:
2485 n = tcoord->point.n;
2486 xyzd = MALLOC(
double *,n * 3 *
sizeof(
double));
2487 for(i=0;i<tcoord->point.n;i++)
2488 float2double(&xyzd[i*3],tcoord->point.p[i].c,3);
2491 case NODE_CoordinateDouble:
2494 n = tcoord->point.n;
2495 xyzd = MALLOC(
double *,n * 3 *
sizeof(
double));
2496 for(i=0;i<tcoord->point.n;i++)
2497 veccopyd(&xyzd[i*3],tcoord->point.p[i].c);
2508float *vecabs3f(
float *res,
float *p){
2511 res[i] = fabsf(p[i]);
2514int ivecdominantdirection3f(
int *irank,
float *p){
2515 float rmax, rmin, vabs[3];
2518 rmax = max(vabs[0],max(vabs[1],vabs[2]));
2519 rmin = min(vabs[0],min(vabs[1],vabs[2]));
2522 if(vabs[i] == rmax) {
2526 if(vabs[i] == rmin) irank[i] = 0;
2530void convert_mesh_to_polyrep(
float *xyz,
int npts,
float *nxyz,
int* tindex,
int ntri,
struct X3D_Node *node){
2542 polyrep = node->_intern;
2543 FREE_IF_NZ(polyrep->cindex);
2544 FREE_IF_NZ(polyrep->actualCoord);
2545 FREE_IF_NZ(polyrep->GeneratedTexCoords[0]);
2546 FREE_IF_NZ(polyrep->colindex);
2547 FREE_IF_NZ(polyrep->color);
2548 FREE_IF_NZ(polyrep->norindex);
2549 FREE_IF_NZ(polyrep->normal);
2550 FREE_IF_NZ(polyrep->flat_normal);
2551 FREE_IF_NZ(polyrep->tcindex);
2554 node->_intern = create_polyrep();
2556 rep_ = polyrep = node->_intern;
2569 rep_->actualCoord = xyz;
2570 rep_->normal = nxyz;
2576 rep_->cindex = tindex;
2577 norindex = rep_->norindex = MALLOC(GLuint *,
sizeof(GLuint)*3*ntri);
2578 memcpy(norindex,tindex,
sizeof(GLuint)*3*ntri);
2585 if (polyrep->ntri != 0) {
2587 stream_polyrep(node, NULL,NULL,NULL,NULL, NULL);
2591 polyrep->irep_change = node->_change;
2648 compute_doublecontrol(trajectory->controlPoint,&nt,&xyzt);
2651 np = xsection->controlPoint.n;
2652 xyzx = (
double*)xsection->controlPoint.p;
2684 if(!strcmp(node->method->strptr,
"FULL"))
2686 if(!strcmp(node->method->strptr,
"TRANSLATE"))
2688 if(node->_method == 1){
2700 controlPoint = (
struct X3D_Coordinate*) createNewX3DNode(NODE_Coordinate);
2701 node->_patch = X3D_NODE(patch);
2702 patch->controlPoint = X3D_NODE(controlPoint);
2704 xyz = MALLOC(
float*,nt * np * 3 *
sizeof(
float));
2705 controlPoint->point.p = (
struct SFVec3f*) xyz;
2706 controlPoint->point.n = nt * np;
2711 double2float(pt,&xyzt[j*3],3);
2714 double2float(pp,&xyzx[2*i],2);
2715 xyz[ic*3 + 0] = pt[0] + pp[0];
2716 xyz[ic*3 + 1] = pt[1] + pp[1];
2717 xyz[ic*3 + 2] = pt[2];
2723 if((trajectory->weight.n && trajectory->weight.n == nt) ||
2724 (xsection->weight.n && xsection->weight.n == np)){
2727 weight = MALLOC(
double*,nt * np *
sizeof(
double));
2729 double wtTj = trajectory->weight.p[j];
2731 weight[j*np + i] = wtTj * xsection->weight.p[i];
2737 patch->weight.p = weight;
2738 patch->weight.n = nt * np;
2740 patch->solid = node->solid;
2742 patch->uDimension = np;
2743 patch->uKnot.p = malloc(xsection->knot.n *
sizeof(
double));
2744 memcpy(patch->uKnot.p,xsection->knot.p,xsection->knot.n *
sizeof(
double));
2745 patch->uKnot.n = xsection->knot.n;
2746 patch->uOrder = xsection->order;
2747 patch->uTessellation = (int)((
float)xsection->tessellation * xsection->_tscale);
2749 patch->vDimension = nt;
2750 patch->vKnot.p = malloc(xsection->knot.n *
sizeof(
double));
2751 memcpy(patch->vKnot.p,trajectory->knot.p,trajectory->knot.n *
sizeof(
double));
2752 patch->vKnot.n = trajectory->knot.n;
2753 patch->vOrder = trajectory->order;
2754 patch->vTessellation = (int)((
float)trajectory->tessellation * trajectory->_tscale);
2759 printf(
"%f %f %f,",xyz[ic*3 + 0], xyz[ic*3 +1], xyz[ic*3 +2]);
2764 printf(
"uDimension=%d vDimension=%d nc=%d\n",np,nt,ic);
2768 if(node->_method == 2){
2770 int mtessv, mtessu, nku, nkv;
2772 float *knotsu,*knotsv,*xyzwu,*xyzwv, urange[2],vrange[2];
2773 float *Tv, *Tangentv, *Bup, *pts;
2782 int mtessu1, mtessv1;
2784 mtessu = compute_tessellation(xsection->tessellation,xsection->order,np);
2785 mtessu = (int)((
float)mtessu * xsection->_tscale);
2786 mtessv = compute_tessellation(trajectory->tessellation,trajectory->order,nt);
2787 mtessv = (int)((
float)mtessv * trajectory->_tscale);
2788 compute_knotvector(xsection->order,np,xsection->knot.n,xsection->knot.p,&nku,&knotsu,urange);
2789 compute_knotvector(trajectory->order,nt,trajectory->knot.n,trajectory->knot.p,&nkv,&knotsv,vrange);
2790 compute_weightedcontrol(xyzt,3,nt, trajectory->weight.n, trajectory->weight.p, &xyzwv);
2791 compute_weightedcontrol(xyzx,2,np, xsection->weight.n, xsection->weight.p, &xyzwu);
2795 printf(
"np %d mtessu %d nku %d, nt %d mtessv %d, nkv %d",np,mtessu,nku,nt,mtessv,nkv);
2796 printf(
"trajectory nt %d points:\n",nt);
2798 printf(
"%d %f %f %f %f\n",i,xyzwv[i*4 + 0],xyzwv[i*4 + 1],xyzwv[i*4 + 2],xyzwv[i*4 + 3]);
2799 printf(
"xsection np %d points:\n",np);
2801 printf(
"%d %f %f %f %f\n",i,xyzwu[i*4 + 0],xyzwu[i*4 + 1],xyzwu[i*4 + 2],xyzwu[i*4 + 3]);
2811 mtessu1 = mtessu + 1;
2812 mtessv1 = mtessv + 1;
2813 Tv = MALLOC(
float*,(mtessv1)*3*
sizeof(
float));
2814 Tangentv = MALLOC(
float*,(mtessv1)*3*
sizeof(
float));
2815 Bup = MALLOC(
float*,(mtessv1)*3*
sizeof(
float));
2816 for(i=0;i<mtessv1;i++){
2817 float cw[4], cw1[4], delta[3], v;
2818 v = (float)i*(vrange[1]-vrange[0])/(float)mtessv;
2819 CurvePoint(nt, trajectory->order-1, knotsv, xyzwv, v, cw );
2820 veccopy3f(&Tv[i*3],cw);
2822 CurvePoint(nt, trajectory->order-1, knotsv, xyzwv, v+.01f, cw1 );
2823 vecdif3f(delta,cw1,cw);
2825 vecnormalize3f(delta,delta);
2826 veccopy3f(&Tangentv[i*3],delta);
2830 int k,irank[3],idom, inondom;
2831 float perp[3], perp2[3];
2832 idom = ivecdominantdirection3f(irank,delta);
2833 inondom = idom + 1 > 2 ? 0 : idom + 1;
2834 for(k=0;k<3;k++)
if(irank[k] == 0) inondom = k;
2835 memset(perp,0,3*
sizeof(
float));
2836 perp[inondom] = 1.0;
2837 veccross3f(perp2,delta,perp);
2838 veccross3f(perp,perp2,delta);
2840 veccopy3f(&Bup[i*3],perp);
2844 float bi[3], bi1dotti, tiscaled[3];
2845 bi1dotti = vecdot3f(&Bup[(i-1)*3],&Tangentv[i*3]);
2846 vecdif3f(bi,&Bup[(i-1)*3],vecscale3f(tiscaled,&Tangentv[i*3],bi1dotti));
2847 vecnormalize3f(&Bup[i*3],bi);
2851 printf(
"trajectory T:\n");
2852 for(i=0;i<mtessv1;i++){
2853 printf(
"%d [%f %f %f] \n",i,
2854 Tv[i*3 +0],Tv[i*3 +1],Tv[i*3 +2]);
2856 printf(
"trajectory T', B:\n");
2857 for(i=0;i<mtessv1;i++){
2858 printf(
"%d [%f %f %f] [%f %f %f] \n",i,
2859 Tangentv[i*3 +0],Tangentv[i*3 +1],Tangentv[i*3 +2],
2860 Bup[i*3 +0],Bup[i*3 +1],Bup[i*3 +2]);
2868 Qu = MALLOC(
float*,(mtessu+1)*3*
sizeof(
float));
2869 Nu = MALLOC(
float*,(mtessu+1)*3*
sizeof(
float));
2870 if(DBGSW) printf(
"Xsection tess pts:\n");
2871 for(i=0;i<mtessu1;i++){
2872 float u, cw[4], cw1[4], delta[3], normal[3];
2873 float zzz[3] = {0.0f,0.0f,1.0f};
2874 u = (float)i*(urange[1]-urange[0])/(float)mtessu;
2875 CurvePoint(np, xsection->order-1, knotsu, xyzwu, u, cw );
2876 veccopy3f(&Qu[i*3],cw);
2877 CurvePoint(np, xsection->order-1, knotsu, xyzwu, u+.01f, cw1 );
2878 vecdif3f(delta,cw1,cw);
2879 vecnormalize3f(delta,delta);
2880 veccross3f(normal,zzz,delta);
2881 veccopy3f(&Nu[i*3],normal);
2882 if(DBGSW) printf(
"%d %f %f %f\n",i,Qu[i*3 +0],Qu[i*3 +1],Qu[i*3 +2]);
2888 pts = MALLOC(
float*,mtessu1 * mtessv1 * 3 *
sizeof(
float));
2889 normals = MALLOC(
float*,mtessu1 * mtessv1 * 3 *
sizeof(
float));
2890 idx = MALLOC(
int *, mtessu * mtessv * 2 * 3 *
sizeof(
int));
2893 for(i=0;i<mtessv1;i++){
2895 float mat [9], matt[9];
2900 veccross3f(&mat[0],&Bup[i*3],&Tangentv[i*3]);
2901 veccopy3f(&mat[3],&Bup[i*3]);
2902 veccopy3f(&mat[6],&Tangentv[i*3]);
2903 mattranspose3f(matt,mat);
2911 memcpy(matB0,mat,9*
sizeof(
float));
2913 matmultiply3f(mat,matt,matB0);
2914 for(j=0;j<mtessu1;j++){
2915 float pp[3], norm[3];
2916 matmultvec3f(pp, mat, &Qu[j*3] );
2917 vecadd3f(pp,pp,&Tv[i*3]);
2918 veccopy3f(&pts[ic*3],pp);
2919 matmultvec3f(norm,mat,&Nu[j*3]);
2920 veccopy3f(&normals[ic*3],norm);
2928 for(j=0;j<mtessu;j++){
2945 printf(
"ntri %d triangle indexes:\n",ntri);
2946 for(i=0;i<ntri;i++){
2950 printf(
"%d ",idx[i*3 +j]);
2954 printf(
"triangle vertices:\n");
2955 for(i=0;i<ntri;i++){
2959 int ix = idx[i*3 +j];
2960 veccopy3f(pt,&pts[ix*3]);
2961 printf(
"%d %d %f %f %f\n",i,ix,pt[0],pt[1],pt[2]);
2967 convert_mesh_to_polyrep(pts,ic,normals,idx,ntri,X3D_NODE(node));
2973 if(node->_method == 1){
2974 if (!node->_patch)
return;
2975 render_ray_polyrep(node->_patch);
2977 if(node->_method == 2){
2978 if(!node->_intern)
return;
2979 render_ray_polyrep(node);
2985 if(node->_method == 1){
2986 if (!node->_patch)
return;
2987 collide_genericfaceset(X3D_INDEXEDFACESET(node->_patch));
2989 if(node->_method == 2){
2990 if (!node->_intern)
return;
2991 collide_genericfaceset(X3D_INDEXEDFACESET(node));
2997 if(node->_method == 1){
2999 if (!node->_patch->_intern)
3002 CULL_FACE(patch->solid)
3003 render_polyrep(patch);
3005 if(node->_method == 2){
3009 render_polyrep(node);
3017 for(i=0;i<node->geometry.n;i++){
3019 switch(gn->_nodeType){
3020 case NODE_NurbsCurve:
3023 g->_tscale = node->tessellationScale;
3027 case NODE_NurbsCurve2D:
3030 g->_tscale = node->tessellationScale;
3034 case NODE_NurbsPatchSurface:
3037 g->_tscale = node->tessellationScale;
3041 case NODE_NurbsTrimmedSurface:
3044 g->_tscale = node->tessellationScale;
3048 case NODE_NurbsSweptSurface:
3051 if(g->_method == 1){
3054 patch->_tscale = node->tessellationScale;
3058 if(g->_method == 2){
3060 curve->_tscale = node->tessellationScale;
3061 MNX(g->crossSectionCurve);
3063 curve->_tscale = node->tessellationScale;
3064 MNX(g->trajectoryCurve);
3068 case NODE_NurbsSwungSurface:
3073 patch->_tscale = node->tessellationScale;
3096void do_NurbsPositionInterpolator (
void *node) {}
3097void do_NurbsOrientationInterpolator (
void *node){}
3098void do_NurbsSurfaceInterpolator (
void *_node){}