using namespace HDK_Sample;
{
}
: mySamplesPerPixelX(1)
, mySamplesPerPixelY(1)
, myUseColourGradient(true)
, myUseZGradient(true)
, myUseOpID(true)
, myColourGradientThreshold(0.1
f)
, myZGradientThreshold(0.005
f)
, myColourGradientWidth(3.0
f)
{
}
RAY_DemoEdgeDetectFilter::~RAY_DemoEdgeDetectFilter()
{
}
{
return pf;
}
void
{
{
myColourGradientThreshold = args.
fargp(
'c');
myUseColourGradient = (myColourGradientThreshold >= 0);
if (myUseColourGradient && args.
found(
'w'))
{
myColourGradientWidth = args.
fargp(
'w');
if (myColourGradientWidth < 0)
myUseColourGradient = false;
myColourGradientWidth =
SYSclamp(myColourGradientWidth, 1.0
f, 1024.0
f);
}
}
{
myOpIDWidth = args.
fargp(
'o');
myUseOpID = (myOpIDWidth >= 0);
myOpIDWidth =
SYSclamp(myOpIDWidth, 1.0
f, 1024.0
f);
}
{
myZGradientThreshold = args.
fargp(
'z');
myUseZGradient = (myZGradientThreshold >= 0);
if (myUseZGradient && args.
found(
's'))
{
myZGradientWidth = args.
fargp(
's');
if (myZGradientWidth < 0)
myUseZGradient = false;
myZGradientWidth =
SYSclamp(myZGradientWidth, 1.0
f, 1024.0
f);
}
}
}
void
{
float filterwidth =
SYSmax(myUseColourGradient ? myColourGradientWidth : 1,
myUseZGradient ? myZGradientWidth : 1,
myUseOpID ? myOpIDWidth : 1);
x = filterwidth;
y = filterwidth;
}
void
{
if (myUseOpID)
if (myUseZGradient)
}
namespace {
float RAYcomputeSumX2(
int samplesperpixel,
float width,
int &halfsamplewidth)
{
float sumx2 = 0;
if (samplesperpixel & 1)
{
for (int i = -halfsamplewidth; i <= halfsamplewidth; ++i)
{
}
}
else
{
halfsamplewidth = (
int)
SYSfloor(
float(samplesperpixel)*0.5f*width + 0.5f);
for (int i = -halfsamplewidth; i < halfsamplewidth; ++i)
{
float x = (
float(i)+0.5f)/
float(samplesperpixel);
}
}
return sumx2;
}
}
void
{
mySamplesPerPixelX = samplesperpixelx;
mySamplesPerPixelY = samplesperpixely;
myColourSumX2 = RAYcomputeSumX2(mySamplesPerPixelX, myColourGradientWidth, myColourSamplesHalfX);
myColourSumY2 = RAYcomputeSumX2(mySamplesPerPixelY, myColourGradientWidth, myColourSamplesHalfY);
myZSumX2 = RAYcomputeSumX2(mySamplesPerPixelX, myZGradientWidth, myZSamplesHalfX);
myZSumY2 = RAYcomputeSumX2(mySamplesPerPixelY, myZGradientWidth, myZSamplesHalfY);
myOpIDSamplesHalfX = (
int)
SYSfloor(
float(mySamplesPerPixelX)*0.5f*myOpIDWidth + ((mySamplesPerPixelX & 1) ? 0.0
f : 0.5
f));
myOpIDSamplesHalfY = (
int)
SYSfloor(
float(mySamplesPerPixelY)*0.5f*myOpIDWidth + ((mySamplesPerPixelY & 1) ? 0.0
f : 0.5
f));
}
void
float *destination,
int vectorsize,
const RAY_SampleBuffer &
source,
int channel,
int sourcewidth,
int sourceheight,
int destwidth,
int destheight,
int destxoffsetinsource,
int destyoffsetinsource,
const RAY_Imager &imager) const
{
const float *const colourdata = myUseColourGradient
: NULL;
const float *const zdata = myUseZGradient
: NULL;
const float *const opiddata = myUseOpID
: NULL;
UT_ASSERT(myUseColourGradient == (colourdata != NULL));
UT_ASSERT(myUseZGradient == (zdata != NULL));
for (int desty = 0; desty < destheight; ++desty)
{
for (int destx = 0; destx < destwidth; ++destx)
{
bool isedge = false;
const int sourcefirstx = destxoffsetinsource + destx*mySamplesPerPixelX;
const int sourcefirsty = destyoffsetinsource + desty*mySamplesPerPixelY;
const int sourcelastx = sourcefirstx + mySamplesPerPixelX-1;
const int sourcelasty = sourcefirsty + mySamplesPerPixelY-1;
const int sourcefirstcx = sourcefirstx + (mySamplesPerPixelX>>1) - myColourSamplesHalfX;
const int sourcefirstcy = sourcefirsty + (mySamplesPerPixelY>>1) - myColourSamplesHalfY;
const int sourcefirstzx = sourcefirstx + (mySamplesPerPixelX>>1) - myZSamplesHalfX;
const int sourcefirstzy = sourcefirsty + (mySamplesPerPixelY>>1) - myZSamplesHalfY;
const int sourcefirstox = sourcefirstx + (mySamplesPerPixelX>>1) - myOpIDSamplesHalfX;
const int sourcefirstoy = sourcefirsty + (mySamplesPerPixelY>>1) - myOpIDSamplesHalfY;
const int sourcelastcx = sourcefirstx + ((mySamplesPerPixelX-1)>>1) + myColourSamplesHalfX;
const int sourcelastcy = sourcefirsty + ((mySamplesPerPixelY-1)>>1) + myColourSamplesHalfY;
const int sourcelastzx = sourcefirstx + ((mySamplesPerPixelX-1)>>1) + myZSamplesHalfX;
const int sourcelastzy = sourcefirsty + ((mySamplesPerPixelY-1)>>1) + myZSamplesHalfY;
const int sourcelastox = sourcefirstx + ((mySamplesPerPixelX-1)>>1) + myOpIDSamplesHalfX;
const int sourcelastoy = sourcefirsty + ((mySamplesPerPixelY-1)>>1) + myOpIDSamplesHalfY;
int sourcefirstrx = sourcefirstx;
int sourcefirstry = sourcefirsty;
int sourcelastrx = sourcelastx;
int sourcelastry = sourcelasty;
if (myUseColourGradient)
{
sourcefirstrx =
SYSmin(sourcefirstrx, sourcefirstcx);
sourcefirstry =
SYSmin(sourcefirstry, sourcefirstcy);
sourcelastrx =
SYSmax(sourcelastrx, sourcelastcx);
sourcelastry =
SYSmax(sourcelastry, sourcelastcy);
}
if (myUseZGradient)
{
sourcefirstrx =
SYSmin(sourcefirstrx, sourcefirstzx);
sourcefirstry =
SYSmin(sourcefirstry, sourcefirstzy);
sourcelastrx =
SYSmax(sourcelastrx, sourcelastzx);
sourcelastry =
SYSmax(sourcelastry, sourcelastzy);
}
if (myUseOpID)
{
sourcefirstrx =
SYSmin(sourcefirstrx, sourcefirstox);
sourcefirstry =
SYSmin(sourcefirstry, sourcefirstoy);
sourcelastrx =
SYSmax(sourcelastrx, sourcelastox);
sourcelastry =
SYSmax(sourcelastry, sourcelastoy);
}
bool opidset = false;
float opid;
if (myUseColourGradient)
{
for (int i = 0; i < vectorsize; ++i)
colourgradientx[i] = 0;
for (int i = 0; i < vectorsize; ++i)
colourgradienty[i] = 0;
}
float zgradientx = 0;
float zgradienty = 0;
float zaverage = 0;
bool hasfarz = false;
bool hasnonfarz = false;
for (int sourcey = sourcefirstry; sourcey <= sourcelastry && !isedge; ++sourcey)
{
for (int sourcex = sourcefirstrx; sourcex <= sourcelastrx; ++sourcex)
{
int sourcei = sourcex + sourcewidth*sourcey;
if (myUseOpID && sourcex >= sourcefirstox && sourcex <= sourcelastox && sourcey >= sourcefirstoy && sourcey <= sourcelastoy)
{
if (!opidset)
{
opid = opiddata[sourcei];
opidset = true;
}
else if (opid != opiddata[sourcei])
{
isedge = true;
break;
}
}
if (myUseColourGradient || myUseZGradient)
{
float x = (
float(sourcex) - 0.5f*
float(sourcelastx + sourcefirstx))/
float(mySamplesPerPixelX);
float y = (
float(sourcey) - 0.5f*
float(sourcelasty + sourcefirsty))/
float(mySamplesPerPixelY);
if (myUseColourGradient && sourcex >= sourcefirstcx && sourcex <= sourcelastcx && sourcey >= sourcefirstcy && sourcey <= sourcelastcy)
{
for (int i = 0; i < vectorsize; ++i)
colourgradientx[i] += x*colourdata[vectorsize*sourcei + i];
for (int i = 0; i < vectorsize; ++i)
colourgradienty[i] += y*colourdata[vectorsize*sourcei + i];
}
if (myUseZGradient && sourcex >= sourcefirstzx && sourcex <= sourcelastzx && sourcey >= sourcefirstzy && sourcey <= sourcelastzy)
{
bool farz = (zdata[sourcei] >= 1.0e37);
hasfarz |= farz;
hasnonfarz |= !farz;
if (hasfarz && hasnonfarz)
{
isedge = true;
break;
}
if (!farz)
{
zgradientx += x*zdata[sourcei];
zgradienty += y*zdata[sourcei];
zaverage += zdata[sourcei];
}
}
}
}
}
if (!isedge)
{
if (myUseColourGradient)
{
int nx = sourcelastcx-sourcefirstcx+1;
int ny = sourcelastcy-sourcefirstcy+1;
for (int i = 0; i < vectorsize; ++i)
colourgradientx[i] /= (ny*myColourSumX2);
float mag2x = 0;
for (int i = 0; i < vectorsize; ++i)
mag2x += colourgradientx[i]*colourgradientx[i];
for (int i = 0; i < vectorsize; ++i)
colourgradienty[i] /= (nx*myColourSumY2);
float mag2y = 0;
for (int i = 0; i < vectorsize; ++i)
mag2y += colourgradienty[i]*colourgradienty[i];
if ((mag2x + mag2y) >= myColourGradientThreshold*myColourGradientThreshold)
isedge = true;
}
if (!isedge && myUseZGradient && hasnonfarz)
{
int nx = sourcelastzx-sourcefirstzx+1;
int ny = sourcelastzy-sourcefirstzy+1;
zgradientx /= (ny*myZSumX2*zaverage);
zgradienty /= (nx*myZSumY2*zaverage);
float mag2x = zgradientx*zgradientx;
float mag2y = zgradienty*zgradienty;
if ((mag2x + mag2y) >= myZGradientThreshold*myZGradientThreshold)
isedge = true;
}
}
float value = isedge ? 1.0f : 0.0f;
for (int i = 0; i < vectorsize; ++i, ++destination)
*destination = value;
}
}
}