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;
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) {
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) {
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) {
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) {
1009 (*ve)->setaShape(vshape);
1012 (*ve)->setaShape(
nullptr);
1022 for (
uint i = 0; i < 3; i++) {
1029 cout <<
"Warning: the bbox size is 0 in dimension " << i << endl;
1040 _Grid->displayDebug();
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;
1177 (*ve)->setIsInImage(
true);
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());
1273 _ViewMap->AddViewShape(vshape);
1276 _pViewEdgeBuilder->setCurrentViewId(_currentId);
1278 _pViewEdgeBuilder->setCurrentFId(_currentFId);
1280 _pViewEdgeBuilder->setCurrentSVertexId(_currentFId);
1281 _pViewEdgeBuilder->BuildViewEdges(
dynamic_cast<WXShape *
>(*it),
1283 _ViewMap->ViewEdges(),
1284 _ViewMap->ViewVertices(),
1286 _ViewMap->SVertices());
1288 _currentId = _pViewEdgeBuilder->currentViewId() + 1;
1289 _currentFId = _pViewEdgeBuilder->currentFId() + 1;
1290 _currentSVertexId = _pViewEdgeBuilder->currentSVertexId() + 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");
1563 _pProgressBar->setTotalSteps(progressBarSteps);
1564 _pProgressBar->setProgress(0);
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;
1700 _pProgressBar->setProgress(_pProgressBar->getProgress() + 1);
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");
1720 _pProgressBar->setTotalSteps(progressBarSteps);
1721 _pProgressBar->setProgress(0);
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;
1833 _pProgressBar->setProgress(_pProgressBar->getProgress() + 1);
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");
1853 _pProgressBar->setTotalSteps(progressBarSteps);
1854 _pProgressBar->setProgress(0);
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;
1888 _pProgressBar->setProgress(_pProgressBar->getProgress() + 1);
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;
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;
2291 for (
uint i = 0; i < 3; i++) {
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");
2368 _pProgressBar->setTotalSteps(progressBarSteps);
2369 _pProgressBar->setProgress(0);
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;
2416 _pProgressBar->setProgress(_pProgressBar->getProgress() + 1);
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");
2530 _pProgressBar->setTotalSteps(progressBarSteps);
2531 _pProgressBar->setProgress(0);
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);
2557 if (progressBarDisplay) {
2560 counter = progressBarStep;
2561 _pProgressBar->setProgress(_pProgressBar->getProgress() + 1);
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.
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a point
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
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)
void castRay(const Vec3r &orig, const Vec3r &end, OccludersSet &occluders, uint timestamp)
id_type getSecond() const
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()
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)
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()
void SplitEdge(FEdge *fe, const vector< TVertex * > &iViewVertices, vector< FEdge * > &ioNewEdges, vector< ViewEdge * > &ioNewViewEdges)
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()
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::Vec2< real > Vec2r
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
Intersection< segment > intersection
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