1 /*=============================================================================
2         File: nurbsS.h
3      Purpose:
4     Revision: $Id: nurbsS.h,v 1.2 2002/05/13 21:07:46 philosophil Exp $
5   Created by: Philippe Lavoie          (3 Oct, 1996)
6  Modified by:
7 
8  Copyright notice:
9           Copyright (C) 1996-1999 Philippe Lavoie
10 
11           This library is free software; you can redistribute it and/or
12           modify it under the terms of the GNU Library General Public
13           License as published by the Free Software Foundation; either
14           version 2 of the License, or (at your option) any later version.
15 
16           This library is distributed in the hope that it will be useful,
17           but WITHOUT ANY WARRANTY; without even the implied warranty of
18           MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19           Library General Public License for more details.
20 
21           You should have received a copy of the GNU Library General Public
22           License along with this library; if not, write to the Free
23           Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 =============================================================================*/
25 
26 #ifndef _nurbs_nurbsS_h_
27 #define _nurbs_nurbsS_h_
28 
29 #include "nurbs.h"
30 #include "surface.h"
31 
32 /*!
33  */
34 namespace PLib{
35 
36   enum Direction { u_direction=1, v_direction=2, both_direction=3} ;
37 
38   template <class T, int N> class NurbsSurfaceArray ;
39 
40   template <class T, int N> void gordonSurface(NurbsCurveArray<T,N>& , NurbsCurveArray<T,N>& , const Matrix< Point_nD<T,N> >& , NurbsSurface<T,N>& );
41   template <class T, int N> int surfMeshParams(const Matrix< Point_nD<T,N> >& , Vector<T>& , Vector<T>& );
42   template <class T, int N> int surfMeshParamsH(const Matrix< HPoint_nD<T,N> >& , Vector<T>& , Vector<T>& );
43   template <class T, int N> int surfMeshParamsClosedU(const Matrix< Point_nD<T,N> >& Qw, Vector<T>& uk, Vector<T>& vl, int degU );
44   template <class T, int N> int surfMeshParamsClosedUH(const Matrix< HPoint_nD<T,N> >& Qw, Vector<T>& uk, Vector<T>& vl, int degU );
45 
46   template <class T, int N> void globalSurfInterpXY(const Matrix< Point_nD<T,N> >& , int , int , NurbsSurface<T,N>& );
47   template <class T, int N> void globalSurfInterpXY(const Matrix< Point_nD<T,N> >& , int , int , NurbsSurface<T,N>& , const Vector<T>& , const Vector<T>& );
48   template <class T, int N> void globalSurfApprox(const Matrix< Point_nD<T,N> >& , int , int , NurbsSurface<T,N>& , double=0);
49   template <class T, int N> void wrapPointMatrix(const Matrix< Point_nD<T,N> >& Q, int , int, Matrix< Point_nD<T,N> >& Qw);
50 
51 
52 
53 /*!
54   \class NurbsSurface nurbsS.h
55   \brief A class to represent a NURBS surface
56 
57   The NURBS surface is composed of points in homogenous space. It can have
58   any degree in both the \a u and the \a v direction.
59 
60   \author Philippe Lavoie
61   \date 4 Oct. 1996
62 */
63 template <class T, int N>
64 class NurbsSurface : public ParaSurface<T,N> {
65 public:
66   NurbsSurface() ;
67   NurbsSurface(const NurbsSurface<T,N>& nS) ;
68   NurbsSurface(int DegU, int DegV, const Vector<T>& Uk, const Vector<T>& Vk, const Matrix< HPoint_nD<T,N> >& Cp) ;
69   NurbsSurface(int DegU, int DegV, Vector<T>& Uk, Vector<T>& Vk, Matrix< Point_nD<T,N> >& Cp, Matrix<T>& W) ;
~NurbsSurface()70   virtual ~NurbsSurface() //!< Empty desctructor
71     {;}
72 
73 public:
74   // Reference to internal data
knotU()75   const Vector<T>& knotU() const //!< A reference to the U knot vector
76     { return U ; }
knotV()77   const Vector<T>& knotV() const //!< A reference to the V knot vector
78     { return V ; }
knotU(int i)79   T knotU(int i) const //!< Returns the i-th knot from U
80     { return U[i] ; }
knotV(int i)81   T knotV(int i) const //!< Returns the i-th knot from V
82     { return V[i] ; }
ctrlPnts()83   const Matrix< HPoint_nD<T,N> >& ctrlPnts() const //!< A reference to the control points
84     { return P; }
ctrlPnts(int i,int j)85   const HPoint_nD<T,N> ctrlPnts(int i, int j) const //!< A reference to the control point at (i,j)
86     { return P(i,j); }
degreeU()87   int degreeU() const //!< A reference to the degree in U of the surface
88     { return degU ; }
degreeV()89   int degreeV() const //!< A reference to the degree in V of the surface
90     { return degV ; }
91 
92   // Basic operators
93   virtual NurbsSurface<T,N>& operator=(const NurbsSurface<T,N>&) ;
94   void resize(int Pu, int Pv, int DegU, int DegV) ;
95   virtual void resizeKeep(int Pu, int Pv, int DegU, int DegV) ;
96   int ok();
97 
98   // Basis functions
99   virtual HPoint_nD<T,N> operator()(T u, T v) const ;
100 
101   void basisFuns(T u, T v, int spanU, int spanV, Vector<T>& Nu, Vector<T>& Nv) const ;
102   void basisFunsU(T u, int span, Vector<T>& N_) const ;
103   void basisFunsV(T u, int span, Vector<T>& N_) const ;
104   void dersBasisFuns(T u, T v, int dU, int dV,int uspan, int vspan,Matrix<T> & Niku, Matrix<T>& Njkv ) const ;
105 
106   // Derivative functions
107   void deriveAt(T u, T v, int d, Matrix< Point_nD<T,N> >& skl) const ;
108   void deriveAtH(T u, T v, int d, Matrix< HPoint_nD<T,N> >& skl) const;
109   Point_nD<T,N> normal(T u, T v) const ;
110 
111 
112   // Surface fitting functions
113 
114   void globalInterp(const Matrix< Point_nD<T,N> >& Q, int pU, int pV);
115   void globalInterpH(const Matrix< HPoint_nD<T,N> >& Q, int pU, int pV);
116   void globalInterpClosedU(const Matrix< Point_nD<T,N> >& Q, int pU, int pV);
117   void globalInterpClosedUH(const Matrix< HPoint_nD<T,N> >& Q, int pU, int pV);
118   void leastSquares(const Matrix< Point_nD<T,N> >& Q, int pU, int pV, int nU, int nV) ;
119   void leastSquaresClosedU(const Matrix< Point_nD<T,N> >& Q, int pU, int pV, int nU, int nV) ;
120 
121 #ifndef HAVE_ISO_FRIEND_DECL
122   friend void gordonSurface (NurbsCurveArray<T,N>& lU, NurbsCurveArray<T,N>& lV, const Matrix< Point_nD<T,N> >& intersections, NurbsSurface<T,N>& gS);
123   friend void globalSurfInterpXY (const Matrix< Point_nD<T,N> >& Q, int pU, int pV, NurbsSurface<T,N>& S);
124   friend void globalSurfInterpXY (const Matrix< Point_nD<T,N> >& Q, int pU, int pV, NurbsSurface<T,N>& S, const Vector<T>& uk, const Vector<T>& vk);
125   friend void globalSurfApprox (const Matrix< Point_nD<T,N> >& Q, int pU, int pV, NurbsSurface<T,N>& S, double error);
126 #else
127   friend void gordonSurface <> (NurbsCurveArray<T,N>& lU, NurbsCurveArray<T,N>& lV, const Matrix< Point_nD<T,N> >& intersections, NurbsSurface<T,N>& gS);
128   friend void globalSurfInterpXY <> (const Matrix< Point_nD<T,N> >& Q, int pU, int pV, NurbsSurface<T,N>& S);
129   friend void globalSurfInterpXY <> (const Matrix< Point_nD<T,N> >& Q, int pU, int pV, NurbsSurface<T,N>& S, const Vector<T>& uk, const Vector<T>& vk);
130   friend void globalSurfApprox <> (const Matrix< Point_nD<T,N> >& Q, int pU, int pV, NurbsSurface<T,N>& S, double error);
131 #endif
132 
133   // Surface generation function
134   int skinV(NurbsCurveArray<T,N>& ca, int degV);
135   int skinU(NurbsCurveArray<T,N>& ca, int degU);
136   void sweep(const NurbsCurve<T,N>& t, const NurbsCurve<T,N>& C, const NurbsCurve<T,N>& Sv, int K,int useAy=0, int invAz=0) ;
137   void sweep(const NurbsCurve<T,N>& t, const NurbsCurve<T,N>& C, int K,int useAy=0, int invAz=0) ;
138   void makeFromRevolution(const NurbsCurve<T,N>& profile, const Point_nD<T,N>& S, const Point_nD<T,N>& T_, double theta) ;
139   void makeFromRevolution(const NurbsCurve<T,N>& profile, const Point_nD<T,N>& S, const Point_nD<T,N>& T_) ;
140   void makeFromRevolution(const NurbsCurve<T,N>& profile) ;
141 
142   void makeSphere(const Point_nD<T,N>& O, T r) ;
143   void makeTorus(const Point_nD<T,N>& O, T R, T r);
144 
145 
146   void degreeElevate(int tU, int tV) ;
147   virtual void degreeElevateU(int tU) ;
148   virtual void degreeElevateV(int tV) ;
149 
150 
151   int decompose(NurbsSurfaceArray<T,N>& Sa) const ;
152 
153   // Knot functions
154   void findSpan(T u, T v, int& spanU, int& spanV) const ;
155   int findSpanU(T u) const ;
156   int findSpanV(T v) const ;
157 
158   int findMultU(int r) const ;
159   int findMultV(int r) const ;
160 
161   virtual void refineKnots(const Vector<T>& nU, const Vector<T>& nV) ;
162   virtual void refineKnotU(const Vector<T>& X);
163   virtual void refineKnotV(const Vector<T>& X);
164 
165   virtual void mergeKnots(const Vector<T>& nU, const Vector<T>& nV) ;
166   virtual void mergeKnotU(const Vector<T>& X);
167   virtual void mergeKnotV(const Vector<T>& X);
168 
169   // Measuring functions
170   T area(T eps=0.001,int n=100) const ;
171   T areaIn(T us, T ue, T vs, T ve, T eps, int n) const ;
172   T areaF(T u, T v) const ;
173 
174   // special functions
175   void isoCurveU(T u, NurbsCurve<T,N>& c) const ;
176   void isoCurveV(T v, NurbsCurve<T,N>& c) const ;
177 
178   // I/O functions
179   int read(const char* filename);
180   int write(const char* filename) const;
181   virtual int read(ifstream &fin) ;
182   int write(ofstream &fout) const ;
writeVRML(const char * filename,const Color & color,int Nu,int Nv,T u_s,T u_e,T v_s,T v_e)183   int writeVRML(const char* filename,const Color& color,int Nu,int Nv, T u_s, T u_e, T v_s, T v_e) const { return ParaSurface<T,N>::writeVRML(filename,color,Nu,Nv,u_s,u_e,v_s,v_e);}
writeVRML(ostream & fout,const Color & color,int Nu,int Nv,T u_s,T u_e,T v_s,T v_e)184   int writeVRML(ostream &fout,const Color& color,int Nu,int Nv, T u_s, T u_e, T v_s, T v_e) const { return ParaSurface<T,N>::writeVRML(fout,color,Nu,Nv,u_s,u_e,v_s,v_e);}
writeVRML97(const char * filename,const Color & color,int Nu,int Nv,T u_s,T u_e,T v_s,T v_e)185   int writeVRML97(const char* filename,const Color& color,int Nu,int Nv, T u_s, T u_e, T v_s, T v_e) const { return ParaSurface<T,N>::writeVRML97(filename,color,Nu,Nv,u_s,u_e,v_s,v_e);}
writeVRML97(ostream & fout,const Color & color,int Nu,int Nv,T u_s,T u_e,T v_s,T v_e)186   int writeVRML97(ostream &fout,const Color& color,int Nu,int Nv, T u_s, T u_e, T v_s, T v_e) const { return ParaSurface<T,N>::writeVRML97(fout,color,Nu,Nv,u_s,u_e,v_s,v_e);}
187   ostream& print(ostream& os) const ;
188 
189   int writeVRML(const char* filename,const Color& color=whiteColor,int Nu=20,int Nv=20) const //!< Calls the ParaSurface routine with proper values
190     { return ParaSurface<T,N>::writeVRML(filename,color,Nu,Nv,U[0],U[U.n()-1],V[0],V[V.n()-1]); }
191   int writeVRML(ostream& fout,const Color& color=whiteColor,int Nu=20,int Nv=20) const //!< Calls the ParaSurface routine with proper values
192     { return ParaSurface<T,N>::writeVRML(fout,color,Nu,Nv,U[0],U[U.n()-1],V[0],V[V.n()-1]); }
193 
194   int writeVRML97(const char* filename,const Color& color=whiteColor,int Nu=20,int Nv=20) const //!< Calls the ParaSurface routine with proper values
195     { return ParaSurface<T,N>::writeVRML97(filename,color,Nu,Nv,U[0],U[U.n()-1],V[0],V[V.n()-1]); }
196   int writeVRML97(ostream& fout,const Color& color=whiteColor,int Nu=20,int Nv=20) const //!< Calls the ParaSurface routine with proper values
197     { return ParaSurface<T,N>::writeVRML97(fout,color,Nu,Nv,U[0],U[U.n()-1],V[0],V[V.n()-1]); }
198 
199   int writePOVRAY(ostream& povray, int patch_type=1, double flatness=0.01, int num_u_steps=8, int num_v_steps=8) const ;
200   int writePOVRAY(T, ostream& povray, const Color& color=Color(250,250,250),int smooth=0 , T ambient=0.2, T diffuse=0.6) const ;
201   int writePOVRAY(const char *filename, const Color& color, const Point_nD<T,N>& view, const Point_nD<T,N>& up, int patch_type=1, double flatness=0.01, int num_u_steps=8, int num_v_steps=8) const ;
202   int writePOVRAY(T tolerance, const char *filename, const Color& color, const Point_nD<T,N>& view, const Point_nD<T,N>& up, int smooth=0, T ambient=0.2, T diffuse=0.6) const ;
203 
204   int writeRIB(ostream& rib) const ;
205   int writeRIB(const char* filename, const Color& color, const Point_nD<T,N>& view) const ;
206 
207   // tesselate is deprecated...
208   void tesselate(T tolerance, BasicList<Point_nD<T,N> > &points, BasicList<int> &connect, BasicList<Point_nD<T,N> > *normal=0) const ;
209 
210   int writePS(const char*, int nu, int nv, const Point_nD<T,N>& camera, const Point_nD<T,N>& lookAt, int cp=0,T magFact=T(-1),T dash=T(5)) const ;
211   int writePSp(const char*, int nu, int nv, const Point_nD<T,N>& camera, const Point_nD<T,N>& lookAt, const Vector< Point_nD<T,N> >&,const Vector< Point_nD<T,N> >&, int cp=0,T magFact=0.0,T dash=5.0) const ;
212   int writeOOGL(const char* filename, T fDu, T fDv,T fBu=0.0, T fBv=0.0, T fEu=1.0, T fEv=1.0, bool bDRawCP=false) const ;
213   int writeOOGL(const char* filename) const ;
214 
215   int writeDisplayQUADMESH(const char* filename, int iNu=100,int iNv=100,const Color& color=blueColor,T fA=.25, T  fO=0.2) const;
216 
217 
218   // Modifies the shape of the surface
219   void transform(const MatrixRT<T>& A) ;
modCP(int i,int j,const HPoint_nD<T,N> & p)220   void modCP(int i, int j, const HPoint_nD<T,N>& p) //!< Modifies a control point
221     { P(i,j) = p ; }
modCPby(int i,int j,const HPoint_nD<T,N> & p)222   void modCPby(int i, int j, const HPoint_nD<T,N>& p) //!< Modifies a control point
223     { P(i,j) += p ; }
224 
modU(int i)225   T& modU(int i) { return U[i] ; }
modU(int i)226   T modU(int i) const { return U[i]; } //!< modifies a knot
modV(int i)227   T& modV(int i) { return V[i] ; } //!< modifies a knot
modV(int i)228   T modV(int i) const { return V[i]; } //!< modifies a knot
229 
modKnotU(const Vector<T> & uKnot)230   void modKnotU(const Vector<T>& uKnot) { if(P.rows()+degU+1==uKnot.n()) U=uKnot ; } //!< modifies the U knot vector if uKnot is of a proper size
modKnotV(const Vector<T> & vKnot)231   void modKnotV(const Vector<T>& vKnot) { if(P.cols()+degV+1==vKnot.n()) V=vKnot ; } //!< modifies the U knot vector if uKnot is of a proper size
232 
233   int movePoint(T u, T v, const Point_nD<T,N>& delta);
234   int movePoint(const Vector<T>& ur, const Vector<T>& vr, const Vector< Point_nD<T,N> >& D, const Vector_INT& Du, const Vector_INT& Dv) ;
235   int movePoint(const Vector<T>& ur, const Vector<T>& vr, const Vector< Point_nD<T,N> >& D, const Vector_INT& Du, const Vector_INT& Dv, const Vector_INT& Dk, const Vector_INT& Dl) ;
236   int movePoint(const Vector<T>& ur, const Vector<T>& vr, const Vector< Point_nD<T,N> >& D, const Vector_INT& Du, const Vector_INT& Dv, const Vector_INT& Dk, const Vector_INT& Dl, const BasicArray<Coordinate>& fixCP) ;
237 
238   NurbsSurface<T,N>& transpose(void) ;
239 
240 
241 protected:
242   Vector<T> U ; //!< the U knot vector
243   Vector<T> V ; //!< the V knot vector
244   Matrix< HPoint_nD<T,N> > P ; //!< The matrix of control points
245   int degU ; //!< the degree of the surface in U
246   int degV ; //!< the degree of the surface in V
247 
248 };
249 
250 typedef NurbsSurface<float,3> NurbsSurfacef ;
251 typedef NurbsSurface<double,3> NurbsSurfaced ;
252 
253 } // end namespace
254 
255 typedef PLib::NurbsSurface<float,3> PlNurbsSurfacef ;
256 typedef PLib::NurbsSurface<double,3> PlNurbsSurfaced ;
257 
258 /*!
259  */
260 namespace PLib {
261 
262 /*!
263   \class  NurbsSurfaceArray nurbsS.h
264   \brief An array of NurbsSurface
265 
266   This class represents an array of NurbsSurface.
267 
268   \author Philippe Lavoie
269   \date 4 Oct. 1996
270 */
271 template <class T, int N>
272 class NurbsSurfaceArray {
273 public:
n()274   int n() const //!< a reference to the size of the array
275     { return sze ; }
276   NurbsSurfaceArray(NurbsSurface<T,N>* Sa, int size) ;
NurbsSurfaceArray()277   NurbsSurfaceArray() { S = 0 ; sze = 0 ; rsize = 0 ;} //<! Default constructor
~NurbsSurfaceArray()278   virtual ~NurbsSurfaceArray(){ if(S){ for(int i=0;i<rsize;i++) delete S[i];  delete []S ; }}
279 
280   virtual NurbsSurface<T,N>& operator[](int i)
281     { return *(S[i]) ; } //!< the ith surface
282   virtual NurbsSurface<T,N> operator[](int i) const
283     { return *(S[i]) ; } //!< the ith surface
284 
285   virtual void resize(int s) ;
286   void init(NurbsSurface<T,N>* Sa, int size) ;
287 
288   NurbsSurfaceArray<T,N>& operator=(const NurbsSurfaceArray<T,N>& Sa) ;
289 
290 protected:
291   int sze ; //!< the number of NURBS curves in the array
292   int rsize ; //!< the number of space allocated for the array
293   NurbsSurface<T,N>** S ; //!< An array of pointers to NURBS curves
294 };
295 
296 }//end namespace
297 
298 // In case someone wants the old behavior for degree elevation
299 template <class T, int N>
degreeElevate(const PLib::NurbsSurface<T,N> & S,int tU,int tV,PLib::NurbsSurface<T,N> & nS)300 inline void degreeElevate(const PLib::NurbsSurface<T,N>& S, int tU, int tV, PLib::NurbsSurface<T,N>& nS) { nS = S ; nS.degreeElevate(tU,tV) ; }
301 template <class T, int N>
degreeElevateU(const PLib::NurbsSurface<T,N> & S,int tU,PLib::NurbsSurface<T,N> & nS)302 inline void degreeElevateU(const PLib::NurbsSurface<T,N>& S, int tU, PLib::NurbsSurface<T,N>& nS) { nS = S ; nS.degreeElevateU(tU) ; }
303 template <class T, int N>
degreeElevateV(const PLib::NurbsSurface<T,N> & S,int tV,PLib::NurbsSurface<T,N> & nS)304 inline void degreeElevateV(const PLib::NurbsSurface<T,N>& S, int tV, PLib::NurbsSurface<T,N>& nS) { nS = S ; nS.degreeElevateV(tV) ; }
305 
306 
307 #ifdef INCLUDE_TEMPLATE_SOURCE
308 #include "nurbsS.cpp"
309 #endif
310 
311 
312 #endif
313