225 void VisualizationHelpers<Scalar, LocalOrdinal, GlobalOrdinal, Node>::doConvexHulls3D(std::vector<int>& vertices, std::vector<int>& geomSizes, LO numLocalAggs, LO numFineNodes,
const std::vector<bool>& ,
const ArrayRCP<LO>& vertex2AggId,
const Teuchos::ArrayRCP<
const typename Teuchos::ScalarTraits<Scalar>::coordinateType>& xCoords,
const Teuchos::ArrayRCP<
const typename Teuchos::ScalarTraits<Scalar>::coordinateType>& yCoords,
const Teuchos::ArrayRCP<
const typename Teuchos::ScalarTraits<Scalar>::coordinateType>& zCoords) {
230 typedef std::list<int>::iterator Iter;
231 for(
int agg = 0; agg < numLocalAggs; agg++) {
232 std::list<int> aggNodes;
233 for(
int i = 0; i < numFineNodes; i++) {
234 if(vertex2AggId[i] == agg)
235 aggNodes.push_back(i);
239 "CoarseningVisualization::doConvexHulls3D: aggregate contains zero nodes!");
240 if(aggNodes.size() == 1) {
241 vertices.push_back(aggNodes.front());
242 geomSizes.push_back(1);
244 }
else if(aggNodes.size() == 2) {
245 vertices.push_back(aggNodes.front());
246 vertices.push_back(aggNodes.back());
247 geomSizes.push_back(2);
251 bool areCollinear =
true;
253 Iter it = aggNodes.begin();
254 myVec3 firstVec(xCoords[*it], yCoords[*it], zCoords[*it]);
258 myVec3 secondVec(xCoords[*it], yCoords[*it], zCoords[*it]);
262 for(; it != aggNodes.end(); it++) {
263 myVec3 thisVec(xCoords[*it], yCoords[*it], zCoords[*it]);
266 areCollinear =
false;
275 Iter min = aggNodes.begin();
276 Iter max = aggNodes.begin();
277 Iter it = ++aggNodes.begin();
278 for(; it != aggNodes.end(); it++) {
279 if(xCoords[*it] < xCoords[*min]) min = it;
280 else if(xCoords[*it] == xCoords[*min]) {
281 if(yCoords[*it] < yCoords[*min]) min = it;
282 else if(yCoords[*it] == yCoords[*min]) {
283 if(zCoords[*it] < zCoords[*min]) min = it;
286 if(xCoords[*it] > xCoords[*max]) max = it;
287 else if(xCoords[*it] == xCoords[*max]) {
288 if(yCoords[*it] > yCoords[*max]) max = it;
289 else if(yCoords[*it] == yCoords[*max]) {
290 if(zCoords[*it] > zCoords[*max])
295 vertices.push_back(*min);
296 vertices.push_back(*max);
297 geomSizes.push_back(2);
300 bool areCoplanar =
true;
303 Iter vert = aggNodes.begin();
304 myVec3 v1(xCoords[*vert], yCoords[*vert], zCoords[*vert]);
306 myVec3 v2(xCoords[*vert], yCoords[*vert], zCoords[*vert]);
308 myVec3 v3(xCoords[*vert], yCoords[*vert], zCoords[*vert]);
313 v3 =
myVec3(xCoords[*vert], yCoords[*vert], zCoords[*vert]);
316 for(; vert != aggNodes.end(); vert++) {
317 myVec3 pt(xCoords[*vert], yCoords[*vert], zCoords[*vert]);
326 planeNorm.
x = fabs(planeNorm.
x);
327 planeNorm.
y = fabs(planeNorm.
y);
328 planeNorm.
z = fabs(planeNorm.
z);
329 std::vector<myVec2> points;
330 std::vector<int> nodes;
331 if(planeNorm.
x >= planeNorm.
y && planeNorm.
x >= planeNorm.
z) {
333 for(Iter it = aggNodes.begin(); it != aggNodes.end(); it++) {
334 nodes.push_back(*it);
335 points.push_back(
myVec2(yCoords[*it], zCoords[*it]));
338 if(planeNorm.
y >= planeNorm.
x && planeNorm.
y >= planeNorm.
z) {
340 for(Iter it = aggNodes.begin(); it != aggNodes.end(); it++) {
341 nodes.push_back(*it);
342 points.push_back(
myVec2(xCoords[*it], zCoords[*it]));
345 if(planeNorm.
z >= planeNorm.
x && planeNorm.
z >= planeNorm.
y) {
346 for(Iter it = aggNodes.begin(); it != aggNodes.end(); it++) {
347 nodes.push_back(*it);
348 points.push_back(
myVec2(xCoords[*it], yCoords[*it]));
351 std::vector<int> convhull2d =
giftWrap(points, nodes, xCoords, yCoords);
352 geomSizes.push_back(convhull2d.size());
353 vertices.reserve(vertices.size() + convhull2d.size());
354 for(
size_t i = 0; i < convhull2d.size(); i++)
355 vertices.push_back(convhull2d[i]);
359 Iter exIt = aggNodes.begin();
360 int extremeSix[] = {*exIt, *exIt, *exIt, *exIt, *exIt, *exIt};
362 for(; exIt != aggNodes.end(); exIt++) {
364 if(xCoords[*it] < xCoords[extremeSix[0]] ||
365 (xCoords[*it] == xCoords[extremeSix[0]] && yCoords[*it] < yCoords[extremeSix[0]]) ||
366 (xCoords[*it] == xCoords[extremeSix[0]] && yCoords[*it] == yCoords[extremeSix[0]] && zCoords[*it] < zCoords[extremeSix[0]]))
368 if(xCoords[*it] > xCoords[extremeSix[1]] ||
369 (xCoords[*it] == xCoords[extremeSix[1]] && yCoords[*it] > yCoords[extremeSix[1]]) ||
370 (xCoords[*it] == xCoords[extremeSix[1]] && yCoords[*it] == yCoords[extremeSix[1]] && zCoords[*it] > zCoords[extremeSix[1]]))
372 if(yCoords[*it] < yCoords[extremeSix[2]] ||
373 (yCoords[*it] == yCoords[extremeSix[2]] && zCoords[*it] < zCoords[extremeSix[2]]) ||
374 (yCoords[*it] == yCoords[extremeSix[2]] && zCoords[*it] == zCoords[extremeSix[2]] && xCoords[*it] < xCoords[extremeSix[2]]))
376 if(yCoords[*it] > yCoords[extremeSix[3]] ||
377 (yCoords[*it] == yCoords[extremeSix[3]] && zCoords[*it] > zCoords[extremeSix[3]]) ||
378 (yCoords[*it] == yCoords[extremeSix[3]] && zCoords[*it] == zCoords[extremeSix[3]] && xCoords[*it] > xCoords[extremeSix[3]]))
380 if(zCoords[*it] < zCoords[extremeSix[4]] ||
381 (zCoords[*it] == zCoords[extremeSix[4]] && xCoords[*it] < xCoords[extremeSix[4]]) ||
382 (zCoords[*it] == zCoords[extremeSix[4]] && xCoords[*it] == xCoords[extremeSix[4]] && yCoords[*it] < yCoords[extremeSix[4]]))
384 if(zCoords[*it] > zCoords[extremeSix[5]] ||
385 (zCoords[*it] == zCoords[extremeSix[5]] && xCoords[*it] > xCoords[extremeSix[5]]) ||
386 (zCoords[*it] == zCoords[extremeSix[5]] && xCoords[*it] == xCoords[extremeSix[5]] && yCoords[*it] > zCoords[extremeSix[5]]))
390 for(
int i = 0; i < 6; i++) {
391 myVec3 thisExtremeVec(xCoords[extremeSix[i]], yCoords[extremeSix[i]], zCoords[extremeSix[i]]);
392 extremeVectors[i] = thisExtremeVec;
397 for(
int i = 0; i < 5; i++) {
398 for(
int j = i + 1; j < 6; j++) {
399 double thisDist =
distance(extremeVectors[i], extremeVectors[j]);
401 if(thisDist > maxDist && thisDist - maxDist > 1e-12) {
408 std::list<myTriangle> hullBuilding;
410 aggNodes.remove(extremeSix[base1]);
411 aggNodes.remove(extremeSix[base2]);
414 tri.
v1 = extremeSix[base1];
415 tri.
v2 = extremeSix[base2];
419 myVec3 b1 = extremeVectors[base1];
420 myVec3 b2 = extremeVectors[base2];
422 for(Iter node = aggNodes.begin(); node != aggNodes.end(); node++) {
423 myVec3 nodePos(xCoords[*node], yCoords[*node], zCoords[*node]);
426 if(dist > maxDist && dist - maxDist > 1e-12) {
433 hullBuilding.push_back(tri);
434 myVec3 b3(xCoords[*thirdNode], yCoords[*thirdNode], zCoords[*thirdNode]);
435 aggNodes.erase(thirdNode);
438 int fourthVertex = -1;
439 for(Iter node = aggNodes.begin(); node != aggNodes.end(); node++) {
440 myVec3 thisNode(xCoords[*node], yCoords[*node], zCoords[*node]);
443 if(nodeDist > maxDist && nodeDist - maxDist > 1e-12) {
445 fourthVertex = *node;
448 aggNodes.remove(fourthVertex);
449 myVec3 b4(xCoords[fourthVertex], yCoords[fourthVertex], zCoords[fourthVertex]);
452 tri = hullBuilding.front();
453 tri.
v1 = fourthVertex;
454 hullBuilding.push_back(tri);
455 tri = hullBuilding.front();
456 tri.
v2 = fourthVertex;
457 hullBuilding.push_back(tri);
458 tri = hullBuilding.front();
459 tri.
v3 = fourthVertex;
460 hullBuilding.push_back(tri);
462 myVec3 barycenter((b1.
x + b2.
x + b3.
x + b4.
x) / 4.0, (b1.
y + b2.
y + b3.
y + b4.
y) / 4.0, (b1.
z + b2.
z + b3.
z + b4.
z) / 4.0);
463 for(std::list<myTriangle>::iterator tetTri = hullBuilding.begin(); tetTri != hullBuilding.end(); tetTri++) {
464 myVec3 triVert1(xCoords[tetTri->v1], yCoords[tetTri->v1], zCoords[tetTri->v1]);
465 myVec3 triVert2(xCoords[tetTri->v2], yCoords[tetTri->v2], zCoords[tetTri->v2]);
466 myVec3 triVert3(xCoords[tetTri->v3], yCoords[tetTri->v3], zCoords[tetTri->v3]);
468 myVec3 ptInPlane = tetTri == hullBuilding.begin() ? b1 : b4;
469 if(
isInFront(barycenter, ptInPlane, trinorm)) {
472 int temp = tetTri->v1;
473 tetTri->v1 = tetTri->v2;
485 for(std::list<myTriangle>::iterator tetTri = hullBuilding.begin(); tetTri != hullBuilding.end(); tetTri++) {
486 myVec3 triVert1(xCoords[tetTri->v1], yCoords[tetTri->v1], zCoords[tetTri->v1]);
487 myVec3 triVert2(xCoords[tetTri->v2], yCoords[tetTri->v2], zCoords[tetTri->v2]);
488 myVec3 triVert3(xCoords[tetTri->v3], yCoords[tetTri->v3], zCoords[tetTri->v3]);
489 trinorms[index] =
getNorm(triVert1, triVert2, triVert3);
492 std::list<int> startPoints1;
493 std::list<int> startPoints2;
494 std::list<int> startPoints3;
495 std::list<int> startPoints4;
498 Iter point = aggNodes.begin();
499 while(!aggNodes.empty())
501 myVec3 pointVec(xCoords[*point], yCoords[*point], zCoords[*point]);
504 if(
isInFront(pointVec, b1, trinorms[0])) {
505 startPoints1.push_back(*point);
506 point = aggNodes.erase(point);
507 }
else if(
isInFront(pointVec, b4, trinorms[1])) {
508 startPoints2.push_back(*point);
509 point = aggNodes.erase(point);
510 }
else if(
isInFront(pointVec, b4, trinorms[2])) {
511 startPoints3.push_back(*point);
512 point = aggNodes.erase(point);
513 }
else if(
isInFront(pointVec, b4, trinorms[3])) {
514 startPoints4.push_back(*point);
515 point = aggNodes.erase(point);
517 point = aggNodes.erase(point);
522 typedef std::list<myTriangle>::iterator TriIter;
523 TriIter firstTri = hullBuilding.begin();
532 if(!startPoints1.empty())
533 processTriangle(hullBuilding, start1, startPoints1, barycenter, xCoords, yCoords, zCoords);
534 if(!startPoints2.empty())
535 processTriangle(hullBuilding, start2, startPoints2, barycenter, xCoords, yCoords, zCoords);
536 if(!startPoints3.empty())
537 processTriangle(hullBuilding, start3, startPoints3, barycenter, xCoords, yCoords, zCoords);
538 if(!startPoints4.empty())
539 processTriangle(hullBuilding, start4, startPoints4, barycenter, xCoords, yCoords, zCoords);
542 vertices.reserve(vertices.size() + 3 * hullBuilding.size());
543 for(TriIter hullTri = hullBuilding.begin(); hullTri != hullBuilding.end(); hullTri++) {
544 vertices.push_back(hullTri->v1);
545 vertices.push_back(hullTri->v2);
546 vertices.push_back(hullTri->v3);
547 geomSizes.push_back(3);
716 typedef std::list<int>::iterator Iter;
717 typedef std::list<myTriangle>::iterator TriIter;
718 typedef list<pair<int, int> >::iterator EdgeIter;
721 myVec3 v1(xCoords[tri.
v1], yCoords[tri.
v1], zCoords[tri.
v1]);
722 myVec3 v2(xCoords[tri.
v2], yCoords[tri.
v2], zCoords[tri.
v2]);
723 myVec3 v3(xCoords[tri.
v3], yCoords[tri.
v3], zCoords[tri.
v3]);
725 Iter farPoint = pointsInFront.begin();
726 for(Iter point = pointsInFront.begin(); point != pointsInFront.end(); point++)
728 myVec3 pointVec(xCoords[*point], yCoords[*point], zCoords[*point]);
731 if(dist > maxDist && dist - maxDist > 1e-12)
734 farPointVec = pointVec;
740 vector<myTriangle> visible;
741 for(TriIter it = tris.begin(); it != tris.end();)
743 myVec3 vec1(xCoords[it->v1], yCoords[it->v1], zCoords[it->v1]);
744 myVec3 vec2(xCoords[it->v2], yCoords[it->v2], zCoords[it->v2]);
745 myVec3 vec3(xCoords[it->v3], yCoords[it->v3], zCoords[it->v3]);
749 visible.push_back(*it);
757 list<pair<int, int> > horizon;
760 for(vector<myTriangle>::iterator it = visible.begin(); it != visible.end(); it++)
762 pair<int, int> e1(it->v1, it->v2);
763 pair<int, int> e2(it->v2, it->v3);
764 pair<int, int> e3(it->v1, it->v3);
766 if(e1.first > e1.second)
769 e1.first = e1.second;
772 if(e2.first > e2.second)
775 e2.first = e2.second;
778 if(e3.first > e3.second)
781 e3.first = e3.second;
784 horizon.push_back(e1);
785 horizon.push_back(e2);
786 horizon.push_back(e3);
792 EdgeIter it = horizon.begin();
793 while(it != horizon.end())
795 int occur = count(horizon.begin(), horizon.end(), *it);
798 pair<int, int> removeVal = *it;
799 while(removeVal == *it && !(it == horizon.end()))
800 it = horizon.erase(it);
807 list<myTriangle> newTris;
808 for(EdgeIter it = horizon.begin(); it != horizon.end(); it++)
810 myTriangle t(it->first, it->second, *farPoint);
811 newTris.push_back(t);
814 vector<myTriangle> trisToProcess;
815 vector<list<int> > newFrontPoints;
816 for(TriIter it = newTris.begin(); it != newTris.end(); it++)
818 myVec3 t1(xCoords[it->v1], yCoords[it->v1], zCoords[it->v1]);
819 myVec3 t2(xCoords[it->v2], yCoords[it->v2], zCoords[it->v2]);
820 myVec3 t3(xCoords[it->v3], yCoords[it->v3], zCoords[it->v3]);
834 trisToProcess.push_back(tris.back());
836 list<int> newInFront;
837 for(Iter point = pointsInFront.begin(); point != pointsInFront.end();)
839 myVec3 pointVec(xCoords[*point], yCoords[*point], zCoords[*point]);
842 newInFront.push_back(*point);
843 point = pointsInFront.erase(point);
848 newFrontPoints.push_back(newInFront);
850 vector<myTriangle> allRemoved;
851 for(
int i = 0; i < int(trisToProcess.size()); i++)
853 if(!newFrontPoints[i].empty())
857 if(find(allRemoved.begin(), allRemoved.end(), trisToProcess[i]) == allRemoved.end() && !(trisToProcess[i] == tri))
859 vector<myTriangle> removedList =
processTriangle(tris, trisToProcess[i], newFrontPoints[i], barycenter, xCoords, yCoords, zCoords);
860 for(
int j = 0; j < int(removedList.size()); j++)
861 allRemoved.push_back(removedList[j]);