[80]  1  /**********************************************************************


 2  *<


 3  FILE: NURBS.h


 4 


 5  DESCRIPTION: Main include file for Non Uniform Rational BSplines


 6 


 7  CREATED BY: Steve Anderson


 8 


 9  HISTORY: Created Dec 31, 1995


 10 


 11  *> Copyright (c) 1995, All Rights Reserved.


 12  **********************************************************************/


 13 


 14  #ifndef _NURBS_H_


 15 


 16  #define _NURBS_H_


 17 


 18  #include <hitdata.h>


 19 


 20  // Value for undefined patches and vertices


 21  #define NURBS_UNDEFINED 1


 22 


 23  #define MULTI_PROCESSING TRUE // TRUE turns on mp vertex transformation


 24 


 25  typedef Tab<int> IntTab;


 26 


 27  class ISave;


 28  class ILoad;


 29  class NurbsMesh;


 30 


 31  // NRVertex flags: contain clip flags, number of normals at the vertex


 32  // and the number of normals that have already been rendered.


 33  // fine PLANE_MASK 0x00003f00UL  now in gfx.h


 34  #define NORCT_MASK 0x000000ffUL


 35  #define SPECIFIED_NORMAL 0x00004000UL


 36  #define OUT_LEFT 0x00010000UL


 37  #define OUT_RIGHT 0x00020000UL


 38  #define OUT_TOP 0x00040000UL


 39  #define OUT_BOTTOM 0x00080000UL


 40  #define RECT_MASK 0x000f0000UL


 41  #define RND_MASK 0xfff00000UL


 42  #define RND_NOR0 0x00100000UL


 43  #define RND_NOR(n) (RND_NOR0 << (n))


 44 


 45  class NRVertex { // NURBS vertex for rendering, like PRVertex in patch.h


 46  public:


 47  NRVertex() { rFlags = 0; }


 48  DllExport ~NRVertex() {}


 49 


 50  DWORD rFlags;


 51  union {


 52  int iPos[3];


 53  float fPos[3];


 54  };


 55  };


 56 


 57  // Nurbs vertex


 58  // (Used in NurbsMesh, not in NurbsCurve.)


 59  class NurbsVert {


 60  public:


 61  Point3 p; // Location


 62  float w; // p = pw/w


 63  IntTab faces; // List of NURBS faces using this vertex


 64  DWORD flags; // Currently no flags


 65 


 66  // General utilities


 67  NurbsVert() { p = Point3(0,0,0); w = 1.0f; flags = 0; }


 68  DllExport NurbsVert(const NurbsVert &from) { (*this) = from; }


 69  ~NurbsVert() { ResetData(); }


 70  DllExport NurbsVert& operator=(const NurbsVert& from);


 71  void ResetData() { faces.Delete(0,faces.Count()); }


 72 


 73  // Face reference handling


 74  DllExport int FindFace(int index);


 75  DllExport void AddFace(int index);


 76  DllExport void DeleteFace(int index);


 77 


 78  // I/O


 79  DllExport IOResult Save(ISave* isave);


 80  DllExport IOResult Load(ILoad* iload);


 81  };


 82 


 83  // NurbsCurve: Not actually used yet; ideally both an independent object


 84  // and a trim curve container in NurbsEdge.


 85  class NurbsCurve {


 86  public:


 87  DllExport NurbsCurve() { Init(); }


 88  NurbsCurve(const NurbsCurve & cv) { Init(); (*this) = cv; }


 89  DllExport NurbsCurve(int ordd, int numm);


 90  virtual ~NurbsCurve() { Clear(); }


 91 


 92  // inquiry methods


 93  DllExport int getOrder() const { return ord; }


 94  DllExport int getNumber() const { return num; }


 95 


 96  // editing methods


 97  DllExport void setControlPoint(int ind, const Point3 & p);


 98  DllExport Point3 & getControlPoint (int ind) const;


 99  DllExport void setWeight (int ind, float w);


 100  DllExport float getWeight (int ind) const;


 101 


 102  // evaluation methods


 103  DllExport void Evaluate(float u, Point3 & p) const;


 104  DllExport void Evaluate(float u, Point3 & p, Point3& dout) const;


 105 


 106  // invert methods


 107  // int Inverter(const Point3 & p1, float & u, double & dis, double init_value = 1.0) const;


 108 


 109  DllExport NurbsCurve & operator = (const NurbsCurve & cv);


 110  void Init ();


 111  void Clear();


 112 


 113  // I/O


 114  DllExport IOResult Save(ISave* isave);


 115  DllExport IOResult Load(ILoad* iload);


 116 


 117  private:


 118  int ord; // Order of polynomials. Order 3 = cubic, etc.


 119  int num; // Number of points.


 120  Point3 *verts;


 121  float *wghts;


 122  float *knots; // Knot vector: length num+ord+1


 123  char rational; // Flag to make computation easier if rational. (Ignore weights.)


 124  };


 125 


 126  class NurbsEdge {


 127  public:


 128  int partner; // "Joined" edge on adjacent face.


 129  int parthost; // host face index of partner


 130  int rendedge; // Used in converting to mesh


 131 


 132  DllExport NurbsEdge () { Init(); }


 133  void Init ();


 134  NurbsEdge& operator = ( const NurbsEdge& from);


 135 


 136  // I/O


 137  DllExport IOResult Save(ISave* isave);


 138  DllExport IOResult Load(ILoad* iload);


 139  };


 140 


 141  DllExport void NurbsEdgeEvaluate (int type, float t, Point3 & p);


 142 


 143  // NurbsFace: this is what you'd call a Patch if it was Bezier, but


 144  // I'm staying away from nonNurbs patch terminology.


 145 


 146  // NurbsFace flags:


 147  // None yet.


 148 


 149  class NurbsFace {


 150  public:


 151  int num; // == uNum*vNum


 152  int uTess, vTess; // Tesselation resolutions


 153  int uOrd, vOrd; // polynomial orders in each dim.


 154  int uNum, vNum; // Numbers of points in each dim.


 155  float *uKnot, *vKnot; // Knot vectors


 156  int *verts; // Indices of verts in NurbsMesh. (Weights handled there too.)


 157  NurbsEdge edges[4]; // U=0, V=0, U=1, V=1


 158  DWORD smGroup; // Defaults to 1  All faces smoothed in a NurbsMesh


 159  DWORD flags; // See flags above.


 160 


 161  DllExport NurbsFace() { Init(); }


 162  NurbsFace (const NurbsFace & from) { Init(); (*this) = from; }


 163  DllExport NurbsFace (int uO, int vO, int uN, int vN);


 164  DllExport ~NurbsFace() { Clear(); }


 165 


 166  // evaluation methods  need to handle these on higher level...


 167  DllExport void Evaluate (NurbsVert *vtx, float u, float v, Point3 & p) const;


 168  DllExport void Evaluate (NurbsVert *vtx, float u, float v, Point3 & p, Point3 & pu, Point3 & pv) const;


 169 


 170  //*************** operators *************************


 171  DllExport NurbsFace & operator = (const NurbsFace & su);


 172  DllExport void Init();


 173  DllExport void Clear();


 174  DllExport void MakeKnotsBezier (int uO, int vO);


 175  DllExport void MakeKnotsUniform (int uO, int vO, int uN, int vN);


 176  DllExport void setVert (int row, int col, int vid);


 177  DllExport void setVert (int ndex, int vid);


 178  DllExport int getVert (int row, int col) const;


 179  DllExport int getVert (int ndex) const;


 180  /*


 181  DllExport int CountU (int *ucl=NULL) { MeasureKnots(); if (ucl) *ucl=closedu; return distinctu; }


 182  DllExport int CountV (int *vcl=NULL) { MeasureKnots(); if (vcl) *vcl=closedv; return distinctv; }


 183  void MeasureKnots ();


 184  DllExport void getDistinctKnotU (float *knot, int *mults=NULL) const;


 185  DllExport void getDistinctKnotV (float *knot, int *mults=NULL) const;


 186  */


 187  //gives uv values at a point on the surface (input is a Point)


 188  /*


 189  int Inverter(Point & pt, Point & uv, double & dis, const Point & guess_uv) const;


 190  int Inverter(Point & pt, Point & uv, double & dis) const { return Inverter(pt, uv, dis, *(Point *) NULL); }


 191  */


 192  DllExport IOResult Save(ISave* isave);


 193  DllExport IOResult Load(ILoad* iload);


 194  };


 195 


 196  // The following #defines and Hitrelated classes have been cut/pasted


 197  // from patch code. Not even sure if it's used, offhand.


 198 


 199  // Render flag definitions


 200  #define COMP_TRANSFORM 0x0001 // forces recalc of model>screen transform; else will attempt to use cache


 201  #define COMP_IGN_RECT 0x0002 // forces all polys to be rendered; else only those intersecting the box will be


 202  #define COMP_LIGHTING 0x0004 // forces relighting of all verts (as when a light moves); else only relight moved verts


 203 


 204  #define COMP_ALL 0x00ff


 205 


 206  // If this bit is set then the node being displayed by this mesh is selected.


 207  // Certain display flags only activate when this bit is set.


 208  #define COMP_OBJSELECTED (1<<8)


 209  #define COMP_OBJFROZEN (1<<9)


 210 


 211 


 212  // Special types for patch vertex hits  Allows us to distinguish what they hit on a pick


 213  #define NURBS_HIT_FACE 0


 214  #define NURBS_HIT_VERTEX 1


 215 


 216  class NurbsSubHitRec {


 217  private:


 218  NurbsSubHitRec *next;


 219  public:


 220  DWORD dist;


 221  NurbsMesh *nmesh;


 222  int index;


 223  int type;


 224 


 225  NurbsSubHitRec( DWORD dist, NurbsMesh *nmesh, int index, int type, NurbsSubHitRec *next )


 226  { this>dist = dist; this>nmesh = nmesh; this>index = index; this>type = type; this>next = next; }


 227 


 228  NurbsSubHitRec *Next() { return next; }


 229  };


 230 


 231  class SubNurbsHitList {


 232  private:


 233  NurbsSubHitRec *first;


 234  public:


 235  SubNurbsHitList() { first = NULL; }


 236  ~SubNurbsHitList() {


 237  NurbsSubHitRec *ptr = first, *fptr;


 238  while ( ptr ) {


 239  fptr = ptr;


 240  ptr = ptr>Next();


 241  delete fptr;


 242  }


 243  first = NULL;


 244  }


 245 


 246  NurbsSubHitRec *First() { return first; }


 247  void AddHit( DWORD dist, NurbsMesh *patch, int index, int type ) {


 248  first = new NurbsSubHitRec(dist,patch,index,type,first);


 249  }


 250  };


 251 


 252 


 253  // Special storage class for hit records so we can know which object was hit


 254  class NurbsHitData : public HitData {


 255  public:


 256  NurbsMesh *nmesh;


 257  int index;


 258  int type;


 259  NurbsHitData(NurbsMesh *nmesh, int index, int type)


 260  { this>nmesh = nmesh; this>index = index; this>type = type; }


 261  };


 262 


 263  // Flags for sub object hit test


 264 


 265  // NOTE: these are the same bits used for object level.


 266  #define SUBHIT_NURBS_SELONLY (1<<0)


 267  #define SUBHIT_NURBS_UNSELONLY (1<<2)


 268  #define SUBHIT_NURBS_ABORTONHIT (1<<3)


 269  #define SUBHIT_NURBS_SELSOLID (1<<4)


 270 


 271  #define SUBHIT_NURBS_VERTS (1<<24)


 272  #define SUBHIT_NURBS_FACES (1<<25)


 273  #define SUBHIT_NURBS_TYPEMASK (SUBHIT_NURBS_VERTSSUBHIT_NURBS_FACES)


 274 


 275 


 276  // Display flags  not used.


 277  #define DISP_VERTTICKS (1<<0)


 278 


 279  #define DISP_SELVERTS (1<<10)


 280  #define DISP_SELFACES (1<<11)


 281 


 282  #define DISP_LATTICE (1<<16)


 283  #define DISP_VERTS (1<<17)


 284 


 285  // Selection level bits.


 286  #define NURBS_OBJECT (1<<0)


 287  #define NURBS_VERTEX (1<<1)


 288  #define NURBS_FACE (1<<2)


 289 


 290  // NurbsMesh: contains faces, edges, verts just like regular mesh.


 291 


 292  class NurbsMesh {


 293  private:


 294  // derived data can be regenerated


 295  NRVertex *rVerts; // <<< instance specific.


 296  GraphicsWindow *cacheGW; // identifies rVerts cache


 297  Box3 bdgBox; // object spacedepends on geom+topo


 298 


 299  int snapVCt;


 300  char *snapV;


 301 


 302  DWORD flags; // work flags None used just yet.


 303 


 304  int renderFace (GraphicsWindow *gw, int index);


 305  void checkRVertsAlloc(void);


 306  void setCacheGW(GraphicsWindow *gw) { cacheGW = gw; }


 307  GraphicsWindow *getCacheGW(void) { return cacheGW; }


 308 


 309  void freeVerts();


 310  void freeFaces();


 311  void freeRVerts();


 312  void freeFaceMtlIndexList();


 313  void freeSnapData();


 314  int buildSnapData(GraphicsWindow *gw);


 315 


 316  public:


 317  // Topology


 318  int numVerts;


 319  int numFaces;


 320  NurbsVert * verts;


 321  NurbsFace * faces;


 322 


 323  DWORD mtlIndex; // object material


 324  DWORD * faceMtlIndex; // material per face


 325  BitArray vertSel; // selected vertices


 326  BitArray faceSel; // selected patches


 327  DWORD dispFlags; // Display attribute flags


 328  DWORD selLevel; // Selection level


 329 


 330  DllExport NurbsMesh() { Init(); }


 331  DllExport NurbsMesh(const NurbsMesh& from) { Init(); (*this) = from; }


 332  DllExport ~NurbsMesh() { FreeAll(); }


 333 


 334  DllExport void Init();


 335  DllExport void FreeAll ();


 336  DllExport NurbsMesh& operator=(const NurbsMesh& from);


 337 


 338  DllExport BOOL setNumVerts(int ct, BOOL keep = FALSE);


 339  int getNumVerts(void) const { return numVerts; }


 340 


 341  DllExport BOOL setNumFaces(int ct, BOOL keep = FALSE);


 342  int getNumFaces(void) const { return numFaces; }


 343 


 344  void setVert(int i, const Point3 &xyz) { verts[i].p = xyz; }


 345  void setVert(int i, float x, float y, float z) { verts[i].p.x=x; verts[i].p.y=y; verts[i].p.z=z; }


 346  void setWeight (int i, float w) { verts[i].w = w; }


 347  void setVert(int i, float x, float y, float z, float w) { verts[i].p = Point3(x,y,z); verts[i].w = w; }


 348  void setVert(int i, const Point3 &xyz, float w) { verts[i].p = xyz; verts[i].w = w; }


 349 


 350  NurbsVert & getVert(int i) const { return verts[i]; }


 351  NurbsVert * getVertPtr(int i) const { return verts+i; }


 352  NRVertex & getRVert(int i) const { return rVerts[i]; }


 353  NRVertex * getRVertPtr(int i) const { return rVerts+i; }


 354 


 355  void setMtlIndex(DWORD i) { mtlIndex = i; }


 356  DWORD getMtlIndex(void) const { return mtlIndex; }


 357  DWORD getFaceMtlIndex(int i) const { return faceMtlIndex? faceMtlIndex[i]: mtlIndex; }


 358 


 359  // Automatically update all the adjacency info, etc.


 360  // Returns TRUE if patch mesh is valid, FALSE if it's not!


 361  DllExport BOOL buildLinkages();


 362 


 363  DllExport void InvalidateGeomCache();


 364  DllExport void render(GraphicsWindow *gw, Material *ma, RECT *rp, int compFlags);


 365  DllExport BOOL select(GraphicsWindow *gw, Material *ma, HitRegion *hr, int abortOnHit = FALSE);


 366  DllExport void snap(GraphicsWindow *gw, SnapInfo *snap, IPoint2 *p, Matrix3 &tm);


 367  DllExport BOOL SubObjectHitTest(GraphicsWindow *gw, Material *ma, HitRegion *hr,


 368  DWORD flags, SubNurbsHitList& hitList );


 369 


 370  DllExport void buildBoundingBox(void);


 371  DllExport Box3 getBoundingBox(Matrix3 *tm=NULL); // RB: optional TM allows the box to be calculated in any space.


 372  // NOTE: this will be slower becuase all the points must be transformed.


 373 


 374  // Join two faces along one of the four standard edges.


 375  DllExport void joinFaces (int f1, int f2, int edgetype);


 376  DllExport BOOL EdgeDegenerate (int f, int e, float tolerance);


 377 


 378  // For meshing functions:


 379  //DllExport void CountTesselatedParams (int *tvct, int *tfct, int steps);


 380  DllExport void Evaluate (int f, float u, float v, Point3& p);


 381  DllExport void Evaluate (int f, float u, float v, Point3& p, Point3& du, Point3& dv);


 382 


 383  // functions for use in data flow evaluation


 384  DllExport void ShallowCopy(NurbsMesh *amesh, unsigned long channels);


 385  DllExport void DeepCopy(NurbsMesh *amesh, unsigned long channels);


 386  DllExport void NewAndCopyChannels(unsigned long channels);


 387  DllExport void FreeChannels( unsigned long channels, int zeroOthers=1);


 388 


 389  // Display flags


 390  void SetDispFlag(DWORD f) { dispFlags = f; }


 391  DWORD GetDispFlag(DWORD f) { return dispFlags & f; }


 392  void ClearDispFlag(DWORD f) { dispFlags &= ~f; }


 393 


 394  // Selection access


 395  BitArray& VertSel() { return vertSel; }


 396  BitArray& FaceSel() { return faceSel; }


 397 


 398  // Constructs a vertex selection list based on the current selection level.


 399  DllExport BitArray VertexTempSel();


 400 


 401  DllExport IOResult Save(ISave* isave);


 402  DllExport IOResult Load(ILoad* iload);


 403  };


 404 


 405  // profiling constants


 406  //#define BUILD_NORMALS 0


 407  #define TRANSFORM_VERTS 1


 408  #define VISEDGE_LIST 2


 409  #define RENDER_PATCHES 3


 410  #define BACK_CULL 4


 411  #define NURBS_PROF_PARTS 5 // always last


 412 


 413 


 414  #endif // _NURBS_H_

