00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef __GD_TrimLoop_h__
00024 #define __GD_TrimLoop_h__
00025
00026 #include "GD_API.h"
00027 #include <UT/UT_Defines.h>
00028 #include <UT/UT_IntArray.h>
00029 #include <UT/UT_RefArray.h>
00030 #include <UT/UT_BoundingRect.h>
00031 #include <UT/UT_Vector2.h>
00032
00033 class UT_Vector2;
00034 class UT_Vector3;
00035 class UT_Vector3Array;
00036 class UT_FloatArray;
00037 class GD_TrimPiece;
00038 class GD_TrimHitInfo;
00039 class gdTrimIntersection;
00040 class GD_Detail;
00041
00042 class GD_API GD_TrimLoopFlags {
00043 public:
00044 GD_TrimLoopFlags() { closed = 0; }
00045 unsigned closed:1,
00046 clockwise:1;
00047 };
00048
00049 enum GD_IsoparmDirection {
00050 GD_YISOPARM = 1,
00051 GD_XISOPARM = 0
00052 };
00053
00054 enum GD_DomainBoundary {
00055 GD_UMIN = 0,
00056 GD_VMIN = 1,
00057 GD_UMAX = 2,
00058 GD_VMAX = 3
00059 };
00060
00061 enum GD_TrimRule {
00062 GD_TrimWindingRule = 0,
00063 GD_TrimAlternatingRule = 1
00064 };
00065
00066
00067 class GD_API GD_TrimLoop {
00068 public:
00069
00070 GD_TrimLoop();
00071
00072
00073 GD_TrimLoop(GD_TrimPiece *curve);
00074
00075
00076 ~GD_TrimLoop();
00077
00078
00079
00080 int evaluate(float u, UT_Vector2 &pos) const;
00081 int evaluate(float u, UT_Vector2 &pos, UT_Vector2 &der)
00082 const;
00083 int evaluateHead(UT_Vector2 &pos) const;
00084 int evaluateTail(UT_Vector2 &pos) const;
00085
00086
00087 void evaluateNormal(UT_Vector3 &normal) const;
00088
00089
00090 void findDirection();
00091
00092
00093 unsigned isClosed() const { return flags.closed; }
00094
00095
00096 void close(int connect_ends = 0);
00097
00098
00099 float length() const;
00100
00101
00102 unsigned isClockwise() const { return flags.clockwise; }
00103
00104
00105 void appendLoop(GD_TrimLoop *loop);
00106
00107
00108
00109 void append(GD_TrimLoop *loop, int consolidate = 0,
00110 int deleteloop = 0,
00111 int join = 0);
00112
00113
00114
00115 void appendPoint(float u, float v);
00116
00117
00118
00119 int appendAtIntersect(GD_TrimLoop *loop, int deleteloop,
00120 float tol=1E-4F);
00121
00122
00123 void append(GD_TrimPiece *piece);
00124
00125
00126
00127 GD_TrimLoop *copy() const;
00128 GD_TrimLoop *copyThis() const;
00129
00130
00131 void reverse();
00132 void reverseThis();
00133
00134
00135
00136
00137
00138
00139
00140
00141 int isInsideJitter(const UT_Vector2 &pt, float tol = 1e-4F,
00142 float dither = 1e-5F) const;
00143 int isInside(const GD_TrimLoop &prim, float tol = 1E-4F)
00144 const;
00145 int isInside(const UT_Vector2 &pt, float tol = 1E-4F)
00146 const;
00147
00148
00149 int isTrimmedIn(const UT_Vector2 &pt,
00150 GD_TrimRule rule = GD_TrimWindingRule) const;
00151 int isTrimmedIn(float u, float v,
00152 GD_TrimRule rule = GD_TrimWindingRule) const;
00153
00154
00155 int isTrimmedIn(const UT_Vector2 &pt,
00156 UT_IntArray &validloops,
00157 GD_TrimRule rule = GD_TrimWindingRule) const;
00158 int isTrimmedIn(float u, float v,
00159 UT_IntArray &validloops,
00160 GD_TrimRule rule = GD_TrimWindingRule) const;
00161
00162
00163 int isTrimmedInJitter(const UT_Vector2 &pt,
00164 GD_TrimRule rule = GD_TrimWindingRule) const;
00165 int isTrimmedInJitter(float u, float v,
00166 GD_TrimRule rule = GD_TrimWindingRule) const;
00167 int isTrimmedIn(GD_TrimLoop *loop,
00168 GD_TrimRule rule = GD_TrimWindingRule) const;
00169
00170 void getParameterRange(float &umin, float &umax) const;
00171
00172
00173 float parametricDist(float u1, float u2) const;
00174
00175
00176 float parametricLength(float u1, float u2) const;
00177
00178
00179 GD_TrimLoop *cut(float u1, float u2) const;
00180
00181
00182
00183 void cutAtIsoparm(GD_TrimLoop **left, GD_TrimLoop **right,
00184 GD_IsoparmDirection iso, float val,
00185 float tol = 1e-4f);
00186
00187
00188
00189 void cutAtTrim(GD_TrimLoop **inside, GD_TrimLoop **outside,
00190 const GD_TrimLoop *cutter,
00191 GD_TrimLoop *source);
00192
00193
00194 int intersect(const GD_TrimLoop &loop,
00195 UT_RefArray<GD_TrimHitInfo> &hitlist,
00196 float tol = 1E-4F) const;
00197
00198
00199 int intersect(GD_TrimPiece &piece,
00200 UT_RefArray<GD_TrimHitInfo> &hitlist,
00201 float tol = 1e-4F) const;
00202
00203
00204 int intersectAll(const GD_TrimLoop &loop,
00205 UT_RefArray<GD_TrimHitInfo> &hitlist,
00206 float tol = 1e-4F) const;
00207
00208
00209
00210 int intersectDomain(const UT_BoundingRect &brect,
00211 UT_RefArray<GD_TrimHitInfo> &hitlist,
00212 float tol = 1E-4F) const;
00213
00214
00215
00216
00217 GD_TrimLoop *domainClip(const UT_BoundingRect &brect,
00218 float tol = 1E-4F, int preservedirection = 1);
00219
00220
00221 int startWalk(float inc, float minstep, float maxstep,
00222 float &u, float &v);
00223
00224 int doWalk(float &u, float &v);
00225 void endWalk();
00226
00227
00228
00229
00230 int getData(UT_IntArray &ncurves,
00231 UT_IntArray &order, UT_IntArray &ncvs,
00232 UT_FloatArray &knots,
00233 UT_FloatArray &min, UT_FloatArray &max,
00234 UT_FloatArray &u, UT_FloatArray &v,
00235 UT_FloatArray &w) const;
00236
00237
00238 int setLoopIds(int id = 0);
00239 int getId() const { return myId; }
00240
00241 GD_TrimLoop *getNext() const { return myNext; }
00242 GD_TrimLoop *getChild() const { return myChild; }
00243
00244 GD_Detail *getDetail() const { return myDetail; }
00245 void setDetail(GD_Detail *gdp) { myDetail = gdp; }
00246
00247
00248
00249 GD_TrimLoop *preprocessLoops(GD_TrimRule rule, int altitude=0);
00250
00251
00252 int getMaxHeight() const;
00253
00254
00255 int getBaseDir() const;
00256
00257
00258 GD_TrimLoop *flatten();
00259
00260 void print(int i = 1, int recurse = 1) const;
00261
00262
00263
00264 int isHeadNearTail(float tol=1E-4F) const;
00265
00266
00267
00268
00269 int hitHead(const UT_BoundingRect &brect,
00270 UT_RefArray<GD_TrimHitInfo> &hitlist,
00271 float tol = 1E-4F) const;
00272 int hitTail(const UT_BoundingRect &brect,
00273 UT_RefArray<GD_TrimHitInfo> &hitlist,
00274 float tol = 1E-4F) const;
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284 static GD_TrimLoop *domainBridge(const UT_BoundingRect &brect,
00285 const UT_Vector2 &posa, float ua, GD_DomainBoundary a,
00286 const UT_Vector2 &posb, float ub, GD_DomainBoundary b,
00287 float tol, const UT_BoundingRect &bbox,
00288 int alwayscounter = 0);
00289
00290
00291
00292
00293 int getPoints(int numdivs, UT_Vector3Array &domain,
00294 int usebreak);
00295
00296
00297
00298
00299 GD_TrimPiece* getPiece(GD_TrimPiece* prev_piece) const;
00300
00301 protected:
00302
00303
00304 void snapPieces();
00305
00306
00307
00308
00309
00310
00311 GD_TrimLoop *applyWindingRule(int isfragmented = 0,
00312 int altitude = 0,
00313 int *maxdepth = 0,
00314 int *basedir = 0);
00315
00316
00317
00318
00319
00320 GD_TrimLoop *fragment(const GD_TrimLoop *loop) const;
00321
00322
00323 int intersect(float val, GD_IsoparmDirection isoparm,
00324 UT_RefArray<GD_TrimHitInfo> &hitlist,
00325 float tol = 1E-4F) const;
00326
00327
00328
00329 int processIsoparmHits(UT_RefArray<GD_TrimHitInfo> &hits,
00330 int hit, float tol = 1E-4F) const;
00331
00332
00333 void doIsoparm(int isoparm, float val, float tol,
00334 GD_DomainBoundary code,
00335 UT_RefArray<GD_TrimHitInfo> &hitlist,
00336 int &hit, int &i) const;
00337
00338
00339
00340
00341
00342 GD_TrimLoop *addPossibleChild(GD_TrimLoop *loop);
00343
00344
00345 GD_TrimLoop *removeDegenerateLoops(float tol=1E-4F);
00346
00347
00348 GD_TrimLoop *removeRedundantLoops();
00349
00350
00351 void findDepths(int depth);
00352
00353
00354 int findMaxDepth() const;
00355
00356
00357 int getBaseTrimDir() const;
00358
00359
00360 void adjustDepths(int deltadepth);
00361
00362 public:
00363 UT_BoundingRect myBBox;
00364
00365
00366 GD_TrimPiece *myTrimPieces;
00367 GD_TrimPiece *myLastTrimPiece;
00368 private:
00369 GD_TrimLoop *myNext, *myChild;
00370 GD_Detail *myDetail;
00371 GD_TrimLoopFlags flags;
00372
00373 float myUStart, myULength;
00374
00375
00376 gdTrimIntersection *myNextIntersection;
00377
00378
00379
00380
00381 GD_TrimLoop const *myParent;
00382 GD_TrimLoop const *myOtherParent;
00383 int inOtherParent;
00384 int myId;
00385
00386 int myDepth;
00387
00388
00389 GD_TrimPiece *myWalkPiece;
00390 float myWalkU;
00391 float myWalkUInc, myWalkMinStep2, myWalkMaxStep2;
00392 float myWalkLastX, myWalkLastY;
00393
00394
00395 UT_Vector2 myInitPoint;
00396 int myHasInitPoint;
00397
00398
00399 GD_TrimLoop *doCopy() const;
00400 };
00401
00402 #endif