00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef _GQ_Edge_h_
00029 #define _GQ_Edge_h_
00030
00031 #include "GQ_API.h"
00032 #include <iostream.h>
00033 #include <UT/UT_VectorTypes.h>
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 class GQ_Point;
00056 class GQ_Face;
00057 class GQ_Detail;
00058 class GEO_Point;
00059
00060
00061
00062 #define GQ_BRIDGE 0x00010000 // Edge is a bridge edge
00063 #define GQ_INTERSECT 0x00020000 // Point is intersect on a plane/surface
00064 #define GQ_INSIDE 0x00040000 // Point is inside a close geometry
00065 #define GQ_OUTSIDE 0x00080000 // Point is outside a close geometry
00066 #define GQ_VISIT 0x00100000 // Visited this edge
00067 #define GQ_DELETE 0x00200000 // Mark as delete edge
00068 #define GQ_NEW 0x00400000 // Mark as new edge
00069 #define GQ_GLUE 0x00800000 // Share edge resulted from unique point op
00070 #define GQ_SELECTED 0x01000000 // Need to process
00071 #define GQ_SPAREPTR 0x02000000 // Spare pointer points to ptr array
00072 #define GQ_VTXBOUNDARY 0x04000000 // Point has differing vertex
00073 #define GQ_EDGE 0x08000000 // Face used to be edge
00074 #define GQ_CORNER 0x10000000 // Face used to be corner
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 #define FOR_QUAD_EDGES(elem, edge, nedges, dir) \
00086 for (edge=elem->getEdge(), nedges=0; \
00087 edge && (edge != elem->getEdge() || !nedges); \
00088 edge=edge->dir(), nedges++)
00089
00090 #define Q_RotN(e,n) (e + (((e)->myIndex + n) & 0x03) - \
00091 ((e)->myIndex & 0x03))
00092 #define Q_ROT(e) (Q_RotN(e, 1))
00093 #define Q_SYM(e) (Q_RotN(e, 2))
00094 #define Q_IROT(e) (Q_RotN(e, 3))
00095 #define Q_ONEXT(e) ((e)->myNext)
00096 #define Q_OPREV(e) (Q_ROT( Q_ONEXT( Q_ROT(e))))
00097 #define Q_DNEXT(e) (Q_SYM( Q_ONEXT( Q_SYM(e))))
00098 #define Q_DPREV(e) (Q_IROT( Q_ONEXT( Q_IROT(e))))
00099 #define Q_LNEXT(e) (Q_ROT( Q_ONEXT( Q_IROT(e))))
00100 #define Q_LPREV(e) (Q_SYM( Q_ONEXT(e)))
00101 #define Q_RNEXT(e) (Q_IROT( Q_ONEXT( Q_ROT(e))))
00102 #define Q_RPREV(e) (Q_ONEXT( Q_SYM(e)))
00103 #define Q_ORG(e) ((e)->myData)
00104 #define Q_DEST(e) (Q_ORG( Q_SYM(e)))
00105 #define Q_LEFT(e) (Q_ORG( Q_IROT(e)))
00106 #define Q_RIGHT(e) (Q_ORG( Q_ROT(e)))
00107
00108 class GQ_API GQ_Edge {
00109 public:
00110
00111
00112 void init(int i);
00113 GQ_Edge *root() { return this-(myIndex & 0x03); }
00114 const GQ_Edge *root() const { return this-(myIndex & 0x03); }
00115 void setData(void *org, void *dest, void *left, void *right);
00116
00117 GQ_Edge *rotN(int n) { return Q_RotN(this,n); }
00118 const GQ_Edge *rotN(int n) const { return Q_RotN(this,n); }
00119 GQ_Edge *rot() { return Q_ROT(this); }
00120 const GQ_Edge *rot() const { return Q_ROT(this); }
00121
00122
00123
00124 GQ_Edge *sym() { return Q_SYM(this); }
00125 const GQ_Edge *sym() const { return Q_SYM(this); }
00126 GQ_Edge *irot() { return Q_IROT(this); }
00127 const GQ_Edge *irot() const { return Q_IROT(this); }
00128
00129
00130
00131 GQ_Edge *&onext() { return myNext; }
00132 const GQ_Edge *onext() const { return myNext; }
00133 GQ_Edge *oprev() { return Q_OPREV(this); }
00134 const GQ_Edge *oprev() const { return Q_OPREV(this); }
00135 GQ_Edge *dnext() { return Q_DNEXT(this); }
00136 const GQ_Edge *dnext() const { return Q_DNEXT(this); }
00137 GQ_Edge *dprev() { return Q_DPREV(this); }
00138 const GQ_Edge *dprev() const { return Q_DPREV(this); }
00139 GQ_Edge *lnext() { return Q_LNEXT(this); }
00140 const GQ_Edge *lnext() const { return Q_LNEXT(this); }
00141 GQ_Edge *lprev() { return Q_LPREV(this); }
00142 const GQ_Edge *lprev() const { return Q_LPREV(this); }
00143 GQ_Edge *rnext() { return Q_RNEXT(this); }
00144 const GQ_Edge *rnext() const { return Q_RNEXT(this); }
00145 GQ_Edge *&rprev() { return Q_RPREV(this); }
00146 const GQ_Edge *rprev() const { return Q_RPREV(this); }
00147
00148
00149 void *&org() { return myData; }
00150 const void *org() const { return myData; }
00151
00152
00153 void *&dest() { return Q_DEST(this); }
00154 const void *dest() const { return Q_DEST(this); }
00155
00156 void *safeDest() {if (dest()) return dest();
00157 if (lnext()->org()) return lnext()->org();
00158 return rnext()->org();
00159 }
00160
00161
00162 void *&left() { return Q_LEFT(this); }
00163 const void *left() const { return Q_LEFT(this); }
00164
00165
00166 void *&right() { return Q_RIGHT(this); }
00167 const void *right() const { return Q_RIGHT(this); }
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184 void splice(GQ_Edge *b);
00185
00186
00187
00188 void connect(GQ_Edge *a, GQ_Edge *b);
00189
00190
00191
00192 void connect(GQ_Point *org, GQ_Edge *b);
00193 void connect(GQ_Edge *b) { splice(b->lnext()); }
00194 void disconnectOrg();
00195
00196
00197 void disconnect();
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216 void swap();
00217 int isBridge() const { return getFlags(GQ_BRIDGE); }
00218 int isShare() const { return org() == oprev()->org() &&
00219 dest() == lnext()->org(); }
00220 int isBoundary() const { return !isShare() || (!isBridge() && (!left() || !right())); }
00221 int intersectPlane(UT_Vector3 &nml, float d, float &t, int donml=1);
00222 int intersect(GQ_Point *pt);
00223 int intersect(GQ_Edge *edge);
00224 int intersect(GQ_Point *org, GQ_Point *dest);
00225 int intersect(GQ_Face *face, float &t);
00226
00227 void setFlags(unsigned mask) { myFlags = mask; }
00228 unsigned getFlags(unsigned mask=~0) const{ return myFlags & mask; }
00229 void addFlags(unsigned mask) { myFlags |= mask; }
00230 void clearFlags(unsigned mask=~0) { myFlags &= ~mask; }
00231
00232
00233
00234 int index() const { return myIndex >> 2; }
00235
00236 ostream &save(ostream &os) const;
00237 friend ostream &operator<<(ostream &os, const GQ_Edge &e)
00238 { e.save(os); return os; }
00239
00240 private:
00241
00242 void *myData;
00243 GQ_Edge *myNext;
00244 unsigned myFlags;
00245
00246
00247
00248 int myIndex;
00249 };
00250
00251 #endif