Main Page   Class Hierarchy   Compound List   File List   Compound Members  

nurbsGL.cpp

00001 /*=============================================================================
00002   File: nurbsGL.cpp
00003   Purpose:       
00004   Revision: $Id: nurbsGL.cpp,v 1.4 2003/01/13 19:41:52 philosophil Exp $
00005   Created by: Philippe Lavoie          (28 September 1997)
00006   Modified by: 
00007 
00008   Copyright notice:
00009   Copyright (C) 1996-1998 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_NURBSGL_SOURCE
00027 #define PLIB_NURBS_NURBSGL_SOURCE
00028 
00029 #include <matrixRT.h>
00030 #include <nurbsGL.h>
00031 #include <string.h>
00032 #include <stdio.h>
00033 #include <iostream> 
00034 
00035 #ifdef WITH_OPENGL
00036 
00039 namespace PLib {
00040 
00041   Color objectColorDefault(255,255,255) ;
00042   Color selectColorDefault(0,255,0) ;
00043   Color currentColorDefault(0,255,255) ;
00044 
00045   Color axisXColorDefault(255,0,0) ;
00046   Color axisYColorDefault(0,255,0) ;
00047   Color axisZColorDefault(0,0,255) ;
00048 
00049   Color cpointColorDefault(255,0,0) ;
00050   Color cpoint0ColorDefault(255,255,255) ;
00051   Color cpointActiveColorDefault(255,0,255) ;
00052   Color cPolygonColorDefault(255,255,0)  ;
00053 
00054   Color knotColorDefault(255,255,0) ;
00055   Color knotActiveColorDefault(0,255,255) ;
00056 
00057   HPoint3Df dummyCPoint ;
00058 
00059   int pSizeDefault = 4 ;
00060 
00061   ObjectGLState objectStateDefault = objectState;
00062 
00063 
00064   const int NURBS_FLAGS_AFFECT_ALL = 1 ;
00065   const int NURBS_FLAGS_AFFECT_ACTIVE_ONLY = 2 ;
00066   const int NURBS_FLAGS_AFFECT_SELECTED_ONLY = 4 ;
00067   const int NURBS_FLAGS_VIEW_BBOX = 8 ; // view the bbox even if object is in hidden.
00068 
00069   const int NURBSLIST_DELETE_AT_RESET = 1;
00070   const int NURBSLIST_KEEP_AT_RESET = 0 ;
00071 
00072   const int NURBS_DISPLAY_NORMAL = 0 ;
00073   const int NURBS_DISPLAY_ISOCURVES  = 1 ;
00074   const int NURBS_DISPLAY_SHADED = 2 ;
00075   const int NURBS_DISPLAY_HIDDEN_LINES = 3 ; 
00076   const int NURBS_DISPLAY_TESSELATION = 4 ;
00077   const int NURBS_DISPLAY_SOLID = 5;
00078 
00079   float tessel_tolerance ;
00080 
00081   int NurbsDisplayMode = 0 ;
00082 
00083 
00084   Point3Df XAxis_3D(1,0,0) ;
00085   Point3Df YAxis_3D(0,1,0) ;
00086   Point3Df ZAxis_3D(0,0,1) ;
00087 
00088 
00089 
00090   void initColorsGL(){
00091     objectColorDefault = Color(0,0,0) ;
00092     selectColorDefault = Color(0,255,0) ;
00093     currentColorDefault = Color(0,255,255) ;
00094   
00095     axisXColorDefault = Color(255,0,0) ;
00096     axisYColorDefault = Color(0,255,0) ;
00097     axisZColorDefault = Color(0,0,255) ;
00098   
00099     cpointColorDefault = Color(255,0,0) ;
00100     cpoint0ColorDefault = Color(255,255,255) ;
00101     cPolygonColorDefault = Color(255,255,0)  ;
00102   
00103     objectStateDefault = objectState;  
00104   }
00105 
00117   ObjectGL::ObjectGL(){
00118     prev_ = 0 ;
00119     next_ = 0 ;
00120     category = badType ; 
00121     callListId = 0 ;
00122     state = objectStateDefault ;
00123     objectColor = objectColorDefault ;
00124     selectColor = selectColorDefault ;
00125     currentColor = currentColorDefault ;
00126     tx = ty = tz = 0 ;
00127     rx = ry = rz = 0 ;
00128     sx = sy = sz = 1 ;
00129     materialColor = new float[4] ;
00130     active = selected = 0 ;
00131     name_ = new char[strlen("unknown")+1] ; 
00132     strcpy(name_,"unknown") ; 
00133   }
00134 
00145   void ObjectGL::setName(const char* n){
00146     int len = strlen(n) ;
00147     if(name_)
00148       delete []name_ ; 
00149     name_ = new char[len+1] ; 
00150     strcpy(name_,n) ; 
00151   }
00152 
00161   char* ObjectGL::typeName() const {
00162     switch(type){
00163     case badObject: return "bad object" ;  break ;
00164     case curveObject: return "NURBS curve" ; break ; 
00165     case surfaceObject: return "NURBS surface" ; break ; 
00166     case pointObject: return "point in 3D" ;  break ; 
00167     case cpointObject: return "control point" ;  break ; 
00168     case cpointPolygonObject: return "control point polygon" ; break ; 
00169     case bboxObject: return "bounding box" ; break ; 
00170     case vectorObject: return "vector" ; break ; 
00171     case listObject: return "list of objects" ; break ; 
00172     case hSurfObject: return "HNURBS surface" ; break ; 
00173     case hcpointObject: return "control point" ; break ; 
00174     case pointListObject: return "list of points" ; break ; 
00175     case spointObject: return "surface point";  break ; 
00176     default:
00177       return 0;
00178     };
00179     return 0 ;
00180   }
00181 
00182 
00193   void ObjectGL::glTransform() const { 
00194     glScalef(sx,sy,sz) ; 
00195     glTranslatef(tx,ty,tz) ; 
00196     glRotatef(rx,1,0,0) ; 
00197     glRotatef(ry,0,1,0) ; 
00198     glRotatef(rz,0,0,1) ; 
00199   }
00200 
00207   ObjectGL::~ObjectGL(){
00208     /*
00209       if(next_){
00210       next_->prev_ = prev_ ;
00211       }
00212       if(prev_){
00213       prev_->next_ = next_ ;
00214       }
00215     */
00216     next_ = 0 ;
00217     prev_ = 0 ;
00218     if(materialColor)
00219       delete materialColor ;
00220     if(name_)
00221       delete []name_ ; 
00222   }
00223 
00235   ObjectListGL::ObjectListGL():ObjectGL(){
00236     first_ = 0 ;
00237     last_ = 0 ;
00238     current_ = 0 ;
00239     n = 0 ;
00240     resetMode = NURBSLIST_DELETE_AT_RESET ;
00241   }
00242 
00249   ObjectListGL::~ObjectListGL(){
00250     reset() ;
00251   }
00252 
00259   ObjectRefListGL::~ObjectRefListGL(){
00260     reset() ;
00261   }
00262 
00272   void ObjectListGL::reset(){
00273     if(resetMode==NURBSLIST_DELETE_AT_RESET){
00274       ObjectGL *c ;
00275       c = first_ ;
00276       while(c){
00277         current_ = c ;
00278         c = current_->next() ;
00279         delete current_ ;
00280       }
00281     }
00282     first_ = current_ = last_ = 0 ;
00283     n = 0 ;
00284   }
00285 
00308   void ObjectListGL::transformBy(GLfloat x, GLfloat y, GLfloat z, GLfloat a, GLfloat b, GLfloat c,GLfloat sx, GLfloat sy, GLfloat sz, int behavior){
00309     ObjectGL *t ;
00310     t = first_ ;
00311     while(t){
00312       if(!(behavior & NURBS_FLAGS_AFFECT_ALL)){
00313         if(behavior & NURBS_FLAGS_AFFECT_ACTIVE_ONLY){
00314           if(!t->isActive()){
00315             t = t->next() ;
00316             continue ;
00317           }
00318         }
00319         if(behavior & NURBS_FLAGS_AFFECT_SELECTED_ONLY){
00320           if(!t->isSelected()){
00321             t = t->next() ;
00322             continue ;
00323           }
00324         }
00325       }
00326       t->tx += x ;
00327       t->ty += y ;
00328       t->tz += z ;
00329       t->rx += a ;
00330       t->ry += b ;
00331       t->rz += c ;
00332       t->sx += sx ;
00333       t->sy += sy ;
00334       t->sz += sz ;
00335       t = t->next() ;
00336     }
00337   }
00338 
00361   void ObjectListGL::transformTo(GLfloat x, GLfloat y, GLfloat z, GLfloat a, GLfloat b, GLfloat c,GLfloat sx, GLfloat sy, GLfloat sz, int behavior){
00362     ObjectGL *t ;
00363     t = first_ ;
00364     while(t){
00365       if(!(behavior & NURBS_FLAGS_AFFECT_ALL)){
00366         if(behavior & NURBS_FLAGS_AFFECT_ACTIVE_ONLY){
00367           if(!t->isActive()){
00368             t = t->next() ;
00369             continue ;
00370           }
00371         }
00372         if(behavior & NURBS_FLAGS_AFFECT_SELECTED_ONLY){
00373           if(!t->isSelected()){
00374             t = t->next() ;
00375             continue ;
00376           }
00377         }
00378       }
00379       t->tx = x ;
00380       t->ty = y ;
00381       t->tz = z ;
00382       t->rx = a ;
00383       t->ry = b ;
00384       t->rz = c ;
00385       t->sx = sx ;
00386       t->sy = sy ;
00387       t->sz = sz ;
00388       t = t->next() ;
00389     }
00390   }
00391 
00398   void CPointGL::glObject() const { 
00399     glDisable(GL_LIGHTING);
00400     glPointSize(psize) ;
00402     glBegin(GL_POINTS) ;
00403     glVertex4fv(cpoint.data) ;
00404     glEnd() ;
00405     glEnable(GL_LIGHTING);
00406   }
00407 
00414   void PointListGL::glObject() const {
00415     BasicNode<Point3Df> *node ;
00416     node = static_cast<BasicNode<Point3Df>*>(list.first()) ;
00417 
00418     glPointSize(psize) ;
00419     glDisable(GL_LIGHTING);
00420     glBegin(GL_POINTS) ;  
00421     //for(int i=0;i<list.size();++i){
00423     for(int i=0;i<minimum(20000,list.size());++i){
00424       glVertex3f(node->data->x(),node->data->y(),node->data->z()) ;
00425       node = node->next ; 
00426     }
00427     glEnd() ;
00428     glEnable(GL_LIGHTING);
00429   }
00430 
00431 
00440   PointListGL::PointListGL(const BasicList<Point3Df> &l): ObjectGL(){
00441     category = pointType ;
00442     type = pointListObject ;
00443     psize = pSizeDefault ;
00444     list = l ;
00445   }
00446 
00447 
00455   PointListGL::PointListGL(const PointListGL &pl): ObjectGL(){
00456     category = pointType ;
00457     type = pointListObject ;
00458     psize = pl.psize ;
00459     list = pl.list ;
00460   }
00461 
00462 
00470   int PointListGL::read(ifstream &fin) {
00471     list.reset() ;
00472 
00473     char *type ;
00474     type = new char [3] ;
00475 
00476     if(!fin.read(type,sizeof(char)*3)) { delete []type ; return 0 ;}
00477     int r1 = strncmp(type,"pt3",3) ;
00478   
00479     if(r1!=0){
00480       delete []type ;
00481       return 0 ;
00482     }
00483     setPsize(2) ;
00484 
00485     while(!fin.eof()){
00486       int mark = fin.tellg() ; // mark position
00487       if(!fin.read(type,sizeof(char)*3)) { delete []type ; return 1 ; }
00488       fin.seekg(mark) ; // restore position
00489       char* ext ;
00490       ext = strstr(type,"#") ;
00491       if(ext) { // this line is a comment
00492         while( *ext != '\n'){
00493           fin.read(ext,sizeof(char)) ;
00494         }
00495       }
00496       else { 
00497         ext = strstr(type,"X") ;
00498         if(ext){ // end of list of points
00499           while(*type != 'X')
00500             fin.read(type,sizeof(char)) ;
00501           fin.read(type,sizeof(char));
00502           delete []type ;
00503           return 1 ;
00504         }
00505         // it should be 3 points as in    x  y  z
00506         double x, y, z ;
00507         if(fin >> x >> y >> z){
00508           Point3Df p;
00509           //float scale = 10.0 ;
00510           //p = Point3Df(x/scale,y/scale,z/scale) ;
00511           p = Point3Df(x,y,z) ;
00512           /*
00513             if(list.size()==0)
00514             offset = p ;
00515             p -= offset  ;
00516           */
00517           list.add(p) ;
00518         }
00519         else{
00520           delete []type ;
00521           return 0 ;
00522         }
00523       }
00524     }
00525     return 1 ;
00526 
00527   }
00528 
00537   int PointListGL::write(ofstream &fout) const {
00538     fout << "pt3" ;
00539     BasicNode<Point3Df> *node ;
00540     node = (BasicNode<Point3Df>*)list.first() ;
00541 
00542     for(int i=0;i<list.size();++i){
00543       fout << *(node->data) << endl ;
00544       node = node->next ;
00545     }
00546     fout << "X\n" ;
00547     if(!fout)
00548       return 0 ;
00549     return 1 ;
00550   }
00551 
00552 
00559   void HCPointGL::glObject() const {
00560     glPointSize(psize) ;
00561     glDisable(GL_LIGHTING);
00563     glBegin(GL_POINTS) ;
00564     glVertex4fv(s->ctrlPnts()(i0,j0).data) ;
00565     glEnd() ;
00566     glEnable(GL_LIGHTING);
00567   }
00568 
00578   void SPointCurveGL::glObject() const {
00579     glPointSize(psize) ;
00580     glDisable(GL_LIGHTING);
00582     glBegin(GL_POINTS) ;
00583     glVertex4fv(cpoint.data) ;
00584     glEnd() ;
00585     glEnable(GL_LIGHTING);
00586   }
00587 
00597   void SPointSurfaceGL::glObject() const {
00598     glPointSize(psize) ;
00599     glDisable(GL_LIGHTING);
00601     glBegin(GL_POINTS) ;
00602     glVertex4fv(cpoint.data) ;
00603     glEnd() ;
00604     glEnable(GL_LIGHTING);
00605   }
00606 
00616   void SPointHSurfaceGL::glObject() const {
00617     glPointSize(psize) ;
00618     glDisable(GL_LIGHTING);
00620     glBegin(GL_POINTS) ;
00621     glVertex4fv(cpoint.data) ;
00622     glEnd() ;
00623     glEnable(GL_LIGHTING);
00624   }
00625 
00632   void HCPointGL::modify(const HPoint3Df& v) {
00633     if(canModify){
00634       offset += v ; 
00635       s->updateSurface(i0,j0) ;
00636     }
00637   }
00638 
00645   void PointGL::glObject() const {
00646     glPointSize(psize) ;
00647     glDisable(GL_LIGHTING);
00649     glBegin(GL_POINTS) ;
00650     glVertex3fv(p.data) ;
00651     glEnd() ;
00652     glEnable(GL_LIGHTING);
00653   }
00654 
00661   void KnotGL::glObject() const {
00662     glPointSize(psize) ;
00663     glDisable(GL_LIGHTING);
00665     glBegin(GL_POINTS) ;
00666     glVertex3fv(p.data) ;
00667     glEnd() ;
00668     glEnable(GL_LIGHTING);
00669   }
00670 
00680   void ObjectListGL::glObject() const {
00681     ObjectGL *t ;
00682     t = first_ ;
00683     while(t){
00684       if(t->getState())
00685         t->glObject() ;
00686       t = t->next() ;
00687     }
00688   }
00689 
00696   void ObjectListGL::display() const {
00697     ObjectGL *t ;
00698     t = first_ ;
00699     while(t){
00700       if(t->getState()){
00701         glPushMatrix() ;
00702         t->glTransform() ;
00703         t->glObject() ;
00704         glPopMatrix() ;
00705       }
00706       t = t->next() ;
00707     }
00708   }
00709 
00716   void ObjectListGL::displayName() const {
00717     ObjectGL *t ;
00718     int name = 1 ;
00719     t = first_ ;
00720     while(t){
00721       if(t->getState()){
00722         glPushMatrix() ;
00723         t->glTransform() ;
00724         glLoadName(name) ;
00725         t->glObject() ;
00726         glPopMatrix() ;
00727         ++name ;
00728       }
00729       t = t->next() ;
00730     }
00731   }
00732 
00739   void NurbsListGL::glObject() const {
00740     ObjectGL *t ;
00741     t = first_ ;
00742     while(t){
00743       t->glObject() ;
00744       t = t->next() ;
00745     }
00746   }
00747 
00754   void NurbsListGL::display() const {
00755     ObjectGL *t ;
00756     t = first_ ;
00757     while(t){
00758       glPushMatrix() ;
00759       t->glTransform() ;
00760       t->glObject() ;
00761       glPopMatrix() ;
00762       t = t->next() ;
00763     }
00764   }
00765 
00782   void NurbsListGL::resetDisplayFlags(int o, int cp, int p, int b, int k, int behavior) {
00783     ObjectGL *pnt ;
00784     pnt = (ObjectGL*)first_ ;
00785 
00786     NurbsGL *t ;
00787     while(pnt){
00788       if(pnt->category == nurbsType)
00789         t = (NurbsGL*)pnt ;
00790       else{
00791         pnt = pnt->next() ;
00792         continue ;
00793       }
00794       
00795       if(!(behavior & NURBS_FLAGS_AFFECT_ALL)){
00796         if(behavior & NURBS_FLAGS_AFFECT_ACTIVE_ONLY){
00797           if(!t->isActive()){
00798             //t = (NurbsGL*)t->next() ;
00799             pnt = pnt->next() ;
00800             continue ;
00801           }
00802         }
00803         if(behavior & NURBS_FLAGS_AFFECT_SELECTED_ONLY){
00804           if(!t->isSelected()){
00805             //t = (NurbsGL*)t->next() ;
00806             pnt = pnt->next() ;
00807             continue ;
00808           }
00809         }
00810       }
00811       if(o){
00812         if(cp)
00813           t->viewCPoints() ;
00814         else
00815           t->hideCPoints() ;
00816         if(p)
00817           t->viewCpolygon() ;
00818         else
00819           t->hideCpolygon() ;
00820         if(b)
00821           t->viewBBox() ;
00822         else
00823           t->hideBBox() ;
00824         if(k)
00825           t->viewKnots() ;
00826         else
00827           t->hideKnots() ;
00828         t->viewObject() ;
00829       }
00830       else{
00831         if(behavior & NURBS_FLAGS_VIEW_BBOX){
00832           if(b)
00833             t->viewBBox() ;
00834           else
00835             t->hideBBox() ;
00836         }
00837         t->hideObject() ;
00838       }
00839     
00840       pnt = pnt->next() ; // (NurbsGL*)t->next() ;
00841     }
00842   }
00843 
00850   void ObjectListGL::deactivate() {
00851     ObjectGL *t ;
00852     t = first_ ;
00853     while(t){
00854       t->deactivate() ;
00855       t = t->next() ;
00856     }
00857   }
00858 
00865   void ObjectListGL::activate(){
00866     ObjectGL *t ;
00867     t = first_ ;
00868     while(t){
00869       t->activate() ;
00870       t = t->next() ;
00871     }
00872   }
00873 
00880   void ObjectListGL::select(){
00881     ObjectGL *t ;
00882     t = first_ ;
00883     while(t){
00884       t->select() ;
00885       t = t->next() ;
00886     }
00887   }
00888 
00889 
00896   void ObjectListGL::deselect(){
00897     ObjectGL *t ;
00898     t = first_ ;
00899     while(t){
00900       t->deselect() ;
00901       t = t->next() ;
00902     }
00903   }
00904 
00918   ObjectGL* ObjectListGL::goTo(int a){
00919     if(a>=n)
00920       return 0 ;
00921     current_ = first_ ;
00922     while(current_ && a>0){
00923       current_ = current_->next() ;
00924       --a ;
00925     }
00926     return current_ ;
00927   }
00928 
00942   ObjectGL* ObjectListGL::goToActive(int a){
00943     if(a>=n)
00944       return 0 ;
00945     current_ = first_ ;
00946     while(current_ ){
00947       if(current_->getState())
00948         --a ;
00949       if(a>=0)
00950         current_ = current_->next() ;
00951       else
00952         break ;
00953     }
00954     return current_ ;
00955   }
00956 
00968   ObjectGL* ObjectListGL::goToNext(){
00969     if(current_->next()){
00970       current_ = current_->next() ;
00971     }
00972     else
00973       current_ = first_ ;
00974     return current_ ;
00975   }
00976 
00988   ObjectGL* ObjectListGL::goToPrevious(){
00989     if(current_->previous()){
00990       current_ = current_->previous() ;
00991     }
00992     else
00993       current_ = last_ ;
00994     return current_ ;
00995   }
00996 
01008   ObjectGL* ObjectListGL::goToNextActive(){
01009     ObjectGL *na ;
01010 
01011     na = 0 ;
01012     if(current_)
01013       na = current_->next() ;
01014     if(!na)
01015       na = first_ ;
01016 
01017     if(na){
01018       while(!na->getState()){
01019         if(!na->next())
01020           na = first_ ;
01021         else
01022           na = na->next() ;
01023         if(na == current_)
01024           break ;
01025       }
01026     }
01027 
01028     current_ = na ;
01029 
01030     return current_ ;
01031   }
01032 
01044   ObjectGL* ObjectListGL::goToPreviousActive(){
01045     ObjectGL *na ;
01046 
01047     na = 0 ;
01048     if(current_)
01049       na = current_->previous() ;
01050     if(!na)
01051       na = last_ ;
01052 
01053     if(na){
01054       while(!na->getState()){
01055         if(!na->previous())
01056           na = last_ ;
01057         else
01058           na = na->previous() ;
01059         if(na == current_)
01060           break ;
01061       }
01062     }
01063     current_ = na ;
01064 
01065     return current_ ;
01066   }
01067 
01079   ObjectGL* ObjectListGL::jumpToNext(){
01080     for(int i=0;i<jumpSize-1;++i)
01081       goToNext() ;
01082     return goToNext() ;
01083   }
01084 
01096   ObjectGL* ObjectListGL::jumpToPrevious(){
01097     for(int i=0;i<jumpSize-1;++i)
01098       goToPrevious() ;
01099     return goToPrevious() ;
01100   }
01101 
01112   void ObjectListGL::add(ObjectGL* obj){
01113     if(obj){
01114       if(!first_){
01115         first_ = obj ;
01116       }
01117       else{
01118         last_->next() = obj ;
01119         obj->previous() = last_ ;
01120       }
01121       last_ = obj ;
01122       obj->next() = 0 ; 
01123       current_ = obj ;
01124       ++n ;
01125     }
01126   }
01127 
01141   ObjectGL* ObjectListGL::remove(ObjectGL* obj){
01142     ObjectGL* t ;
01143 
01144     if(!obj)
01145       return 0 ;
01146 
01147     if(current_ == obj){
01148       t = obj ;
01149       current_ = 0 ;
01150       if(t->previous()){
01151         t->previous()->next() = t->next() ;
01152         current_ = t->previous() ;
01153       }
01154       if(t->next()){
01155         t->next()->previous() = t->previous() ;
01156         current_ = t->next() ;
01157       }
01158       --n ;
01159       if(first_==t)
01160         first_ = t->next() ;
01161       if(last_==t)
01162         last_ = t->previous() ;
01163       return t;
01164     }
01165 
01166     t = first_ ;
01167     while(t){
01168       if(t==obj){
01169         if(t->previous())
01170           t->previous()->next() = t->next() ;
01171         if(t->next())
01172           t->next()->previous() = t->previous() ;
01173         --n ;
01174         if(first_ ==t)
01175           first_ = t->next() ;
01176         if(last_ ==t)
01177           last_ = t->previous() ;
01178         return t;
01179       }
01180       else
01181         t = t->next() ;
01182     }
01183     return 0 ;
01184   }
01185 
01203   ObjectGL* ObjectRefListGL::remove(ObjectGL* obj){
01204     ObjectGL* t ;
01205     ObjectRefGL* t2 ;
01206 
01207     if(((ObjectRefGL*)current_)->ptr == obj){
01208       t2 = (ObjectRefGL*)current_ ;
01209       current_ = 0 ;
01210       if(t2->previous()){
01211         t2->previous()->next() = t2->next() ;
01212         current_ = t2->previous() ;
01213       }
01214       if(t2->next()){
01215         t2->next()->previous() = t2->previous() ;
01216         current_ = t2->next() ;
01217       }
01218       --n ;
01219       if(first_ ==t2)
01220         first_ = t2->next() ;
01221       if(last_ ==t2)
01222         last_ = t2->previous() ;
01223       return t2;
01224     }
01225 
01226     t2 = (ObjectRefGL*)first_ ;
01227     while(t2){
01228       if(t2->ptr==obj){
01229         if(t2->previous())
01230           t2->previous()->next() = t2->next() ;
01231         if(t2->next())
01232           t2->next()->previous() = t2->previous() ;
01233         --n ;
01234         if(first_ ==t2)
01235           first_  = t2->next() ;
01236         if(last_ ==t2)
01237           last_  = t2->previous() ;
01238         return t2;
01239       }
01240       else
01241         t2 = (ObjectRefGL*)t2->next() ;
01242     }
01243 
01244     if(current_ == obj){
01245       t = obj ;
01246       current_ = 0 ;
01247       if(t->previous()){
01248         t->previous()->next() = t->next() ;
01249         current_ = t->previous() ;
01250       }
01251       if(t->next()){
01252         t->next()->previous() = t->previous() ;
01253         current_ = t->next() ;
01254       }
01255       --n ;
01256       if(first_ ==t)
01257         first_  = t->next() ;
01258       if(last_ ==t)
01259         last_  = t->previous() ;
01260       return t;
01261     }
01262 
01263     t = first_ ;
01264     while(t){
01265       if(t==obj){
01266         if(t->previous())
01267           t->previous()->next() = t->next() ;
01268         if(t->next())
01269           t->next()->previous() = t->previous() ;
01270         --n ;
01271         if(first_ ==t)
01272           first_  = t->next() ;
01273         if(last_ ==t)
01274           last_  = t->previous() ;
01275         return t;
01276       }
01277       else
01278         t = t->next() ;
01279     }
01280     return 0 ;
01281   }
01282 
01298   void ObjectRefListGL::refList(const ObjectListGL* list, int addOnce) {
01299     ObjectGL *t ;
01300     t = (ObjectGL*)list->first() ;
01301     while(t){
01302       if(addOnce){
01303         int addOk ;
01304         // check if t is already in the list
01305         ObjectRefGL *t2 ;
01306         t2 = (ObjectRefGL*)first_ ;
01307         addOk = 1 ;
01308         while(t2){
01309           if(t2->ptr == t){
01310             addOk = 0 ;
01311             break ;
01312           }
01313           t2 = (ObjectRefGL*)t2->next() ;
01314         }
01315         if(addOk)
01316           add(t) ;
01317       }
01318       else
01319         add(t) ;
01320       t = t->next() ;
01321     }
01322   }
01323 
01324 
01337   void ObjectGL::glNewList(){
01338     if(callListId)
01339       glDeleteLists(callListId,1) ;
01340 
01341     callListId = glGenLists(1) ;
01342     ::glNewList(callListId,GL_COMPILE) ;
01343     glObject() ;
01344     glEndList() ;
01345   }
01346 
01359   BoundingBoxGL::BoundingBoxGL():ObjectGL() {
01360     objectColor = cpoint0ColorDefault ;
01361     colorX = axisXColorDefault ;
01362     colorY = axisYColorDefault ;
01363     colorZ = axisZColorDefault ;
01364     type = bboxObject ;
01365   }
01366 
01367 
01376   void BoundingBoxGL::glObject() const {
01377     glDisable(GL_LIGHTING);
01378     glBegin(GL_LINES);
01379 
01380     //glColor3f(colorX) ;
01381     glColor(colorX) ;
01382     glVertex3f(minP.x(),minP.y(),minP.z()) ;
01383     glVertex3f(maxP.x(),minP.y(),minP.z()) ;
01384 
01385     //glColor3f(colorY) ;
01386     glColor(colorY) ;
01387     glVertex3f(minP.x(),minP.y(),minP.z()) ;
01388     glVertex3f(minP.x(),maxP.y(),minP.z()) ;
01389 
01390     //glColor3f(colorZ) ;
01391     glColor(colorZ) ;
01392     glVertex3f(minP.x(),minP.y(),minP.z()) ;
01393     glVertex3f(minP.x(),minP.y(),maxP.z()) ;
01394 
01396     glVertex3f(minP.x(),minP.y(),maxP.z()) ;  glVertex3f(minP.x(),maxP.y(),maxP.z()) ;
01397     glVertex3f(minP.x(),maxP.y(),minP.z()) ;  glVertex3f(maxP.x(),maxP.y(),minP.z()) ;
01398     glVertex3f(minP.x(),maxP.y(),minP.z()) ;  glVertex3f(minP.x(),maxP.y(),maxP.z()) ;
01399     glVertex3f(minP.x(),minP.y(),maxP.z()) ;  glVertex3f(maxP.x(),minP.y(),maxP.z()) ;
01400     glVertex3f(minP.x(),maxP.y(),maxP.z()) ;  glVertex3f(maxP.x(),maxP.y(),maxP.z()) ;
01401     glVertex3f(maxP.x(),minP.y(),minP.z()) ;  glVertex3f(maxP.x(),minP.y(),maxP.z()) ;
01402     glVertex3f(maxP.x(),minP.y(),maxP.z()) ;  glVertex3f(maxP.x(),maxP.y(),maxP.z()) ;
01403     glVertex3f(maxP.x(),maxP.y(),minP.z()) ;  glVertex3f(maxP.x(),minP.y(),minP.z()) ;
01404     glVertex3f(maxP.x(),maxP.y(),maxP.z()) ;  glVertex3f(maxP.x(),maxP.y(),minP.z()) ;
01405 
01406     glEnd() ;
01407     glEnable(GL_LIGHTING);
01408   }
01409 
01418   NurbsGL::NurbsGL() : 
01419     ObjectGL(), editSP(1), nurbsRenderer(0), nUlines(4), nVlines(4)
01420   { 
01421     polygon = 0 ;
01422     nurbsState = objectState; 
01423     category = nurbsType ;
01424     editControlPoints(0) ;
01425     editFixPoints(0) ; 
01426     cpoints.objectColor = cpointColorDefault ;
01427     cpoints.currentColor = cpointActiveColorDefault ;
01428     knots.objectColor = knotColorDefault ;
01429     knots.currentColor = knotActiveColorDefault ;
01430     cpoints.hideObject() ;
01431     knots.hideObject() ;
01432     setULines(4) ;
01433     setVLines(4) ; 
01434     //resetAll(); 
01435   }
01436 
01437 
01446   void NurbsGL::glObject() const {
01447     if(getState()){
01448       if(nurbsState){
01449         gluNurbs() ;
01450       }
01451       if(cpoints.getState())
01452         cpoints.glObject() ;
01453       if(polygon->getState())
01454         polygon->glObject() ;
01455       if(knots.getState())
01456         knots.glObject() ;
01457     }
01458     if(bbox.getState())
01459       bbox.glObject() ;
01460   }
01461 
01482   NurbsGL* readNurbsObject(const char* filename) {
01483     NurbsGL *temp ;
01484     // guess the type of the curve first, if that doesn't work try all of them
01485     char* ext ; 
01486     //ext = strstr(filename,".n()ca") ;
01487     //if(ext){
01488     //  openByType = OPENCURVEARRAY ;      
01489     //}
01490     //else{
01491     ext = strstr(filename,".n()c") ;
01492     if(ext){
01493       temp = new NurbsCurveGL ;
01494       if(temp->read(filename)){
01495         temp->resetBoundingBox() ;
01496         return temp ;
01497       }
01498       else
01499         delete temp ;
01500     }
01501     else{
01502       ext = strstr(filename,".n()s") ;
01503       if(ext){
01504         temp = new NurbsSurfaceGL ;
01505         if(temp->read(filename)){
01506           return temp ;
01507         }
01508         else
01509           delete temp ;
01510       }
01511     }
01512     //}
01513    
01514     // try all the types 1 by 1
01515     temp = new NurbsCurveGL ;
01516     if(temp->read(filename)){
01517       return temp ;
01518     }
01519     else
01520       delete temp ;
01521   
01522     temp = new NurbsSurfaceGL ;
01523     if(temp->read(filename)){
01524       return temp ;
01525     }
01526     else
01527       delete temp ;
01528 
01529     return 0 ;
01530   }
01531 
01543   void NurbsCurveGL::resetBoundingBox(){
01544     bbox.minP.x() = extremum(1,coordX) ;
01545     bbox.minP.y() = extremum(1,coordY) ;
01546     bbox.minP.z() = extremum(1,coordZ) ;
01547     bbox.maxP.x() = extremum(0,coordX) ;
01548     bbox.maxP.y() = extremum(0,coordY) ;
01549     bbox.maxP.z() = extremum(0,coordZ) ;
01550   }
01551 
01563   void NurbsSurfaceGL::resetBoundingBox(){
01564     bbox.minP.x() = extremum(1,coordX) ;
01565     bbox.minP.y() = extremum(1,coordY) ;
01566     bbox.minP.z() = extremum(1,coordZ) ;
01567     bbox.maxP.x() = extremum(0,coordX) ;
01568     bbox.maxP.y() = extremum(0,coordY) ;
01569     bbox.maxP.z() = extremum(0,coordZ) ;
01570   }
01571 
01583   void HNurbsSurfaceGL::resetBoundingBox(){
01584     bbox.minP.x() = extremum(1,coordX) ;
01585     bbox.minP.y() = extremum(1,coordY) ;
01586     bbox.minP.z() = extremum(1,coordZ) ;
01587     bbox.maxP.x() = extremum(0,coordX) ;
01588     bbox.maxP.y() = extremum(0,coordY) ;
01589     bbox.maxP.z() = extremum(0,coordZ) ;
01590   }
01591 
01592 
01602   void NurbsCurveGL::gluNurbs() const{
01603     if(nurbsRenderer){
01604       GLenum t = GL_MAP1_VERTEX_4 ;
01605     
01606       gluBeginCurve(nurbsRenderer) ;
01608       gluNurbsCurve(nurbsRenderer, U.n(), U.memory(), 4, P.memory()->data, deg_+1, t) ;
01609       gluEndCurve(nurbsRenderer) ;
01610     
01611       /*
01612       // This code tests the tesselation code for a Nurbs Curve
01613       BasicList<Point3Df> list ;
01614       list = tesselate(0.01) ;
01615       BasicNode<Point3Df>* node = (BasicNode<Point3Df>*)list.first ;
01616       glBegin(GL_LINE_STRIP) ;
01617       glColor() ;
01618       while(node){
01619       glVertex3fv(node->data->data) ;
01620       node = node->next ;
01621       }    
01622       glEnd() ;
01623       */
01624     }
01625   }
01626 
01636   void SimpleNurbsCurveGL::gluNurbs() const{
01637     if(nurbsRenderer){
01638       GLenum t = GL_MAP1_VERTEX_4 ;
01639     
01640       gluBeginCurve(nurbsRenderer) ;
01642       gluNurbsCurve(nurbsRenderer, U.n(), U.memory(), 4, P.memory()->data, deg_+1, t) ;
01643       gluEndCurve(nurbsRenderer) ;
01644     
01645     }
01646   }
01647 
01658   void PointListGL::applyTransform(){
01659     rx *= M_PI/180.0 ;
01660     ry *= M_PI/180.0 ;
01661     rz *= M_PI/180.0 ;
01662 
01663     MatrixRT<float> Tx(rx,ry,rz,tx,ty,tz) ;
01664     MatrixRT<float> Sx ; 
01665     Sx.scale(sx,sy,sz) ;
01666 
01667     MatrixRT<float> TM(Tx*Sx) ;
01668 
01669     BasicNode<Point3Df> *node ;
01670     node = (BasicNode<Point3Df>*)list.first() ;
01671   
01672     while(node){
01673       *node->data = TM * (*node->data) ;
01674       node = node->next ;
01675     }
01676   
01677     tx = ty = tz = rx = ry = rz = 0 ;
01678     sx = sy = sz = 1 ;
01679   }
01680 
01691   void NurbsCurveGL::applyTransform(){
01692     rx *= M_PI/180.0 ;
01693     ry *= M_PI/180.0 ;
01694     rz *= M_PI/180.0 ;
01695 
01696     MatrixRTf T(rx,ry,rz,tx,ty,tz) ;
01697     MatrixRTf Sx ; 
01698     Sx.scale(sx,sy,sz) ;
01699 
01700     transform(T*Sx) ;
01701   
01702     tx = ty = tz = rx = ry = rz = 0 ;
01703     sx = sy = sz = 1 ;
01704     resetAll() ;
01705   }
01706 
01717   void NurbsSurfaceGL::applyTransform(){
01718     rx *= M_PI/180.0 ;
01719     ry *= M_PI/180.0 ;
01720     rz *= M_PI/180.0 ;
01721 
01722     MatrixRTf T(rx,ry,rz,tx,ty,tz) ;
01723     MatrixRTf Sx ; 
01724     Sx.scale(sx,sy,sz) ;
01725 
01726     transform(T*Sx) ;
01727   
01728     tx = ty = tz = rx = ry = rz = 0 ;
01729     sx = sy = sz = 1 ;
01730     resetAll() ;
01731   }
01732 
01743   void NurbsCpolygonGL::glObject() const{
01744 
01745     glBegin(GL_LINE_STRIP);
01747     for(int i=0;i<curve.ctrlPnts().n();++i)
01748       glVertex4fv(curve.ctrlPnts()[i].data) ;
01749     glEnd() ;
01750   }
01751 
01752 
01763   void NurbsSpolygonGL::glObject() const{
01764     int i,j ;
01765     for(i=0;i<surface.ctrlPnts().rows();++i){
01766       glBegin(GL_LINE_STRIP);
01768       for(j=0;j<surface.ctrlPnts().cols();++j)
01769         glVertex4fv(surface.ctrlPnts()(i,j).data) ;
01770       glEnd() ;
01771     }
01772   
01773     for(j=0;j<surface.ctrlPnts().cols();++j){
01774       glBegin(GL_LINE_STRIP);
01776       for(i=0;i<surface.ctrlPnts().rows();++i)
01777         glVertex4fv(surface.ctrlPnts()(i,j).data);
01778       glEnd() ;
01779     }    
01780   }
01781 
01790   void NurbsCurveGL::resetCPoints() {
01791     CPointGL *tempCP ;
01792 
01793     cpoints.reset() ;
01794     if(P.n()>10)
01795       cpoints.setJumpSize(int(P.n()/10.0)) ;
01796     else
01797       cpoints.setJumpSize(int(float(P.n())/2.001 + 1)) ;
01798 
01799     for(int i=0;i<P.n();++i){
01800       if(editControlPoints())
01801         tempCP = new CPointGL(P[i],i) ;
01802       else
01803         tempCP = new SPointCurveGL(i,this,editFix) ;
01804       tempCP->setObjectColor(cpointColorDefault) ;
01805       tempCP->setCurrentColor(cpointActiveColorDefault) ;
01806       if(i==0)
01807         tempCP->setObjectColor(cpoint0ColorDefault) ;
01808       cpoints.add(tempCP) ;
01809     }
01810   
01811     if(editSurfacePoints()){  
01812       // we need to setup the start-end data for the surface points
01813       SPointCurveGL *a,*b ;
01814       a = (SPointCurveGL*)cpoints.first() ;
01815       while(a){
01816         b = a ; 
01817         int r ;
01818         r = 0 ;
01819         while(b->previous() && r<deg_+1){
01820           b = (SPointCurveGL*)b->previous() ; 
01821           ++r ; 
01822         }
01823         a->setStartEnd(b,deg_+r+1) ; 
01824         a = (SPointCurveGL*) a->next() ;
01825       }
01826     }
01827 
01828   }
01829 
01838   void NurbsCurveGL::resetKnots() {
01839     KnotGL *tempCP ;
01840 
01841     knots.reset() ;
01842     if(P.n()>10)
01843       knots.setJumpSize(int(P.n()/10.0)) ;
01844     else
01845       knots.setJumpSize(2) ;
01846 
01847     for(int i=0;i<U.n();++i){
01848       Point3Df p = pointAt(U[i]) ;
01849       // we must represent multiple knots by only 1 point
01850       // but with a bigger radius (increase radius by 1)
01851       tempCP = new KnotGL(p,i,-1) ;
01852       tempCP->setObjectColor(knots.objectColor) ;
01853       tempCP->setCurrentColor(knots.currentColor) ;
01854       if(i==0)
01855         tempCP->setObjectColor(cpoint0ColorDefault) ;
01856       int psize = 4 ;
01857       int j=i ;
01858       while(j<U.n()-1){
01859         if(U[j+1]<=U[j]){
01860           ++psize ; ++j ;
01861         }
01862         else
01863           j = U.n() ;
01864       }
01865       tempCP->setPsize(psize) ;
01866       knots.add(tempCP) ;
01867     }
01868   }
01869 
01878   void NurbsSurfaceGL::resetCPoints() {
01879     CPointGL *tempCP ;
01880 
01881     cpoints.reset() ;
01882     cpoints.setJumpSize(P.cols()) ;
01883 
01884     for(int i=0;i<P.rows();++i)
01885       for(int j=0;j<P.cols();++j){
01886         if(editControlPoints())
01887           tempCP = new CPointGL(P(i,j),i,j) ;
01888         else
01889           tempCP = new SPointSurfaceGL(i,j,this,&cpoints,editFix) ; 
01890         tempCP->setObjectColor(cpointColorDefault) ;
01891         tempCP->setCurrentColor(cpointActiveColorDefault) ;
01892         if(j==0 && (i!=P.rows()-1))
01893           tempCP->setObjectColor(cpoint0ColorDefault) ;
01894         cpoints.add(tempCP) ;
01895       }
01896 
01897     if(editSurfacePoints()){  
01898       // we need to setup the start-end data for the surface points
01899       SPointSurfaceGL *a,*b ;
01900       a = (SPointSurfaceGL*)cpoints.first() ;
01901       while(a){
01902         b = a ; 
01903         int r,c ;
01904         r = 0 ;
01905         c = 0 ;
01906         cpoints.current() = (ObjectGL*)a ;
01907         while(cpoints.jumpToPrevious() && r<degU){
01908           if(((SPointSurfaceGL*)cpoints.current())->row() < a->row() )
01909             b = (SPointSurfaceGL*) cpoints.current() ;
01910           else
01911             break ;
01912           ++r ;
01913         }
01914         
01915         while(b->previous() && c<degV){
01916           if(((SPointSurfaceGL*)b->previous())->col() < a->col() )
01917             b = (SPointSurfaceGL*)b->previous() ; 
01918           else
01919             break ;
01920           ++c ; 
01921         }
01922         a->setStartEnd(b,degU+r+1,degV+c+1) ; 
01923         a = (SPointSurfaceGL*) a->next() ;
01924       }
01925       cpoints.current() = (ObjectGL*)cpoints.first() ;
01926     }
01927   }
01928 
01937   void HNurbsSurfaceGL::resetCPoints() {
01938     ObjectGL *tempCP ;
01939     if(activePatch){
01940       cpoints.reset() ;
01941       cpoints.setJumpSize(activePatch->ctrlPnts().cols()) ;
01942     
01943       for(int i=0;i<activePatch->ctrlPnts().rows();++i)
01944         for(int j=0;j<activePatch->ctrlPnts().cols();++j){
01945           int mod ;
01946           mod = 1 ;
01947           if(i==0 || j==0 
01948              || i==activePatch->ctrlPnts().rows()-1 
01949              || j==activePatch->ctrlPnts().cols()-1)
01950             mod = 0 ;
01951           mod = 1 ; // if we don't use multi-patches it should be safe
01952           if(editControlPoints())
01953             tempCP = new HCPointGL(activePatch->offset(i,j),i,j,activePatch,mod) ;
01954           else
01955             tempCP = new SPointHSurfaceGL(i,j,activePatch,&cpoints,editFix) ; 
01956           tempCP->setObjectColor(cpointColorDefault) ;
01957           tempCP->setCurrentColor(cpointActiveColorDefault) ;
01958           if(j==0 && (i!=activePatch->ctrlPnts().rows()-1))
01959             tempCP->setObjectColor(cpoint0ColorDefault) ;
01960           cpoints.add(tempCP) ;
01961         }
01962 
01963       if(editSurfacePoints()){  
01964         // we need to setup the start-end data for the surface points
01965         SPointSurfaceGL *a,*b ;
01966         a = (SPointSurfaceGL*)cpoints.first() ;
01967         while(a){
01968           b = a ; 
01969           int r,c ;
01970           r = 0 ;
01971           c = 0 ;
01972           cpoints.current() = (ObjectGL*)a ;
01973           while(cpoints.jumpToPrevious() && r<degU){
01974             if(((SPointSurfaceGL*)cpoints.current())->row() < a->row() )
01975               b = (SPointSurfaceGL*) cpoints.current() ;
01976             else
01977               break ;
01978             ++r ;
01979           }
01980         
01981           while(b->previous() && c<degV){
01982             if(((SPointSurfaceGL*)b->previous())->col() < a->col() )
01983               b = (SPointSurfaceGL*)b->previous() ; 
01984             else
01985               break ;
01986             ++c ; 
01987           }
01988           a->setStartEnd(b,degU+r+1,degV+c+1) ; 
01989           a = (SPointSurfaceGL*) a->next() ;
01990         }
01991         cpoints.current() = (ObjectGL*)cpoints.first() ;
01992       }
01993     }
01994   }
01995 
02004   void NurbsSurfaceGL::resetKnots() {
02005     KnotGL *tempCP ;
02006 
02007     knots.reset() ;
02008     knots.setJumpSize(P.cols()) ;
02009 
02010     Vector<int> sU,sV ;
02011     sU.resize(U.n()) ;
02012     sV.resize(V.n()) ;
02013 
02014     int i,j ;
02015   
02016     sU[0] = 0 ;
02017     for(i=0;i<U.n()-1;++i){
02018       if(U[i+1]>=U[i]){
02019         sU[i+1] = sU[i]+1 ;
02020         sU[i] = 0 ;
02021       }
02022       else
02023         sU[i+1] = 1 ;
02024     }
02025 
02026     sV[0] = 0 ;
02027     for(i=0;i<V.n()-1;++i){
02028       if(V[i+1]>=V[i]){
02029         sV[i+1] = sV[i]+1 ;
02030         sV[i] = 0 ;
02031       }
02032       else
02033         sV[i+1] = 1 ;
02034     }
02035 
02036     for(i=0;i<U.n();++i)
02037       for(j=0;j<V.n();++j){
02038         //if(sU[i] && sV[i]){
02039         Point3Df p = pointAt(U[i],V[j]) ;
02040         // we must represent multiple knots by only 1 point
02041         // but with a bigger radius (increase radius by 1)
02042         tempCP = new KnotGL(p,i,j) ;
02043         tempCP->setObjectColor(knotColorDefault) ;
02044         tempCP->setCurrentColor(knotActiveColorDefault) ;
02045         if(j==0 && (i!=P.rows()-1))
02046           tempCP->setObjectColor(cpoint0ColorDefault) ;
02047         tempCP->setPsize(3+maximum(sU[i],sV[j])) ;
02048         knots.add(tempCP) ;
02049         //}
02050       }
02051   }
02052 
02068   void NurbsCurveGL::point(float &u,float &v,int pSize,const Color& colorP, int cp_flag) const {
02069     if(u<U[0])
02070       u = U[0] ;
02071     if(u>U[U.n()-1])
02072       u = U[U.n()-1] ;
02073     glPointSize(pSize) ;
02074     glBegin(GL_POINTS);
02075     float color[4] ;
02076     color[0] = color[1] = color[2] =  0.0 ;
02077     color[3] = 1.0 ;
02078     glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,color) ;
02079     color[0] = float(colorP.r)/255.0 ;
02080     color[1] = float(colorP.g)/255.0 ;
02081     color[2] = float(colorP.b)/255.0 ;
02082     glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION,color) ;
02083     glVertex4fv(hpointAt(u).data) ;
02084     glEnd() ;
02085     v *= 1.0 ; // to shut up the warning messages
02086   
02087     if(cp_flag){ // if this is set, only display CP which affect the point
02088     
02089     }
02090   }
02091 
02101   void NurbsSurfaceGL::displaySolid() const{
02102     GLenum t = GL_MAP2_VERTEX_4 ;  
02103     gluNurbsProperty(nurbsRenderer, GLU_SAMPLING_TOLERANCE, 25.0);
02104     gluNurbsProperty(nurbsRenderer, GLU_DISPLAY_MODE, GLU_FILL);
02105     gluBeginSurface(nurbsRenderer) ;
02106     gluNurbsSurface(nurbsRenderer, U.n(), U.memory(), V.n(), V.memory(),4,4*P.rows(), P[0]->data, degU+1, degV+1, t) ;
02107     gluEndSurface(nurbsRenderer) ;
02108   }
02109 
02119   void NurbsSurfaceGL::displayWireframe() const{
02120     GLenum t = GL_MAP2_VERTEX_4 ; 
02121     gluNurbsProperty(nurbsRenderer,GLU_DISPLAY_MODE,GLU_OUTLINE_POLYGON) ;
02122     gluBeginSurface(nurbsRenderer) ;
02123     gluNurbsSurface(nurbsRenderer, U.n(), U.memory(), V.n(), V.memory(),4,4*P.rows(), P[0]->data, degU+1, degV+1, t) ;
02124     
02125     for(std::list<NurbsCurve_2Df*>::const_iterator it = trimmedCurves.begin() ;
02126         it != trimmedCurves.end(); ++it){
02127       NurbsCurve_2Df *tc = *it ; 
02128       gluBeginTrim(nurbsRenderer) ;
02129       gluNurbsCurve(nurbsRenderer,tc->knot().n(),tc->knot().memory(),3,tc->ctrlPnts().memory()->data, 3, GLU_MAP1_TRIM_3 ) ;
02130       gluEndTrim(nurbsRenderer) ; 
02131     }
02132     
02133     gluEndSurface(nurbsRenderer) ;
02134   }
02135 
02136 
02137 
02147   void NurbsSurfaceGL::gluNurbs() const{
02148     int i ;
02149     if(nurbsRenderer){
02150       switch(NurbsDisplayMode){
02151       case NURBS_DISPLAY_SOLID:
02152         displaySolid();
02153         break;
02154       case NURBS_DISPLAY_ISOCURVES:
02155         {
02156           // create iso curves
02157           SimpleNurbsCurveGL t ;
02158           t.setObjectColor(objectColor,selectColor,currentColor) ;
02159           t.setNurbsRenderer(nurbsRenderer) ;
02160           t.hideBBox() ;
02161           t.hideCPoints() ;
02162           t.hideCpolygon() ;
02163           t.viewNurbs() ;
02164           if(isActive()) t.activate() ;
02165           if(isSelected()) t.select() ;
02166 
02167           int i ;
02168           for(i=0;i<nUlines;++i){
02169             float u = U[0] + float(i)/float(nUlines-1) * (U[U.n()-1]-U[0]) ; 
02170             isoCurveU(u,t) ;
02171             t.glObject() ;
02172           }
02173 
02174           for(i=0;i<nVlines;++i){
02175             float v = V[0] + float(i)/float(nVlines-1) * (V[V.n()-1]-V[0]) ; 
02176             isoCurveV(v,t) ;
02177             t.glObject() ;
02178           }
02179         }
02180         break ;
02181       case NURBS_DISPLAY_SHADED:
02182         {
02183           GLenum t = GL_MAP2_VERTEX_4 ; 
02184           if(image)
02185             glShadeModel(GL_FLAT) ;
02186           else
02187             glShadeModel(GL_SMOOTH) ;
02188           gluNurbsProperty(nurbsRenderer,GLU_DISPLAY_MODE,GLU_FILL) ;
02189 
02190         
02191           //GLfloat lmodel_ambient[] = { 0.3, 0.3, 0.3, 1.0 };
02192 
02193           //glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
02194 
02195           //glEnable(GL_LIGHTING);
02196 
02197 
02198           //glDepthFunc(GL_LESS);
02199           //glEnable(GL_DEPTH_TEST);
02200           //glEnable(GL_AUTO_NORMAL);
02201     
02202           //colorToMaterial(Color(255,100,255),materialColor) ;
02203           //glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,materialColor) ;
02204           //colorToMaterial(Color(0,0,0),materialColor) ;
02205           //glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION,materialColor) ;
02206           //glColor() ;
02207 
02208 
02209           gluBeginSurface(nurbsRenderer) ;
02210           if(image){
02211             static GLfloat texpts[2][2][2] = {{{0,0},{0,1}},{{1,0},{1,1}}} ;
02212       
02213             glMap2f(GL_MAP2_TEXTURE_COORD_2,0,1,2,2,0,1,4,2,&texpts[0][0][0]) ;
02214             glEnable(GL_MAP2_TEXTURE_COORD_2) ;
02215             glMapGrid2f(20,0,1,20,0,1) ;
02216             glEvalMesh2(GL_FILL,0,20,0,20) ;
02217             glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE, GL_DECAL) ;
02218             glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT) ;
02219             glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT) ;
02220             glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST) ;
02221             glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST) ;
02222             glTexImage2D(GL_TEXTURE_2D,0,3,imgW,imgH,0,GL_RGB,GL_UNSIGNED_BYTE,image) ;
02223             glShadeModel(GL_FLAT) ;
02224             glEnable(GL_TEXTURE_2D) ;
02225           }
02226           GLfloat mat_ambient[] = { 0.8, 0.8, 0.8, 1.0 };
02227           GLfloat mat_diffuse[] = { 0.8, 0.8, 0.8, 1.0 };
02228           GLfloat mat_specular[] = { 0.8, 0.8, 0.8, 1.0 };
02229           GLfloat mat_shininess[] = { 50.0 };
02230           glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat_ambient);
02231           glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse);
02232           glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
02233           glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
02234 
02235           gluNurbsSurface(nurbsRenderer, U.n(), U.memory(), V.n(), V.memory(),4,4*P.rows(), P[0]->data, degU+1, degV+1, t) ;
02236           gluEndSurface(nurbsRenderer) ;
02237           glDisable(GL_TEXTURE_2D) ;
02238         }
02239         break ;
02240       case NURBS_DISPLAY_HIDDEN_LINES:
02241         {
02242           GLenum t = GL_MAP2_VERTEX_4 ; 
02243           gluNurbsProperty(nurbsRenderer,GLU_DISPLAY_MODE,GLU_FILL) ;
02244 
02245           glDisable(GL_LIGHTING);
02246           glColor3f(.7f, .7f, .7f);
02247         
02248           glEnable(GL_STENCIL_TEST);
02249           glStencilFunc(GL_ALWAYS, 0, 0); /* clear stencil for this object */
02250 
02251           gluBeginSurface(nurbsRenderer) ;
02252           //glColor() ;
02253           gluNurbsSurface(nurbsRenderer, U.n(), U.memory(), V.n(), V.memory(),4,4*P.rows(), P[0]->data, degU+1, degV+1, t) ;
02254           gluEndSurface(nurbsRenderer) ;
02255 
02256           glEnable(GL_LIGHTING);
02257 
02258           glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); /* turn off color */
02259           glDisable(GL_DEPTH_TEST); /* turn off depth */
02260           glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
02261           glStencilFunc(GL_ALWAYS, 1, 1);
02262           glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
02263 
02264           gluBeginSurface(nurbsRenderer) ;
02265           //glColor() ;
02266           gluNurbsSurface(nurbsRenderer, U.n(), U.memory(), V.n(), V.memory(),4,4*P.rows(), P[0]->data, degU+1, degV+1, t) ;
02267           gluEndSurface(nurbsRenderer) ;
02268 
02269           glStencilFunc(GL_EQUAL, 1 , 1);
02270           glEnable(GL_DEPTH_TEST);
02271           glDepthFunc(GL_LEQUAL);
02272           glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
02273           glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
02274 
02275           gluBeginSurface(nurbsRenderer) ;
02276           //glColor() ;
02277           gluNurbsSurface(nurbsRenderer, U.n(), U.memory(), V.n(), V.memory(),4,4*P.rows(), P[0]->data, degU+1, degV+1, t) ;
02278           gluEndSurface(nurbsRenderer) ;
02279 
02280 
02281           /* clean up state */
02282           glDisable(GL_STENCIL_TEST);
02283           glDepthFunc(GL_LESS);
02284         }
02285         break ;
02286       case NURBS_DISPLAY_TESSELATION:
02287         {
02288           /*
02289             BasicList<Point3Df> pts ;
02290             BasicList<int> connect ;
02291             if(tessel_tolerance<0.001) 
02292             tessel_tolerance = 0.001 ;
02293             tesselate(tessel_tolerance,pts,connect) ;
02294 
02295             glPolygonMode(GL_FRONT_AND_BACK,GL_LINE) ;
02296             glBegin(GL_TRIANGLES) ;
02297             glColor() ;
02298             connect.goToFirst() ;
02299             pts.goToFirst() ;
02300             for(i=0;i<connect.size();++i){
02301             if(*(connect[i]->data) >= 0)
02302             glVertex3fv(pts[*(connect[i]->data)]->data->data) ;
02303             }
02304             glEnd() ;
02305           */
02306           Color col ;
02307           if(isActive()) col = currentColor ;
02308           else{
02309             if(isSelected()) col = selectColor ; 
02310             else col = objectColor ; 
02311           }
02312           NurbsSubSurfaceGL s(*this,col) ;
02313           s.drawSubdivisionGL(0.01) ;
02314         }
02315         break ;
02316       case NURBS_DISPLAY_NORMAL:
02317       default:
02318         displayWireframe();
02319       }
02320     }
02321   }
02322 
02323   /*
02324     void splitAtActiveInU(NurbsCurveGL &t, NurbsCurveGL &ta, float u, HNurbsSurface *active, int lod){
02325     if(lod >= 0 && lod < active->level)
02326     return ;
02327     if(u<active->uS || u >active->uE){
02328     t.glObject() ;
02329     return ;
02330     }
02331     NurbsCurve c ;
02332     c = t ;
02333     ta = c ;
02334     if(active->vS<=c.Knot[0] && active->vE>=c.Knot[c.Knot.n()-1]){
02335     ta.glObject() ;
02336     return ;
02337     }
02338     if(active->vS>c.Knot[0] && active->vE < c.Knot[c.Knot.n()-1]){
02339     // active curve is in the middle
02340     c.splitAt(active->vS,t,ta) ;
02341     t.glObject() ;
02342     c = ta ;
02343     c.splitAt(active->vE,ta,t) ;
02344     t.glObject() ;
02345     ta.glObject() ;
02346     }
02347     else{
02348     if(active->vS>c.Knot[0]) {
02349     c.splitAt(active->vS,t,ta) ;
02350     t.glObject() ;
02351     ta.glObject() ;
02352     }
02353     else{
02354     c.splitAt(active->vE,ta,t) ;
02355     t.glObject() ;
02356     ta.glObject() ;
02357     }
02358     }
02359     }
02360 
02361     void splitAtActiveInV(NurbsCurveGL &t, NurbsCurveGL &ta, float v, HNurbsSurface *active, int lod){
02362     if(lod >= 0 && lod < active->level)
02363     return ;
02364     if(v<active->vS || v >active->vE){
02365     t.glObject() ;
02366     return ;
02367     }
02368     NurbsCurve c ;
02369     c = t ;
02370     ta = c ;
02371     if(active->uS<=c.Knot[0] && active->uE>=c.Knot[c.Knot.n()-1]){
02372     ta.glObject() ;
02373     return ;
02374     }
02375     if(active->uS>c.Knot[0] && active->uE < c.Knot[c.Knot.n()-1]){
02376     // active curve is in the middle
02377     c.splitAt(active->uS,t,ta) ;
02378     t.glObject() ;
02379     c = ta ;
02380     c.splitAt(active->uE,ta,t) ;
02381     t.glObject() ;
02382     ta.glObject() ;
02383     }
02384     else{
02385     if(active->uS>c.Knot[0]) {
02386     c.splitAt(active->uS,t,ta) ;
02387     t.glObject() ;
02388     ta.glObject() ;
02389     }
02390     else{
02391     c.splitAt(active->uE,ta,t) ;
02392     t.glObject() ;
02393     ta.glObject() ;
02394     }
02395     }
02396     }
02397   */
02398 
02399   void isoCurves(const HNurbsSurfaceSPf *hs, SimpleNurbsCurveGL &t, int lod, int nu, int nv){
02400     if(lod<0)
02401       lod = hs->maxLevel() ; 
02402 
02403     if(lod>=0 && lod<hs->level()){
02404       return ;
02405     }
02406 
02407     if(lod == hs->level()){
02408       int i ;
02409       for(i=0;i<nu+hs->level();++i){
02410         float u = hs->knotU()[0] + float(i)/float(nu+hs->level()-1) * (hs->knotU()[hs->knotU().n()-1] - hs->knotU()[0]) ; 
02411         hs->isoCurveU(u,t,lod) ; 
02412         t.glObject() ; 
02413       }
02414       for(i=0;i<nv+hs->level();++i){
02415         float v = hs->knotV()[0] + float(i)/float(nv+hs->level()-1) * (hs->knotV()[hs->knotV().n()-1] - hs->knotV()[0]) ; 
02416         hs->isoCurveV(v,t,lod) ; 
02417         t.glObject() ; 
02418       }
02419       return ; 
02420     }
02421  
02422     HNurbsSurfaceSPf *child ; 
02423     child = (HNurbsSurfaceSPf*) hs->nextLevel() ;
02424     if(child){
02425       isoCurves(child,t,lod,nu,nv) ;
02426     }
02427     return ; 
02428   }
02429 
02439   void HNurbsSurfaceGL::gluNurbs() const{
02440     if(nurbsRenderer){
02441 
02442       HNurbsSurfaceGL* dispPatch ;
02443       dispPatch = activePatch ;
02444       int level = levelOfDetail() ;
02445       if(level<0) 
02446         level = maxLevel() ;
02447       while(dispPatch->level() < level)
02448         dispPatch = (HNurbsSurfaceGL*)dispPatch->nextLevel() ;
02449     
02450       switch(NurbsDisplayMode){
02451       case NURBS_DISPLAY_ISOCURVES:
02452         {
02453           // create iso curves
02454           SimpleNurbsCurveGL t ;
02455           t.setObjectColor(objectColor,selectColor,currentColor) ;
02456           t.setNurbsRenderer(nurbsRenderer) ;
02457           t.hideBBox() ;
02458           t.hideCPoints() ;
02459           t.hideCpolygon() ;
02460           t.viewNurbs() ;
02461           if(isActive()) t.activate() ;
02462           if(isSelected()) t.select() ;
02463 
02464           isoCurves(dispPatch,t,level,nUlines,nVlines) ; 
02465 
02466           if(dispPatch->level() != activePatch->level()){
02467             t.setObjectColor(Color(255,255,0),Color(255,255,0),Color(255,255,0));
02468             isoCurves(activePatch,t,activePatch->level(),nUlines,nVlines) ; 
02469           }
02470 
02471         }
02472         break ;
02473       case NURBS_DISPLAY_SHADED:
02474       case NURBS_DISPLAY_HIDDEN_LINES:
02475       case NURBS_DISPLAY_TESSELATION:
02476       case NURBS_DISPLAY_NORMAL:
02477       default:
02478         {
02479           GLenum t = GL_MAP2_VERTEX_4 ; 
02480           gluNurbsProperty(nurbsRenderer,GLU_DISPLAY_MODE,GLU_OUTLINE_POLYGON) ;
02481           gluBeginSurface(nurbsRenderer) ;
02483           gluNurbsSurface(nurbsRenderer, dispPatch->U.n(), dispPatch->U.memory(), dispPatch->V.n(), dispPatch->V.memory(),4,4*dispPatch->P.rows(), dispPatch->P[0]->data, dispPatch->degU+1, dispPatch->degV+1, t) ;
02484           gluEndSurface(nurbsRenderer) ;
02485         }      
02486       }
02487     }
02488   }
02489 
02505   void NurbsSurfaceGL::point(float &u, float &v, int pSize,const Color& colorP, int cp_flag) const {
02506     if(u<U[0])
02507       u = U[0] ;
02508     if(u>U[U.n()-1])
02509       u = U[U.n()-1] ;
02510     if(v<V[0])
02511       v = V[0] ;
02512     if(v>V[V.n()-1])
02513       v = V[V.n()-1] ;
02514     glPointSize(pSize) ;
02515     glBegin(GL_POINTS);
02516     float color[4] ;
02517     color[0] = color[1] = color[2] =  0.0 ;
02518     color[3] = 1.0 ;
02519     glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,color) ;
02520     color[0] = float(colorP.r)/255.0 ;
02521     color[1] = float(colorP.g)/255.0 ;
02522     color[2] = float(colorP.b)/255.0 ;
02523     glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION,color) ;
02524     glVertex4fv(hpointAt(u,v).data) ;
02525     glEnd() ;
02526 
02527     SimpleNurbsCurveGL t ;
02528     t.setObjectColor(colorP,colorP,colorP) ;
02529     t.setNurbsRenderer(nurbsRenderer) ;
02530     t.hideBBox() ;
02531     t.hideCPoints() ;
02532     t.hideCpolygon() ;
02533     t.viewNurbs() ;
02534     isoCurveU(u,t) ;
02535     t.glObject() ;
02536     isoCurveV(v,t) ;
02537     t.glObject() ;
02538   }
02539 
02540 
02556   void HNurbsSurfaceGL::point(float &u, float &v, int pSize,const Color& colorP, int cp_flag) const {
02557     if(u<U[0])
02558       u = U[0] ;
02559     if(u>U[U.n()-1])
02560       u = U[U.n()-1] ;
02561     if(v<V[0])
02562       v = V[0] ;
02563     if(v>V[V.n()-1])
02564       v = V[V.n()-1] ;
02565     glPointSize(pSize) ;
02566     glBegin(GL_POINTS);
02567     float color[4] ;
02568     color[0] = color[1] = color[2] =  0.0 ;
02569     color[3] = 1.0 ;
02570     glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,color) ;
02571     color[0] = float(colorP.r)/255.0 ;
02572     color[1] = float(colorP.g)/255.0 ;
02573     color[2] = float(colorP.b)/255.0 ;
02574     glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION,color) ;
02575     glVertex4fv(hpointAt(u,v,levelOfDetail()).data) ;
02576     glEnd() ;
02577 
02578 
02579     SimpleNurbsCurveGL t ;
02580     t.setObjectColor(colorP,colorP,colorP) ;
02581     t.setNurbsRenderer(nurbsRenderer) ;
02582     t.hideBBox() ;
02583     t.hideCPoints() ;
02584     t.hideCpolygon() ;
02585     t.viewNurbs() ;
02586     isoCurveU(u,t,levelOfDetail()) ;
02587     t.glObject() ;
02588     isoCurveV(v,t,levelOfDetail()) ;
02589     t.glObject() ;  
02590 
02591     if(cp_flag){ // display only the CP affected by the point
02592       int spanU, spanV ;
02593       activePatch->findSpan(u,v,spanU,spanV) ;
02594       int i,j,n ;
02595     
02596       ObjectGL *pnt ;
02597       pnt = (ObjectGL*)cpoints.first() ;
02598       n = 0 ;
02599       while(pnt){
02600         i = n / activePatch->ctrlPnts().cols() ;
02601         j = n % activePatch->ctrlPnts().cols() ;
02602         if(i<spanU-activePatch->degreeU() || i>spanU)
02603           pnt->hideObject() ;
02604         else{
02605           if(j<spanV-activePatch->degreeV() || j>spanV)
02606             pnt->hideObject() ;
02607           else
02608             pnt->viewObject() ;
02609         }
02610         ++n ;
02611         pnt = pnt->next() ;      
02612       }
02613     }
02614   }
02615 
02616 
02626   Material::Material(){
02627     // POV-Ray options
02628     // finish options
02629     //double ambient = 0.2 ;
02630     //double diffuse = 0.6 ;
02631     //double roughness = 0 ;
02632   }
02633 
02644   int ObjectListGL::read(const char* filename){
02645     ifstream fin(filename) ;
02646     if(!fin)
02647       return 0 ;
02648     fin.clear() ;
02649     fin.seekg(0,std::ios::beg) ;
02650 
02651     char *type ;
02652     type = new char[3] ;
02653 
02654     ObjectGL* newObject ;
02655 
02656     while(!fin.eof()){
02657       // get the first 3 characters to determine the type of the object
02658       int mark = fin.tellg() ; // mark position
02659       if(!fin.read(type,sizeof(char)*3)){ delete []type ;  return 1 ;  }
02660       fin.seekg(mark) ; // restore position
02661 
02662       int ot=0 ; // unknown object
02663       char* ext ;
02664 
02665       ext = strstr(type,"nc3");
02666       if(ext) ot = 1 ;
02667       if(!ot){
02668         ext = strstr(type,"nc4");
02669         if(ext) ot = 1 ;
02670       }
02671       if(!ot){
02672         ext = strstr(type,"ns3");
02673         if(ext) ot = 2 ;
02674       }
02675       if(!ot){
02676         ext = strstr(type,"ns4");
02677         if(ext) ot = 2 ;
02678       }
02679       if(!ot){
02680         ext = strstr(type,"hns");
02681         if(ext) ot = 3 ;
02682       }
02683       if(!ot){
02684         ext = strstr(type,"pt3");
02685         if(ext) ot = 4 ;
02686       }
02687     
02688     
02689       if(!ot){  delete []type ;  return 1 ;     }
02690     
02691       newObject = 0 ;
02692       switch(ot){
02693       case 0: break ;
02694       case 1: // A NURBS curve
02695         newObject = new NurbsCurveGL ;
02696         if(!newObject->read(fin)) {delete []type ; return 0 ;}
02697         break ;
02698       case 2: // A NURBS surface
02699         newObject = new NurbsSurfaceGL ;
02700         if(!newObject->read(fin)) {delete []type ; return 0 ;}
02701         break ;
02702       case 3: // A HNURBS surface
02703         newObject = new HNurbsSurfaceGL ;
02704         if(!newObject->read(fin)) { delete []type ; return 0 ; }
02705         ((HNurbsSurfaceGL*)newObject)->updateLevels() ;
02706         ((HNurbsSurfaceGL*)newObject)->highestLevelOfDetail() ;      
02707         break ;
02708       case 4: // a list of points in 3D
02709         newObject = new PointListGL ;
02710         if(!newObject->read(fin)) { delete []type ; cerr << "B" ; return 0 ;}
02711         break ;
02712       }
02713     
02714       if(newObject)
02715         add(newObject) ;
02716 
02717       //if(fin.fail()){ delete []type ; return 0 ;  } 
02718     }
02719     delete []type ;
02720     return 1 ;
02721   }
02722 
02733   int ObjectListGL::write(const char* filename) const {
02734     ofstream fout(filename) ;
02735     if(!fout)
02736       return 0 ;
02737   
02738     ObjectGL *t ;
02739     t = (ObjectGL*)first_ ;
02740     while(t){
02741       if(!t->write(fout))
02742         return 0 ;
02743       t = t->next() ;
02744     }
02745     return fout.good() ;
02746   }
02747 
02758   int ObjectListGL::writeRIB(const char* filename) const {
02759     ofstream fout(filename) ;
02760     if(!fout)
02761       return 0 ;
02762   
02763     ObjectGL *t ;
02764     t = (ObjectGL*)first_ ;
02765     while(t){
02766       if(!t->writeRIB(fout))
02767         return 0;
02768       t = t->next() ;
02769     }
02770     return fout.good() ;
02771   }
02772 
02783   int ObjectListGL::writePOVRAY(const char* filename) const {
02784     ofstream fout(filename) ;
02785     if(!fout)
02786       return 0 ;
02787   
02788     ObjectGL *t ;
02789     t = (ObjectGL*)first_ ;
02790     while(t){
02791       if(!t->writePOVRAY(fout))
02792         return 0;
02793       t = t->next() ;
02794     }
02795     return fout.good() ;
02796   }
02797 
02804   /*
02805     void HNurbsSurfaceGL::selectNextPatch(){
02806     if(activePatch){
02807     if(activePatch->nextLevel_)
02808     activePatch = (HNurbsSurfaceGL*)activePatch->nextPatch ;
02809     else
02810     if(activePatch->base)
02811     activePatch = (HNurbsSurfaceGL*)activePatch->base->firstPatch ;
02812     }
02813     }
02814   */
02821   /*void HNurbsSurfaceGL::selectPrevPatch(){
02822     if(activePatch){
02823     if(activePatch->prevPatch)
02824     activePatch = (HNurbsSurfaceGL*)activePatch->prevPatch ;
02825     else
02826     if(activePatch->baseLevel()){
02827     activePatch = (HNurbsSurfaceGL*)activePatch->base->lastPatch ;
02828     }
02829     }
02830     }
02831   */
02838   void HNurbsSurfaceGL::selectHigherLevel() {
02839     if(activePatch){
02840       if(activePatch->level() < levelOfDetail())
02841         if(activePatch->nextLevel())
02842           activePatch = (HNurbsSurfaceGL*)activePatch->nextLevel() ;
02843     }
02844   }
02845 
02852   void HNurbsSurfaceGL::selectHighestLevel() {
02853     if(activePatch){
02854       while(activePatch->level() < levelOfDetail())
02855         if(activePatch->nextLevel())
02856           activePatch = (HNurbsSurfaceGL*)activePatch->nextLevel() ;
02857     }
02858   }
02859 
02866   void HNurbsSurfaceGL::selectLowerLevel() {
02867     if(activePatch){
02868       if(activePatch->baseLevel())
02869         activePatch = (HNurbsSurfaceGL*)activePatch->baseLevel() ;
02870     }
02871   }
02872 
02879   void HNurbsSurfaceGL::decreaseLevelOfDetail() {
02880     --lod ; 
02881     if(lod<0) lod=0 ; 
02882     if(activePatch)
02883       while(activePatch->level() > lod)
02884         activePatch = (HNurbsSurfaceGL*)activePatch->baseLevel() ;
02885   }
02886 
02898   ObjectGL& ObjectGL::operator=(const ObjectGL &a){
02899     objectColor = a.objectColor ;
02900     selectColor = a.selectColor ;
02901     currentColor = a.currentColor ;
02902     type = a.type ;
02903     tx = a.tx ;
02904     ty = a.ty ;
02905     tz = a.tz ;
02906     rx = a.rx ;
02907     ry = a.ry ;
02908     rz = a.rz ;
02909     sx = a.sx ;
02910     sy = a.sy ;
02911     sz = a.sz ;
02912     selected = a.selected ;
02913     active = a.active ;
02914     state = a.state ;
02915   
02916     return *this ;
02917   }
02918 
02927   NurbsGL& NurbsGL::operator=(const NurbsGL &a){
02928     this->ObjectGL::operator=(a) ;
02929   
02930     nurbsRenderer = a.nurbsRenderer ;
02931     cpoints.objectColor = a.cpoints.objectColor ;
02932     cpoints.currentColor = a.cpoints.currentColor ;
02933     knots.objectColor = a.knots.objectColor ;
02934     knots.currentColor = a.knots.currentColor ;
02935   
02936     editSP = a.editSP ;
02937 
02938     editFix = a.editFix ; 
02939 
02940     nUlines = a.nUlines ;
02941     nVlines = a.nVlines ;
02942 
02943     return *this ;  
02944   }
02945 
02954   NurbsCurveGL& NurbsCurveGL::operator=(const NurbsCurveGL &a){
02955     this->NurbsCurveSPf::operator=(a) ;
02956     this->NurbsGL::operator=(a) ;
02957     resetAll() ;
02958     return *this ;  
02959   }
02960 
02969   NurbsCurveGL& NurbsCurveGL::operator=(const NurbsCurvef &a){
02970     this->NurbsCurveSPf::operator=(a) ;
02971     return *this ;
02972   }
02973 
02982   NurbsSurfaceGL& NurbsSurfaceGL::operator=(const NurbsSurfaceGL &a){
02983     this->NurbsSurfaceSPf::operator=(a) ;
02984     this->NurbsGL::operator=(a) ;
02985     resetAll() ;
02986     return *this ;  
02987   }
02988 
02997   NurbsSurfaceGL& NurbsSurfaceGL::operator=(const NurbsSurfacef &a){
02998     this->NurbsSurfaceSPf::operator=(a) ;
02999     return *this ;
03000   }
03001 
03014   void NurbsCurveGL::modifyPoint(float u, float v, float dx, float dy, float dz){
03015     Point3Df delta(dx,dy,dz) ;
03016     if(u<U[0]) u = U[0] ;
03017     if(u>U[U.n()-1]) u = U[U.n()-1] ;
03018     movePoint(u,delta) ;
03019   }
03020 
03033   void NurbsSurfaceGL::modifyPoint(float u, float v, float dx, float dy, float dz){
03034     Point3Df delta(dx,dy,dz) ;
03035     boundTo(u,knotU()[0],knotU()[knotU().n()-1]) ;
03036     boundTo(v,knotV()[0],knotV()[knotV().n()-1]) ; 
03037     movePoint(u,v,delta) ;
03038   }
03039 
03052   void HNurbsSurfaceGL::modifyPoint(float u, float v, float dx, float dy, float dz){
03053     Point3Df delta(dx,dy,dz) ;
03054     boundTo(u,activePatch->knotU()[0],activePatch->knotU()[activePatch->knotU().n()-1]) ;
03055     boundTo(v,activePatch->knotV()[0],activePatch->knotV()[activePatch->knotV().n()-1]) ;
03056     activePatch->movePointOffset(u,v,delta) ;
03057     resetCPoints() ; 
03058   }
03059 
03070   void HNurbsSurfaceGL::applyTransform(){
03071     rx *= M_PI/180.0 ;
03072     ry *= M_PI/180.0 ;
03073     rz *= M_PI/180.0 ;
03074 
03075     MatrixRTf Tx(rx,ry,rz,tx,ty,tz) ;
03076 
03077     transform(Tx) ; // only need to transform the base class...
03078     scale(Point3Df(sx,sy,sz)) ; 
03079     // but scaling doesn't work then... sucks.
03080   
03081     tx = ty = tz = rx = ry = rz = 0 ;
03082     sx = sy = sz = 1 ;
03083 
03084     offset = P ; 
03085     ++updateN ;
03086     updateLevels(lod) ; 
03087 
03088     resetAll() ;
03089   }
03090 
03097   HNurbsSurfaceGL::HNurbsSurfaceGL():HNurbsSurfaceSPf(),NurbsGL() {
03098     type = hSurfObject ; 
03099     polygon = new NurbsSpolygonGL(*this) ; 
03100     lod = maxLevel() ; 
03101     activePatch = this ; 
03102   }
03103 
03112   HNurbsSurfaceGL::HNurbsSurfaceGL(const NurbsSurfacef& nS):HNurbsSurfaceSPf(nS),NurbsGL() { 
03113     type = hSurfObject ; 
03114     polygon = new NurbsSpolygonGL(*this) ; 
03115     lod = maxLevel() ; 
03116     activePatch = this ; 
03117   }
03118 
03131   HNurbsSurfaceGL::HNurbsSurfaceGL(const HNurbsSurfaceGL& bS):HNurbsSurfaceSPf(bS),NurbsGL() { 
03132     type = hSurfObject ;
03133     polygon = new NurbsSpolygonGL(*this) ; 
03134     lod = maxLevel() ; 
03135     activePatch = this ; 
03136   }
03137 
03146   HNurbsSurfaceGL::HNurbsSurfaceGL(const HNurbsSurfaceGL* bS): HNurbsSurfaceSPf(*bS),NurbsGL() {  
03147     type = hSurfObject ; 
03148     polygon = new NurbsSpolygonGL(*this) ; 
03149     lod = maxLevel() ; 
03150     activePatch = this ; 
03151   }
03152 
03159   HNurbsSurfaceSPf* HNurbsSurfaceGL::addLevel() {  
03160     // go to the last level
03161     if(activePatch){
03162       activePatch = (HNurbsSurfaceGL*)activePatch->lastLevel() ;
03163       return activePatch->HNurbsSurfaceSPf::addLevel(1) ;
03164     }
03165     return 0 ;
03166   }
03167 
03174   void HNurbsSurfaceGL::resetPolygon() {
03175     int h ;
03176     h = 0 ; 
03177     if(polygon){
03178       h = polygon->getState() ;
03179       delete polygon ;
03180     }
03181     polygon = new NurbsSpolygonGL(*activePatch) ;
03182     if(h)
03183       viewCpolygon() ;
03184     else
03185       hideCpolygon() ;
03186   }
03187 
03194   void ObjectListGL::viewAllObjects(){
03195     state = objectState ;
03196     ObjectGL* obj = first_ ;
03197     while(obj){
03198       obj->viewObject() ;
03199       obj = obj->next() ;
03200     }
03201   }
03202 
03209   void ObjectListGL::hideAllObjects(){
03210     state = hideState ;
03211     ObjectGL* obj = first_ ;
03212     while(obj){
03213       obj->hideObject() ;
03214       obj = obj->next() ;
03215     }
03216   }
03217 
03226   void CPointGL::modifySym(const HPoint3Df &v) {
03227     modify(v) ;
03228     if(symPoint){
03229       HPoint3Df v2(v) ;
03230       v2.x() *= xCoord ;
03231       v2.y() *= yCoord ;
03232       v2.z() *= zCoord ;
03233       //v2.w() *= wCoord ;
03234       symPoint->modify(v2) ;
03235     }
03236   }
03237 
03246   void HNurbsSurfaceGL::setSym(int set, int uDir, float x, float y, float z, float w) {
03247     if(activePatch){
03248       int r = activePatch->ctrlPnts().rows() ;
03249       int c = activePatch->ctrlPnts().cols() ;
03250       if(true){
03251         if(uDir) { // do it so that (i,j) and (rows-i,j) are symmetrical
03252           ObjectGL *pnt = (ObjectGL*)cpoints.first() ;
03253           int i,j ;
03254           i = 0 ;
03255           j = 0 ;
03256           while(pnt){
03257             ((CPointGL*)pnt)->setSym((CPointGL*)cpoints.goTo((r-1-i)*c+j),x,y,z,w) ;
03258             ++j ;
03259             if(j>=c){
03260               j = 0 ;
03261               ++i ;
03262             }
03263             pnt = pnt->next() ;
03264           }
03265         }
03266         else{  // (i,j) and (i,cols-j) are symmetrical
03267           ObjectGL *pnt = (ObjectGL*)cpoints.first() ;
03268           int i,j ;
03269           i = 0 ;
03270           j = 0 ;
03271           while(pnt){
03272             ((CPointGL*)pnt)->setSym((CPointGL*)cpoints.goTo(i*c+(c-1-j)),x,y,z,w) ;
03273             ++j ;
03274             if(j>=c){
03275               j = 0 ;
03276               ++i ;
03277             }
03278             pnt = pnt->next() ;
03279           }
03280         }
03281       }
03282       else{
03283         ObjectGL *pnt = (ObjectGL*)cpoints.first() ;
03284         while(pnt){
03285           ((CPointGL*)pnt)->setSym((CPointGL*)0,float(1),float(1),float(1),float(1)) ;
03286           pnt = pnt->next() ;
03287         }
03288       }
03289     }
03290   }
03291 
03300   void NurbsSurfaceGL::setSym(int set, int uDir, float x, float y, float z, float w) {
03301     if(set){
03302       const int r = ctrlPnts().rows() ;
03303       const int c = ctrlPnts().cols() ;
03304       if(uDir) { // do it so that (i,j) and (rows-i,j) are symmetrical
03305         ObjectGL *pnt = (ObjectGL*)cpoints.first() ;
03306         int i,j ;
03307         i = 0 ;
03308         j = 0 ;
03309         while(pnt){
03310           ((CPointGL*)pnt)->setSym((CPointGL*)cpoints.goTo((r-1-i)*c+j),x,y,z,w) ;
03311           ++j ;
03312           if(j>=c){
03313             j = 0 ;
03314             ++i ;
03315           }
03316           pnt = pnt->next() ;
03317         }
03318       }
03319       else{  // (i,j) and (i,cols-j) are symmetrical
03320         ObjectGL *pnt = (ObjectGL*)cpoints.first() ;
03321         int i,j ;
03322         i = 0 ;
03323         j = 0 ;
03324         while(pnt){
03325           ((CPointGL*)pnt)->setSym((CPointGL*)cpoints.goTo(i*c+(c-1-j)),x,y,z,w) ;
03326           ++j ;
03327           if(j>=c){
03328             j = 0 ;
03329             ++i ;
03330           }
03331           pnt = pnt->next() ;
03332         }
03333       }
03334     }
03335     else{
03336       ObjectGL *pnt = (ObjectGL*)cpoints.first() ;
03337       while(pnt){
03338         ((CPointGL*)pnt)->setSym((CPointGL*)0,float(1),float(1),float(1),float(1)) ;
03339         pnt = pnt->next() ;
03340       }
03341     }
03342   }
03343 
03369   void NurbsSurfaceGL::setImage(GLubyte *img, GLint w, GLint h) { 
03370     if(image) { delete []image ; } 
03371     int hs = 2 ;
03372     int ws = 2 ;
03373     while(ws<w)
03374       ws *= 2 ;
03375     while(hs<h)
03376       hs *= 2 ;
03377   
03378     image = new GLubyte[hs*ws*3] ;
03379 
03380     imgW = ws ; 
03381     imgH = hs ;
03382 
03383     if(w<ws || h<hs){// must patch the data
03384       for(int i=0;i<hs;++i)
03385         for(int j=0;j<ws;++j){
03386           if(i<h && j<w){
03387             image[(hs-1-i)*ws*3+j*3] =  img[i*w*3+j*3] ;
03388             image[(hs-1-i)*ws*3+j*3+1] =  img[i*w*3+j*3+1] ;
03389             image[(hs-1-i)*ws*3+j*3+2] =  img[i*w*3+j*3+2];
03390           }
03391           else{
03392             image[(hs-1-i)*ws*3+j*3] = 0 ;
03393             image[(hs-1-i)*ws*3+j*3+1] = 0  ;
03394             image[(hs-1-i)*ws*3+j*3+2] = 0 ;
03395           }
03396         }
03397     
03398     }
03399     else{ // just reverse the data
03400       for(int i=0;i<hs;++i)
03401         for(int j=0;j<ws;++j){
03402           image[(h-1-i)*w*3+j*3] =  img[i*w*3+j*3] ;
03403           image[(h-1-i)*w*3+j*3+1] =  img[i*w*3+j*3+1];
03404           image[(h-1-i)*w*3+j*3+2] = img[i*w*3+j*3+2] ;
03405         }
03406     }
03407 
03408   }
03409 
03419   SPointCurveGL::SPointCurveGL(int i, NurbsCurveSPf *c,int fix): 
03420     SPointGL(spoint,i,-1,fix), curve(c)
03421   { 
03422     if(!c){
03423 #ifdef USE_EXCEPTION
03424       throw NurbsInputError() ; 
03425 #else
03426       Error error("SPointCurveGL constructor with a curve point") ;
03427       error << "You must provide a *valid* nurbs curve pointer." ;
03428       error.fatal() ; 
03429 #endif
03430     }
03431     type = spointObject; 
03432     psize=pSizeDefault ; 
03433     i0 = i ; 
03434     cpoint = curve->surfP(i) ; 
03435     if(!curve->okMax()) { // it wasn't setup properly
03436       curve->updateMaxU() ; 
03437     }
03438     start = 0 ;
03439     rows = 0 ; 
03440   } 
03441 
03452   SPointSurfaceGL::SPointSurfaceGL(int i, int j, NurbsSurfaceSPf *s, ObjectListGL *sp,int fix): 
03453     SPointGL(spoint,i,j,fix), surface(s), spoints(sp)
03454   { 
03455     if(!s){
03456 #ifdef USE_EXCEPTION
03457       throw NurbsInputError();
03458 #else
03459       Error error("SPointSurfaceGL constructor with a surface point") ;
03460       error << "You must provide a *valid* nurbs surface pointer." ;
03461       error.fatal() ; 
03462 #endif
03463     }
03464     if(!spoints){
03465 #ifdef USE_EXCEPTION
03466       throw NurbsInputError();
03467 #else
03468       Error error("SPointSurfaceGL constructor with a surface point") ;
03469       error << "You must provide a *valid* point list pointer." ;
03470       error.fatal() ; 
03471 #endif
03472     }
03473     type = spointObject; 
03474     psize=pSizeDefault ; 
03475     i0=i ; 
03476     j0=j ; 
03477     if(!surface->okMax()) // it wasn't setup properly
03478       surface->updateMaxUV() ; 
03479 
03480     cpoint = surface->surfP(i,j) ; 
03481   } 
03482 
03493   SPointHSurfaceGL::SPointHSurfaceGL(int i, int j, HNurbsSurfaceSPf *s, ObjectListGL *sp,int fix): 
03494     SPointGL(spoint,i,j,fix), surface(s), spoints(sp)
03495   { 
03496     if(!s){
03497 #ifdef USE_EXCEPTION
03498       throw NurbsInputError();
03499 #else
03500       Error error("SPointSurfaceGL constructor with a surface point") ;
03501       error << "You must provide a *valid* nurbs surface pointer." ;
03502       error.fatal() ; 
03503 #endif
03504     }
03505     if(!spoints){
03506 #ifdef USE_EXCEPTION
03507       throw NurbsInputError();
03508 #else
03509       Error error("SPointSurfaceGL constructor with a surface point") ;
03510       error << "You must provide a *valid* point list pointer." ;
03511       error.fatal() ; 
03512 #endif
03513     }
03514     type = spointObject; 
03515     psize=pSizeDefault ; 
03516     i0=i ; 
03517     j0=j ; 
03518     if(!surface->okMax()) // it wasn't setup properly
03519       surface->updateMaxUV() ; 
03520 
03521     if(i>surface->ctrlPnts().rows())
03522       cerr << " BIG ERROR\n" ;
03523     if(j>surface->ctrlPnts().cols())
03524       cerr << " HUGE ERROR\n" ;
03525 
03526     cpoint = surface->surfP(i,j,surface->level()) ; 
03527   } 
03528 
03535   void SPointCurveGL::updateOthers(){
03536     SPointCurveGL *a ;
03537     a = start ;
03538     int n = 0 ;
03539     if(curve)
03540       while(a && n<rows){
03541         if(a!=this){
03542           a->spoint = a->curve->surfP(a->i0) ; 
03543         }
03544         a = (SPointCurveGL*) a->next() ;      
03545         ++n ; 
03546       }
03547   }
03548 
03555   void SPointSurfaceGL::updateOthers(){
03556     SPointSurfaceGL *a ;
03557     a = start ;
03558     int n = 0 ;
03559     int c = 0 ;
03560     if(surface){
03561       ObjectGL* saveCurrent = spoints->current() ;
03562       ObjectGL* rowStart ;
03563       spoints->current() = a ;
03564       rowStart = a ; 
03565       int mc = a->col() ;
03566       while(a && n<rows){
03567         if(a!=this){
03568           a->spoint = a->surface->surfP(a->i0,a->j0) ;
03569         }
03570         if(a->next()){
03571           if(((SPointSurfaceGL*)a->next())->col() > mc)
03572             a = (SPointSurfaceGL*) a->next() ; 
03573           else
03574             c = cols ;
03575         }
03576         ++c ;       
03577         if(c>=cols){
03578           ++n ; 
03579           if(n==rows)
03580             break ; 
03581           spoints->current() = (ObjectGL*)rowStart ; 
03582           a = (SPointSurfaceGL*) spoints->jumpToNext() ;
03583           rowStart = a ; 
03584           if(a->row() == 0)
03585             break ; 
03586           c = 0 ;
03587         }
03588       }
03589       spoints->current() = saveCurrent ;
03590     }
03591   }
03592 
03599   void SPointHSurfaceGL::updateOthers(){
03600     SPointHSurfaceGL *a ;
03601     a = start ;
03602     int n = 0 ;
03603     int c = 0 ;
03604     if(surface){
03605       ObjectGL* saveCurrent = spoints->current() ;
03606       ObjectGL* rowStart ;
03607       spoints->current() = a ;
03608       rowStart = a ; 
03609       int mc = a->col() ;
03610       while(a && n<rows){
03611         if(a!=this){
03612           a->spoint = a->surface->surfP(a->i0,a->j0,a->surface->level()) ;
03613         }
03614         if(a->next()){
03615           if(((SPointSurfaceGL*)a->next())->col() > mc)
03616             a = (SPointHSurfaceGL*) a->next() ; 
03617           else
03618             c = cols ;
03619         }
03620         ++c ;       
03621         if(c>=cols){
03622           ++n ; 
03623           if(n==rows)
03624             break ; 
03625           spoints->current() = (ObjectGL*)rowStart ; 
03626           a = (SPointHSurfaceGL*) spoints->jumpToNext() ;
03627           rowStart = a ; 
03628           if(a->row() == 0)
03629             break ; 
03630           c = 0 ;
03631         }
03632       }
03633       spoints->current() = saveCurrent ;
03634     }
03635   }
03636 
03645   void SPointCurveGL::modify(const HPoint3Df& v)  
03646   { 
03647     if(curve){
03648       if(editFix)
03649         curve->modOnlySurfCPby(i0,v) ; 
03650       else{
03651         curve->modSurfCPby(i0,v) ; 
03652         updateOthers(); 
03653       }
03654       spoint += v ; 
03655     }
03656   }
03657 
03665   void SPointSurfaceGL::modify(const HPoint3Df& v)  
03666   { 
03667     if(surface) {
03668       if(editFix)
03669         surface->modOnlySurfCPby(i0,j0,v) ; 
03670       else{
03671         surface->modSurfCPby(i0,j0,v) ; 
03672         updateOthers();
03673       }
03674       spoint += v ; 
03675     } 
03676   }
03677 
03687   void SPointHSurfaceGL::modify(const HPoint3Df& v)  
03688   { 
03689     if(surface) {
03690       if(editFix)
03691         surface->modOnlySurfCPby(i0,j0,v) ; 
03692       else{
03693         surface->modSurfCPby(i0,j0,v) ;
03694         updateOthers();
03695       }
03696       spoint = surface->surfP(i0,j0,surface->level()) ; 
03697     } 
03698   }
03699 
03710   int NurbsCurveGL::read(ifstream &fin) { 
03711     static int ncurves = 0 ;
03712     if(NurbsCurvef::read(fin)){ 
03713       if(!ObjectGL::read(fin)){
03714         char *maxName = new char[25] ; 
03715         sprintf(maxName,"curve_%d",ncurves++) ; 
03716         setName(maxName) ; 
03717         delete []maxName ; 
03718       }
03719       return 1 ;
03720     }
03721     return 0 ; 
03722   }
03723 
03734   int NurbsSurfaceGL::read(ifstream &fin) { 
03735     static int nsurfaces = 0 ;
03736     if(NurbsSurfacef::read(fin)){ 
03737       if(!ObjectGL::read(fin)){
03738         char *maxName = new char[25] ; 
03739         sprintf(maxName,"surface_%d",nsurfaces++) ; 
03740         setName(maxName) ; 
03741         delete []maxName ; 
03742       }
03743       return 1 ;
03744     }
03745     return 0 ; 
03746   }
03747 
03758   int HNurbsSurfaceGL::read(ifstream &fin) { 
03759     static int nhsurfaces = 0 ;
03760     if(HNurbsSurfacef::read(fin)){ 
03761       if(!ObjectGL::read(fin)){
03762         char *maxName = new char[25] ; 
03763         sprintf(maxName,"hsurface_%d",nhsurfaces++) ; 
03764         setName(maxName) ; 
03765         delete []maxName ; 
03766       }
03767       return 1 ;
03768     }
03769     return 0 ; 
03770   }
03771 
03782   int NurbsCurveGL::write(ofstream &fout) const {
03783     if(!NurbsCurvef::write(fout))
03784       return 0 ; 
03785     if(!ObjectGL::write(fout))
03786       return 0 ; 
03787     return 1;
03788   }
03789 
03800   int HNurbsSurfaceGL::write(ofstream &fout) const {
03801     if(!HNurbsSurfacef::write(fout))
03802       return 0 ; 
03803     if(!ObjectGL::write(fout))
03804       return 0 ; 
03805     return 1;
03806   }
03807 
03818   int NurbsSurfaceGL::write(ofstream &fout) const {
03819     if(!NurbsSurfacef::write(fout))
03820       return 0 ; 
03821     if(!ObjectGL::write(fout))
03822       return 0 ; 
03823     return 1;
03824   }
03825 
03826 
03837   int ObjectGL::read(ifstream &fin) { 
03838     // We might have some name and global transform information 
03839     // attached to this object
03840     int mark = fin.tellg() ; // marker position
03841     char *type = new char[5] ; 
03842     if(!fin.read(type,sizeof(char)*5)){ delete []type ; return 0 ; }
03843   
03844     char *maxName ;
03845     maxName = new char[256] ; // more then enough
03846     char *pat ;
03847     pat = strstr(type,"object") ;
03848     if(pat) {
03849       // setup the name and global transform information
03850       fin >> maxName ; 
03851       setName(maxName) ;
03852       fin >> tx >> ty >> tz >> rx >> ry >> rz >> sx >> sy >> sz ; 
03853     }
03854     else{
03855       // restore to the marker position
03856       fin.seekg(mark) ; 
03857       delete []type ; 
03858       delete []maxName ; 
03859       return 0 ; 
03860     }
03861     delete []type ; 
03862     delete []maxName ; 
03863     return 1 ; 
03864   }
03865 
03876   int ObjectGL::write(ofstream &fout) const {
03877     fout << "object" << name_ << tx << ty << tz << rx << ry << rz << sx << sy << sz ;
03878     if(!fout)
03879       return 0 ; 
03880     return 1 ; 
03881   }
03882 
03892   int ObjectGL::read(const char* filename) {
03893     ifstream fin(filename) ; 
03894     if(!fin) 
03895       return 0 ; 
03896     return read(fin) ; 
03897   }
03898 
03909   int ObjectGL::write(const char* filename) const {
03910     ofstream fout(filename) ; 
03911     if(!fout) 
03912       return 0 ; 
03913     return write(fout) ; 
03914   }
03915 
03916 
03917   template <class T>
03918   class RenderMeshGL : public RenderMesh<T> {
03919   public:
03920     RenderMeshGL(const Color& c): color(c) {;}
03921     virtual ~RenderMeshGL() { }
03922     virtual void drawHeader() ;
03923     virtual void drawTriangle( const SurfSample<T> &v0, const SurfSample<T> &v1, const SurfSample<T> & v2 );
03924     virtual void drawFooter() ;
03925     virtual void screenProject(const HPoint_nD<T,3> &worldPt, Point_nD<T,3> &screenPt ) ; 
03926   protected:
03927     Color color ; 
03928   };
03929 
03930   template <class T>
03931   void RenderMeshGL<T>::screenProject(const HPoint_nD<T,3> &worldPt, Point_nD<T,3> &screenPt )
03932   {
03933     screenPt = project(worldPt) ;
03934   }
03935 
03936   template <class T>
03937   void RenderMeshGL<T>::drawHeader()
03938   {
03939     //glBegin(GL_TRIANGLES);
03940     glBegin(GL_LINE_LOOP);
03942   }
03943  
03944   template <class T>
03945   void RenderMeshGL<T>::drawFooter(){
03946     glEnd();
03947   }
03948 
03949 
03950   template <class T>
03951   void RenderMeshGL<T>::drawTriangle(const SurfSample<T> &v0, const SurfSample<T> &v1, const SurfSample<T> & v2 )
03952   {
03953     glVertex3f(v0.point.x(),v0.point.y(),v0.point.z());
03954     glVertex3f(v1.point.x(),v1.point.y(),v1.point.z());
03955     glVertex3f(v2.point.x(),v2.point.y(),v2.point.z());
03956   }
03957 
03958 
03959   void NurbsSubSurfaceGL::drawSubdivisionGL(float tolerance)
03960   {
03961     if(render)
03962       delete render ;
03963     render = new RenderMeshGL<float>(color) ;
03964     drawSubdivision(tolerance) ;
03965   }
03966 
03967 
03968 
03969 #ifdef NO_IMPLICIT_TEMPLATES
03970 
03971   template class std::list<NurbsCurve_2Df*> ;
03972   template class std::list<NurbsCurve_2Df*>::iterator ;
03973 
03974   template class RenderMeshGL<float> ;
03975 
03976   template class std::allocator<PLib::NurbsCurve<float, 2> *>;
03977 
03978 #if GCC_VERSION >= 30000
03979 
03980 #else
03981   template void  std::_List_base<PLib::NurbsCurve<float, 2> *, std::allocator<PLib::NurbsCurve<float, 2> *> >::clear(void);
03982 #endif
03983 
03984   template void std::list<NurbsCurve_2Df*>::clear(void);
03985 
03986   template void std::list<PLib::NurbsCurve<float, 2> *, std::allocator<PLib::NurbsCurve<float, 2> *> >::_M_insert_dispatch<std::_List_iterator<PLib::NurbsCurve<float, 2> *, PLib::NurbsCurve<float, 2> *const &, PLib::NurbsCurve<float, 2> *const *> >(std::_List_iterator<PLib::NurbsCurve<float, 2> *, PLib::NurbsCurve<float, 2> *&, PLib::NurbsCurve<float, 2> **>, std::_List_iterator<PLib::NurbsCurve<float, 2> *, PLib::NurbsCurve<float,2> *const &, PLib::NurbsCurve<float, 2> *const *>, std::_List_iterator<PLib::NurbsCurve<float, 2> *, PLib::NurbsCurve<float, 2> *const &, PLib::NurbsCurve<float, 2> *const *>, __false_type);
03987 
03988   /*
03989     template void list<PLib::NurbsCurve<float, 2> *, __default_alloc_template<0, 0> >::insert<__list_iterator<PLib::NurbsCurve<float, 2> *, PLib::NurbsCurve<float, 2> *const &, PLib::NurbsCurve<float, 2> *const *> >(__list_iterator<PLib::NurbsCurve<float, 2> *, PLib::NurbsCurve<float, 2> *&, PLib::NurbsCurve<float, 2> **>, __list_iterator<PLib::NurbsCurve<float, 2> *, PLib::NurbsCurve<float, 2> *const &, PLib::NurbsCurve<float, 2> *const *>, __list_iterator<PLib::NurbsCurve<float, 2> *, PLib::NurbsCurve<float, 2> *const &, PLib::NurbsCurve<float, 2> *const *>) ;
03990     template void list<PLib::NurbsCurve<float, 2> *, __default_alloc_template<1, 0> >::insert<__list_iterator<PLib::NurbsCurve<float, 2> *, PLib::NurbsCurve<float, 2> *const &, PLib::NurbsCurve<float, 2> *const *> >(__list_iterator<PLib::NurbsCurve<float, 2> *, PLib::NurbsCurve<float, 2> *&, PLib::NurbsCurve<float, 2> **>, __list_iterator<PLib::NurbsCurve<float, 2> *, PLib::NurbsCurve<float, 2> *const &, PLib::NurbsCurve<float, 2> *const *>, __list_iterator<PLib::NurbsCurve<float, 2> *, PLib::NurbsCurve<float, 2> *const &, PLib::NurbsCurve<float, 2> *const *>) ;
03991 
03992 
03993     #if defined(USING_GNU_SOLARIS) 
03994     template void* __default_alloc_template<true, 0>::refill(unsigned int) ;
03995     template void* __default_alloc_template<true, 0>::free_list ; 
03996     template char* __default_alloc_template<true, 0>::chunk_alloc(unsigned int, int &);
03997     template void* __default_alloc_template<true, 0>::heap_size ;
03998     template void* __default_alloc_template<true, 0>::end_free ;
03999     template void* __default_alloc_template<true, 0>::start_free ;
04000     #endif 
04001 
04002     #ifdef USING_LINUX
04003     template void* __default_alloc_template<false, 0>::free_list ;
04004     template void* __default_alloc_template<false, 0>::refill (unsigned int) ;
04005     template char* __default_alloc_template<false, 0>::chunk_alloc(unsigned int, int &);
04006     template void* __default_alloc_template<false, 0>::end_free;
04007     template void* __default_alloc_template<false, 0>::heap_size;
04008     template void* __default_alloc_template<false, 0>::start_free ;
04009     #endif
04010 
04011   */
04012 
04013 #endif
04014 
04015 } // end namespace
04016 
04017 #endif
04018 
04019 
04020 #endif // #define PLIB_NURBS_NURBSGL_SOURCE
04021 

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