Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F85155656
pmaproi.c
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Fri, Sep 27, 04:04
Size
7 KB
Mime Type
text/x-c
Expires
Sun, Sep 29, 04:04 (2 d)
Engine
blob
Format
Raw Data
Handle
21135888
Attached To
R10977 RADIANCE Photon Map
pmaproi.c
View Options
#ifndef lint
static const char RCSid[] = "$Id$";
#endif
/*
======================================================================
Regions of interest used by mkpmap to constrain location of photons
Roland Schregle (roland.schregle@{hslu.ch, gmail.com}
(c) Fraunhofer Institute for Solar Energy Systems,
supported by the German Research Foundation
(DFG LU-204/10-2, "Fassadenintegrierte Regelsysteme" (FARESYS))
(c) Lucerne University of Applied Sciences and Arts,
supported by the Swiss National Science Foundation
(SNSF #147053, "Daylight Redirecting Components",
SNSF #179067, "Light Fields for Spatio-Temporal Glare Assessment")
(c) Tokyo University of Science,
supported by the JSPS Grants-in-Aid for Scientific Research
(KAKENHI JP19KK0115, "Three-Dimensional Light Flow")
======================================================================
$Id$
*/
#include "pmaproi.h"
#include "otspecial.h"
#include "otypes.h"
#include "face.h"
/* Rectangular / spherical regions of interest */
unsigned pmapNumROI = 0;
PhotonMapROI *pmapROI = NULL;
/* Polyhedral regions of interest by modifier */
char *pmapROImodList [MAXSET + 1] = {NULL};
OBJECT polyROIset [PMAP_MAXROI + 1] = {0};
/* Bounding box for polyhedral ROI */
PhotonMapROI polyROIbbox = {
{FHUGE, FHUGE, FHUGE}, {-FHUGE, -FHUGE, -FHUGE}
};
void getPolyROIs (char **roiModList)
/* Find geometry comprising polyhedral regions of interest from modifiers in
* roiModList */
{
OBJECT i, j;
OBJREC *obj, *objMat;
FACE *objFace;
char **lp;
unsigned lastNumPolys = 0, v;
RREAL *objVert;
/* Init poly ROI set */
polyROIset [0] = 0;
if (!roiModList [0])
return;
for (lp = roiModList; *lp; lp++) {
lastNumPolys = polyROIset [0];
for (i = 0; i < nobjects; i++) {
obj = objptr(i);
objMat = findmaterial(obj);
/* Check if object is a polygon and its modifier is in list */
if (objMat && !strcmp(objMat -> oname, *lp) &&
issurface(obj -> otype)
) {
if (obj -> otype == OBJ_FACE) {
if (polyROIset [0] >= PMAP_MAXROI)
error(USER, "too many polyhedral ROI objects");
else {
insertelem(polyROIset, i);
/* Get polygon and iterate over its vertices */
if (objFace = getface(obj)) {
for (v = 0; v < objFace -> nv; v++) {
objVert = VERTEX(objFace, v);
/* Update bounding box with vertex (note hacky
treatment of polyROIbbox.siz as max here) */
for (j = 0; j < 3; j++) {
if (objVert [j] < polyROIbbox.pos [j])
polyROIbbox.pos [j] = objVert [j];
else if (objVert [j] > polyROIbbox.siz [j])
polyROIbbox.siz [j] = objVert [j];
}
}
}
else {
sprintf(errmsg,
"got egg on face extracting vertices for "
"polyhedral ROI modifier %s", *lp
);
error(CONSISTENCY, errmsg);
}
}
}
else {
sprintf(errmsg,
"non-polygonal ROI geometry for modifier %s", *lp
);
error(USER, errmsg);
}
}
}
if (polyROIset [0] == lastNumPolys) {
/* No geometry added for this modifier */
sprintf(errmsg, "no polyhedral ROI geometry for modifier %s", *lp);
error(USER, errmsg);
}
}
if (!polyROIset [0])
/* Made redundant by check above? */
error(USER, "no polyhedral ROI found");
}
int photonInROI (const RAY *photonRay)
/* Returns nonzero if photon defined by photonRay lies in any defined region
* of interest */
{
int inROI = 0, i;
if (pmapNumROI && pmapROI) {
/* Check rectangular / spherical ROIs */
FVECT photonDist;
for (i = 0; i < pmapNumROI; i++) {
VSUB(photonDist, photonRay -> rop, pmapROI [i].pos);
/* NOTE: Size of spherical ROI is _squared_ */
inROI = (PMAP_ROI_ISSPHERE(pmapROI + i)
? DOT(photonDist, photonDist) <= pmapROI [i].siz [0]
: fabs(photonDist [0]) <= pmapROI [i].siz [0] &&
fabs(photonDist [1]) <= pmapROI [i].siz [1] &&
fabs(photonDist [2]) <= pmapROI [i].siz [2]
);
if (inROI)
/* Bail out early, skip remaining ROIs */
return 1;
}
/* Failed inclusion test on all rectangular/spherical ROIs */
return 0;
}
if (polyROIset [0]) {
/* Check polyhedral ROI */
RAY testRay;
int rayFlip = 0;
#if 1
/* Start with quick bounding box test (note hacky treatment of
polyROIbbox.siz as maximum coords here) */
for (i = 0; i < 3; i++) {
if (photonRay -> rop [i] < polyROIbbox.pos [i] ||
photonRay -> rop [i] > polyROIbbox.siz [i]
)
return 0;
}
#endif
/* Init inclusion test ray at photon origin */
rayorigin(&testRay, PRIMARY, NULL, NULL);
testRay.rmax = FHUGE;
/* Now send rays and count number of crossed polygons in ROI set */
do {
if (!rayFlip) {
/* 1st iteration: set up forward test ray from photon hitpoint,
offset slightly in reversed direction to avoid potential
boundary issues with surface-bound (i.e. global, caustic)
photons */
VSUM(testRay.rorg, photonRay -> rop,
photonRay -> rdir, -2 * FTINY
);
VCOPY(testRay.rdir, photonRay -> rdir);
}
else {
/* 2nd iteration: reverse test ray direction from photon
hitpoint. This additional test mitigates issues with
semi-open ROIs */
VCOPY(testRay.rorg, photonRay -> rop);
for (i = 0; i < 3; i++)
testRay.rdir [i] = -photonRay -> rdir [i];
}
/* Follow inclusion test ray until it leaves the scene */
while (localhit(&testRay, &thescene)) {
/* Toggle odd/even number of crossings if intersected object is in
ROI set (note this works since inset() returns 0 or 1!) */
inROI ^= inset(polyROIset, testRay.robj);
/* Update ray origin with intersection for next iteration */
VCOPY(testRay.rorg, testRay.rop);
}
if (!(rayFlip || inROI))
/* Preempt reversed test ray if fwd already outside ROI */
return 0;
} while (rayFlip ^= 1);
/* inROI==0 if odd #crossings (=inside) in each iteration */
return !inROI;
}
/* No ROIs defined; accept photon unconditionally */
return 1;
}
Event Timeline
Log In to Comment