Main Page   Class Hierarchy   Compound List   File List   Compound Members  

nurbsArray.cpp

00001 /*=====================================================================
00002         File: nurbsArray.h
00003      Purpose:       
00004     Revision: $Id: nurbsArray.cpp,v 1.3 2003/01/13 19:41:48 philosophil Exp $
00005   Created by: Philippe Lavoie          (7 Oct, 1997)
00006   
00007 
00008  Copyright notice:
00009           Copyright (C) 1996-1997 Philippe Lavoie
00010  
00011           This library is free software; you can redistribute it and/or
00012           modify it under the terms of the GNU Library General Public
00013           License as published by the Free Software Foundation; either
00014           version 2 of the License, or (at your option) any later version.
00015  
00016           This library is distributed in the hope that it will be useful,
00017           but WITHOUT ANY WARRANTY; without even the implied warranty of
00018           MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019           Library General Public License for more details.
00020  
00021           You should have received a copy of the GNU Library General Public
00022           License along with this library; if not, write to the Free
00023           Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00024 =====================================================================*/
00025 
00026 #ifndef PLIB_NURBS_NURBSARRAY_SOURCE
00027 #define PLIB_NURBS_NURBSARRAY_SOURCE
00028 
00029 
00030 #include <nurbs.h>
00031 #include <nurbsS.h>
00032 #include <string.h>
00033 
00036 namespace PLib {
00037 
00044 template <class T, int N>
00045 NurbsCurveArray<T,N>::NurbsCurveArray(NurbsCurve<T,N>* Ca, int s){
00046   sze = rsize = 0 ;
00047   resize(s) ;
00048   for(int i=0;i<n();++i)
00049     C[i] = &Ca[i] ;
00050 }
00051 
00061 template <class T, int N>
00062 void NurbsCurveArray<T,N>::init(NurbsCurve<T,N>* ca,int size){
00063   resize(size) ;
00064   for(int i=0;i<n();++i)
00065     C[i] = &ca[i] ;
00066 }
00067 
00076 template <class T, int N>
00077 void NurbsCurveArray<T,N>::resize(int size) {
00078   int i ;
00079   if(size<=rsize){
00080     sze = size ;
00081     return ;
00082   }
00083   NurbsCurve<T,N>** t;
00084   t = new NurbsCurve<T,N>* [size] ;
00085   if(C){
00086     for(i=0;i<rsize;++i)
00087       t[i] = C[i] ;
00088     delete []C ;
00089   }
00090   for(i=rsize;i<size;++i)
00091     t[i] = new NurbsCurve<T,N> ;
00092   C = t ;
00093   sze = size ;
00094   rsize = size ;
00095 }
00096 
00107 template <class T, int N>
00108 int NurbsCurveArray<T,N>::read(const char* filename){
00109   ifstream fin(filename) ;
00110   if(!fin) {
00111     return 0 ;
00112   }
00113   int np,d;
00114   int na ;
00115   char *type ;
00116   type = new char[3] ;
00117   if(!fin.read(type,sizeof(char)*3)) return 0 ;
00118   int r1 = strncmp(type,"nca",3) ;
00119   if(!(r1==0))
00120     return 0 ;
00121   if(!fin.read((char*)&na,sizeof(int))) return 0 ;
00122 
00123   resize(na) ;
00124 
00125   int nread = 0 ;
00126   while(nread < na){
00127     if(!fin.read((char*)&np,sizeof(int))) return 0 ;
00128     if(!fin.read((char*)&d,sizeof(int))) return 0 ;
00129     
00130     operator[](nread).resize(np,d) ;
00131     
00132     if(!fin.read((char*)operator[](nread).knot().memory(),sizeof(T)*operator[](nread).knot().n())) return 0 ;
00133     
00134     T *p,*p2 ;
00135     p = new T[4*np] ;
00136     if(!fin.read((char*)p,sizeof(T)*4*np)) return 0 ;
00137     p2 = p ;
00138     for(int i=0;i<np;++i){
00139       HPoint_nD<T,N> t ;
00140       t.x() = *(p++) ;
00141       t.y() = *(p++) ;
00142       t.z() = *(p++) ;
00143       t.w() = *(p++) ;
00144       operator[](nread).modCP(i,t) ;
00145     }
00146     delete []p2 ;
00147     ++nread ;
00148   }
00149 
00150   delete []type ;
00151   return 1 ;
00152 }
00153 
00154 
00165 template <class T, int N>
00166 int NurbsCurveArray<T,N>::write(const char* filename){
00167   ofstream fout(filename) ;
00168   if(!fout) {
00169     return 0 ;
00170   }
00171   if(!fout.write((char*)&"nca",sizeof(char)*3)) return 0 ;
00172   if(!fout.write((char*)&sze,sizeof(int))) return 0 ;
00173 
00174   int nwrote = 0 ;
00175   while(nwrote < sze){
00176     int nn = operator[](nwrote).ctrlPnts().n() ;
00177     int nd = operator[](nwrote).degree() ; 
00178     if(!fout.write((char*)&nn,sizeof(int))) return 0 ;
00179     if(!fout.write((char*)&nd,sizeof(int))) return 0 ;
00180     if(!fout.write((char*)operator[](nwrote).knot().memory(),sizeof(T)*operator[](nwrote).knot().n())) return 0 ;
00181         
00182     T *p,*p2 ;
00183     p = new T[4*operator[](nwrote).ctrlPnts().n()] ;
00184     p2 = p ;
00185     for(int i=0;i<operator[](nwrote).ctrlPnts().n();++i){
00186       *p = operator[](nwrote).ctrlPnts()[i].x() ; ++p ;
00187       *p = operator[](nwrote).ctrlPnts()[i].y() ; ++p ;
00188       *p = operator[](nwrote).ctrlPnts()[i].z() ; ++p ;
00189       *p = operator[](nwrote).ctrlPnts()[i].w() ; ++p ;
00190     }
00191     if(!fout.write((char*)p2,sizeof(T)*4*operator[](nwrote).ctrlPnts().n())) return 0 ;
00192     delete []p2 ;
00193 
00194     ++nwrote ;
00195   }
00196 
00197   return 1 ;
00198 }
00199 
00206 template <class T, int N>
00207 NurbsSurfaceArray<T,N>::NurbsSurfaceArray(NurbsSurface<T,N>* Sa, int s){
00208   sze = rsize = 0 ;
00209   resize(s) ;
00210   for(int i=0;i<n();++i)
00211     S[i] = &Sa[i] ;
00212 }
00213 
00223 template <class T, int N>
00224 void NurbsSurfaceArray<T,N>::init(NurbsSurface<T,N>* Sa,int size){
00225   resize(size) ;
00226   for(int i=0;i<n();++i)
00227     S[i] = &Sa[i] ;
00228 }
00229 
00238 template <class T, int N>
00239 void NurbsSurfaceArray<T,N>::resize(int size) {
00240   int i ;
00241   if(size<=rsize){
00242     sze = size ;
00243     return ;
00244   }
00245   NurbsSurface<T,N>** t;
00246   t = new NurbsSurface<T,N>* [size] ;
00247   if(S){
00248     for(i=0;i<rsize;++i)
00249       t[i] = S[i] ;
00250     delete []S ;
00251   }
00252   for(i=rsize;i<size;++i)
00253     t[i] = new NurbsSurface<T,N> ;
00254   S = t ;
00255   sze = size ;
00256   rsize = size ;
00257 }
00258 
00269 template <class T, int N>
00270 NurbsSurfaceArray<T,N>& NurbsSurfaceArray<T,N>::operator=(const NurbsSurfaceArray<T,N>& Sa){
00271   resize(Sa.n()) ;
00272 
00273   for(int i=0;i<n();++i)
00274     *(S[i]) = Sa[i] ;
00275   return *this ;
00276 }
00277 
00278 
00279 // duplicating some codes from nurbs.cpp
00280 #ifndef INCLUDE_TEMPLATE_SOURCE
00281 
00282 template <class T, int N>
00283 inline Point_nD<T,N> project2D(const HPoint_nD<T,N>& p){
00284   Point_nD<T,N> pnt ;
00285   if(absolute(p.z()+T(1))>0.0001){
00286     pnt.x() = p.x()/p.w() ;
00287     pnt.y() = p.y()/p.w() ;
00288     //pnt.x() /= p.z()+1 ; 
00289     //pnt.y() /= p.z()+1 ; 
00290   }
00291   else{
00292     pnt.x() = p.x()/p.w();
00293     pnt.y() = p.y()/p.w();
00294   }
00295   return pnt ;
00296 }
00297 
00298 const float offX = 50 ;
00299 const float offY = 70 ;
00300 
00301 template <class T>
00302 inline void movePsP(Point_nD<T,3> &p, T magFact){
00303   p *= magFact ;
00304   p += Point_nD<T,3>(offX,offY,0) ;
00305   //p = p*magFact+Point_nD<T,N>(offX,offY,0)  ;
00306 }
00307 
00308 template <class T>
00309 inline void movePsP(Point_nD<T,2> &p, T magFact){
00310   p *= magFact ;
00311   p += Point_nD<T,2>(offX,offY) ;
00312   //p = p*magFact+Point_nD<T,N>(offX,offY,0)  ;
00313 }
00314 
00315 #endif // !INCLUDE_TEMPLATE_SOURCE
00316 
00317 
00343 template <class T, int N>
00344 int NurbsCurveArray<T,N>::writePS(const char* filename,int cp,T magFact, T dash, bool ) const {
00345 
00346   ofstream fout(filename) ;  
00347 
00348   if(!fout)
00349     return 0 ;
00350 
00351   if(curve(0).degree()<3){
00352     NurbsCurveArray<T,N> a3 ;
00353     a3.resize(n()) ;
00354     for(int i=0;i<sze;++i){
00355       a3[i] = curve(i) ;
00356       a3[i].degreeElevate(3 - curve(i).degree()) ;
00357     }
00358     return a3.writePS(filename,cp,magFact,dash) ;
00359   }
00360   if(curve(0).degree()>3){
00361     return 0 ; 
00362   }
00363 
00364   // find bounding box parameters
00365   T mx,my,Mx,My ;
00366   mx = Mx = 0 ;
00367   my = My = 0 ;
00368 
00369   for(int i=0;i<n();++i){
00370     Point_nD<T,N> p ;
00371     int step ;
00372     step = curve(i).ctrlPnts().n() + 5 ;
00373     for(int j=0;j<=step;++j){
00374       T u ;
00375       u = (T)j/(T)step ;
00376       p = project2D(curve(i)(u)) ;
00377       if(i==0){
00378         mx = Mx = p.x() ;
00379         my = My = p.y() ;
00380       }
00381       if(p.x() < mx)
00382         mx = p.x() ;
00383       if(p.x() > Mx)
00384         Mx = p.x() ;
00385       if(p.y() < my)
00386         my = p.y() ;
00387       if(p.y() > My) 
00388         My = p.y() ;      
00389     }
00390   }
00391 
00392   int guess =0 ;
00393   if(magFact<= T() ){
00394     magFact = T(1) ;
00395     guess = 1 ;
00396   }
00397   
00398   if(guess){
00399     //magFact = minimum((T)500/(T)(Mx-mx),(T)700/(T)(My-my)) ;
00400   }
00401 
00402   mx = mx*magFact+offX;
00403   my = my*magFact+offY;
00404   Mx = Mx*magFact+offX;
00405   My = My*magFact+offY;
00406 
00407 
00408   fout << "%!PS-Adobe-2.1\n%%Title: " << filename << endl ;
00409   fout << "%%Creator: NurbsCurve<T,N>::writePS\n" ;
00410   fout << "%%BoundingBox: " << mx << ' ' << my << ' ' << Mx << ' ' << My << endl ;
00411   fout << "%%Pages: 0" << endl ;
00412   fout << "%%EndComments" << endl ;
00413   fout << "0 setlinewidth\n" ;
00414   fout << "0 setgray\n" ;
00415   fout << endl ;
00416 
00417   for(int k=0;k<n();++k){
00418     NurbsCurveArray<T,N> Ca ;
00419     curve(k).decompose(Ca) ;
00420     int deg = curve(k).degree() ;
00421 
00422     Matrix< Point_nD<T,N> > pnts(Ca.n(),deg+1) ;
00423     int i,j ;
00424 
00425     for(i=0;i<Ca.n();++i){
00426       for(j=0;j<deg+1;++j){
00427         pnts(i,j) = project2D(Ca[i].ctrlPnts()[j]) ;
00428         movePsP(pnts(i,j),magFact) ;
00429       }
00430     }
00431 
00432     fout << "newpath\n" ;
00433     fout << pnts(0,0).x() << ' ' << pnts(0,0).y() << " moveto\n" ;
00434     for(i=0;i<Ca.n();++i){
00435       for(j=1;j<deg+1;++j){
00436         fout << pnts(i,j).x() << ' ' << pnts(i,j).y() << ' ' ;
00437       }
00438       fout << "curveto\n" ;
00439     }
00440     fout << "stroke\n" ;
00441 
00442     if(cp>0){ // draw the control points of the original curve
00443       Vector< Point_nD<T,N> > pts(curve(k).ctrlPnts().n()) ;
00444       for(i=0;i<curve(k).ctrlPnts().n();++i){
00445         pts[i] = project2D(curve(k).ctrlPnts()[i]) ;
00446         movePsP(pts[i],magFact) ;
00447         fout << "newpath\n" ;
00448         fout << pts[i].x() << ' ' << pts[i].y() << "  3 0 360 arc\nfill\n" ;
00449       }
00450       if(dash>0)
00451         fout << "[" << dash << "] " << dash << " setdash\n" ;
00452       fout << "newpath\n" ;
00453     
00454       fout << pts[0].x() << ' ' << pts[0].y() << " moveto\n" ;
00455       for(i=1;i<curve(k).ctrlPnts().n();++i)
00456         fout << pts[i].x() << ' ' << pts[i].y() << " lineto\n" ;
00457       fout << "stroke\n" ;
00458     }
00459     else{
00460       if(cp<0){
00461         Vector< Point_nD<T,N> > pts(curve(k).ctrlPnts().n()*Ca.n()) ;
00462         int l=0 ;
00463         for(i=0;i<Ca.n();++i)
00464           for(j=0;j<deg+1;++j){
00465             pts[l] = project2D(Ca[i].ctrlPnts()[j]) ;
00466             movePsP(pts[l],magFact) ;
00467             fout << "newpath\n" ;
00468             fout << pts[l].x() << ' ' << pts[l].y() << "  3 0 360 arc\nfill\n" ;
00469             ++l ;
00470           }
00471         if(dash>0)
00472           fout << "[" << dash << "] " << dash << " setdash\n" ;
00473         fout << "newpath\n" ;
00474         
00475         fout << pts[0].x() << ' ' << pts[0].y() << " moveto\n" ;
00476         for(i=1;i<l;++i)
00477           fout << pts[i].x() << ' ' << pts[i].y() << " lineto\n" ;
00478         fout << "stroke\n" ;      
00479       }
00480     }
00481   }
00482 
00483   fout << "showpage\n%%EOF\n" ;
00484   return 1 ;
00485 }
00486 
00520 template <class T, int N>
00521 int NurbsCurveArray<T,N>::writePSp(const char* filename,const Vector< Point_nD<T,N> >& points, const Vector< Point_nD<T,N> >& vectors, int cp, T magFact, T dash, bool ) const {
00522 
00523   ofstream fout(filename) ;  
00524 
00525   if(!fout)
00526     return 0 ;
00527 
00528   if(curve(0).degree()<3){
00529     NurbsCurveArray<T,N> a3 ;
00530     a3.resize(n()) ;
00531     for(int i=0;i<n();++i){
00532       a3[i] = curve(i) ;
00533       a3[i].degreeElevate(3-curve(i).degree()) ;
00534     }
00535     return a3.writePSp(filename,points,vectors,cp,magFact,dash) ;
00536   }
00537   if(curve(0).degree()>3){
00538     return 0 ; 
00539   }
00540 
00541 
00542   // find bounding box parameters
00543   T mx,my,Mx,My ;
00544   mx = Mx = 0 ;
00545   my = My = 0 ;
00546 
00547   for(int i=0;i<n();++i){
00548     Point_nD<T,N> p ;
00549     int step ;
00550     step = curve(i).ctrlPnts().n() + 5 ;
00551     for(int j=0;j<=step;++j){
00552       T u ;
00553       u = (T)j/(T)step ;
00554       p = project2D(curve(i)(u)) ;
00555       if(i==0){
00556         mx = Mx = p.x() ;
00557         my = My = p.y() ;
00558       }
00559       if(p.x() < mx)
00560         mx = p.x() ;
00561       if(p.x() > Mx)
00562         Mx = p.x() ;
00563       if(p.y() < my)
00564         my = p.y() ;
00565       if(p.y() > My) 
00566         My = p.y() ;      
00567     }
00568   }
00569 
00570   int guess =0 ;
00571   if(magFact<= T() ){
00572     magFact = T(1) ;
00573     guess = 1 ;
00574   }
00575   
00576   if(guess){
00577     //magFact = minimum((T)500/(T)(Mx-mx),(T)700/(T)(My-my)) ;
00578   }
00579 
00580   mx = mx*magFact+offX;
00581   my = my*magFact+offY;
00582   Mx = Mx*magFact+offX;
00583   My = My*magFact+offY;
00584 
00585 
00586   fout << "%!PS-Adobe-2.1\n%%Title: " << filename << endl ;
00587   fout << "%%Creator: NurbsCurve<T,N>::writePS\n" ;
00588   fout << "%%BoundingBox: " << mx << ' ' << my << ' ' << Mx << ' ' << My << endl ;
00589   fout << "%%Pages: 0" << endl ;
00590   fout << "%%EndComments" << endl ;
00591   fout << "0 setlinewidth\n" ;
00592   fout << "0 setgray\n" ;
00593   fout << endl ;
00594 
00595   for(int k=0;k<n();++k){
00596     NurbsCurveArray<T,N> Ca ;
00597     curve(k).decompose(Ca) ;
00598     int deg = curve(k).degree() ;
00599 
00600     Matrix< Point_nD<T,N> > pnts(Ca.n(),deg+1) ;
00601     int i,j ;
00602 
00603     for(i=0;i<Ca.n();++i){
00604       for(j=0;j<deg+1;++j){
00605         pnts(i,j) = project2D(Ca[i].ctrlPnts()[j]) ;
00606         movePsP(pnts(i,j),magFact) ;
00607       }
00608     }
00609 
00610     fout << "newpath\n" ;
00611     fout << pnts(0,0).x() << ' ' << pnts(0,0).y() << " moveto\n" ;
00612     for(i=0;i<Ca.n();++i){
00613       for(j=1;j<deg+1;++j){
00614         fout << pnts(i,j).x() << ' ' << pnts(i,j).y() << ' ' ;
00615       }
00616       fout << "curveto\n" ;
00617     }
00618     fout << "stroke\n" ;
00619 
00620     if(cp>0){ // draw the control points of the original curve
00621       Vector< Point_nD<T,N> > pts(curve(k).ctrlPnts().n()) ;
00622       for(i=0;i<curve(k).ctrlPnts().n();++i){
00623         pts[i] = project2D(curve(k).ctrlPnts()[i]) ;
00624         movePsP(pts[i],magFact) ;
00625         fout << "newpath\n" ;
00626         fout << pts[i].x() << ' ' << pts[i].y() << "  3 0 360 arc\nfill\n" ;
00627       }
00628       if(dash>0)
00629         fout << "[" << dash << "] " << dash << " setdash\n" ;
00630       fout << "newpath\n" ;
00631     
00632       fout << pts[0].x() << ' ' << pts[0].y() << " moveto\n" ;
00633       for(i=1;i<curve(k).ctrlPnts().n();++i)
00634         fout << pts[i].x() << ' ' << pts[i].y() << " lineto\n" ;
00635       fout << "stroke\n" ;
00636     }
00637     else{
00638       if(cp<0){
00639         Vector< Point_nD<T,N> > pts(curve(k).ctrlPnts().n()*Ca.n()) ;
00640         int l=0 ;
00641         for(i=0;i<Ca.n();++i)
00642           for(j=0;j<deg+1;++j){
00643             pts[l] = project2D(Ca[i].ctrlPnts()[j]) ;
00644             movePsP(pts[l],magFact) ;
00645             fout << "newpath\n" ;
00646             fout << pts[l].x() << ' ' << pts[l].y() << "  3 0 360 arc\nfill\n" ;
00647             l++ ;
00648           }
00649         if(dash>0)
00650           fout << "[" << dash << "] " << dash << " setdash\n" ;
00651         fout << "newpath\n" ;
00652         
00653         fout << pts[0].x() << ' ' << pts[0].y() << " moveto\n" ;
00654         for(i=1;i<l;++i)
00655           fout << pts[i].x() << ' ' << pts[i].y() << " lineto\n" ;
00656         fout << "stroke\n" ;      
00657       }
00658     }
00659   }
00660 
00661   for(int i=0;i<points.n();++i){
00662     Point_nD<T,N> p ;
00663     p = points[i] ;
00664     movePsP(p,magFact) ;
00665     fout << "newpath\n" ;
00666     fout << p.x() << ' ' << p.y() << "  3 0 360 arc\nfill\n" ;
00667   }
00668 
00669   if(vectors.n()==points.n()){
00670     for(int i=0;i<points.n();++i){
00671       Point_nD<T,N> p,p2 ;
00672       p = points[i] ;
00673       p2 = points[i] + vectors[i] ;
00674       movePsP(p,magFact) ;
00675       movePsP(p2,magFact) ;
00676       fout << "newpath\n" ;
00677       fout << p.x() << ' ' << p.y() << " moveto\n" ;
00678       if(dash>0)
00679         fout << "[" << dash/2.0 << "] " << dash/2.0 << " setdash\n" ;
00680       fout << p2.x() << ' ' << p2.y() << " lineto\n" ;
00681       fout << "stroke\n" ;
00682     }
00683   }
00684 
00685   fout << "showpage\n%%EOF\n" ;
00686   return 1 ;
00687 }
00688 
00689 } // end namespace
00690 
00691 
00692 #endif //  PLIB_NURBS_NURBSARRAY_SOURCE

Generated on Tue Jun 24 13:26:57 2003 for NURBS++ by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002