/*============================================================================= File: nurbsS.h Purpose: Revision: $Id: nurbsS.h,v 1.2 2002/05/13 21:07:46 philosophil Exp $ Created by: Philippe Lavoie (3 Oct, 1996) Modified by: Copyright notice: Copyright (C) 1996-1999 Philippe Lavoie This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. =============================================================================*/ #ifndef _nurbs_nurbsS_h_ #define _nurbs_nurbsS_h_ #include "nurbs.h" #include "surface.h" /*! */ namespace PLib{ enum Direction { u_direction=1, v_direction=2, both_direction=3} ; template class NurbsSurfaceArray ; template void gordonSurface(NurbsCurveArray& , NurbsCurveArray& , const Matrix< Point_nD >& , NurbsSurface& ); template int surfMeshParams(const Matrix< Point_nD >& , Vector& , Vector& ); template int surfMeshParamsH(const Matrix< HPoint_nD >& , Vector& , Vector& ); template int surfMeshParamsClosedU(const Matrix< Point_nD >& Qw, Vector& uk, Vector& vl, int degU ); template int surfMeshParamsClosedUH(const Matrix< HPoint_nD >& Qw, Vector& uk, Vector& vl, int degU ); template void globalSurfInterpXY(const Matrix< Point_nD >& , int , int , NurbsSurface& ); template void globalSurfInterpXY(const Matrix< Point_nD >& , int , int , NurbsSurface& , const Vector& , const Vector& ); template void globalSurfApprox(const Matrix< Point_nD >& , int , int , NurbsSurface& , double=0); template void wrapPointMatrix(const Matrix< Point_nD >& Q, int , int, Matrix< Point_nD >& Qw); /*! \class NurbsSurface nurbsS.h \brief A class to represent a NURBS surface The NURBS surface is composed of points in homogenous space. It can have any degree in both the \a u and the \a v direction. \author Philippe Lavoie \date 4 Oct. 1996 */ template class NurbsSurface : public ParaSurface { public: NurbsSurface() ; NurbsSurface(const NurbsSurface& nS) ; NurbsSurface(int DegU, int DegV, const Vector& Uk, const Vector& Vk, const Matrix< HPoint_nD >& Cp) ; NurbsSurface(int DegU, int DegV, Vector& Uk, Vector& Vk, Matrix< Point_nD >& Cp, Matrix& W) ; virtual ~NurbsSurface() //!< Empty desctructor {;} public: // Reference to internal data const Vector& knotU() const //!< A reference to the U knot vector { return U ; } const Vector& knotV() const //!< A reference to the V knot vector { return V ; } T knotU(int i) const //!< Returns the i-th knot from U { return U[i] ; } T knotV(int i) const //!< Returns the i-th knot from V { return V[i] ; } const Matrix< HPoint_nD >& ctrlPnts() const //!< A reference to the control points { return P; } const HPoint_nD ctrlPnts(int i, int j) const //!< A reference to the control point at (i,j) { return P(i,j); } int degreeU() const //!< A reference to the degree in U of the surface { return degU ; } int degreeV() const //!< A reference to the degree in V of the surface { return degV ; } // Basic operators virtual NurbsSurface& operator=(const NurbsSurface&) ; void resize(int Pu, int Pv, int DegU, int DegV) ; virtual void resizeKeep(int Pu, int Pv, int DegU, int DegV) ; int ok(); // Basis functions virtual HPoint_nD operator()(T u, T v) const ; void basisFuns(T u, T v, int spanU, int spanV, Vector& Nu, Vector& Nv) const ; void basisFunsU(T u, int span, Vector& N) const ; void basisFunsV(T u, int span, Vector& N) const ; void dersBasisFuns(T u, T v, int dU, int dV,int uspan, int vspan,Matrix & Niku, Matrix& Njkv ) const ; // Derivative functions void deriveAt(T u, T v, int d, Matrix< Point_nD >& skl) const ; void deriveAtH(T u, T v, int d, Matrix< HPoint_nD >& skl) const; Point_nD normal(T u, T v) const ; // Surface fitting functions void globalInterp(const Matrix< Point_nD >& Q, int pU, int pV); void globalInterpH(const Matrix< HPoint_nD >& Q, int pU, int pV); void globalInterpClosedU(const Matrix< Point_nD >& Q, int pU, int pV); void globalInterpClosedUH(const Matrix< HPoint_nD >& Q, int pU, int pV); void leastSquares(const Matrix< Point_nD >& Q, int pU, int pV, int nU, int nV) ; void leastSquaresClosedU(const Matrix< Point_nD >& Q, int pU, int pV, int nU, int nV) ; #ifndef HAVE_ISO_FRIEND_DECL friend void gordonSurface (NurbsCurveArray& lU, NurbsCurveArray& lV, const Matrix< Point_nD >& intersections, NurbsSurface& gS); friend void globalSurfInterpXY (const Matrix< Point_nD >& Q, int pU, int pV, NurbsSurface& S); friend void globalSurfInterpXY (const Matrix< Point_nD >& Q, int pU, int pV, NurbsSurface& S, const Vector& uk, const Vector& vk); friend void globalSurfApprox (const Matrix< Point_nD >& Q, int pU, int pV, NurbsSurface& S, double error); #else friend void gordonSurface <> (NurbsCurveArray& lU, NurbsCurveArray& lV, const Matrix< Point_nD >& intersections, NurbsSurface& gS); friend void globalSurfInterpXY <> (const Matrix< Point_nD >& Q, int pU, int pV, NurbsSurface& S); friend void globalSurfInterpXY <> (const Matrix< Point_nD >& Q, int pU, int pV, NurbsSurface& S, const Vector& uk, const Vector& vk); friend void globalSurfApprox <> (const Matrix< Point_nD >& Q, int pU, int pV, NurbsSurface& S, double error); #endif // Surface generation function int skinV(NurbsCurveArray& ca, int degV); int skinU(NurbsCurveArray& ca, int degU); void sweep(const NurbsCurve& t, const NurbsCurve& C, const NurbsCurve& Sv, int K,int useAy=0, int invAz=0) ; void sweep(const NurbsCurve& t, const NurbsCurve& C, int K,int useAy=0, int invAz=0) ; void makeFromRevolution(const NurbsCurve& profile, const Point_nD& S, const Point_nD& T, double theta) ; void makeFromRevolution(const NurbsCurve& profile, const Point_nD& S, const Point_nD& T) ; void makeFromRevolution(const NurbsCurve& profile) ; void makeSphere(const Point_nD& O, T r) ; void makeTorus(const Point_nD& O, T R, T r); void degreeElevate(int tU, int tV) ; virtual void degreeElevateU(int tU) ; virtual void degreeElevateV(int tV) ; int decompose(NurbsSurfaceArray& Sa) const ; // Knot functions void findSpan(T u, T v, int& spanU, int& spanV) const ; int findSpanU(T u) const ; int findSpanV(T v) const ; int findMultU(int r) const ; int findMultV(int r) const ; virtual void refineKnots(const Vector& nU, const Vector& nV) ; virtual void refineKnotU(const Vector& X); virtual void refineKnotV(const Vector& X); virtual void mergeKnots(const Vector& nU, const Vector& nV) ; virtual void mergeKnotU(const Vector& X); virtual void mergeKnotV(const Vector& X); // Measuring functions T area(T eps=0.001,int n=100) const ; T areaIn(T us, T ue, T vs, T ve, T eps, int n) const ; T areaF(T u, T v) const ; // special functions void isoCurveU(T u, NurbsCurve& c) const ; void isoCurveV(T v, NurbsCurve& c) const ; // I/O functions int read(const char* filename); int write(const char* filename) const; virtual int read(ifstream &fin) ; int write(ofstream &fout) const ; 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::writeVRML(filename,color,Nu,Nv,u_s,u_e,v_s,v_e);} 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::writeVRML(fout,color,Nu,Nv,u_s,u_e,v_s,v_e);} 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::writeVRML97(filename,color,Nu,Nv,u_s,u_e,v_s,v_e);} 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::writeVRML97(fout,color,Nu,Nv,u_s,u_e,v_s,v_e);} ostream& print(ostream& os) const ; int writeVRML(const char* filename,const Color& color=whiteColor,int Nu=20,int Nv=20) const //!< Calls the ParaSurface routine with proper values { return ParaSurface::writeVRML(filename,color,Nu,Nv,U[0],U[U.n()-1],V[0],V[V.n()-1]); } int writeVRML(ostream& fout,const Color& color=whiteColor,int Nu=20,int Nv=20) const //!< Calls the ParaSurface routine with proper values { return ParaSurface::writeVRML(fout,color,Nu,Nv,U[0],U[U.n()-1],V[0],V[V.n()-1]); } int writeVRML97(const char* filename,const Color& color=whiteColor,int Nu=20,int Nv=20) const //!< Calls the ParaSurface routine with proper values { return ParaSurface::writeVRML97(filename,color,Nu,Nv,U[0],U[U.n()-1],V[0],V[V.n()-1]); } int writeVRML97(ostream& fout,const Color& color=whiteColor,int Nu=20,int Nv=20) const //!< Calls the ParaSurface routine with proper values { return ParaSurface::writeVRML97(fout,color,Nu,Nv,U[0],U[U.n()-1],V[0],V[V.n()-1]); } int writePOVRAY(ostream& povray, int patch_type=1, double flatness=0.01, int num_u_steps=8, int num_v_steps=8) const ; int writePOVRAY(T, ostream& povray, const Color& color=Color(250,250,250),int smooth=0 , T ambient=0.2, T diffuse=0.6) const ; int writePOVRAY(const char *filename, const Color& color, const Point_nD& view, const Point_nD& up, int patch_type=1, double flatness=0.01, int num_u_steps=8, int num_v_steps=8) const ; int writePOVRAY(T tolerance, const char *filename, const Color& color, const Point_nD& view, const Point_nD& up, int smooth=0, T ambient=0.2, T diffuse=0.6) const ; int writeRIB(ostream& rib) const ; int writeRIB(const char* filename, const Color& color, const Point_nD& view) const ; // tesselate is deprecated... void tesselate(T tolerance, BasicList > &points, BasicList &connect, BasicList > *normal=0) const ; int writePS(const char*, int nu, int nv, const Point_nD& camera, const Point_nD& lookAt, int cp=0,T magFact=T(-1),T dash=T(5)) const ; int writePSp(const char*, int nu, int nv, const Point_nD& camera, const Point_nD& lookAt, const Vector< Point_nD >&,const Vector< Point_nD >&, int cp=0,T magFact=0.0,T dash=5.0) const ; 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 ; int writeOOGL(const char* filename) const ; int writeDisplayQUADMESH(const char* filename, int iNu=100,int iNv=100,const Color& color=blueColor,T fA=.25, T fO=0.2) const; // Modifies the shape of the surface void transform(const MatrixRT& A) ; void modCP(int i, int j, const HPoint_nD& p) //!< Modifies a control point { P(i,j) = p ; } void modCPby(int i, int j, const HPoint_nD& p) //!< Modifies a control point { P(i,j) += p ; } T& modU(int i) { return U[i] ; } T modU(int i) const { return U[i]; } //!< modifies a knot T& modV(int i) { return V[i] ; } //!< modifies a knot T modV(int i) const { return V[i]; } //!< modifies a knot void modKnotU(const Vector& uKnot) { if(P.rows()+degU+1==uKnot.n()) U=uKnot ; } //!< modifies the U knot vector if uKnot is of a proper size void modKnotV(const Vector& vKnot) { if(P.cols()+degV+1==vKnot.n()) V=vKnot ; } //!< modifies the U knot vector if uKnot is of a proper size int movePoint(T u, T v, const Point_nD& delta); int movePoint(const Vector& ur, const Vector& vr, const Vector< Point_nD >& D, const Vector_INT& Du, const Vector_INT& Dv) ; int movePoint(const Vector& ur, const Vector& vr, const Vector< Point_nD >& D, const Vector_INT& Du, const Vector_INT& Dv, const Vector_INT& Dk, const Vector_INT& Dl) ; int movePoint(const Vector& ur, const Vector& vr, const Vector< Point_nD >& D, const Vector_INT& Du, const Vector_INT& Dv, const Vector_INT& Dk, const Vector_INT& Dl, const BasicArray& fixCP) ; NurbsSurface& transpose(void) ; protected: Vector U ; //!< the U knot vector Vector V ; //!< the V knot vector Matrix< HPoint_nD > P ; //!< The matrix of control points int degU ; //!< the degree of the surface in U int degV ; //!< the degree of the surface in V }; typedef NurbsSurface NurbsSurfacef ; typedef NurbsSurface NurbsSurfaced ; } // end namespace typedef PLib::NurbsSurface PlNurbsSurfacef ; typedef PLib::NurbsSurface PlNurbsSurfaced ; /*! */ namespace PLib { /*! \class NurbsSurfaceArray nurbsS.h \brief An array of NurbsSurface This class represents an array of NurbsSurface. \author Philippe Lavoie \date 4 Oct. 1996 */ template class NurbsSurfaceArray { public: int n() const //!< a reference to the size of the array { return sze ; } NurbsSurfaceArray(NurbsSurface* Sa, int size) ; NurbsSurfaceArray() { S = 0 ; sze = 0 ; rsize = 0 ;} //& operator[](int i) { return *(S[i]) ; } //!< the ith surface virtual NurbsSurface operator[](int i) const { return *(S[i]) ; } //!< the ith surface virtual void resize(int s) ; void init(NurbsSurface* Sa, int size) ; NurbsSurfaceArray& operator=(const NurbsSurfaceArray& Sa) ; protected: int sze ; //!< the number of NURBS curves in the array int rsize ; //!< the number of space allocated for the array NurbsSurface** S ; //!< An array of pointers to NURBS curves }; }//end namespace // In case someone wants the old behavior for degree elevation template inline void degreeElevate(const PLib::NurbsSurface& S, int tU, int tV, PLib::NurbsSurface& nS) { nS = S ; nS.degreeElevate(tU,tV) ; } template inline void degreeElevateU(const PLib::NurbsSurface& S, int tU, PLib::NurbsSurface& nS) { nS = S ; nS.degreeElevateU(tU) ; } template inline void degreeElevateV(const PLib::NurbsSurface& S, int tV, PLib::NurbsSurface& nS) { nS = S ; nS.degreeElevateV(tV) ; } #ifdef INCLUDE_TEMPLATE_SOURCE #include "nurbsS.cpp" #endif #endif