42template<
typename G,
typename I>
52 vector<WVertex *> &faceVertices)
54 WFace *face =
nullptr;
67 Vec3r v(-u[0], -u[1], -u[2]);
68 bool noIntersection =
true;
71 for (occluders.initAfterTarget(); occluders.validAfterTarget(); occluders.nextOccludee()) {
74 cout <<
"\t\tEvaluating intersection for occludee " << occluders.getWFace() <<
" and ray "
75 << A <<
" * " << u << endl;
78 oface = occluders.getWFace();
79 Polygon3r *p = occluders.getCameraSpacePolygon();
83 if (
nullptr != face) {
90 if (faceVertices.empty()) {
94 for (vector<WVertex *>::iterator fv = faceVertices.begin(), fvend = faceVertices.end();
98 if ((*fv)->isBoundary()) {
103 for (ie = iebegin; ie != ieend; ++ie) {
104 if ((*ie) ==
nullptr) {
108 WFace *sface = (*ie)->GetbFace();
109 if (sface == oface) {
131 cout <<
"\t\tRejecting occluder for target coincidence." << endl;
141 cout <<
"\t\tRay " << A <<
" * " <<
v <<
" intersects at time " << t << endl;
142 cout <<
"\t\t(v * normal) == " << (
v * p->
getNormal()) <<
" for normal "
151 noIntersection =
false;
155 cout <<
"\t\tIs occludee" << endl;
162 occluders.reportDepth(A,
v, t);
166 if (noIntersection) {
172template<
typename G,
typename I>
178 A =
Vec3r(((fe)->vertexA()->point3D() + (fe)->vertexB()->point3D()) / 2.0);
179 edgeDir =
Vec3r((fe)->vertexB()->point3D() - (fe)->vertexA()->point3D());
181 origin =
Vec3r((fe)->vertexA()->point3D());
183 if (grid.orthographicProjection()) {
184 u =
Vec3r(0.0, 0.0, grid.viewpoint().z() - A.z());
187 u =
Vec3r(grid.viewpoint() - A);
191 vector<WVertex *> faceVertices;
193 WFace *face =
nullptr;
200 face->RetrieveVertexList(faceVertices);
203 I occluders(grid, A, epsilon);
204 findOccludee<G, I>(fe, grid, occluders, epsilon, oaFace, u, A, origin, edgeDir, faceVertices);
209template<
typename G,
typename I>
216 set<ViewShape *> *foundOccluders)
230 if (grid.orthographicProjection()) {
231 vp =
Vec3r(center.
x(), center.
y(), grid.viewpoint().z());
234 vp =
Vec3r(grid.viewpoint());
236 Vec3r u(vp - center);
240 WFace *face =
nullptr;
245 vector<WVertex *> faceVertices;
255 I occluders(grid, center, epsilon);
257 for (occluders.initBeforeTarget(); occluders.validBeforeTarget(); occluders.nextOccluder()) {
262 oface = occluders.getWFace();
263 Polygon3r *p = occluders.getCameraSpacePolygon();
267 cout <<
"\t\tEvaluating intersection for occluder " << (p->
getVertices())[0]
269 <<
"\t\t\tand ray " << vp <<
" * " << u <<
" (center " << center <<
")" << endl;
277 vector<Vec3r> points;
279 for (vector<WOEdge *>::const_iterator woe = oface->
getEdgeList().begin(),
284 points.push_back(
Vec3r((*woe)->GetaVertex()->GetVertex()));
302 cout <<
"\t\tDetermining face adjacency...";
310 cout <<
" Rejecting occluder for face concurrency." << endl;
316 for (vector<WVertex *>::iterator fv = faceVertices.begin(), fvend = faceVertices.end();
320 if ((*fv)->isBoundary()) {
326 for (ie = iebegin; ie != ieend; ++ie) {
327 if ((*ie) ==
nullptr) {
331 WFace *sface = (*ie)->GetbFace();
334 if (sface == oface) {
346 cout <<
" Rejecting occluder for face adjacency." << endl;
361 cout <<
"\t\tRejecting occluder for target coincidence." << endl;
372 cout <<
"\t\tRay should intersect at time " << (rl -
x) <<
". Center: " << center
373 <<
", V: " <<
v <<
", RL: " << rl <<
", T:" << x << endl;
376 cout <<
"\t\tRay should not intersect. Center: " << center <<
", V: " <<
v
377 <<
", RL: " << rl << endl;
385 cout <<
"\t\tRay " << center <<
" * " << u <<
" intersects at time " << t
386 <<
" (raylength is " << raylength <<
")" << endl;
387 cout <<
"\t\t(u * normal) == " << (u * p->
getNormal()) <<
" for normal " << p->
getNormal()
392 if ((t > 0.0) && (t < raylength)) {
395 cout <<
"\t\tIs occluder" << endl;
398 if (foundOccluders !=
nullptr) {
400 foundOccluders->insert(vshape);
404 if (!grid.enableQI()) {
409 occluders.reportDepth(center, u, t);
416 fe, grid, occluders, epsilon, oaWFace, u, center, origin, edgeDir, faceVertices);
430template<
typename G,
typename I>
436 vector<ViewEdge *> &vedges = ioViewMap->
ViewEdges();
440 vector<WFace *> wFaces;
441 WFace *wFace =
nullptr;
446 uint maxIndex, maxCard;
448 for (vector<ViewEdge *>::iterator ve = vedges.begin(), veend = vedges.end(); ve != veend; ve++) {
449 if (iRenderMonitor) {
453 if (
count % count_step == 0) {
455 ss <<
"Freestyle: Visibility computations " << (100 *
count / vedges.size()) <<
"%";
456 iRenderMonitor->
setInfo(ss.str());
463 cout <<
"Processing ViewEdge " << (*ve)->getId() << endl;
467 if (!(*ve)->isInImage()) {
470 (*ve)->setaShape(
nullptr);
473 cout <<
"\tCulled." << endl;
480 festart = (*ve)->fedgeA();
481 fe = (*ve)->fedgeA();
488 }
while (fe && fe != festart);
490 if (qiMajority == 0) {
494 cout <<
"View Edge in viewport without occludable FEdges: " << (*ve)->
getId() << endl;
499 (*ve)->setaShape(
nullptr);
508 cout <<
"\tqiMajority: " << qiMajority << endl;
516 memset(qiClasses, 0, 256 *
sizeof(*qiClasses));
517 set<ViewShape *> foundOccluders;
519 fe = (*ve)->fedgeA();
525 if (maxCard < qiMajority) {
528 ioViewMap, fe, grid, epsilon, *ve, &wFace, &foundOccluders);
531 cout <<
"\tFEdge: visibility " << tmpQI << endl;
538 cerr <<
"Warning: too many occluding levels" << endl;
543 if (++qiClasses[tmpQI] > maxCard) {
544 maxCard = qiClasses[tmpQI];
554 cout <<
"\tFEdge: occludee only (" << (wFace !=
nullptr ?
"found" :
"not found") <<
")"
562 vector<Vec3r> vertices;
563 for (
int i = 0, numEdges = wFace->
numberOfEdges(); i < numEdges; ++i) {
567 poly.userdata = (
void *)wFace;
569 wFaces.push_back(wFace);
573 cout <<
"\tFound occludee" << endl;
583 }
while ((maxCard < qiMajority) && (fe) && (fe != festart));
587 cout <<
"\tFinished with " << nSamples <<
" samples, maxCard = " << maxCard << endl;
594 for (
uint count = 0, i = 0; i < 256; ++i) {
595 count += qiClasses[i];
596 if (
count >= qiMajority) {
604 for (set<ViewShape *>::iterator o = foundOccluders.begin(), oend = foundOccluders.end();
608 (*ve)->AddOccluder(*o);
612 cout <<
"\tConclusion: QI = " << maxIndex <<
", " << (*ve)->
occluders_size() <<
" occluders."
619 if (!wFaces.empty()) {
620 if (wFaces.size() <=
float(nSamples) / 2.0f) {
621 (*ve)->setaShape(
nullptr);
625 (*wFaces.begin())->GetVertex(0)->shape()->GetId());
626 (*ve)->setaShape(vshape);
632 if (iRenderMonitor && !vedges.empty()) {
634 ss <<
"Freestyle: Visibility computations " << (100 *
count / vedges.size()) <<
"%";
635 iRenderMonitor->
setInfo(ss.str());
640template<
typename G,
typename I>
646 vector<ViewEdge *> &vedges = ioViewMap->
ViewEdges();
650 vector<WFace *> wFaces;
651 WFace *wFace =
nullptr;
654 uint maxIndex, maxCard;
656 for (vector<ViewEdge *>::iterator ve = vedges.begin(), veend = vedges.end(); ve != veend; ve++) {
657 if (iRenderMonitor && iRenderMonitor->
testBreak()) {
662 cout <<
"Processing ViewEdge " << (*ve)->getId() << endl;
666 if (!(*ve)->isInImage()) {
669 (*ve)->setaShape(
nullptr);
672 cout <<
"\tCulled." << endl;
679 festart = (*ve)->fedgeA();
680 fe = (*ve)->fedgeA();
687 }
while (fe && fe != festart);
689 if (qiMajority == 0) {
693 cout <<
"View Edge in viewport without occludable FEdges: " << (*ve)->
getId() << endl;
698 (*ve)->setaShape(
nullptr);
707 cout <<
"\tqiMajority: " << qiMajority << endl;
715 memset(qiClasses, 0, 256 *
sizeof(*qiClasses));
716 set<ViewShape *> foundOccluders;
718 fe = (*ve)->fedgeA();
724 if (maxCard < qiMajority) {
727 ioViewMap, fe, grid, epsilon, *ve, &wFace, &foundOccluders);
730 cout <<
"\tFEdge: visibility " << tmpQI << endl;
737 cerr <<
"Warning: too many occluding levels" << endl;
742 if (++qiClasses[tmpQI] > maxCard) {
743 maxCard = qiClasses[tmpQI];
753 cout <<
"\tFEdge: occludee only (" << (wFace !=
nullptr ?
"found" :
"not found") <<
")"
761 vector<Vec3r> vertices;
762 for (
int i = 0, numEdges = wFace->
numberOfEdges(); i < numEdges; ++i) {
766 poly.userdata = (
void *)wFace;
768 wFaces.push_back(wFace);
772 cout <<
"\tFound occludee" << endl;
782 }
while ((maxCard < qiMajority) && (fe) && (fe != festart));
786 cout <<
"\tFinished with " << nSamples <<
" samples, maxCard = " << maxCard << endl;
792 (*ve)->setQI(maxIndex);
796 for (set<ViewShape *>::iterator o = foundOccluders.begin(), oend = foundOccluders.end();
800 (*ve)->AddOccluder(*o);
804 cout <<
"\tConclusion: QI = " << maxIndex <<
", " << (*ve)->
occluders_size() <<
" occluders."
809 if (!wFaces.empty()) {
810 if (wFaces.size() <=
float(nSamples) / 2.0f) {
811 (*ve)->setaShape(
nullptr);
815 (*wFaces.begin())->GetVertex(0)->shape()->GetId());
816 (*ve)->setaShape(vshape);
824template<
typename G,
typename I>
827 vector<ViewEdge *> &vedges = ioViewMap->
ViewEdges();
831 vector<WFace *> wFaces;
832 WFace *wFace =
nullptr;
835 uint maxIndex, maxCard;
838 for (vector<ViewEdge *>::iterator ve = vedges.begin(), veend = vedges.end(); ve != veend; ve++) {
840 if (!(*ve)->isInImage()) {
843 (*ve)->setaShape(
nullptr);
848 festart = (*ve)->fedgeA();
849 fe = (*ve)->fedgeA();
854 if (even_test && fe && fe->
isInImage()) {
856 even_test = !even_test;
859 }
while (fe && fe != festart);
861 if (qiMajority == 0) {
865 cout <<
"View Edge in viewport without occludable FEdges: " << (*ve)->
getId() << endl;
870 (*ve)->setaShape(
nullptr);
881 memset(qiClasses, 0, 256 *
sizeof(*qiClasses));
882 set<ViewShape *> foundOccluders;
884 fe = (*ve)->fedgeA();
891 if (maxCard < qiMajority) {
894 ioViewMap, fe, grid, epsilon, *ve, &wFace, &foundOccluders);
899 cerr <<
"Warning: too many occluding levels" << endl;
904 if (++qiClasses[tmpQI] > maxCard) {
905 maxCard = qiClasses[tmpQI];
916 vector<Vec3r> vertices;
917 for (
int i = 0, numEdges = wFace->
numberOfEdges(); i < numEdges; ++i) {
921 poly.userdata = (
void *)wFace;
923 wFaces.push_back(wFace);
928 even_test = !even_test;
930 }
while ((maxCard < qiMajority) && (fe) && (fe != festart));
933 (*ve)->setQI(maxIndex);
936 for (set<ViewShape *>::iterator o = foundOccluders.begin(), oend = foundOccluders.end();
940 (*ve)->AddOccluder(*o);
944 if (!wFaces.empty()) {
945 if (wFaces.size() < nSamples / 2) {
946 (*ve)->setaShape(
nullptr);
950 (*wFaces.begin())->GetVertex(0)->shape()->GetId());
951 (*ve)->setaShape(vshape);
959template<
typename G,
typename I>
962 vector<ViewEdge *> &vedges = ioViewMap->
ViewEdges();
966 WFace *wFace =
nullptr;
968 for (vector<ViewEdge *>::iterator ve = vedges.begin(), veend = vedges.end(); ve != veend; ve++) {
970 if (!(*ve)->isInImage()) {
973 (*ve)->setaShape(
nullptr);
976 fe = (*ve)->fedgeA();
979 while (fe && !fe->
isInImage() && fe != festart) {
988 cout <<
"View Edge in viewport without occludable FEdges: " << (*ve)->
getId() << endl;
1001 vector<Vec3r> vertices;
1002 for (
int i = 0, numEdges = wFace->
numberOfEdges(); i < numEdges; ++i) {
1006 poly.userdata = (
void *)wFace;
1009 (*ve)->setaShape(vshape);
1012 (*ve)->setaShape(
nullptr);
1022 for (
uint i = 0; i < 3; i++) {
1026 size[i] += size[i] / 10.0;
1029 cout <<
"Warning: the bbox size is 0 in dimension " << i << endl;
1052 _currentSVertexId = 0;
1071 return ::hypot((point[0] - origin[0]), (point[1] - origin[1]));
1076 Vec2r min(proscenium[0], proscenium[2]);
1077 Vec2r max(proscenium[1], proscenium[3]);
1086 return !(point[0] < proscenium[0] || point[0] > proscenium[1] || point[1] < proscenium[2] ||
1087 point[1] > proscenium[3]);
1091 real viewProscenium[4],
1092 real occluderProscenium[4],
1093 bool extensiveFEdgeSearch)
1105 real prosceniumOrigin[2];
1106 prosceniumOrigin[0] = (viewProscenium[1] - viewProscenium[0]) / 2.0;
1107 prosceniumOrigin[1] = (viewProscenium[3] - viewProscenium[2]) / 2.0;
1109 cout <<
"Proscenium culling:" << endl;
1110 cout <<
"Proscenium: [" << viewProscenium[0] <<
", " << viewProscenium[1] <<
", "
1111 << viewProscenium[2] <<
", " << viewProscenium[3] <<
"]" << endl;
1112 cout <<
"Origin: [" << prosceniumOrigin[0] <<
", " << prosceniumOrigin[1] <<
"]" << endl;
1125 ViewMap::viewedges_container::iterator ve, veend;
1127 for (ve = ioViewMap->
ViewEdges().begin(), veend = ioViewMap->
ViewEdges().end(); ve != veend;
1139 bool bestOccluderTargetFound =
false;
1140 FEdge *bestOccluderTarget =
nullptr;
1141 real bestOccluderDistance = 0.0;
1142 FEdge *festart = (*ve)->fedgeA();
1143 FEdge *fe = festart;
1154 if (!bestOccluderTargetFound) {
1160 bestOccluderTargetFound =
true;
1161 bestOccluderTarget = fe;
1166 if (bestOccluderTarget ==
nullptr || d < bestOccluderDistance) {
1168 bestOccluderDistance = d;
1169 bestOccluderTarget = fe;
1180 }
while (fe && fe != festart && !(bestOccluderTargetFound && (*ve)->isInImage()));
1184 while (fe && fe != festart) {
1191 if ((*ve)->isInImage() && bestOccluderTarget !=
nullptr && !bestOccluderTargetFound) {
1194 if (point[0] < occluderProscenium[0]) {
1195 occluderProscenium[0] = point[0];
1197 else if (point[0] > occluderProscenium[1]) {
1198 occluderProscenium[1] = point[0];
1200 if (point[1] < occluderProscenium[2]) {
1201 occluderProscenium[2] = point[1];
1203 else if (point[1] > occluderProscenium[3]) {
1204 occluderProscenium[3] = point[1];
1213 const real epsilon = 1.0e-6;
1214 occluderProscenium[0] -= epsilon;
1215 occluderProscenium[1] += epsilon;
1216 occluderProscenium[2] -= epsilon;
1217 occluderProscenium[3] += epsilon;
1230 if (extensiveFEdgeSearch) {
1232 for (ve = ioViewMap->
ViewEdges().begin(), veend = ioViewMap->
ViewEdges().end(); ve != veend;
1235 if (!(*ve)->isInImage()) {
1239 FEdge *festart = (*ve)->fedgeA();
1240 FEdge *fe = festart;
1248 }
while (fe && fe != festart);
1258 for (vector<WShape *>::const_iterator it = wshapes.begin(); it != wshapes.end(); it++) {
1259 if (_pRenderMonitor && _pRenderMonitor->
testBreak()) {
1265 psShape->
setId((*it)->GetId());
1266 psShape->
setName((*it)->getName());
1289 _currentFId = _pViewEdgeBuilder->
currentFId() + 1;
1298 vector<ViewEdge *> newVEdges;
1300 ViewMap::viewedges_container::iterator ve = vedges.begin(), veend = vedges.end();
1301 for (; ve != veend; ++ve) {
1302 if (_pRenderMonitor && _pRenderMonitor->
testBreak()) {
1308 FEdge *fe = (*ve)->fedgeA();
1309 FEdge *fefirst = fe;
1311 bool positive =
true;
1314 Vec3r A((fes)->vertexA()->point3d());
1315 Vec3r B((fes)->vertexB()->point3d());
1319 Vec3r crossP(AB ^ (fes)->normal());
1322 if (_orthographicProjection) {
1323 viewvector =
Vec3r(0.0, 0.0, m.
z() - _viewpoint.
z());
1326 viewvector =
Vec3r(m - _viewpoint);
1330 if (((crossP) * (viewvector)) > 0) {
1341 if (((crossP) * (viewvector)) < -0.1) {
1354 if (((crossP) * (viewvector)) > 0.1) {
1364 }
while (fe && fe != fefirst);
1366 for (ve = newVEdges.begin(), veend = newVEdges.end(); ve != veend; ++ve) {
1367 (*ve)->viewShape()->AddEdge(*ve);
1368 vedges.push_back(*ve);
1382 if (_orthographicProjection) {
1383 transform = std::make_unique<BoxGrid::Transform>();
1386 transform = std::make_unique<SphericalGrid::Transform>();
1390 source = std::make_unique<CulledOccluderSource>(*transform, we, *ioViewMap,
true);
1393 source = std::make_unique<OccluderSource>(*transform, we);
1398 if (_orthographicProjection) {
1399 BoxGrid grid(*source, *density, ioViewMap, _viewpoint, _EnableQI);
1401 ioViewMap, grid, epsilon, _pRenderMonitor);
1404 SphericalGrid grid(*source, *density, ioViewMap, _viewpoint, _EnableQI);
1406 ioViewMap, grid, epsilon, _pRenderMonitor);
1420 if (_orthographicProjection) {
1421 transform = std::make_unique<BoxGrid::Transform>();
1424 transform = std::make_unique<SphericalGrid::Transform>();
1428 source = std::make_unique<CulledOccluderSource>(*transform, we, *ioViewMap,
true);
1431 source = std::make_unique<OccluderSource>(*transform, we);
1436 if (_orthographicProjection) {
1437 BoxGrid grid(*source, *density, ioViewMap, _viewpoint, _EnableQI);
1439 ioViewMap, grid, epsilon, _pRenderMonitor);
1442 SphericalGrid grid(*source, *density, ioViewMap, _viewpoint, _EnableQI);
1444 ioViewMap, grid, epsilon, _pRenderMonitor);
1461 cout <<
"Using ordinary ray casting" << endl;
1468 cout <<
"Using fast ray casting" << endl;
1475 cout <<
"Using very fast ray casting" << endl;
1482 cout <<
"Using culled adaptive grid with heuristic density and traditional QI calculation"
1505 <<
"Using unculled adaptive grid with heuristic density and traditional QI calculation"
1518 cout <<
"Using culled adaptive grid with heuristic density and cumulative QI calculation"
1531 cout <<
"Using unculled adaptive grid with heuristic density and cumulative QI calculation"
1552 vector<ViewEdge *> &vedges = ioViewMap->
ViewEdges();
1553 bool progressBarDisplay =
false;
1554 uint progressBarStep = 0;
1555 uint vEdgesSize = vedges.size();
1556 uint fEdgesSize = ioViewMap->
FEdges().size();
1560 progressBarStep = vEdgesSize / progressBarSteps;
1561 _pProgressBar->
reset();
1562 _pProgressBar->
setLabelText(
"Computing Ray casting Visibility");
1565 progressBarDisplay =
true;
1568 uint counter = progressBarStep;
1569 FEdge *fe, *festart;
1571 vector<Polygon3r *> aFaces;
1574 uint qiClasses[256];
1575 uint maxIndex, maxCard;
1577 static uint timestamp = 1;
1578 for (vector<ViewEdge *>::iterator ve = vedges.begin(), veend = vedges.end(); ve != veend; ve++) {
1579 if (_pRenderMonitor && _pRenderMonitor->
testBreak()) {
1584 cout <<
"Processing ViewEdge " << (*ve)->
getId() << endl;
1587 festart = (*ve)->fedgeA();
1588 fe = (*ve)->fedgeA();
1593 }
while (fe && fe != festart);
1597 cout <<
"\tqiMajority: " << qiMajority << endl;
1605 fe = (*ve)->fedgeA();
1606 memset(qiClasses, 0, 256 *
sizeof(*qiClasses));
1607 set<ViewShape *> occluders;
1609 if (maxCard < qiMajority) {
1614 cout <<
"\tFEdge: visibility " << tmpQI << endl;
1620 cerr <<
"Warning: too many occluding levels" << endl;
1625 if (++qiClasses[tmpQI] > maxCard) {
1626 maxCard = qiClasses[tmpQI];
1635 cout <<
"\tFEdge: occludee only (" << (aFace !=
nullptr ?
"found" :
"not found") <<
")"
1643 aFaces.push_back(aFace);
1647 cout <<
"\tFound occludee" << endl;
1661 }
while ((maxCard < qiMajority) && (fe) && (fe != festart));
1664 cout <<
"\tFinished with " << nSamples <<
" samples, maxCard = " << maxCard << endl;
1670 (*ve)->setQI(maxIndex);
1672 for (set<ViewShape *>::iterator o = occluders.begin(), oend = occluders.end(); o != oend; ++o)
1674 (*ve)->AddOccluder(*o);
1678 cout <<
"\tConclusion: QI = " << maxIndex <<
", " << (*ve)->
occluders_size() <<
" occluders."
1683 if (!aFaces.empty()) {
1684 if (aFaces.size() <=
float(nSamples) / 2.0f) {
1685 (*ve)->setaShape(
nullptr);
1688 vector<Polygon3r *>::iterator p = aFaces.begin();
1692 (*ve)->setaShape(vshape);
1696 if (progressBarDisplay) {
1699 counter = progressBarStep;
1709 vector<ViewEdge *> &vedges = ioViewMap->
ViewEdges();
1710 bool progressBarDisplay =
false;
1711 uint progressBarStep = 0;
1712 uint vEdgesSize = vedges.size();
1713 uint fEdgesSize = ioViewMap->
FEdges().size();
1717 progressBarStep = vEdgesSize / progressBarSteps;
1718 _pProgressBar->
reset();
1719 _pProgressBar->
setLabelText(
"Computing Ray casting Visibility");
1722 progressBarDisplay =
true;
1725 uint counter = progressBarStep;
1726 FEdge *fe, *festart;
1728 vector<Polygon3r *> aFaces;
1731 uint qiClasses[256];
1732 uint maxIndex, maxCard;
1734 static uint timestamp = 1;
1736 for (vector<ViewEdge *>::iterator ve = vedges.begin(), veend = vedges.end(); ve != veend; ve++) {
1737 if (_pRenderMonitor && _pRenderMonitor->
testBreak()) {
1741 festart = (*ve)->fedgeA();
1742 fe = (*ve)->fedgeA();
1747 }
while (fe && fe != festart);
1748 if (qiMajority >= 4) {
1755 set<ViewShape *> occluders;
1761 memset(qiClasses, 0, 256 *
sizeof(*qiClasses));
1762 fe = (*ve)->fedgeA();
1765 if (maxCard < qiMajority) {
1771 cerr <<
"Warning: too many occluding levels" << endl;
1776 if (++qiClasses[tmpQI] > maxCard) {
1777 maxCard = qiClasses[tmpQI];
1788 aFaces.push_back(aFace);
1797 }
while ((maxCard < qiMajority) && (fe) && (fe != festart));
1799 (*ve)->setQI(maxIndex);
1801 if (!aFaces.empty()) {
1802 if (aFaces.size() < nSamples / 2) {
1803 (*ve)->setaShape(
nullptr);
1806 vector<Polygon3r *>::iterator p = aFaces.begin();
1811 for (; p != pend; ++p) {
1822 (*ve)->setaShape(vshape);
1829 if (progressBarDisplay) {
1832 counter = progressBarStep;
1842 vector<ViewEdge *> &vedges = ioViewMap->
ViewEdges();
1843 bool progressBarDisplay =
false;
1844 uint progressBarStep = 0;
1845 uint vEdgesSize = vedges.size();
1846 uint fEdgesSize = ioViewMap->
FEdges().size();
1850 progressBarStep = vEdgesSize / progressBarSteps;
1851 _pProgressBar->
reset();
1852 _pProgressBar->
setLabelText(
"Computing Ray casting Visibility");
1855 progressBarDisplay =
true;
1858 uint counter = progressBarStep;
1862 static uint timestamp = 1;
1863 for (vector<ViewEdge *>::iterator ve = vedges.begin(), veend = vedges.end(); ve != veend; ve++) {
1864 if (_pRenderMonitor && _pRenderMonitor->
testBreak()) {
1868 set<ViewShape *> occluders;
1870 fe = (*ve)->fedgeA();
1876 (*ve)->setaShape(vshape);
1879 (*ve)->setaShape(
nullptr);
1884 if (progressBarDisplay) {
1887 counter = progressBarStep;
1903 vector<WVertex *> &faceVertices)
1905 WFace *face =
nullptr;
1915 OccludersSet::iterator p, pend;
1917 *oaPolygon =
nullptr;
1921 Vec3r v(-u[0], -u[1], -u[2]);
1924 bool noIntersection =
true;
1927 for (p = occluders.begin(), pend = occluders.end(); p != pend; p++) {
1932 Vec3r v1((*p)->getVertices()[0]);
1933 Vec3r normal((*p)->getNormal());
1934 real d = -(v1 * normal);
1940 if (face == oface) {
1944 if (faceVertices.empty()) {
1948 for (vector<WVertex *>::iterator fv = faceVertices.begin(), fvend = faceVertices.end();
1952 if ((*fv)->isBoundary()) {
1957 for (ie = iebegin; ie != ieend; ++ie) {
1958 if ((*ie) ==
nullptr) {
1962 WFace *sface = (*ie)->GetbFace();
1963 if (sface == oface) {
1983 if ((*p)->rayIntersect(A,
v, t, t_u, t_v)) {
1984 if (
fabs(
v * normal) > 0.0001) {
1989 noIntersection =
false;
1997 if (noIntersection) {
1998 *oaPolygon =
nullptr;
2009 A =
Vec3r(((fe)->vertexA()->point3D() + (fe)->vertexB()->point3D()) / 2.0);
2010 edgeDir =
Vec3r((fe)->vertexB()->point3D() - (fe)->vertexA()->point3D());
2012 origin =
Vec3r((fe)->vertexA()->point3D());
2014 if (_orthographicProjection) {
2015 u =
Vec3r(0.0, 0.0, _viewpoint.
z() - A.z());
2018 u =
Vec3r(_viewpoint - A);
2022 cerr <<
"Warning: point is out of the grid for fedge " << fe->
getId().
getFirst() <<
"-"
2026 vector<WVertex *> faceVertices;
2028 WFace *face =
nullptr;
2034 face->RetrieveVertexList(faceVertices);
2038 fe, iGrid, epsilon, oaPolygon, timestamp, u, A, origin, edgeDir, faceVertices);
2044 set<ViewShape *> &oOccluders,
2063 if ((center.
x() < gridOrigin.
x()) || (center.
y() < gridOrigin.
y()) ||
2064 (center.
z() < gridOrigin.
z()) || (center.
x() > gridExtremity.
x()) ||
2065 (center.
y() > gridExtremity.
y()) || (center.
z() > gridExtremity.
z()))
2067 cerr <<
"Warning: point is out of the grid for fedge " << fe->
getId() << endl;
2076 if ((A.x() < viewport[0]) || (A.x() > viewport[2]) || (A.y() < viewport[1]) ||
2077 (A.y() > viewport[3]) || (
B.x() < viewport[0]) || (
B.x() > viewport[2]) ||
2078 (
B.y() < viewport[1]) || (
B.y() > viewport[3]))
2080 cerr <<
"Warning: point is out of the grid for fedge " << fe->
getId() << endl;
2086 if (_orthographicProjection) {
2087 vp =
Vec3r(center.
x(), center.
y(), _viewpoint.
z());
2090 vp =
Vec3r(_viewpoint);
2092 Vec3r u(vp - center);
2099 cout <<
"center " << center.
x() <<
"," << center.
y() <<
"," << center.
z() << endl;
2103 iGrid->
castRay(center, vp, occluders, timestamp);
2105 WFace *face =
nullptr;
2110 vector<WVertex *> faceVertices;
2115 OccludersSet::iterator p, pend;
2120 for (p = occluders.begin(), pend = occluders.end(); p != pend; p++) {
2128 cout <<
"\t\tEvaluating intersection for occluder " << ((*p)->getVertices())[0]
2129 << ((*p)->getVertices())[1] << ((*p)->getVertices())[2] << endl
2130 <<
"\t\t\tand ray " << vp <<
" * " << u <<
" (center " << center <<
")" << endl;
2133 Vec3r v1((*p)->getVertices()[0]);
2134 Vec3r normal((*p)->getNormal());
2135 real d = -(v1 * normal);
2140 cout <<
"\t\tp: " << ((*p)->getVertices())[0] << ((*p)->getVertices())[1]
2141 << ((*p)->getVertices())[2] <<
", norm: " << (*p)->getNormal() << endl;
2148 cout <<
"\t\tDetermining face adjacency...";
2153 if (face == oface) {
2156 cout <<
" Rejecting occluder for face concurrency." << endl;
2162 for (vector<WVertex *>::iterator fv = faceVertices.begin(), fvend = faceVertices.end();
2166 if ((*fv)->isBoundary()) {
2172 for (ie = iebegin; ie != ieend; ++ie) {
2173 if ((*ie) ==
nullptr) {
2177 WFace *sface = (*ie)->GetbFace();
2180 if (sface == oface) {
2192 cout <<
" Rejecting occluder for face adjacency." << endl;
2208 cout <<
"\t\tRejecting occluder for target coincidence." << endl;
2215 if ((*p)->rayIntersect(center, u, t, t_u, t_v)) {
2218 cout <<
"\t\tRay " << vp <<
" * " << u <<
" intersects at time " << t <<
" (raylength is "
2219 << raylength <<
")" << endl;
2220 cout <<
"\t\t(u * normal) == " << (u * normal) <<
" for normal " << normal << endl;
2223 if (
fabs(u * normal) > 0.0001) {
2224 if ((t > 0.0) && (t < raylength)) {
2227 cout <<
"\t\tIs occluder" << endl;
2232 oOccluders.insert(vshape);
2243 FindOccludee(fe, iGrid, epsilon, oaPolygon, timestamp, u, center, origin, edgeDir, faceVertices);
2262 for (ViewMap::viewvertices_container::iterator vv = vvertices.begin(), vvend = vvertices.end();
2268 cout <<
"TVertex " << tvertex->
getId() <<
" has :" << endl;
2269 cout <<
"FrontEdgeA: " << tvertex->
frontEdgeA().first << endl;
2270 cout <<
"FrontEdgeB: " << tvertex->
frontEdgeB().first << endl;
2271 cout <<
"BackEdgeA: " << tvertex->
backEdgeA().first << endl;
2272 cout <<
"BackEdgeB: " << tvertex->
backEdgeB().first << endl << endl;
2289 Vec3r A = x->point2D();
2291 for (
uint i = 0; i < 3; i++) {
2319 real tx = x->getParameter(edge);
2320 real ty = y->getParameter(edge);
2346 vector<SVertex *> &svertices = ioViewMap->
SVertices();
2347 bool progressBarDisplay =
false;
2348 uint sVerticesSize = svertices.size();
2349 uint fEdgesSize = ioViewMap->
FEdges().size();
2353 for (ViewMap::fedges_container::const_iterator f = fedges.begin(), end = fedges.end();
2357 cout << (*f)->aMaterialIndex() <<
"-" << (*f)->bMaterialIndex() << endl;
2361 uint progressBarStep = 0;
2365 progressBarStep = sVerticesSize / progressBarSteps;
2366 _pProgressBar->
reset();
2367 _pProgressBar->
setLabelText(
"Computing Sweep Line Intersections");
2370 progressBarDisplay =
true;
2373 uint counter = progressBarStep;
2379 vector<FEdge *> &ioEdges = ioViewMap->
FEdges();
2381 vector<segment *> segments;
2383 vector<FEdge *>::iterator fe, fend;
2385 for (fe = ioEdges.begin(), fend = ioEdges.end(); fe != fend; fe++) {
2386 segment *s =
new segment((*fe), (*fe)->vertexA()->point2D(), (*fe)->vertexB()->point2D());
2387 (*fe)->userdata = s;
2388 segments.push_back(s);
2391 vector<segment *> vsegments;
2392 for (vector<SVertex *>::iterator sv = svertices.begin(), svend = svertices.end(); sv != svend;
2395 if (_pRenderMonitor && _pRenderMonitor->
testBreak()) {
2399 const vector<FEdge *> &vedges = (*sv)->fedges();
2401 for (vector<FEdge *>::const_iterator sve = vedges.begin(), sveend = vedges.end();
2405 vsegments.push_back((
segment *)((*sve)->userdata));
2408 Vec3r evt((*sv)->point2D());
2410 SL.
process(evt, vsegments, sbr, epsilon);
2412 if (progressBarDisplay) {
2415 counter = progressBarStep;
2422 if (_pRenderMonitor && _pRenderMonitor->
testBreak()) {
2424 if (!segments.empty()) {
2425 vector<segment *>::iterator s, send;
2426 for (s = segments.begin(), send = segments.end(); s != send; s++) {
2434 for (fe = ioEdges.begin(), fend = ioEdges.end(); fe != fend; fe++) {
2435 (*fe)->userdata =
nullptr;
2439 vector<FEdge *> newEdges;
2448 vector<intersection *>::iterator i, iend;
2449 for (i = intersections.begin(), iend = intersections.end(); i != iend; i++) {
2450 FEdge *fA = (*i)->EdgeA->edge();
2451 FEdge *fB = (*i)->EdgeB->edge();
2466 if ((ta < -epsilon) || (ta > 1 + epsilon)) {
2467 cerr <<
"Warning: 2D intersection out of range for edge " << fA->
vertexA()->
getId() <<
" - "
2471 if ((tb < -epsilon) || (tb > 1 + epsilon)) {
2472 cerr <<
"Warning: 2D intersection out of range for edge " << fB->
vertexA()->
getId() <<
" - "
2479 if ((Ta < -epsilon) || (Ta > 1 + epsilon)) {
2480 cerr <<
"Warning: 3D intersection out of range for edge " << fA->
vertexA()->
getId() <<
" - "
2484 if ((Tb < -epsilon) || (Tb > 1 + epsilon)) {
2485 cerr <<
"Warning: 3D intersection out of range for edge " << fB->
vertexA()->
getId() <<
" - "
2491 if ((Ta < -epsilon) || (Ta > 1 + epsilon) || (Tb < -epsilon) || (Tb > 1 + epsilon)) {
2492 printf(
"ta %.12e\n", ta);
2493 printf(
"tb %.12e\n", tb);
2494 printf(
"a1 %e, %e -- a2 %e, %e\n", a1[0], a1[1], a2[0], a2[1]);
2495 printf(
"b1 %e, %e -- b2 %e, %e\n", b1[0], b1[1], b2[0], b2[1]);
2498 if ((Ta < -epsilon) || (Ta > 1 + epsilon)) {
2499 printf(
"Ta %.12e\n", Ta);
2501 if ((Tb < -epsilon) || (Tb > 1 + epsilon)) {
2502 printf(
"Tb %.12e\n", Tb);
2504 printf(
"A1 %e, %e, %e -- A2 %e, %e, %e\n",
A1[0],
A1[1],
A1[2],
A2[0],
A2[1],
A2[2]);
2505 printf(
"B1 %e, %e, %e -- B2 %e, %e, %e\n",
B1[0],
B1[1],
B1[2],
B2[0],
B2[1],
B2[2]);
2511 Vec3r(a1 + ta * (a2 - a1)),
2514 Vec3r(b1 + tb * (b2 - b1)),
2522 progressBarStep = 0;
2524 if (progressBarDisplay) {
2525 uint iEdgesSize = iedges.size();
2527 progressBarStep = iEdgesSize / progressBarSteps;
2528 _pProgressBar->
reset();
2529 _pProgressBar->
setLabelText(
"Splitting intersected edges");
2534 counter = progressBarStep;
2536 vector<TVertex *> edgeVVertices;
2537 vector<ViewEdge *> newVEdges;
2538 vector<segment *>::iterator s, send;
2539 for (s = iedges.begin(), send = iedges.end(); s != send; s++) {
2540 edgeVVertices.clear();
2544 FEdge *fedge = (*s)->edge();
2548 vector<intersection *> &eIntersections = (*s)->intersections();
2551 for (i = eIntersections.begin(), iend = eIntersections.end(); i != iend; i++) {
2552 edgeVVertices.push_back((
TVertex *)(*i)->userdata);
2555 shape->SplitEdge(fedge, edgeVVertices, ioViewMap->
FEdges(), ioViewMap->
ViewEdges());
2557 if (progressBarDisplay) {
2560 counter = progressBarStep;
2567 for (fe = ioEdges.begin(), fend = ioEdges.end(); fe != fend; fe++) {
2568 (*fe)->userdata =
nullptr;
2572 if (!segments.empty()) {
2573 for (s = segments.begin(), send = segments.end(); s != send; s++) {
Class to define a cell grid surrounding the projected image of a scene.
Class to define a cell grid surrounding the projected image of a scene.
Various tools for geometry.
Class to define a cell grid surrounding the projected image of a scene.
Class to define a cell grid surrounding the projected image of a scene.
Class to define a cell grid surrounding the projected image of a scene.
Class to define a cell grid surrounding the projected image of a scene.
Class to build silhouette edges from a Winged-Edge structure.
Class to fill in a grid from a SceneGraph (uses only the WingedEdge structures)
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
static DBVT_INLINE btDbvtNode * sort(btDbvtNode *n, btDbvtNode *&r)
const Point & getMin() const
const Point & getMax() const
void setOccludeeEmpty(bool iempty)
ViewEdge * viewedge() const
int occluders_size() const
void setIsInImage(bool iFlag)
void setaFace(Polygon3r &iFace)
void setOccludeeIntersection(const Vec3r &iPoint)
bool rayIntersect(const Vec3r &orig, const Vec3r &dir, real &t, real &u, real &v, real epsilon=M_EPSILON) const
const vector< Point > & getVertices() const
virtual AutoPtr< GridDensityProvider > newGridDensityProvider(OccluderSource &source, const real proscenium[4])=0
const Vec3r & getOrigin() const
void castInfiniteRay(const Vec3r &orig, const Vec3r &dir, OccludersSet &occluders, uint timestamp)
virtual void configure(const Vec3r &orig, const Vec3r &size, uint nb)
void castRay(const Vec3r &orig, const Vec3r &end, OccludersSet &occluders, uint timestamp)
id_type getSecond() const
virtual void setLabelText(const string &s)
virtual void setTotalSteps(uint n)
virtual void setProgress(uint i)
void setInfo(string info)
void setFrsMaterials(const vector< FrsMaterial > &iMaterials)
void setLibraryPath(const string &path)
void setName(const string &name)
const Vec3r & point2d() const
const Vec3r & point2D() const
virtual real getProjectedY() const
virtual real getProjectedX() const
const Vec3r & point3D() const
static real ImageToWorldParameter(FEdge *fe, real t)
static void retrieveViewport(int viewport[4])
vector< Intersection< Segment< T, Point > > * > & intersections()
vector< Segment< T, Point > * > & intersectedEdges()
void process(Point &p, vector< Segment< T, Point > * > &segments, binary_rule< Segment< T, Point >, Segment< T, Point > > &binrule, real epsilon=M_EPSILON)
directedViewEdge & backEdgeB()
directedViewEdge & frontEdgeB()
directedViewEdge & frontEdgeA()
directedViewEdge & backEdgeA()
Vec< T, N > & normalize()
virtual void BuildViewEdges(WXShape *iWShape, ViewShape *oVShape, std::vector< ViewEdge * > &ioVEdges, std::vector< ViewVertex * > &ioVVertices, std::vector< FEdge * > &ioFEdges, std::vector< SVertex * > &ioSVertices)
int currentSVertexId() const
void setCurrentViewId(int id)
void setCurrentFId(int id)
int currentViewId() const
void setCurrentSVertexId(int id)
void ComputeFastRayCastingVisibility(ViewMap *ioViewMap, real epsilon=1.0e-6)
void ComputeCumulativeVisibility(ViewMap *ioViewMap, WingedEdge &we, const BBox< Vec3r > &bbox, real epsilon, bool cull, GridDensityProviderFactory &factory)
void BuildGrid(WingedEdge &we, const BBox< Vec3r > &bbox, uint sceneNumFaces)
ViewMap * BuildViewMap(WingedEdge &we, visibility_algo iAlgo, real epsilon, const BBox< Vec3r > &bbox, uint sceneNumFaces)
@ ray_casting_adaptive_cumulative
@ ray_casting_adaptive_traditional
@ ray_casting_culled_adaptive_cumulative
@ ray_casting_culled_adaptive_traditional
void CullViewEdges(ViewMap *ioViewMap, real viewProscenium[4], real occluderProscenium[4], bool extensiveFEdgeSearch=true)
void computeInitialViewEdges(WingedEdge &)
void ComputeRayCastingVisibility(ViewMap *ioViewMap, real epsilon=1.0e-6)
void FindOccludee(FEdge *fe, Grid *iGrid, real epsilon, Polygon3r **oaPolygon, uint timestamp)
void ComputeEdgesVisibility(ViewMap *ioViewMap, WingedEdge &we, const BBox< Vec3r > &bbox, uint sceneNumFaces, visibility_algo iAlgo=ray_casting, real epsilon=1.0e-6)
void computeCusps(ViewMap *ioViewMap)
void ComputeIntersections(ViewMap *ioViewMap, intersection_algo iAlgo=sweep_line, real epsilon=1.0e-06)
void ComputeSweepLineIntersections(ViewMap *ioViewMap, real epsilon=1.0e-6)
void ComputeVeryFastRayCastingVisibility(ViewMap *ioViewMap, real epsilon=1.0e-6)
void ComputeDetailedVisibility(ViewMap *ioViewMap, WingedEdge &we, const BBox< Vec3r > &bbox, real epsilon, bool cull, GridDensityProviderFactory &factory)
vector< FEdge * > fedges_container
ViewShape * viewShape(uint id)
void AddViewShape(ViewShape *iVShape)
vector< ViewVertex * > viewvertices_container
vector< ViewEdge * > viewedges_container
TVertex * CreateTVertex(const Vec3r &iA3D, const Vec3r &iA2D, FEdge *iFEdgeA, const Vec3r &iB3D, const Vec3r &iB2D, FEdge *iFEdgeB, const Id &id)
viewvertices_container & ViewVertices()
svertices_container & SVertices()
ViewVertex * InsertViewVertex(SVertex *iVertex, vector< ViewEdge * > &newViewEdges)
viewedges_container & ViewEdges()
fedges_container & FEdges()
virtual Nature::VertexNature getNature() const
void setNature(Nature::VertexNature iNature)
const vector< WOEdge * > & getEdgeList()
int numberOfEdges() const
void RetrieveVertexList(vector< WVertex * > &oVertices)
WVertex * GetVertex(uint index)
vector< WShape * > & getWShapes()
draw_view in_light_buf[] float
ccl_device_inline float2 fabs(const float2 a)
ccl_device_inline float3 ceil(const float3 a)
bool intersect2dSeg2dArea(const Vec2r &min, const Vec2r &max, const Vec2r &A, const Vec2r &B)
intersection_test intersectRayPlane(const Vec3r &orig, const Vec3r &dir, const Vec3r &norm, const real d, real &t, const real epsilon)
VecMat::Vec3< real > Vec3r
void getDefaultViewProscenium(real viewProscenium[4])
static const EdgeNature BORDER
static const VertexNature T_VERTEX
static const VertexNature CUSP
static const EdgeNature SILHOUETTE
static void computeDetailedVisibility(ViewMap *ioViewMap, G &grid, real epsilon, RenderMonitor *iRenderMonitor)
static const uint gProgressBarMinSize
static void computeFastVisibility(ViewMap *ioViewMap, G &grid, real epsilon)
static real distance2D(const Vec3r &point, const real origin[2])
static double B1(double u)
static const Global & _global
Segment< FEdge *, Vec3r > segment
static bool insideProscenium(const real proscenium[4], const Vec3r &point)
static void computeCumulativeVisibility(ViewMap *ioViewMap, G &grid, real epsilon, RenderMonitor *iRenderMonitor)
static int computeVisibility(ViewMap *viewMap, FEdge *fe, G &grid, real epsilon, ViewEdge *, WFace **oaWFace, set< ViewShape * > *foundOccluders)
vector< Polygon3r * > OccludersSet
static void findOccludee(FEdge *fe, G &, I &occluders, real epsilon, WFace **oaWFace, Vec3r &u, Vec3r &A, Vec3r &origin, Vec3r &edgeDir, vector< WVertex * > &faceVertices)
static double B2(double u)
static bool crossesProscenium(real proscenium[4], FEdge *fe)
static void computeVeryFastVisibility(ViewMap *ioViewMap, G &grid, real epsilon)
static const uint gProgressBarMaxSteps
bool operator()(intersection *x, intersection *y)
less_Intersection(segment *iEdge)
bool operator()(SVertex *x, SVertex *y)
bool operator()(segment &s1, segment &s2) override