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
00029
00030 #include "EUC_Expression.h"
00031
00032 #include <SYS/SYS_Math.h>
00033 #include <UT/UT_Vector3.h>
00034 #include <UT/UT_RootFinder.h>
00035
00036 using namespace HDK_Sample;
00037
00038 EUC_ExpressionList EUC_Expression::ourExpressionList;
00039 int EUC_Expression::ourEvaluateTime = 0;
00040
00041
00042
00043
00044 EUC_Expression::EUC_Expression()
00045 {
00046 myRefCount = 0;
00047 myUid = ourExpressionList.entries();
00048 myLastEvaluateTime = 0;
00049 myCd = 1;
00050 myVisible = true;
00051 ourExpressionList.append(this);
00052 }
00053
00054 EUC_Expression::~EUC_Expression()
00055 {
00056
00057 ourExpressionList(getUid()) = 0;
00058 }
00059
00060 void
00061 EUC_Expression::addRef()
00062 {
00063 myRefCount++;
00064 }
00065
00066 void
00067 EUC_Expression::removeRef()
00068 {
00069 myRefCount--;
00070 if (myRefCount <= 0)
00071 delete this;
00072 }
00073
00074 EUC_Expression *
00075 EUC_Expression::getExprFromUid(int uid)
00076 {
00077
00078 if (uid < 0 || uid >= ourExpressionList.entries())
00079 return 0;
00080
00081 return ourExpressionList(uid);
00082 }
00083
00084 void
00085 EUC_Expression::setLook(bool visible, const UT_Vector3 &cd)
00086 {
00087 myVisible = visible;
00088 myCd = cd;
00089 }
00090
00091 void
00092 EUC_Expression::applyLook(EUC_Object *obj)
00093 {
00094 obj->setLook(myVisible, myCd);
00095 }
00096
00097 void
00098 EUC_Expression::evaluate(EUC_ObjectList &results)
00099 {
00100
00101 ourEvaluateTime++;
00102
00103
00104 EUC_ObjectList tmp;
00105
00106 evaluateRecurse(tmp, results);
00107 }
00108
00109 void
00110 EUC_Expression::evaluateRecurse(EUC_ObjectList &result,
00111 EUC_ObjectList &totalobj)
00112 {
00113
00114 if (myLastEvaluateTime == ourEvaluateTime)
00115 {
00116 result = myObjectCache;
00117 return;
00118 }
00119
00120 myLastEvaluateTime = ourEvaluateTime;
00121 myObjectCache.entries(0);
00122 evaluateSubclass(myObjectCache, totalobj);
00123 result = myObjectCache;
00124 }
00125
00126
00127
00128
00129 EUC_ExprPoint::EUC_ExprPoint(const UT_Vector2 &pos) : EUC_Expression()
00130 {
00131 myPos = pos;
00132 }
00133
00134 void
00135 EUC_ExprPoint::evaluateSubclass(EUC_ObjectList &result,
00136 EUC_ObjectList &totalobj)
00137 {
00138 EUC_Point *pt;
00139
00140 pt = new EUC_Point(myPos);
00141 applyLook(pt);
00142 result.entries(0);
00143 result.append(pt);
00144 totalobj.append(pt);
00145 }
00146
00147
00148
00149
00150 EUC_ExprPointFromObject::EUC_ExprPointFromObject(EUC_Expression *src, int idx) : EUC_Expression()
00151 {
00152 src->addRef();
00153 mySource = src;
00154 myIndex = idx;
00155 }
00156
00157 EUC_ExprPointFromObject::~EUC_ExprPointFromObject()
00158 {
00159 mySource->removeRef();
00160 }
00161
00162 void
00163 EUC_ExprPointFromObject::evaluateSubclass(EUC_ObjectList &result,
00164 EUC_ObjectList &totalobj)
00165 {
00166 EUC_Point *pt;
00167 EUC_ObjectList objlist;
00168 EUC_Object *obj;
00169 int i, n;
00170 UT_Vector2 pos;
00171 bool haspos;
00172
00173 result.entries(0);
00174 mySource->evaluateRecurse(objlist, totalobj);
00175 n = objlist.entries();
00176 for (i = 0; i < n; i++)
00177 {
00178 obj = objlist(i);
00179 haspos = false;
00180 switch (obj->getType())
00181 {
00182 case EUC_PointType:
00183 if (myIndex == 0)
00184 {
00185 haspos = true;
00186 pos = ((EUC_Point *)obj)->getPos();
00187 }
00188 break;
00189 case EUC_LineType:
00190 case EUC_CircleType:
00191 if (myIndex >= 0 && myIndex <= 1)
00192 {
00193 haspos = true;
00194 pos = ((EUC_Line *)obj)->getPt(myIndex);
00195 }
00196 break;
00197 }
00198
00199 if (haspos)
00200 {
00201 pt = new EUC_Point(pos);
00202 applyLook(pt);
00203 result.append(pt);
00204 totalobj.append(pt);
00205 }
00206 }
00207 }
00208
00209
00210
00211
00212 EUC_ExprLineFromPoints::EUC_ExprLineFromPoints(EUC_Expression *pta, EUC_Expression *ptb) : EUC_Expression()
00213 {
00214 pta->addRef();
00215 ptb->addRef();
00216 myPtA = pta;
00217 myPtB = ptb;
00218 }
00219
00220 EUC_ExprLineFromPoints::~EUC_ExprLineFromPoints()
00221 {
00222 myPtA->removeRef();
00223 myPtB->removeRef();
00224 }
00225
00226 void
00227 EUC_ExprLineFromPoints::evaluateSubclass(EUC_ObjectList &result,
00228 EUC_ObjectList &totalobj)
00229 {
00230 EUC_Line *line;
00231 EUC_ObjectList ptalist, ptblist;
00232 int i, n;
00233 UT_Vector2 a, b;
00234
00235 result.entries(0);
00236 myPtA->evaluateRecurse(ptalist, totalobj);
00237 myPtB->evaluateRecurse(ptblist, totalobj);
00238 n = SYSmin(ptalist.entries(), ptblist.entries());
00239 for (i = 0; i < n; i++)
00240 {
00241 if (ptalist(i)->getType() == EUC_PointType &&
00242 ptblist(i)->getType() == EUC_PointType)
00243 {
00244 a = ((EUC_Point *)ptalist(i))->getPos();
00245 b = ((EUC_Point *)ptblist(i))->getPos();
00246 line = new EUC_Line();
00247 applyLook(line);
00248 line->setPt(0, a);
00249 line->setPt(1, b);
00250 result.append(line);
00251 totalobj.append(line);
00252 }
00253 }
00254 }
00255
00256
00257
00258
00259 EUC_ExprCircleFromPoints::EUC_ExprCircleFromPoints(EUC_Expression *center, EUC_Expression *pt) : EUC_Expression()
00260 {
00261 center->addRef();
00262 pt->addRef();
00263 myCenter = center;
00264 myPoint = pt;
00265 }
00266
00267 EUC_ExprCircleFromPoints::~EUC_ExprCircleFromPoints()
00268 {
00269 myCenter->removeRef();
00270 myPoint->removeRef();
00271 }
00272
00273 void
00274 EUC_ExprCircleFromPoints::evaluateSubclass(EUC_ObjectList &result,
00275 EUC_ObjectList &totalobj)
00276 {
00277 EUC_Circle *circle;
00278 EUC_ObjectList ptalist, ptblist;
00279 int i, n;
00280 UT_Vector2 a, b;
00281
00282 result.entries(0);
00283 myCenter->evaluateRecurse(ptalist, totalobj);
00284 myPoint->evaluateRecurse(ptblist, totalobj);
00285 n = SYSmin(ptalist.entries(), ptblist.entries());
00286 for (i = 0; i < n; i++)
00287 {
00288 if (ptalist(i)->getType() == EUC_PointType &&
00289 ptblist(i)->getType() == EUC_PointType)
00290 {
00291 a = ((EUC_Point *)ptalist(i))->getPos();
00292 b = ((EUC_Point *)ptblist(i))->getPos();
00293 circle = new EUC_Circle();
00294 applyLook(circle);
00295 circle->setPt(0, a);
00296 circle->setPt(1, b);
00297 result.append(circle);
00298 totalobj.append(circle);
00299 }
00300 }
00301 }
00302
00303
00304
00305
00306 EUC_ExprIntersect::EUC_ExprIntersect(EUC_Expression *expra, EUC_Expression *exprb) : EUC_Expression()
00307 {
00308 expra->addRef();
00309 exprb->addRef();
00310 myExprA = expra;
00311 myExprB = exprb;
00312 }
00313
00314 EUC_ExprIntersect::~EUC_ExprIntersect()
00315 {
00316 myExprA->removeRef();
00317 myExprB->removeRef();
00318 }
00319
00320 void
00321 EUC_ExprIntersect::evaluateSubclass(EUC_ObjectList &result,
00322 EUC_ObjectList &totalobj)
00323 {
00324 EUC_Point *pt;
00325 EUC_ObjectList ptalist, ptblist;
00326 EUC_Object *obja, *objb;
00327 int i, n;
00328 UT_Vector2 pos;
00329
00330 result.entries(0);
00331 myExprA->evaluateRecurse(ptalist, totalobj);
00332 myExprB->evaluateRecurse(ptblist, totalobj);
00333 n = SYSmin(ptalist.entries(), ptblist.entries());
00334 for (i = 0; i < n; i++)
00335 {
00336
00337 if (ptalist(i)->getType() < ptblist(i)->getType())
00338 {
00339 obja = ptalist(i);
00340 objb = ptblist(i);
00341 }
00342 else
00343 {
00344 objb = ptalist(i);
00345 obja = ptblist(i);
00346 }
00347
00348
00349 if (obja->getType() == EUC_PointType)
00350 {
00351
00352 continue;
00353 }
00354
00355 if (obja->getType() == EUC_LineType)
00356 {
00357
00358 if (objb->getType() == EUC_LineType)
00359 {
00360
00361 UT_Vector3 p1, p2, v1, v2, isect;
00362 int retcode;
00363
00364 pos = ((EUC_Line *)obja)->getPt(0);
00365 p1.assign(pos.x(), pos.y(), 0);
00366 pos = ((EUC_Line *)obja)->getPt(1);
00367 v1.assign(pos.x(), pos.y(), 0);
00368 v1 -= p1;
00369
00370 pos = ((EUC_Line *)objb)->getPt(0);
00371 p2.assign(pos.x(), pos.y(), 0);
00372 pos = ((EUC_Line *)objb)->getPt(1);
00373 v2.assign(pos.x(), pos.y(), 0);
00374 v2 -= p2;
00375
00376 retcode = isect.lineIntersect(p1, v1, p2, v2);
00377
00378 if (retcode != -1)
00379 {
00380 pos = isect;
00381 pt = new EUC_Point(pos);
00382 applyLook(pt);
00383 result.append(pt);
00384 totalobj.append(pt);
00385 }
00386 }
00387 else
00388 {
00389
00390 UT_Vector2 p, v, center, isect;
00391 float radius, a, b, c, t0, t1;
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404 p = ((EUC_Line *)obja)->getPt(0);
00405 v = ((EUC_Line *)obja)->getPt(1);
00406 v -= p;
00407
00408 center = ((EUC_Circle *)objb)->getCenter();
00409 radius = ((EUC_Circle *)objb)->getRadius();
00410
00411 center = p - center;
00412 a = dot(v, v);
00413 b = 2 * dot(v, center);
00414 c = dot(center, center) - radius*radius;
00415 if (UT_RootFinder::quadratic(a, b, c, t0, t1))
00416 {
00417
00418 pos = p + t0 * v;
00419 pt = new EUC_Point(pos);
00420 applyLook(pt);
00421 result.append(pt);
00422 totalobj.append(pt);
00423
00424 pos = p + t1 * v;
00425 pt = new EUC_Point(pos);
00426 applyLook(pt);
00427 result.append(pt);
00428 totalobj.append(pt);
00429 }
00430 }
00431 }
00432 else
00433 {
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446 float rA, rB, t, d, hA2, hB2;
00447 UT_Vector2 cA, cB, v, perpv;
00448
00449 rA = ((EUC_Circle *)obja)->getRadius();
00450 cA = ((EUC_Circle *)obja)->getCenter();
00451 rB = ((EUC_Circle *)objb)->getRadius();
00452 cB = ((EUC_Circle *)objb)->getCenter();
00453 v = cB;
00454 v -= cA;
00455 d = v.length();
00456 v.normalize();
00457 if (!SYSequalZero(d))
00458 {
00459
00460 t = (rA*rA - rB*rB + d*d) / (2.0 * d);
00461
00462
00463 hA2 = rA*rA - t*t;
00464 hB2 = rB*rB - (t-d)*(t-d);
00465 if (hA2 >= 0 && hB2 >= 0)
00466 {
00467
00468 perpv.x() = v.y();
00469 perpv.y() = -v.x();
00470
00471 hA2 = SYSsqrt(hA2);
00472
00473
00474 pos = cA + t * v + hA2 * perpv;
00475 pt = new EUC_Point(pos);
00476 applyLook(pt);
00477 result.append(pt);
00478 totalobj.append(pt);
00479
00480 pos = cA + t * v - hA2 * perpv;
00481 pt = new EUC_Point(pos);
00482 applyLook(pt);
00483 result.append(pt);
00484 totalobj.append(pt);
00485 }
00486 }
00487 }
00488 }
00489 }
00490
00491
00492
00493
00494 EUC_ExprSelect::EUC_ExprSelect(EUC_Expression *src, int idx) : EUC_Expression()
00495 {
00496 src->addRef();
00497 mySource = src;
00498 myIndex = idx;
00499 }
00500
00501 EUC_ExprSelect::~EUC_ExprSelect()
00502 {
00503 mySource->removeRef();
00504 }
00505
00506 void
00507 EUC_ExprSelect::evaluateSubclass(EUC_ObjectList &result,
00508 EUC_ObjectList &totalobj)
00509 {
00510 EUC_ObjectList objlist;
00511
00512 result.entries(0);
00513 mySource->evaluateRecurse(objlist, totalobj);
00514
00515 if (myIndex >= 0 && myIndex < objlist.entries())
00516 result.append(objlist(myIndex));
00517 }
00518