00001 /*
00002 File: HRMesh.cc
00003
00004 Function: See header file
00005
00006 Author(s): Andrew Willmott
00007
00008 Copyright: (c) 1997-2000, Andrew Willmott
00009
00010 */
00011
00012 #include "HRMesh.h"
00013 #include "RadMethod.h"
00014 #include "Samples.h"
00015 #include "gcl/Draw.h"
00016
00017 #ifdef RAD_VIS
00018 #include "gcl/Forms.h"
00019 #include "gcl/ScenePane.h"
00020 #endif
00021
00022 #define MAX_ELT_SAMPLES 32
00023
00024
00025 // --- HRMeshElem methods -----------------------------------------------------
00026
00027 HRMeshElem::HRMeshElem() : HRElem(), HierElem()
00028 {
00029 flags.Set(hrPatch);
00030 }
00031
00032 Void HRMeshElem::Reset()
00033 {
00034 HRElem::Reset();
00035 HierElem::FreeChildren();
00036 flags.UnSet(hrIntNode);
00037 }
00038
00039 Void HRMeshElem::ApplyToChildren(Void (HRElem::*method)(Void *), Void *ref)
00040 {
00041 if (!IsLeaf())
00042 for (Int i = 0; i < 4; i++)
00043 (((HRMeshElem*)child[i])->*method)(ref);
00044 }
00045
00046 // ----------------------------------------------------------------------------
00047
00048 Void HRMeshElem::Print(ostream &s)
00049 {
00050 HRLinkIter i;
00051
00052 PrintID(s);
00053 s << " = ";
00054 HierElem::PrintSelf(s);
00055 s << ' ';
00056 for (i.Begin(links); !i.AtEnd(); i.Inc())
00057 s << i.Data();
00058
00059 s << endl;
00060 }
00061
00062 Void HRMeshElem::CreatePatches(PatchList &patches)
00063 {
00064 patches.Append(this);
00065 }
00066
00067
00068 // --- kernel sampling --------------------------------------------------------
00069
00070
00071 Void HRMeshElem::MakeChildLinks(HRElem *other, HRLink *link,
00072 Int which, Int levels)
00073 {
00074 Int i;
00075
00076 if (IsLeaf())
00077 {
00078 if (!HasChildren())
00079 Subdivide();
00080 flags.Set(hrIntNode);
00081 Push();
00082 }
00083
00084 if (which == kSubTo)
00085 for (i = 0; i < 4; i++)
00086 Child(i)->RefineLink(
00087 link->CreateSubLink(other, Child(i)),
00088 levels);
00089 else if (which == kSubFrom)
00090 for (i = 0; i < 4; i++)
00091 other->RefineLink(
00092 link->CreateSubLink(Child(i), other),
00093 levels);
00094 else if (which == kSubBoth)
00095 for (i = 0; i < 4; i++)
00096 other->MakeChildLinks(Child(i), link, kSubFrom, levels);
00097 else
00098 _Error("split type not implemented");
00099 }
00100
00101 Void HRMeshElem::SampleKernel(
00102 const GCLMat &fromU, // source patch samples
00103 HRMeshElem *to, // dest. patch
00104 const GCLMat &toU, // destination samples
00105 GCLMat &samples, // results of sampling the kernel.
00106 GCLReal *visPtr // if visPtr is set, accumulate
00107 // visibility into it
00108 )
00109 // x, y E [0, 1], origin at patch's lower left corner (vertex 1).
00110 {
00111 GCLReal result, vf = 1.0 / (fromU.Rows() * toU.Rows()), xs, ys;
00112 Vector temp, delta;
00113 Point srcPt[MAX_ELT_SAMPLES], srcPtE, srcPtV;
00114 Vector dstPt[MAX_ELT_SAMPLES], dstPtE, dstPtV;
00115 Vector dx2 = to->Vertex(2) - to->Vertex(1);
00116 Vector dy2 = to->Vertex(0) - to->Vertex(1);
00117 Vector dx1 = Vertex(2) - Vertex(1);
00118 Vector dy1 = Vertex(0) - Vertex(1);
00119 Int i, j;
00120
00121 #ifdef RAD_VIS
00122 if ((gRadControl->showRays && visPtr) || gRadControl->showLinks)
00123 {
00124 RM_DISPLAY_START;
00125 gRadControl->radObject->display->Begin(renLines);
00126 }
00127 #endif
00128
00129 samples.SetSize(toU.Rows(), fromU.Rows());
00130
00131 // calculate sample positions on source patch (that's us).
00132 srcPtE = Normal();
00133 srcPtE *= kRaySurfEps;
00134 for (j = 0; j < fromU.Rows(); j++)
00135 {
00136 srcPt[j] = Vertex(1);
00137 srcPt[j] += fromU[j][0] * dx1;
00138 srcPt[j] += fromU[j][1] * dy1;
00139 }
00140
00141 // ditto for destination
00142 dstPtE = to->Normal();
00143 dstPtE *= kRaySurfEps;
00144 for (i = 0; i < toU.Rows(); i++)
00145 {
00146 dstPt[i] = to->Vertex(1);
00147 dstPt[i] += toU[i][0] * dx2;
00148 dstPt[i] += toU[i][1] * dy2;
00149 }
00150
00151 for (i = 0; i < toU.Rows(); i++)
00152 {
00153 for (j = 0; j < fromU.Rows(); j++)
00154 {
00155 #ifdef RAD_VIS
00156 if (gRadControl->showLinks)
00157 gRadControl->radObject->display->C(cYellow).P(dstPt[i]).P(srcPt[j]);
00158 #endif
00159
00160 delta = dstPt[i];
00161 delta -= srcPt[j];
00162 temp = safe_norm(delta);
00163 result = dot(Normal(), temp);
00164
00165 if (result <= 0.0)
00166 result = 0.0;
00167 else
00168 {
00169 result *= -dot(to->Normal(), temp);
00170 if (result <= 0.0)
00171 result = 0.0;
00172 else
00173 {
00174 result *= area / (sqrlen(delta) * vl_pi);
00175
00176 if (visPtr)
00177 {
00178 Bool hit;
00179
00180 // Sample visibility too...
00181 srcPtV = srcPt[j] + srcPtE;
00182 dstPtV = dstPt[i] + dstPtE;
00183 hit = gRadControl->radObject->IntersectsWithRay(
00184 srcPtV, dstPtV);
00185 if (!hit)
00186 *visPtr += vf;
00187 else
00188 result = 0.0;
00189
00190 #ifdef RAD_VIS
00191 if (gRadControl->showRays)
00192 {
00193 if (hit)
00194 gRadControl->radObject->display->C(cRed);
00195 else
00196 gRadControl->radObject->display->C(cGreen);
00197 gRadControl->radObject->display->P(srcPtV).P(dstPtV);
00198 }
00199 #endif
00200
00201 }
00202 }
00203 }
00204 samples[i][j] = result;
00205 }
00206 }
00207
00208 #ifdef RAD_VIS
00209 if ((gRadControl->showRays && visPtr) || gRadControl->showLinks)
00210 {
00211 gRadControl->radObject->display->End();
00212 RM_DISPLAY_END;
00213 RM_OUT1("Visibility: " << *visPtr);
00214 if (RM_PAUSE)
00215 ;
00216 }
00217 #endif
00218 }
00219
00220
00221 Void HRMeshElem::EstSubFormFactor(
00222 Int nFrom,
00223 HRMeshElem *to,
00224 const GCLMat &toU,
00225 GCLMat &samples,
00226 GCLReal *visPtr
00227 )
00228 // x, y E [0, 1], origin at patch's bottom left corner (vertex 1).
00229 // XXX this is way too big and way too crufty. split up.
00230 {
00231 GCLReal rad4, npt, res2;
00232 GCLReal result, vf = 1.0 / (sqr(nFrom) * toU.Rows()), xs, ys;
00233 Vector temp, dxy;
00234 Point srcPt[MAX_ELT_SAMPLES], srcPtV, *srcPtP;
00235 Vector dstPt[MAX_ELT_SAMPLES], dstPtV;
00236 Vector dx2 = to->Vertex(2) - to->Vertex(1);
00237 Vector dy2 = to->Vertex(0) - to->Vertex(1);
00238 Vector dx1 = Vertex(2) - Vertex(1);
00239 Vector dy1 = Vertex(0) - Vertex(1);
00240 GCLReal rn = nFrom;
00241 Int i1, j1, i2, j;
00242
00243 #ifdef RAD_VIS
00244 if (gRadControl->showRays && visPtr)
00245 RM_DISPLAY_START;
00246 #endif
00247
00248 samples.SetSize(toU.Rows(), sqr(nFrom));
00249
00250 // generate sample points at centers of panes in source
00251 srcPtP = srcPt;
00252 for (i1 = 0; i1 < nFrom; i1++)
00253 for (j1 = 0; j1 < nFrom; j1++)
00254 {
00255 if (IsQuad())
00256 {
00257 xs = (j1 + 0.5) / rn;
00258 ys = (i1 + 0.5) / rn;
00259 }
00260 else if (i1 + j1 >= nFrom)
00261 {
00262 xs = 1 - (i1 + 1.0/3.0) / rn;
00263 ys = 1 - (j1 + 1.0/3.0) / rn;
00264 }
00265 else
00266 {
00267 xs = (j1 + 1.0/3.0) / rn;
00268 ys = (i1 + 1.0/3.0) / rn;
00269 }
00270 *srcPtP++ = (Vertex(1) + xs * dx1 + ys * dy1);
00271 }
00272
00273 // these will come in handy if we have to explicitly find
00274 // the pane's corners
00275 dx1 /= rn;
00276 dy1 /= rn;
00277 dxy = -(dx1 + dy1); // vector to get from centre of pane to upper-left
00278 if (IsQuad())
00279 dxy /= 2.0;
00280 else
00281 dxy /= 3.0;
00282
00283 // find destination sample points
00284 for (i2 = 0; i2 < toU.Rows(); i2++)
00285 {
00286 dstPt[i2] = to->Vertex(1);
00287 dstPt[i2] += toU[i2][0] * dx2;
00288 dstPt[i2] += toU[i2][1] * dy2;
00289 }
00290
00291 for (i2 = 0; i2 < toU.Rows(); i2++)
00292 {
00293 for (srcPtP = srcPt, j = 0, i1 = 0; i1 < nFrom; i1++)
00294 for (j1 = 0; j1 < nFrom; j1++, srcPtP++, j++)
00295 {
00296 temp = *srcPtP;
00297 temp -= dstPt[i2];
00298
00299 #ifdef RAD_VIS
00300 if (gRadControl->showLinks)
00301 gRadControl->radObject->display->P(dstPt[i2]).P(*srcPtP);
00302 #endif
00303
00304 result = dot(to->Normal(), temp);
00305
00306 if (result <= 0)
00307 result = 0.0;
00308 else
00309 {
00310 npt = -dot(Normal(), temp);
00311
00312 if (npt <= 0)
00313 result = 0.0;
00314 else
00315 {
00316 GCLReal sArea = area / sqr(rn);
00317
00318 rad4 = sqr(sqrlen(temp));
00319 result *= sArea / vl_pi;
00320 res2 = result * Max(npt, 0.25 * sqrt(sArea));
00321
00322 if (gRadControl->quadLevel > 0 &&
00323 rad4 * gRadControl->dFError < res2)
00324 {
00325 Vector v0, v1, v2, v3;
00326
00327 // result is blowing up!
00328 // let's bail to the area-to-point formula
00329
00330 // work out exact vertices of the source pane
00331 v1 = temp; // this is vector to its centre
00332 if (IsQuad())
00333 {
00334 v1 += dxy;
00335 v0 = v1 + dy1;
00336 v2 = v1 + dx1;
00337 v3 = v2 + dy1;
00338 }
00339 else if (i1 + j1 >= nFrom)
00340 {
00341 v1 -= dxy;
00342 v0 = v1 - dy1;
00343 v2 = v1 - dx1;
00344 }
00345 else
00346 {
00347 v1 += dxy;
00348 v0 = v1 + dy1;
00349 v2 = v1 + dx1;
00350 }
00351
00352 // find analytic A->dA factor
00353 result = EdgeArea(v0, v1, to->Normal());
00354 result += EdgeArea(v1, v2, to->Normal());
00355 if (IsQuad())
00356 {
00357 result += EdgeArea(v2, v3, to->Normal());
00358 result += EdgeArea(v3, v0, to->Normal());
00359 #ifdef RAD_VIS
00360 if (gRadControl->showLinks)
00361 gRadControl->radObject->display->
00362 P(dstPt[i2] + v0).P(dstPt[i2] + v1).
00363 P(dstPt[i2] + v1).P(dstPt[i2] + v2).
00364 P(dstPt[i2] + v2).P(dstPt[i2] + v3).
00365 P(dstPt[i2] + v3).P(dstPt[i2] + v0);
00366 #endif
00367 }
00368 else
00369 {
00370 result += EdgeArea(v2, v0, to->Normal());
00371 #ifdef RAD_VIS
00372 if (gRadControl->showLinks)
00373 gRadControl->radObject->display->
00374 P(dstPt[i2] + v0).P(dstPt[i2] + v1).
00375 P(dstPt[i2] + v1).P(dstPt[i2] + v2).
00376 P(dstPt[i2] + v2).P(dstPt[i2] + v0);
00377 #endif
00378 }
00379 if (result < 0.0)
00380 result = 0.0;
00381 }
00382 else
00383 result *= npt / rad4;
00384
00385 if (visPtr)
00386 {
00387 Bool hit;
00388
00389 dstPtV = dstPt[i2] + kRaySurfEps * to->Normal();
00390 srcPtV = *srcPtP + kRaySurfEps * Normal();
00391
00392 hit = gRadControl->radObject->IntersectsWithRay(
00393 srcPtV, dstPtV);
00394 if (!hit)
00395 *visPtr += vf;
00396 else
00397 result = 0.0;
00398 #ifdef RAD_VIS
00399 if (gRadControl->showRays)
00400 {
00401 if (hit)
00402 gRadControl->radObject->display->
00403 Begin(renLines).C(cRed).P(srcPtV).P(dstPtV).End();
00404 else
00405 gRadControl->radObject->display->
00406 Begin(renLines).C(cGreen).P(srcPtV).P(dstPtV).End();
00407 }
00408 #endif
00409 }
00410 }
00411 }
00412 samples[i2][j] = result;
00413 }
00414 }
00415 #ifdef RAD_VIS
00416 if (gRadControl->showRays && visPtr)
00417 {
00418 RM_DISPLAY_END;
00419 if (visPtr)
00420 RM_OUT1("Visibility: " << *visPtr);
00421 if (RM_PAUSE)
00422 ;
00423 }
00424 #endif
00425 }
00426
00427 Void HRMeshElem::SubToSubFormFactor(
00428 Int nFrom,
00429 HRMeshElem *to,
00430 Int nTo,
00431 GCLMat &samples,
00432 GCLReal *visPtr
00433 )
00434 {
00435 Coord uv[MAX_ELT_SAMPLES], *uvP;
00436 Int i2, j2;
00437
00438 Assert(sqr(nTo) < MAX_ELT_SAMPLES, "increase MAX_ELT_SAMPLES");
00439 // find uv samples on the destination
00440 if (to->IsQuad())
00441 for (uvP = uv, i2 = 0; i2 < nTo; i2++)
00442 for (j2 = 0; j2 < nTo; j2++, uvP++)
00443 {
00444 *uvP = Coord(j2 + 0.5, i2 + 0.5);
00445 *uvP *= 1.0 / nTo;
00446 }
00447 else
00448 for (uvP = uv, i2 = 0; i2 < nTo; i2++)
00449 for (j2 = 0; j2 < nTo; j2++, uvP++)
00450 {
00451 if (i2 + j2 >= nTo)
00452 {
00453 *uvP = Coord(1.0 - i2 + 1.0/3.0, 1.0 - j2 + 1.0/3.0);
00454 *uvP *= 1.0 / nTo;
00455 }
00456 else
00457 {
00458 *uvP = Coord(j2 + 1.0/3.0, i2 + 1.0/3.0);
00459 *uvP *= 1.0 / nTo;
00460 }
00461 }
00462
00463 // call EstSubFormFactor with the results
00464 EstSubFormFactor(nFrom, to, GCLMat(sqr(nTo), 2, (GCLReal*) uv), samples, visPtr);
00465 }
00466
00467
00468 // --- Drawing ----------------------------------------------------------------
00469
00470
00471 Void HRMeshElem::Draw(Renderer &r)
00472 {
00473 // pass on to the HRElem Draw
00474 DrawElem(r);
00475 }
00476
00477 Void HRMeshElem::DrawSampledLeaf(Renderer &r, Int n)
00478 {
00479 Int i, j;
00480 Vector dx = (Vertex(2) - Vertex(1)) / GCLReal(n);
00481 Vector dy = (Vertex(0) - Vertex(1)) / GCLReal(n);
00482 Point pt;
00483 GCLReal ds = 1.0 / GCLReal(n);
00484 GCLReal su, sv;
00485 Bool project = gRadControl->funcView;
00486
00487 // Render patch by drawing a mesh of (linearly interpolated)
00488 // sample points. 'n' controls the number of elements in the mesh.
00489 // This is a generic drawing function that only requires SampleLeaf()
00490 // to be defined.
00491
00492 for (i = 0; i < n; i++)
00493 for (j = 0; j < n; j++)
00494 {
00495 // draw pane (i, j)
00496 if (project)
00497 {
00498 r.Begin(renPoly);
00499
00500 if (IsQuad())
00501 {
00502 pt = Vertex(1) + dx * j + dy * i;
00503 su = ds * j; sv = ds * i;
00504 // XXX
00505 // Project(r, SampleLeaf(Coord(su, sv + ds)), pt + dy);
00506 // Project(r, SampleLeaf(Coord(su, sv)), pt);
00507 // Project(r, SampleLeaf(Coord(su + ds, sv)), pt + dx);
00508 // Project(r, SampleLeaf(Coord(su + ds, sv + ds)),
00509 // pt + dx + dy);
00510 }
00511 else if (j + i >= n)
00512 {
00513 pt = Vertex(1) + dx * (n - i) + dy * (n - j);
00514 su = 1 - ds * i; sv = 1 - ds * j;
00515 // Project(r, SampleLeaf(Coord(su, sv - ds)), pt - dy);
00516 // Project(r, SampleLeaf(Coord(su, sv)), pt);
00517 // Project(r, SampleLeaf(Coord(su - ds, sv)), pt - dx);
00518 }
00519 else
00520 {
00521 pt = Vertex(1) + dx * j + dy * i;
00522 su = ds * j; sv = ds * i;
00523 // Project(r, SampleLeaf(Coord(su, sv + ds)), pt + dy);
00524 // Project(r, SampleLeaf(Coord(su, sv)), pt);
00525 // Project(r, SampleLeaf(Coord(su + ds, sv)), pt + dx);
00526 }
00527
00528 r.End();
00529 }
00530 else
00531 {
00532 r.Begin(renPoly);
00533
00534 if (IsQuad())
00535 {
00536 pt = Vertex(1) + dx * j + dy * i;
00537 su = ds * j; sv = ds * i;
00538 r.C(SampleLeaf(Coord(su, sv + ds))).P(pt + dy);
00539 r.C(SampleLeaf(Coord(su, sv))).P(pt);
00540 r.C(SampleLeaf(Coord(su + ds, sv))).P(pt + dx);
00541 r.C(SampleLeaf(Coord(su + ds, sv + ds))).P(pt + dx + dy);
00542 }
00543 else if (j + i >= n)
00544 {
00545 pt = Vertex(1) + dx * (n - i) + dy * (n - j);
00546 su = 1 - ds * i; sv = 1 - ds * j;
00547 r.C(SampleLeaf(Coord(su, sv - ds))).P(pt - dy);
00548 r.C(SampleLeaf(Coord(su, sv))).P(pt);
00549 r.C(SampleLeaf(Coord(su - ds, sv))).P(pt - dx);
00550 }
00551 else
00552 {
00553 pt = Vertex(1) + dx * j + dy * i;
00554 su = ds * j; sv = ds * i;
00555 r.C(SampleLeaf(Coord(su, sv + ds))).P(pt + dy);
00556 r.C(SampleLeaf(Coord(su, sv))).P(pt);
00557 r.C(SampleLeaf(Coord(su + ds, sv))).P(pt + dx);
00558 }
00559
00560 r.End();
00561 }
00562 }
00563 }
00564
00565 Void HRMeshElem::DrawMatrixRec(Void *dmi)
00566 {
00567 #ifdef RAD_VIS
00568 HRLinkIter i;
00569 Int j;
00570 GCLReal x, y, wx, wy, n, m, temp, start, wstart;
00571 DMInfo *dmInfo = (DMInfo*) dmi;
00572 Renderer *r = dmInfo->r;
00573 Int baseNum = dmInfo->baseNum;
00574
00575 // Step through links, and draw each one in the appropriate position.
00576 // to do this for a general hierarchy, we would need a complete treeCode
00577 // for all HRElems in the hierarchy...
00578
00579 // find the "square" our root patch is in
00580 wstart = 2.0 / baseNum;
00581 start = 1.0 - (2.0 * props->id) / baseNum;
00582
00583 m = 1.0 / (1 << (2 * level));
00584 wy = wstart * m;
00585 y = start - treeCode * wy;
00586
00587 // Draw row of the matrix
00588
00589 for (i.Begin(links); !i.AtEnd(); i.Inc())
00590 {
00591 HRMeshElem *elt = (HRMeshElem*) i.Data().from;
00592
00593 start = (2.0 * elt->props->id) / baseNum - 1.0;
00594 n = 1.0 / (1 << (2 * elt->level));
00595 wx = wstart * n;
00596 x = start + elt->treeCode * wx;
00597
00598 if (highlight == 2 || elt->highlight == 3)
00599 {
00600 if (highlight == 2 && elt->highlight == 3)
00601 r->C(cPurple);
00602 else if (highlight == 2)
00603 r->C(cYellow);
00604 else
00605 r->C(cGreen);
00606 PaintRect(*r, Coord(x, y - wy), Coord(x + wx, y));
00607 }
00608 else
00609 // we are drawing form-factor, which is proportional to 'from'
00610 // area, which is prop. to 1 / (2 ^ 2 * level)
00611 i.Data().DrawLink(*r, x, y - wy, x + wx, y, baseNum *
00612 (1 << (2 * elt->level)));
00613 }
00614
00615 if (!IsLeaf())
00616 ApplyToChildren(&HRElem::DrawMatrixRec, dmi);
00617 #endif
00618 }
00619
00620
00621 Void HRMeshElem::EltSetVisPoints(HRElem *to, Point p[])
00622 {
00623 SetVisPoints(p);
00624 };
00625
00626 Void HRMeshElem::EltUpdateBounds(Point &min, Point &max)
00627 {
00628 UpdateBounds(Vertex(0), min, max);
00629 UpdateBounds(Vertex(1), min, max);
00630 UpdateBounds(Vertex(2), min, max);
00631 if (IsQuad())
00632 UpdateBounds(Vertex(3), min, max);
00633 }
00634
00635 Void HRMeshElem::DrawNodeElem(Renderer &r)
00636 {
00637 Int i;
00638
00639 if (flags.IsSet(hrMark))
00640 {
00641 flags.UnSet(hrMark);
00642 return;
00643 }
00644
00645 if (HasChildren()
00646 #ifdef RAD_VIS
00647 && !highlight
00648 #endif
00649 && (!gRadControl->choke || gRadControl->choke > level))
00650 for (i = 0; i < 4; i++)
00651 ((HRMeshElem*) child[i])->DrawElem(r);
00652 else
00653 DrawLeafElem(r);
00654 }
00655
00656 Void HRMeshElem::DrawLeafElem(Renderer &r)
00657 {
00658 DrawLeaf(r);
00659 }
00660
00661 Void HRMeshElem::HRCorrectLeaves()
00662 {
00663 if (IsLeaf())
00664 CorrectLeaves();
00665 else
00666 {
00667 Child(0)->HRCorrectLeaves();
00668 Child(1)->HRCorrectLeaves();
00669 Child(2)->HRCorrectLeaves();
00670 Child(3)->HRCorrectLeaves();
00671 }
00672 }
00673
00674 static GCLReal tRegSquareSamples[16][2] =
00675 {
00676 0.125, 0.125,
00677 0.375, 0.125,
00678 0.625, 0.125,
00679 0.875, 0.125,
00680 0.125, 0.375,
00681 0.375, 0.375,
00682 0.625, 0.375,
00683 0.875, 0.375,
00684 0.125, 0.625,
00685 0.375, 0.625,
00686 0.625, 0.625,
00687 0.875, 0.625,
00688 0.125, 0.875,
00689 0.375, 0.875,
00690 0.625, 0.875,
00691 0.875, 0.875,
00692 };
00693
00694 Void HRMeshElem::EltGetSamples(Int numSamples, Point pts[])
00695 {
00696 Int i;
00697 Vector dx, dy;
00698 Coord *samps;
00699 Point orig, sampPt;
00700
00701 dy = Vertex(0) - Vertex(1);
00702 dx = Vertex(2) - Vertex(1);
00703 orig = Vertex(1);
00704
00705 if (IsQuad())
00706 samps = (Coord *) tSquareSamples;
00707 else
00708 samps = (Coord *) tTriangleSamples;
00709
00710 for (i = 0; i < numSamples; i++)
00711 {
00712 sampPt = orig;
00713 sampPt += samps[i][0] * dx;
00714 sampPt += samps[i][1] * dy;
00715 pts[i] = sampPt;
00716 }
00717 }
00718
00719 Void HRMeshElem::SetHighlight(Int h)
00720 {
00721 #ifdef RAD_VIS
00722 HRElem::SetHighlight(h);
00723 RadElem::SetHighlight(h);
00724 #endif
00725 }