nurbs.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. /**********************************************************************
  2. *<
  3. FILE: NURBS.h
  4. DESCRIPTION: Main include file for Non Uniform Rational B-Splines
  5. CREATED BY: Steve Anderson
  6. HISTORY: Created Dec 31, 1995
  7. *> Copyright (c) 1995, All Rights Reserved.
  8. **********************************************************************/
  9. #ifndef _NURBS_H_
  10. #define _NURBS_H_
  11. #include <hitdata.h>
  12. // Value for undefined patches and vertices
  13. #define NURBS_UNDEFINED -1
  14. #define MULTI_PROCESSING TRUE // TRUE turns on mp vertex transformation
  15. typedef Tab<int> IntTab;
  16. class ISave;
  17. class ILoad;
  18. class NurbsMesh;
  19. // NRVertex flags: contain clip flags, number of normals at the vertex
  20. // and the number of normals that have already been rendered.
  21. // fine PLANE_MASK 0x00003f00UL -- now in gfx.h
  22. #define NORCT_MASK 0x000000ffUL
  23. #define SPECIFIED_NORMAL 0x00004000UL
  24. #define OUT_LEFT 0x00010000UL
  25. #define OUT_RIGHT 0x00020000UL
  26. #define OUT_TOP 0x00040000UL
  27. #define OUT_BOTTOM 0x00080000UL
  28. #define RECT_MASK 0x000f0000UL
  29. #define RND_MASK 0xfff00000UL
  30. #define RND_NOR0 0x00100000UL
  31. #define RND_NOR(n) (RND_NOR0 << (n))
  32. class NRVertex { // NURBS vertex for rendering, like PRVertex in patch.h
  33. public:
  34. NRVertex() { rFlags = 0; }
  35. DllExport ~NRVertex() {}
  36. DWORD rFlags;
  37. union {
  38. int iPos[3];
  39. float fPos[3];
  40. };
  41. };
  42. // Nurbs vertex
  43. // (Used in NurbsMesh, not in NurbsCurve.)
  44. class NurbsVert {
  45. public:
  46. Point3 p; // Location
  47. float w; // p = pw/w
  48. IntTab faces; // List of NURBS faces using this vertex
  49. DWORD flags; // Currently no flags
  50. // General utilities
  51. NurbsVert() { p = Point3(0,0,0); w = 1.0f; flags = 0; }
  52. DllExport NurbsVert(const NurbsVert &from) { (*this) = from; }
  53. ~NurbsVert() { ResetData(); }
  54. DllExport NurbsVert& operator=(const NurbsVert& from);
  55. void ResetData() { faces.Delete(0,faces.Count()); }
  56. // Face reference handling
  57. DllExport int FindFace(int index);
  58. DllExport void AddFace(int index);
  59. DllExport void DeleteFace(int index);
  60. // I/O
  61. DllExport IOResult Save(ISave* isave);
  62. DllExport IOResult Load(ILoad* iload);
  63. };
  64. // NurbsCurve: Not actually used yet; ideally both an independent object
  65. // and a trim curve container in NurbsEdge.
  66. class NurbsCurve {
  67. public:
  68. DllExport NurbsCurve() { Init(); }
  69. NurbsCurve(const NurbsCurve & cv) { Init(); (*this) = cv; }
  70. DllExport NurbsCurve(int ordd, int numm);
  71. virtual ~NurbsCurve() { Clear(); }
  72. // inquiry methods
  73. DllExport int getOrder() const { return ord; }
  74. DllExport int getNumber() const { return num; }
  75. // editing methods
  76. DllExport void setControlPoint(int ind, const Point3 & p);
  77. DllExport Point3 & getControlPoint (int ind) const;
  78. DllExport void setWeight (int ind, float w);
  79. DllExport float getWeight (int ind) const;
  80. // evaluation methods
  81. DllExport void Evaluate(float u, Point3 & p) const;
  82. DllExport void Evaluate(float u, Point3 & p, Point3& dout) const;
  83. // invert methods
  84. // int Inverter(const Point3 & p1, float & u, double & dis, double init_value = -1.0) const;
  85. DllExport NurbsCurve & operator = (const NurbsCurve & cv);
  86. void Init ();
  87. void Clear();
  88. // I/O
  89. DllExport IOResult Save(ISave* isave);
  90. DllExport IOResult Load(ILoad* iload);
  91. private:
  92. int ord; // Order of polynomials. Order 3 = cubic, etc.
  93. int num; // Number of points.
  94. Point3 *verts;
  95. float *wghts;
  96. float *knots; // Knot vector: length num+ord+1
  97. char rational; // Flag to make computation easier if rational. (Ignore weights.)
  98. };
  99. class NurbsEdge {
  100. public:
  101. int partner; // "Joined" edge on adjacent face.
  102. int parthost; // host face index of partner
  103. int rendedge; // Used in converting to mesh
  104. DllExport NurbsEdge () { Init(); }
  105. void Init ();
  106. NurbsEdge& operator = ( const NurbsEdge& from);
  107. // I/O
  108. DllExport IOResult Save(ISave* isave);
  109. DllExport IOResult Load(ILoad* iload);
  110. };
  111. DllExport void NurbsEdgeEvaluate (int type, float t, Point3 & p);
  112. // NurbsFace: this is what you'd call a Patch if it was Bezier, but
  113. // I'm staying away from non-Nurbs patch terminology.
  114. // NurbsFace flags:
  115. // None yet.
  116. class NurbsFace {
  117. public:
  118. int num; // == uNum*vNum
  119. int uTess, vTess; // Tesselation resolutions
  120. int uOrd, vOrd; // polynomial orders in each dim.
  121. int uNum, vNum; // Numbers of points in each dim.
  122. float *uKnot, *vKnot; // Knot vectors
  123. int *verts; // Indices of verts in NurbsMesh. (Weights handled there too.)
  124. NurbsEdge edges[4]; // U=0, V=0, U=1, V=1
  125. DWORD smGroup; // Defaults to 1 -- All faces smoothed in a NurbsMesh
  126. DWORD flags; // See flags above.
  127. DllExport NurbsFace() { Init(); }
  128. NurbsFace (const NurbsFace & from) { Init(); (*this) = from; }
  129. DllExport NurbsFace (int uO, int vO, int uN, int vN);
  130. DllExport ~NurbsFace() { Clear(); }
  131. // evaluation methods -- need to handle these on higher level...
  132. DllExport void Evaluate (NurbsVert *vtx, float u, float v, Point3 & p) const;
  133. DllExport void Evaluate (NurbsVert *vtx, float u, float v, Point3 & p, Point3 & pu, Point3 & pv) const;
  134. //*************** operators *************************
  135. DllExport NurbsFace & operator = (const NurbsFace & su);
  136. DllExport void Init();
  137. DllExport void Clear();
  138. DllExport void MakeKnotsBezier (int uO, int vO);
  139. DllExport void MakeKnotsUniform (int uO, int vO, int uN, int vN);
  140. DllExport void setVert (int row, int col, int vid);
  141. DllExport void setVert (int ndex, int vid);
  142. DllExport int getVert (int row, int col) const;
  143. DllExport int getVert (int ndex) const;
  144. /*
  145. DllExport int CountU (int *ucl=NULL) { MeasureKnots(); if (ucl) *ucl=closedu; return distinctu; }
  146. DllExport int CountV (int *vcl=NULL) { MeasureKnots(); if (vcl) *vcl=closedv; return distinctv; }
  147. void MeasureKnots ();
  148. DllExport void getDistinctKnotU (float *knot, int *mults=NULL) const;
  149. DllExport void getDistinctKnotV (float *knot, int *mults=NULL) const;
  150. */
  151. //gives uv values at a point on the surface (input is a Point)
  152. /*
  153. int Inverter(Point & pt, Point & uv, double & dis, const Point & guess_uv) const;
  154. int Inverter(Point & pt, Point & uv, double & dis) const { return Inverter(pt, uv, dis, *(Point *) NULL); }
  155. */
  156. DllExport IOResult Save(ISave* isave);
  157. DllExport IOResult Load(ILoad* iload);
  158. };
  159. // The following #defines and Hit-related classes have been cut/pasted
  160. // from patch code. Not even sure if it's used, offhand.
  161. // Render flag definitions
  162. #define COMP_TRANSFORM 0x0001 // forces recalc of model->screen transform; else will attempt to use cache
  163. #define COMP_IGN_RECT 0x0002 // forces all polys to be rendered; else only those intersecting the box will be
  164. #define COMP_LIGHTING 0x0004 // forces re-lighting of all verts (as when a light moves); else only relight moved verts
  165. #define COMP_ALL 0x00ff
  166. // If this bit is set then the node being displayed by this mesh is selected.
  167. // Certain display flags only activate when this bit is set.
  168. #define COMP_OBJSELECTED (1<<8)
  169. #define COMP_OBJFROZEN (1<<9)
  170. // Special types for patch vertex hits -- Allows us to distinguish what they hit on a pick
  171. #define NURBS_HIT_FACE 0
  172. #define NURBS_HIT_VERTEX 1
  173. class NurbsSubHitRec {
  174. private:
  175. NurbsSubHitRec *next;
  176. public:
  177. DWORD dist;
  178. NurbsMesh *nmesh;
  179. int index;
  180. int type;
  181. NurbsSubHitRec( DWORD dist, NurbsMesh *nmesh, int index, int type, NurbsSubHitRec *next )
  182. { this->dist = dist; this->nmesh = nmesh; this->index = index; this->type = type; this->next = next; }
  183. NurbsSubHitRec *Next() { return next; }
  184. };
  185. class SubNurbsHitList {
  186. private:
  187. NurbsSubHitRec *first;
  188. public:
  189. SubNurbsHitList() { first = NULL; }
  190. ~SubNurbsHitList() {
  191. NurbsSubHitRec *ptr = first, *fptr;
  192. while ( ptr ) {
  193. fptr = ptr;
  194. ptr = ptr->Next();
  195. delete fptr;
  196. }
  197. first = NULL;
  198. }
  199. NurbsSubHitRec *First() { return first; }
  200. void AddHit( DWORD dist, NurbsMesh *patch, int index, int type ) {
  201. first = new NurbsSubHitRec(dist,patch,index,type,first);
  202. }
  203. };
  204. // Special storage class for hit records so we can know which object was hit
  205. class NurbsHitData : public HitData {
  206. public:
  207. NurbsMesh *nmesh;
  208. int index;
  209. int type;
  210. NurbsHitData(NurbsMesh *nmesh, int index, int type)
  211. { this->nmesh = nmesh; this->index = index; this->type = type; }
  212. };
  213. // Flags for sub object hit test
  214. // NOTE: these are the same bits used for object level.
  215. #define SUBHIT_NURBS_SELONLY (1<<0)
  216. #define SUBHIT_NURBS_UNSELONLY (1<<2)
  217. #define SUBHIT_NURBS_ABORTONHIT (1<<3)
  218. #define SUBHIT_NURBS_SELSOLID (1<<4)
  219. #define SUBHIT_NURBS_VERTS (1<<24)
  220. #define SUBHIT_NURBS_FACES (1<<25)
  221. #define SUBHIT_NURBS_TYPEMASK (SUBHIT_NURBS_VERTS|SUBHIT_NURBS_FACES)
  222. // Display flags -- not used.
  223. #define DISP_VERTTICKS (1<<0)
  224. #define DISP_SELVERTS (1<<10)
  225. #define DISP_SELFACES (1<<11)
  226. #define DISP_LATTICE (1<<16)
  227. #define DISP_VERTS (1<<17)
  228. // Selection level bits.
  229. #define NURBS_OBJECT (1<<0)
  230. #define NURBS_VERTEX (1<<1)
  231. #define NURBS_FACE (1<<2)
  232. // NurbsMesh: contains faces, edges, verts just like regular mesh.
  233. class NurbsMesh {
  234. private:
  235. // derived data-- can be regenerated
  236. NRVertex *rVerts; // <<< instance specific.
  237. GraphicsWindow *cacheGW; // identifies rVerts cache
  238. Box3 bdgBox; // object space--depends on geom+topo
  239. int snapVCt;
  240. char *snapV;
  241. DWORD flags; // work flags- None used just yet.
  242. int renderFace (GraphicsWindow *gw, int index);
  243. void checkRVertsAlloc(void);
  244. void setCacheGW(GraphicsWindow *gw) { cacheGW = gw; }
  245. GraphicsWindow *getCacheGW(void) { return cacheGW; }
  246. void freeVerts();
  247. void freeFaces();
  248. void freeRVerts();
  249. void freeFaceMtlIndexList();
  250. void freeSnapData();
  251. int buildSnapData(GraphicsWindow *gw);
  252. public:
  253. // Topology
  254. int numVerts;
  255. int numFaces;
  256. NurbsVert * verts;
  257. NurbsFace * faces;
  258. DWORD mtlIndex; // object material
  259. DWORD * faceMtlIndex; // material per face
  260. BitArray vertSel; // selected vertices
  261. BitArray faceSel; // selected patches
  262. DWORD dispFlags; // Display attribute flags
  263. DWORD selLevel; // Selection level
  264. DllExport NurbsMesh() { Init(); }
  265. DllExport NurbsMesh(const NurbsMesh& from) { Init(); (*this) = from; }
  266. DllExport ~NurbsMesh() { FreeAll(); }
  267. DllExport void Init();
  268. DllExport void FreeAll ();
  269. DllExport NurbsMesh& operator=(const NurbsMesh& from);
  270. DllExport BOOL setNumVerts(int ct, BOOL keep = FALSE);
  271. int getNumVerts(void) const { return numVerts; }
  272. DllExport BOOL setNumFaces(int ct, BOOL keep = FALSE);
  273. int getNumFaces(void) const { return numFaces; }
  274. void setVert(int i, const Point3 &xyz) { verts[i].p = xyz; }
  275. 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; }
  276. void setWeight (int i, float w) { verts[i].w = w; }
  277. void setVert(int i, float x, float y, float z, float w) { verts[i].p = Point3(x,y,z); verts[i].w = w; }
  278. void setVert(int i, const Point3 &xyz, float w) { verts[i].p = xyz; verts[i].w = w; }
  279. NurbsVert & getVert(int i) const { return verts[i]; }
  280. NurbsVert * getVertPtr(int i) const { return verts+i; }
  281. NRVertex & getRVert(int i) const { return rVerts[i]; }
  282. NRVertex * getRVertPtr(int i) const { return rVerts+i; }
  283. void setMtlIndex(DWORD i) { mtlIndex = i; }
  284. DWORD getMtlIndex(void) const { return mtlIndex; }
  285. DWORD getFaceMtlIndex(int i) const { return faceMtlIndex? faceMtlIndex[i]: mtlIndex; }
  286. // Automatically update all the adjacency info, etc.
  287. // Returns TRUE if patch mesh is valid, FALSE if it's not!
  288. DllExport BOOL buildLinkages();
  289. DllExport void InvalidateGeomCache();
  290. DllExport void render(GraphicsWindow *gw, Material *ma, RECT *rp, int compFlags);
  291. DllExport BOOL select(GraphicsWindow *gw, Material *ma, HitRegion *hr, int abortOnHit = FALSE);
  292. DllExport void snap(GraphicsWindow *gw, SnapInfo *snap, IPoint2 *p, Matrix3 &tm);
  293. DllExport BOOL SubObjectHitTest(GraphicsWindow *gw, Material *ma, HitRegion *hr,
  294. DWORD flags, SubNurbsHitList& hitList );
  295. DllExport void buildBoundingBox(void);
  296. DllExport Box3 getBoundingBox(Matrix3 *tm=NULL); // RB: optional TM allows the box to be calculated in any space.
  297. // NOTE: this will be slower becuase all the points must be transformed.
  298. // Join two faces along one of the four standard edges.
  299. DllExport void joinFaces (int f1, int f2, int edgetype);
  300. DllExport BOOL EdgeDegenerate (int f, int e, float tolerance);
  301. // For meshing functions:
  302. //DllExport void CountTesselatedParams (int *tvct, int *tfct, int steps);
  303. DllExport void Evaluate (int f, float u, float v, Point3& p);
  304. DllExport void Evaluate (int f, float u, float v, Point3& p, Point3& du, Point3& dv);
  305. // functions for use in data flow evaluation
  306. DllExport void ShallowCopy(NurbsMesh *amesh, unsigned long channels);
  307. DllExport void DeepCopy(NurbsMesh *amesh, unsigned long channels);
  308. DllExport void NewAndCopyChannels(unsigned long channels);
  309. DllExport void FreeChannels( unsigned long channels, int zeroOthers=1);
  310. // Display flags
  311. void SetDispFlag(DWORD f) { dispFlags |= f; }
  312. DWORD GetDispFlag(DWORD f) { return dispFlags & f; }
  313. void ClearDispFlag(DWORD f) { dispFlags &= ~f; }
  314. // Selection access
  315. BitArray& VertSel() { return vertSel; }
  316. BitArray& FaceSel() { return faceSel; }
  317. // Constructs a vertex selection list based on the current selection level.
  318. DllExport BitArray VertexTempSel();
  319. DllExport IOResult Save(ISave* isave);
  320. DllExport IOResult Load(ILoad* iload);
  321. };
  322. // profiling constants
  323. //#define BUILD_NORMALS 0
  324. #define TRANSFORM_VERTS 1
  325. #define VISEDGE_LIST 2
  326. #define RENDER_PATCHES 3
  327. #define BACK_CULL 4
  328. #define NURBS_PROF_PARTS 5 // always last
  329. #endif // _NURBS_H_