source: golgotha/src/maxtool/sdk_inc/nurbs.h @ 80

Last change on this file since 80 was 80, checked in by Sam Hocevar, 11 years ago
  • Adding the Golgotha source code. Not sure what's going to be interesting in there, but since it's all public domain, there's certainly stuff to pick up.
  • Property svn:keywords set to Id
File size: 14.3 KB
RevLine 
[80]1/**********************************************************************
2 *<
3        FILE: NURBS.h
4
5        DESCRIPTION: Main include file for Non Uniform Rational B-Splines
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
25typedef Tab<int> IntTab;
26
27class ISave;
28class ILoad;
29class 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
45class 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.)
59class 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.
85class 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
126class 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
141DllExport 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 non-Nurbs patch terminology.
145
146// NurbsFace flags:
147// None yet.
148
149class 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 Hit-related 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 re-lighting 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
216class 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
231class 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
254class 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_VERTS|SUBHIT_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
292class NurbsMesh {
293        private:
294                // derived data-- can be regenerated
295                NRVertex                *rVerts;                // <<< instance specific.
296                GraphicsWindow  *cacheGW;               // identifies rVerts cache
297                Box3                    bdgBox;                 // object space--depends 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_
Note: See TracBrowser for help on using the repository browser.