rendered paste bodyfloat _Oslo(double *KnotVectorX, double *KnotVectorY, int K, int J, int I) { float NA,DA,NB,DB,RA,RB; //K ranges from Order-1 to 0 //J ranges from 0 to (tot pts - 1) //I ranges from 0 ... if (K == 1) { if ((KnotVectorY[J] >= KnotVectorX[I]) && (KnotVectorY[J] < KnotVectorX[I+1])) { return(1); } else { return(0); } //fi } else { NA= (KnotVectorY[J+K-1] - KnotVectorX[I]); DA= (KnotVectorX[I+K-1] - KnotVectorX[I]); NB= (KnotVectorX[I+K] - KnotVectorY[J+K-1]); DB= (KnotVectorX[I+K] - KnotVectorX[I+1]); if (DA) RA= (NA/DA); else RA= 0; if (DB) RB= (NB/DB); else RB= 0; return( RA*_Oslo(KnotVectorX,KnotVectorY,K-1,J,I) + RB*_Oslo(KnotVectorX,KnotVectorY,K-1,J,I+1) ); } //fi} //eof _Oslo()void NURBS_Knot::_Insert(Object_NURBS *obj, bool UV, double *KV, int KVLen) { Point3d *NewPts; int i,n,k,ind1,ind2; double oslo; UV ? obj -> SetLength(obj -> Length(0),KVLen - obj -> Order(1)) : obj -> SetLength(KVLen - obj -> Order(0),obj -> Length(1)); //NewPts= (Point3d*)malloc(sizeof(Point3d)*(KVLen - obj -> Order(UV))*obj -> Length(!UV)); NewPts= (Point3d*)MEM_callocN(sizeof(Point3d)*(KVLen - obj -> Order(UV))*obj -> Length(!UV),"_Insert() NewPts"); printf("_Insert::NewPts: %d\n",(KVLen - obj -> Order(UV))*obj -> Length(!UV)); // Assign the new Control Point Locations // Calculate New Control Points through Recursive Oslo Algorithm for (i= 0; i < obj -> Length(!UV); i++) { for (n= 0; n < KVLen - obj -> Order(UV); n++) { UV ? ind1= n+i*(KVLen - obj -> Order(UV)) : ind1= i+n*obj -> Length(!UV); NewPts[ind1].x= NewPts[ind1].y= NewPts[ind1].z= 0; for (k= 0; k < obj -> Length(UV); k++) { UV ? ind2= k+i*obj -> Length(UV) : ind2= i+k*obj -> Length(!UV); oslo= _Oslo(obj -> KnotVector(UV),KV,obj -> Order(UV),n,k); printf("oslo: %f\n",oslo); NewPts[ind1].x+= oslo * obj -> CtlPts()[ind2].x; NewPts[ind1].y+= oslo * obj -> CtlPts()[ind2].y; NewPts[ind1].z+= oslo * obj -> CtlPts()[ind2].z; } //eof } //eof } //eof obj -> Length(UV,KVLen - obj -> Order(UV)); // Save new points for (i= 0; i < obj -> Length(0) * obj -> Length(1); i++) { obj -> CtlPts()[i].x= NewPts[i].x; obj -> CtlPts()[i].y= NewPts[i].y; obj -> CtlPts()[i].z= NewPts[i].z; printf("pt[%d]: [%.3f][%.3f][%.3f]\n",i,NewPts[i].x,NewPts[i].y,NewPts[i].z); } //eof // Save new Knot Vector (U) for (i= 0; i < KVLen; i++) obj -> KnotVector(UV)[i]= KV[i]; MEM_freeN(NewPts);} //eof NURBS_Knot::_Insert()void NURBS_Knot::Subdivide(Object_NURBS *obj) { int i,n; double *KV; // Subdivide U if (obj -> Length(0) > 1) { //KV= (double*)malloc(sizeof(double)*2*(obj -> Length(0) + obj -> Order(0))); KV= (double*)MEM_callocN(sizeof(double)*2*(obj -> Length(0) + obj -> Order(0)),"Subdivide() KVu"); for (i= n= 0; i < obj -> Length(0) + obj -> Order(0) - 1; i++) { KV[n++]= obj -> KnotVector(0)[i]; if (obj -> KnotVector(0)[i+1] - obj -> KnotVector(0)[i]) KV[n++]= (obj -> KnotVector(0)[i+1] + obj -> KnotVector(0)[i])/2.0; } //eof KV[n++]= obj -> KnotVector(0)[i]; _Insert(obj,0,KV,n); MEM_freeN(KV); } //fi // Subdivide V if (obj -> Length(1) > 1) { //KV= (double*)malloc(sizeof(double)*2*(obj -> Length(1) + obj -> Order(1))); KV= (double*)MEM_callocN(sizeof(double)*2*(obj -> Length(1) + obj -> Order(1)),"Subdivide() KVv"); for (i= n= 0; i < obj -> Length(1) + obj -> Order(1) - 1; i++) { KV[n++]= obj -> KnotVector(1)[i]; if (obj -> KnotVector(1)[i+1] - obj -> KnotVector(1)[i]) KV[n++]= (obj -> KnotVector(1)[i+1] + obj -> KnotVector(1)[i])/2.0; } //eof KV[n++]= obj -> KnotVector(1)[i]; _Insert(obj,1,KV,n); //MEM_freeN(KV); eman FIXME } //fi} //eof NURBS_Knot::Subdivide()void NURBS_Knot::Insert(Object_NURBS *obj, int U, int V) { int IntPos,i,n,k; double IntLen,Length,KV[1]; if (U) { IntLen= 0; for (i= 0; i < obj -> Length(0) - obj -> Order(0) + 1; i++) { Length= 0; for (n= 0; n < obj -> Order(0) - 1; n++) for (k= 0; k < obj -> Length(1); k++) Length+= NurbanaMath::Dist3d(obj -> CtlPts()[(i+n)*obj -> Length(1) + k], obj -> CtlPts()[(i+n+1)*obj -> Length(1) + k]); Length/= obj -> Length(1); if (Length > IntLen) { IntLen= Length; IntPos= i; } //fi } //eof// printf("New Knot: %f\n",(obj -> KnotVector(0)[obj -> Order(0) + IntPos - 1] + obj -> KnotVector(0)[obj -> Order(0) + IntPos])/2.0); KV[0]= (obj -> KnotVector(0)[obj -> Order(0) + IntPos - 1] + obj -> KnotVector(0)[obj -> Order(0) + IntPos])/2.0; Refine(obj,KV,1,0); Insert(obj,U-1,V); } else if (V) { IntLen= 0; for (i= 0; i < obj -> Length(1) - obj -> Order(1) + 1; i++) { Length= 0; for (n= 0; n < obj -> Order(1) - 1; n++) for (k= 0; k < obj -> Length(0); k++) Length+= NurbanaMath::Dist3d(obj -> CtlPts()[(k)*obj -> Length(1) + i+n], obj -> CtlPts()[(k)*obj -> Length(1) + i+n+1]); Length/= obj -> Length(1); if (Length > IntLen) { IntLen= Length; IntPos= i; } //fi } //eof// printf("New Knot: %f\n",(obj -> KnotVector(0)[obj -> Order(0) + IntPos - 1] + obj -> KnotVector(0)[obj -> Order(0) + IntPos])/2.0); KV[0]= (obj -> KnotVector(1)[obj -> Order(1) + IntPos - 1] + obj -> KnotVector(1)[obj -> Order(1) + IntPos])/2.0; Refine(obj,KV,1,1); Insert(obj,U,V-1); } //fi} //eof NURBS_Knot::Insert()float _Dist4d(Point3d P1, Point3d P2) { return( sqrt((P2.x-P1.x)*(P2.x-P1.x)+(P2.y-P1.y)*(P2.y-P1.y)+(P2.z-P1.z)*(P2.z-P1.z)) );} //eof _Dist4d()