00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef __GU_RayIntersect_h__
00022 #define __GU_RayIntersect_h__
00023
00024 #include "GU_API.h"
00025 #include <UT/UT_Defines.h>
00026 #include <UT/UT_RefArray.h>
00027 #include <UT/UT_PtrArray.h>
00028 #include <UT/UT_Vector3.h>
00029
00030 class GB_Group;
00031 class GB_PrimitiveGroup;
00032 class GU_Detail;
00033 class GEO_Point;
00034 class guRayTree;
00035 class GEO_Primitive;
00036 class GU_RayPrimInfo;
00037 class GU_IsectCurveSet;
00038 class GU_PrimGroupClosure;
00039 class TS_MetaExpression;
00040
00041
00042 enum GU_RayFindType {
00043 GU_FIND_CLOSEST = 0,
00044 GU_FIND_FURTHEST = 1,
00045 GU_FIND_ALL = 2
00046 };
00047
00048 class GU_API GU_RayInfoHit {
00049 public:
00050 int operator==(const GU_RayInfoHit &x) const
00051 {
00052 return (t==x.t && u == x.u && v == x.v && d2 == x.d2 && prim == x.prim);
00053 }
00054 float t, u, v, d2;
00055 const GEO_Primitive *prim;
00056 };
00057
00058 class GU_API GU_RayInfoCache {
00059 public:
00060 GU_RayInfoCache( )
00061 {
00062 valid = 0;
00063 priminfo = 0;
00064 data = 0;
00065 }
00066
00067 GU_RayPrimInfo *priminfo;
00068 void *data;
00069 int valid;
00070 };
00071
00072 class GU_API GU_RayInfo {
00073 public:
00074 GU_RayInfo(float max = 1E18f, float min=0.0f,
00075 GU_RayFindType type = GU_FIND_CLOSEST, float tol = 1e-1F)
00076 {
00077 myHitList = 0;
00078 myCurveSet = 0;
00079 myTtol = 1E-2f;
00080
00081 myIgnoreTrims = true;
00082 myUseAlgebraic = false;
00083 myIgnoreMeta = false;
00084 myExpandPolygon = false;
00085 myTValid = false;
00086 myDomainTol = 1E-2f;
00087 mySteps = 100;
00088 myMaxHits = 0;
00089 myTimeChange = 0.0F;
00090 myUnitTimeOffset = 0.0F;
00091 init(max, min, type, tol);
00092 }
00093 ~GU_RayInfo();
00094
00095 void setFindType(GU_RayFindType type);
00096 void init(float max = 1E18f, float min=0.0f,
00097 GU_RayFindType type = GU_FIND_CLOSEST,
00098 float tolerance = 1e-1F, int ignoretrims=1,
00099 int usealgebraic = 0);
00100
00101 int testHit(float t)
00102 {
00103 return (t >= myTmin && t <= myTmax);
00104 }
00105
00106 int insertHit(float nt, float nu=0, float nv=0,
00107 float nd2=0, const GEO_Primitive *nprim=0);
00108
00109 void addCurveSet(GU_IsectCurveSet &curveset);
00110
00111 void invalidateCache() { myCache.valid = 0; }
00112 int isCacheValid() { return( myCache.valid ); }
00113
00114 GU_RayFindType getFindType() const { return myFindType; }
00115
00116 void reset();
00117
00118 const GEO_Primitive *myPrim;
00119 UT_Vector3 myNml;
00120 float myTmin;
00121 float myTmax;
00122 float myT;
00123 float myU, myV;
00124 float myD2;
00125 float myTol;
00126 float myTtol;
00127
00128 float myDomainTol;
00129 int mySteps;
00130 bool myIgnoreTrims;
00131 bool myUseAlgebraic;
00132 bool myExpandPolygon;
00133
00134
00135 bool myIgnoreMeta;
00136 bool myTValid;
00137 int myMaxHits;
00138
00139
00140 GU_RayInfoCache myCache;
00141 UT_RefArray<GU_RayInfoHit> *myHitList;
00142 GU_IsectCurveSet *myCurveSet;
00143
00144 float myTimeChange;
00145 float myUnitTimeOffset;
00146 private:
00147 GU_RayFindType myFindType;
00148 };
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158 class GU_API GU_MinInfo {
00159 public:
00160 GU_MinInfo(float max = 1E18F, float min=1e-14F, int naccurate = 1)
00161 {
00162 dmin = min;
00163 dmax = max;
00164 accurate = naccurate;
00165 u1 = v1 = u2 = v2 = 0.0f;
00166 prim = 0;
00167 }
00168
00169 void init(float max = 1E18F, float min=1e-14F)
00170 {
00171 dmin = min;
00172 dmax = max;
00173 }
00174
00175 int addMin(float dist)
00176 {
00177 if (dist < dmax)
00178 {
00179
00180 dmax = dist;
00181 return 1;
00182 }
00183 else return 0;
00184 }
00185
00186 void insertMin(float nd2, float nu1, float nv1,
00187 float nu2, float nv2,
00188 const GEO_Primitive *p)
00189 {
00190 d = nd2;
00191 u1 = nu1;
00192 v1 = nv1;
00193 u2 = nu2;
00194 v2 = nv2;
00195 prim = p;
00196 }
00197
00198 void swapOrder()
00199 {
00200 float tmp;
00201
00202 tmp = u1;
00203 u1 = u2;
00204 u2 = tmp;
00205
00206 tmp = v1;
00207 v1 = v2;
00208 v2 = tmp;
00209 }
00210
00211 int operator==( const GU_MinInfo &other ) const
00212 {
00213 return( dmin == other.dmin
00214 && dmax == other.dmax
00215 && d == other.d
00216 && u1 == other.u1
00217 && v1 == other.v1
00218 && u2 == other.u2
00219 && v2 == other.v2
00220 && accurate == other.accurate
00221 && prim == other.prim );
00222 }
00223
00224 float dmin, dmax;
00225 float d;
00226 float u1, v1;
00227 float u2, v2;
00228 int accurate;
00229 const GEO_Primitive*prim;
00230 };
00231
00232 class GU_API GU_ProximityHelper
00233 {
00234 public:
00235 GU_ProximityHelper() {}
00236 virtual ~GU_ProximityHelper() {}
00237
00238 virtual float getMaxRadius( int prim_num ) const = 0;
00239 virtual float getRadius( int prim_num,
00240 float u_real, float v_real ) const = 0;
00241 };
00242
00243 class GU_API GU_RayIntersect {
00244 public:
00245 GU_RayIntersect();
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262 GU_RayIntersect(const GU_Detail *gdp, const GB_PrimitiveGroup *group = 0,
00263 int picking = 0, int polyline = 0, int harden = 0,
00264 int usevisibility = 0);
00265
00266
00267
00268
00269 GU_RayIntersect(const GU_Detail *gdp, const GU_PrimGroupClosure &closure,
00270 bool closure_hidden, int picking = 0, int polyline = 0,
00271 int harden = 0);
00272
00273
00274 GU_RayIntersect(const GU_Detail *gdp, const GEO_Primitive *prim,
00275 int polyline = 0);
00276
00277
00278
00279
00280
00281
00282 GU_RayIntersect(const GU_Detail *gdp0, const GU_Detail *gdp1);
00283
00284
00285
00286
00287
00288 GU_RayIntersect(const GU_Detail *gdp,
00289 const GU_Detail *limit_gdp,
00290 const GB_PrimitiveGroup *vis_group,
00291 int picking = 0, int polyline = 0, int harden = 0,
00292 int usevisibility = 0);
00293
00294 ~GU_RayIntersect();
00295
00296
00297
00298 static bool validForDeformingGeometry(const GU_Detail *gdp0,
00299 const GU_Detail *gdp1);
00300
00301 void init(const GU_Detail *gdp, const GB_PrimitiveGroup *group = 0,
00302 int picking = 0, int polyline = 0);
00303 void init(const GU_Detail *gdp, const GEO_Primitive *prim,
00304 int polyline = 0);
00305 void init(const GU_Detail *gdp,
00306 const GU_Detail *limit_gdp,
00307 const GB_PrimitiveGroup *limit_group,
00308 int picking = 0, int polyline = 0, int harden = 0,
00309 int usevisibility = 0);
00310
00311 int init() const { return myTree != 0; }
00312
00313
00314
00315 bool validForDetail(const GU_Detail *gdp) const;
00316
00317
00318
00319
00320
00321 int sendRay(const UT_Vector3 &org, const UT_Vector3 &dir,
00322 GU_RayInfo &hitinfo);
00323
00324
00325
00326 int minimumPoint(const UT_Vector3 &p, GU_MinInfo &mininfo,
00327 const GEO_Primitive *prim = 0);
00328
00329
00330
00331
00332
00333 int proximityPoint( UT_RefArray<GU_MinInfo> &hit_list,
00334 const UT_Vector3 &p,
00335 bool normalize_weights,
00336 const GU_ProximityHelper *helper,
00337 float radius = 0.0f ) const;
00338
00339
00340
00341 int intersectPrim(GU_RayPrimInfo &prim, GU_RayInfo &hitinfo);
00342
00343
00344
00345 int intersectCaches(GU_RayIntersect &intersect,
00346 GU_RayInfo &hitInfo);
00347
00348
00349
00350 int minimumCaches(const GU_RayIntersect &intersect,
00351 GU_MinInfo &minInfo) const;
00352
00353 int isInside(const UT_Vector3 &pt, int ignoretrim = 1);
00354 int isInside(const UT_Vector4 &pt, int ignoretrim = 1);
00355 int determineState(const UT_Vector3 &pt,
00356 const GEO_Primitive *&prim,
00357 int n, long seed = 1, int ignoretrim = 1);
00358 int determineState(const UT_Vector4 &pt,
00359 const GEO_Primitive *&prim,
00360 int n, long seed = 1, int ignoretrim = 1);
00361
00362 int isInsideWinding(const UT_Vector3 &pt, int ignoretrim = 1);
00363 int isInsideWinding(const UT_Vector4 &pt, int ignoretrim = 1);
00364 int determineStateWinding(const UT_Vector3 &pt,
00365 const GEO_Primitive *&prim,
00366 int n, long seed = 1, int ignoretrim = 1);
00367 int determineStateWinding(const UT_Vector4 &pt,
00368 const GEO_Primitive *&prim,
00369 int n, long seed = 1, int ignoretrim = 1);
00370
00371 UT_PtrArray<GU_RayPrimInfo *> &getPrimList() const;
00372
00373 private:
00374 void initDetailTracking(const GU_Detail *gdp);
00375 void initMetaExpr(const GU_Detail *gdp, bool first_time);
00376
00377 guRayTree *myTree;
00378 int mySerial;
00379 TS_MetaExpression *myMetaExpr;
00380
00381
00382
00383 int myDetailUniqueId;
00384 int myDetailCacheCount;
00385 };
00386
00387 #endif