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 }