00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef __GU_SubDivPatch_h__
00021 #define __GU_SubDivPatch_h__
00022
00023 #include "GU_API.h"
00024 #include <SYS/SYS_Types.h>
00025 #include <SYS/SYS_Math.h>
00026 #include <UT/UT_Assert.h>
00027 #include <UT/UT_PtrArray.h>
00028 #include <UT/UT_RefArray.h>
00029 #include <UT/UT_IntArray.h>
00030
00031 class GU_Detail;
00032 class GU_SubDivVertex;
00033 class GU_SubDivPatch;
00034
00035
00036
00037
00038
00039
00040
00041 static const uint8 SUBD_HARD_EDGE = 0x01;
00042 static const uint8 SUBD_LINEAR_CREASES = 0x02;
00043
00044 class GU_API GU_SubDivEdge
00045 {
00046 public:
00047 GU_SubDivEdge(GU_SubDivVertex *v1, GU_SubDivVertex *v2,
00048 const GU_SubDivEdge *parent = 0);
00049 ~GU_SubDivEdge();
00050
00051
00052 void catclarkChild();
00053 GU_SubDivVertex *getChild()
00054 {
00055 if (!myChild)
00056 catclarkChild();
00057 return myChild;
00058 }
00059
00060
00061 GU_SubDivVertex *getOther(const GU_SubDivVertex *vtx) const
00062 {
00063 return (vtx == myVertex[0]) ?
00064 myVertex[1] : myVertex[0];
00065 }
00066
00067 void setFlag(uint8 f) { myFlag |= f; }
00068 void clearFlag(uint8 f) { myFlag &= ~f; }
00069 bool getFlag(uint8 f) const { return myFlag & f; }
00070
00071 void setWeight(fpreal weight) { myWeight = weight; }
00072 fpreal getWeight() const { return myWeight; }
00073 bool isHardVertex() const { return myHardVertex; }
00074 void initHardVertex(int size)
00075 {
00076 if (!myHardVertex)
00077 myHardVertex = new uint8[size];
00078 }
00079 void initHardVertex(const UT_IntArray &sizes)
00080 {
00081 int i;
00082
00083 if (!myHardVertex)
00084 {
00085 myHardVertex = new uint8[sizes.entries()];
00086 for (i = 0; i < sizes.entries(); i++)
00087 myHardVertex[i] = sizes[i];
00088 }
00089 }
00090 void setHardVertex(int i)
00091 { myHardVertex[i] = getHardVertexSize(i) | 0x80; }
00092 void clearHardVertex(int i)
00093 { myHardVertex[i] = getHardVertexSize(i); }
00094 bool getHardVertex(int i) const
00095 { return myHardVertex ? myHardVertex[i] & 0x80 : 0; }
00096 int getHardVertexSize(int i) const
00097 { return myHardVertex ? myHardVertex[i] & 0x7F : 0; }
00098 int getHardVertexCount(int vcount) const
00099 {
00100 int i, off;
00101 for (i = 0, off = 0; off < vcount; i++)
00102 off += getHardVertexSize(i);
00103 return i;
00104 }
00105
00106 private:
00107 GU_SubDivEdge() {}
00108
00109 private:
00110 GU_SubDivVertex *myChild;
00111 GU_SubDivVertex *myVertex[2];
00112 uint8 *myHardVertex;
00113 fpreal myWeight;
00114 uint8 myFlag;
00115 };
00116
00117
00118
00119
00120
00121
00122 static const uint8 SUBD_VTX_COMPLETE = 0x01;
00123 static const uint8 SUBD_VTX_VTXSET = 0x02;
00124 static const uint8 SUBD_VTX_MARK = 0x04;
00125
00126 class GU_API GU_SubDivVertex
00127 {
00128 public:
00129 static GU_SubDivVertex *allocVertex(int valence, int datasize,
00130 int vertexsize);
00131 static GU_SubDivVertex *allocVertex(const GU_SubDivVertex &src);
00132 static void freeVertex(GU_SubDivVertex *vtx);
00133
00134 void incRefCount() { myRefCount++; }
00135 void decRefCount()
00136 {
00137 myRefCount--;
00138 UT_ASSERT(myRefCount >= 0);
00139 if (myRefCount <= 0)
00140 freeVertex(this);
00141 }
00142
00143 void setNum(int num) { myGeoNum = num; }
00144 int getNum() const { return myGeoNum; }
00145
00146
00147
00148 GU_SubDivEdge *setEdge(GU_SubDivVertex *vtx, int idx = -1,
00149 GU_SubDivEdge *parent = 0);
00150 void setEdge(GU_SubDivEdge *edge, int idx)
00151 { myEdges[idx] = edge; }
00152 void clearEdge(GU_SubDivEdge *edge);
00153
00154
00155
00156 void removeEdge(int idx);
00157
00158
00159
00160
00161 void setFace(GU_SubDivPatch *face, int idx = -1);
00162 void clearFace(GU_SubDivPatch *face);
00163
00164
00165
00166 void setAllIncomplete();
00167 void copyIncomplete(const GU_SubDivVertex *vtx);
00168 void setComplete(int i) { myFaces[i] = 0; }
00169
00170
00171 fpreal *getData() const { return myData; }
00172 fpreal *getVertexData(const GU_SubDivPatch *face) const;
00173
00174
00175
00176
00177
00178
00179
00180 void setVertexData(const fpreal *data, int idx,
00181 const UT_IntArray &offsets);
00182
00183
00184 void defaultVertexData(int low, int high);
00185
00186 int getSize() const { return myFloatCount; }
00187 int getVertexSize() const { return myVertexCount; }
00188
00189
00190 void sum(const GU_SubDivVertex *vtx)
00191 {
00192 for (int i = 0; i < myFloatCount; i++)
00193 myData[i] += vtx->myData[i];
00194 }
00195 void sum(const GU_SubDivVertex *vtx,
00196 const GU_SubDivPatch *face);
00197 void sumVertex(const GU_SubDivVertex *vtx,
00198 const GU_SubDivPatch *face, int idx,
00199 int low = 0, int high = -1);
00200 void scale(fpreal scale)
00201 {
00202 for (int i = 0; i < myFloatCount; i++)
00203 myData[i] *= scale;
00204 }
00205 void scaleVertex(fpreal scale,
00206 int low = 0, int high = -1);
00207 void copyVertex(int src, int dest, int low = 0, int high = -1);
00208
00209
00210 void getVertices(UT_PtrArray<GU_SubDivVertex *> &list);
00211 void getFaces(UT_PtrArray<GU_SubDivPatch *> &list,
00212 const GU_SubDivPatch *face) const;
00213
00214
00215 GU_SubDivVertex *getChild()
00216 {
00217 if (!myChild)
00218 catclarkChild();
00219 return myChild;
00220 }
00221
00222 int getEdgeIndex(const GU_SubDivVertex *vtx) const;
00223 GU_SubDivEdge *getEdge(int idx) const { return myEdges[idx]; }
00224 GU_SubDivEdge *getEdge(const GU_SubDivVertex *vtx) const
00225 {
00226 int idx = getEdgeIndex(vtx);
00227 return idx >= 0 ? myEdges[idx] : 0;
00228 }
00229 GU_SubDivVertex *getEdgeChild(const GU_SubDivVertex *vtx) const
00230 { return getEdge(vtx)->getChild(); }
00231
00232 int getFaceIndex(const GU_SubDivPatch *face) const;
00233 GU_SubDivPatch *getFace(int idx) const { return myFaces[idx]; }
00234 bool hasFace(const GU_SubDivPatch *face) const
00235 { return getFaceIndex(face) >= 0; }
00236
00237 int getValence() const { return myValence; }
00238 bool hasHardEdge() const;
00239
00240
00241 void sortEdges();
00242 void setWeight(fpreal weight, bool linear,
00243 const GU_SubDivPatch *face);
00244
00245 void setFlag(uint8 f) { myFlag |= f; }
00246 void clearFlag(uint8 f) { myFlag &= ~f; }
00247 bool getFlag(uint8 f) const { return myFlag & f; }
00248
00249
00250 void dumpGeo(char c, const GU_SubDivPatch *face = 0) const;
00251
00252 protected:
00253 void catclarkRule(GU_SubDivVertex *dest,
00254 int creaseidx[2], int hcount);
00255 void catclarkRuleVertex(GU_SubDivVertex *dest,
00256 int creaseidx[2], int hcount,
00257 int low, int high);
00258
00259 private:
00260 GU_SubDivVertex() {}
00261 ~GU_SubDivVertex() {}
00262
00263 void catclarkChild();
00264
00265 private:
00266 GU_SubDivVertex *myChild;
00267 GU_SubDivEdge **myEdges;
00268 GU_SubDivPatch **myFaces;
00269 fpreal *myData;
00270 fpreal *myVertexData;
00271 int myValence;
00272 int myRefCount;
00273 int myFloatCount;
00274 int myVertexCount;
00275 int myGeoNum;
00276 uint8 myFlag;
00277 };
00278
00279
00280
00281
00282
00283
00284
00285
00286 static const uint8 SUBD_PATCH_LIVE = 0x01;
00287 static const uint8 SUBD_PATCH_REVERSE = 0x02;
00288 static const uint8 SUBD_PATCH_MARK = 0x04;
00289
00290 class GU_API GU_SubDivPatch
00291 {
00292 public:
00293 static GU_SubDivPatch *allocPatch(
00294 const UT_PtrArray<GU_SubDivVertex *> &vertices, bool islive);
00295 static void freePatch(GU_SubDivPatch *patch);
00296
00297 void decRefCount();
00298 int getRefCount() { return myRefCount; }
00299
00300
00301
00302
00303
00304
00305
00306 void catclark(UT_PtrArray<GU_SubDivPatch *> &patches);
00307
00308
00309 GU_SubDivVertex *getChild()
00310 {
00311 if (!myChild)
00312 catclarkChild();
00313 return myChild;
00314 }
00315
00316
00317 int getValence() const { return myValence; }
00318
00319 GU_SubDivVertex *getNextVertex(GU_SubDivVertex *vtx) const;
00320 GU_SubDivVertex *getPrevVertex(GU_SubDivVertex *vtx) const;
00321
00322
00323 bool isBezier() const;
00324
00325
00326 void getBezier(UT_PtrArray<GU_SubDivVertex *> &vtx,
00327 UT_PtrArray<fpreal *> &vtxdata) const;
00328
00329 void getVertices(UT_PtrArray<GU_SubDivVertex *> &vtx) const;
00330 GU_SubDivVertex *getVertex(int i) const { return myVertex[i]; }
00331 void getFaceRing(UT_PtrArray<GU_SubDivPatch *> &list) const;
00332
00333
00334 GU_SubDivPatch *copy() const;
00335
00336
00337
00338
00339 void makeLive();
00340 bool isLive() const { return myFlag & SUBD_PATCH_LIVE; }
00341
00342
00343
00344 void reverse();
00345
00346
00347 void dumpGeo() const;
00348
00349 void setFlag(uint8 f) { myFlag |= f; }
00350 void clearFlag(uint8 f) { myFlag &= ~f; }
00351 void toggleFlag(uint8 f) { myFlag ^= f; }
00352 bool getFlag(uint8 f) const { return myFlag & f; }
00353
00354 protected:
00355 void decRefCountInternal()
00356 {
00357 myRefCount--;
00358 UT_ASSERT(myRefCount >= 0);
00359 if (myRefCount == 0)
00360 freePatch(this);
00361 }
00362
00363
00364
00365 void catclarkPatches(GU_SubDivPatch *face = 0);
00366
00367 private:
00368 GU_SubDivPatch() {}
00369 ~GU_SubDivPatch() {}
00370
00371 void incRefCount() { myRefCount++; }
00372 void catclarkChild();
00373
00374 private:
00375 GU_SubDivPatch **mySubPatches;
00376 GU_SubDivVertex *myChild;
00377 GU_SubDivVertex **myVertex;
00378 int myValence;
00379 int myRefCount;
00380 uint8 myFlag;
00381 };
00382
00383
00384 class GU_API GU_SubDivPatchSet
00385 {
00386 public:
00387
00388
00389 GU_SubDivPatchSet(const UT_PtrArray<GU_Detail *> &details,
00390 const UT_IntArray *ptattribs = 0,
00391 const UT_IntArray *vtxattribs = 0,
00392 bool linearcreases = true);
00393 virtual ~GU_SubDivPatchSet();
00394
00395 void stealPatches(UT_PtrArray<GU_SubDivPatch *> &patches);
00396
00397
00398
00399 void catclark(int levels);
00400
00401 private:
00402 UT_PtrArray<GU_Detail *> myDetails;
00403 UT_PtrArray<GU_SubDivPatch *> myPatches;
00404 };
00405
00406 #endif