void HitMissTransform::processMatrix( const Imath::M33f &m, int &mask, int &elements ) const
{
	mask = elements = 0;
	const float *x = m.getValue();
	for( unsigned i=0; i<9; i++)
	{
		if( *x >= 0.0f )
		{
			mask |= 3 << (i*2);
			if( *x > 0.0f )
			{
				elements |= 1 << (i*2);
			}
		}
		
		x++;
	}
}
Example #2
0
static void
test_texture3d (ustring filename)
{
    std::cerr << "Testing 3d texture " << filename << ", output = " 
              << output_filename << "\n";
    const int nchannels = 4;
    ImageSpec outspec (output_xres, output_yres, nchannels, TypeDesc::HALF);
    ImageBuf image (output_filename, outspec);
    ImageBufAlgo::zero (image);

    Imath::M33f scale;  scale.scale (Imath::V2f (0.5, 0.5));
    Imath::M33f rot;    rot.rotate (radians(30.0f));
    Imath::M33f trans;  trans.translate (Imath::V2f (0.35f, 0.15f));
    Imath::M33f xform = scale * rot * trans;
    xform.invert();

    TextureOptions opt;
    opt.sblur = blur;
    opt.tblur = blur;
    opt.rblur = blur;
    opt.swidth = width;
    opt.twidth = width;
    opt.rwidth = width;
    opt.nchannels = nchannels;
    float localfill = (fill >= 0 ? fill : 0.0f);
    opt.fill = localfill;
    if (missing[0] >= 0)
        opt.missingcolor.init ((float *)&missing, 0);

    opt.swrap = opt.twrap = opt.rwrap = TextureOptions::WrapPeriodic;
    int shadepoints = blocksize*blocksize;
    Imath::V3f *P = ALLOCA (Imath::V3f, shadepoints);
    Runflag *runflags = ALLOCA (Runflag, shadepoints);
    Imath::V3f *dPdx = ALLOCA (Imath::V3f, shadepoints);
    Imath::V3f *dPdy = ALLOCA (Imath::V3f, shadepoints);
    Imath::V3f *dPdz = ALLOCA (Imath::V3f, shadepoints);
    float *result = ALLOCA (float, shadepoints*nchannels);
    
    for (int iter = 0;  iter < iters;  ++iter) {
        // Iterate over blocks

        // Trick: switch to second texture, if given, for second iteration
        if (iter && filenames.size() > 1)
            filename = ustring (filenames[1]);

        for (int by = 0;  by < output_yres;  by+=blocksize) {
            for (int bx = 0;  bx < output_xres;  bx+=blocksize) {
                // Process pixels within a block.  First save the texture warp
                // (s,t) and derivatives into SIMD vectors.
                int idx = 0;
                for (int y = by; y < by+blocksize; ++y) {
                    for (int x = bx; x < bx+blocksize; ++x) {
                        if (x < output_xres && y < output_yres) {
                            if (nowarp) {
                                P[idx][0] = (float)x/output_xres * sscale;
                                P[idx][1] = (float)y/output_yres * tscale;
                                P[idx][2] = 0.5f * sscale;
                                P[idx] += offset;
                                dPdx[idx][0] = 1.0f/output_xres * sscale;
                                dPdx[idx][1] = 0;
                                dPdx[idx][2] = 0;
                                dPdy[idx][0] = 0;
                                dPdy[idx][1] = 1.0f/output_yres * tscale;
                                dPdy[idx][2] = 0;
                                dPdz[idx].setValue (0,0,0);
                            } else {
                                Imath::V3f coord = warp ((float)x/output_xres,
                                                         (float)y/output_yres,
                                                         0.5, xform);
                                coord.x *= sscale;
                                coord.y *= tscale;
                                coord += offset;
                                Imath::V3f coordx = warp ((float)(x+1)/output_xres,
                                                          (float)y/output_yres,
                                                          0.5, xform);
                                coordx.x *= sscale;
                                coordx.y *= tscale;
                                coordx += offset;
                                Imath::V3f coordy = warp ((float)x/output_xres,
                                                          (float)(y+1)/output_yres,
                                                          0.5, xform);
                                coordy.x *= sscale;
                                coordy.y *= tscale;
                                coordy += offset;
                                P[idx] = coord;
                                dPdx[idx] = coordx - coord;
                                dPdy[idx] = coordy - coord;
                                dPdz[idx].setValue (0,0,0);
                            }
                            runflags[idx] = RunFlagOn;
                        } else {
                            runflags[idx] = RunFlagOff;
                        }
                        ++idx;
                    }
                }
                // Call the texture system to do the filtering.
                bool ok = texsys->texture3d (filename, opt, runflags, 0, shadepoints,
                                             Varying(P), Varying(dPdx),
                                             Varying(dPdy), Varying(dPdz),
                                             result);
                if (! ok) {
                    std::string e = texsys->geterror ();
                    if (! e.empty())
                        std::cerr << "ERROR: " << e << "\n";
                }
                for (int i = 0;  i < shadepoints*nchannels;  ++i)
                    result[i] *= scalefactor;

                // Save filtered pixels back to the image.
                idx = 0;
                for (int y = by; y < by+blocksize; ++y) {
                    for (int x = bx; x < bx+blocksize; ++x) {
                        if (runflags[idx]) {
                            image.setpixel (x, y, result + idx*nchannels);
                        }
                        ++idx;
                    }
                }
            }
        }
    }
    
    if (! image.save ()) 
        std::cerr << "Error writing " << output_filename 
                  << " : " << image.geterror() << "\n";
}
Example #3
0
static void
test_plain_texture ()
{
    std::cerr << "Testing 2d texture " << filenames[0] << ", output = " 
              << output_filename << "\n";
    const int nchannels = 4;
    ImageSpec outspec (output_xres, output_yres, nchannels, TypeDesc::HALF);
    ImageBuf image (output_filename, outspec);
    ImageBufAlgo::zero (image);

    Imath::M33f scale;  scale.scale (Imath::V2f (0.5, 0.5));
    Imath::M33f rot;    rot.rotate (radians(30.0f));
    Imath::M33f trans;  trans.translate (Imath::V2f (0.35f, 0.15f));
    Imath::M33f xform = scale * rot * trans;
    xform.invert();

    TextureOptions opt;
    opt.sblur = blur;
    opt.tblur = blur;
    opt.swidth = width;
    opt.twidth = width;
    opt.nchannels = nchannels;
    
    float localfill = (fill >= 0.0f) ? fill : 1.0f;
    opt.fill = localfill;
    if (missing[0] >= 0)
        opt.missingcolor.init ((float *)&missing, 0);
//    opt.interpmode = TextureOptions::InterpSmartBicubic;
//    opt.mipmode = TextureOptions::MipModeAniso;
    opt.swrap = opt.twrap = TextureOptions::WrapPeriodic;
//    opt.twrap = TextureOptions::WrapBlack;

#if 1
    TextureOpt opt1;
    opt1.sblur = blur;
    opt1.tblur = blur;
    opt1.swidth = width;
    opt1.twidth = width;
    opt1.nchannels = nchannels;
    opt1.fill = localfill;
    if (missing[0] >= 0)
        opt1.missingcolor = (float *)&missing;
    opt1.swrap = opt1.twrap = TextureOpt::WrapPeriodic;
#endif

    int shadepoints = blocksize*blocksize;
    float *s = ALLOCA (float, shadepoints);
    float *t = ALLOCA (float, shadepoints);
    Runflag *runflags = ALLOCA (Runflag, shadepoints);
    float *dsdx = ALLOCA (float, shadepoints);
    float *dtdx = ALLOCA (float, shadepoints);
    float *dsdy = ALLOCA (float, shadepoints);
    float *dtdy = ALLOCA (float, shadepoints);
    float *result = ALLOCA (float, shadepoints*nchannels);
    
    ustring filename = ustring (filenames[0]);
    TextureSystem::Perthread *perthread_info = texsys->get_perthread_info ();
    TextureSystem::TextureHandle *texture_handle = texsys->get_texture_handle (filename);

    for (int iter = 0;  iter < iters;  ++iter) {
        if (iters > 1 && filenames.size() > 1) {
            // Use a different filename for each iteration
            int texid = std::min (iter, (int)filenames.size()-1);
            filename = ustring (filenames[texid]);
            std::cerr << "iter " << iter << " file " << filename << "\n";
        }

        // Iterate over blocks
        for (int by = 0, b = 0;  by < output_yres;  by+=blocksize) {
            for (int bx = 0;  bx < output_xres;  bx+=blocksize, ++b) {
                // Trick: switch to other textures on later iterations, if any
                if (iters == 1 && filenames.size() > 1) {
                    // Use a different filename from block to block
                    filename = ustring (filenames[b % (int)filenames.size()]);
                }

                // Process pixels within a block.  First save the texture warp
                // (s,t) and derivatives into SIMD vectors.
                int idx = 0;
                for (int y = by; y < by+blocksize; ++y) {
                    for (int x = bx; x < bx+blocksize; ++x) {
                        if (x < output_xres && y < output_yres) {
                            if (nowarp) {
                                s[idx] = (float)x/output_xres * sscale + offset[0];
                                t[idx] = (float)y/output_yres * tscale + offset[1];
                                dsdx[idx] = 1.0f/output_xres * sscale;
                                dtdx[idx] = 0;
                                dsdy[idx] = 0;
                                dtdy[idx] = 1.0f/output_yres * tscale;
                            } else {
                                Imath::V3f coord = warp ((float)x/output_xres,
                                                         (float)y/output_yres,
                                                         xform);
                                coord.x *= sscale;
                                coord.y *= tscale;
                                coord += offset;
                                Imath::V3f coordx = warp ((float)(x+1)/output_xres,
                                                          (float)y/output_yres,
                                                          xform);
                                coordx.x *= sscale;
                                coordx.y *= tscale;
                                coordx += offset;
                                Imath::V3f coordy = warp ((float)x/output_xres,
                                                          (float)(y+1)/output_yres,
                                                          xform);
                                coordy.x *= sscale;
                                coordy.y *= tscale;
                                coordy += offset;
                                s[idx] = coord[0];
                                t[idx] = coord[1];
                                dsdx[idx] = coordx[0] - coord[0];
                                dtdx[idx] = coordx[1] - coord[1];
                                dsdy[idx] = coordy[0] - coord[0];
                                dtdy[idx] = coordy[1] - coord[1];
                            }
                            runflags[idx] = RunFlagOn;
                        } else {
                            runflags[idx] = RunFlagOff;
                        }
                        ++idx;
                    }
                }

                // Call the texture system to do the filtering.
                bool ok;
                if (blocksize == 1) {
                    if (use_handle)
                        ok = texsys->texture (texture_handle, perthread_info, opt1,
                                              s[0], t[0], dsdx[0], dtdx[0],
                                              dsdy[0], dtdy[0], result);
                    else
                        ok = texsys->texture (filename, opt1,
                                              s[0], t[0], dsdx[0], dtdx[0],
                                              dsdy[0], dtdy[0], result);
                } else {
                    ok = texsys->texture (filename, opt, runflags, 0,
                                          shadepoints, Varying(s), Varying(t),
                                          Varying(dsdx), Varying(dtdx),
                                          Varying(dsdy), Varying(dtdy), result);
                }
                if (! ok) {
                    std::string e = texsys->geterror ();
                    if (! e.empty())
                        std::cerr << "ERROR: " << e << "\n";
                }
                for (int i = 0;  i < shadepoints*nchannels;  ++i)
                    result[i] *= scalefactor;

                // Save filtered pixels back to the image.
                idx = 0;
                for (int y = by; y < by+blocksize; ++y) {
                    for (int x = bx; x < bx+blocksize; ++x) {
                        if (runflags[idx]) {
                            image.setpixel (x, y, result + idx*nchannels);
                        }
                        ++idx;
                    }
                }
            }
        }
    }
    
    if (! image.save ()) 
        std::cerr << "Error writing " << output_filename 
                  << " : " << image.geterror() << "\n";
}
Example #4
0
static void
test_plain_texture ()
{
    std::cerr << "Testing 2d texture " << filenames[0] << ", output = " 
              << output_filename << "\n";
    const int nchannels = 4;
    ImageSpec outspec (output_xres, output_yres, nchannels, TypeDesc::HALF);
    if (! dataformatname.empty()) {
        if (dataformatname == "uint8")
            outspec.set_format (TypeDesc::UINT8);
        else if (dataformatname == "int8")
            outspec.set_format (TypeDesc::INT8);
        else if (dataformatname == "uint10") {
            outspec.attribute ("oiio:BitsPerSample", 10);
            outspec.set_format (TypeDesc::UINT16);
        }
        else if (dataformatname == "uint12") {
            outspec.attribute ("oiio:BitsPerSample", 12);
            outspec.set_format (TypeDesc::UINT16);
        }
        else if (dataformatname == "uint16")
            outspec.set_format (TypeDesc::UINT16);
        else if (dataformatname == "int16")
            outspec.set_format (TypeDesc::INT16);
        else if (dataformatname == "half")
            outspec.set_format (TypeDesc::HALF);
        else if (dataformatname == "float")
            outspec.set_format (TypeDesc::FLOAT);
        else if (dataformatname == "double")
            outspec.set_format (TypeDesc::DOUBLE);
        outspec.channelformats.clear ();
    }
    ImageBuf image (output_filename, outspec);
    ImageBufAlgo::zero (image);

    Imath::M33f scale;  scale.scale (Imath::V2f (0.5, 0.5));
    Imath::M33f rot;    rot.rotate (radians(30.0f));
    Imath::M33f trans;  trans.translate (Imath::V2f (0.35f, 0.15f));
    Imath::M33f xform = scale * rot * trans;
    xform.invert();

    TextureOptions opt;
    opt.sblur = blur;
    opt.tblur = blur;
    opt.swidth = width;
    opt.twidth = width;
    opt.nchannels = nchannels;
    
    float localfill = (fill >= 0.0f) ? fill : 1.0f;
    opt.fill = localfill;
    if (missing[0] >= 0)
        opt.missingcolor.init ((float *)&missing, 0);
//    opt.interpmode = TextureOptions::InterpSmartBicubic;
//    opt.mipmode = TextureOptions::MipModeAniso;
    TextureOptions::parse_wrapmodes (wrapmodes.c_str(), opt.swrap, opt.twrap);

    TextureOpt opt1;
    opt1.sblur = blur;
    opt1.tblur = blur;
    opt1.swidth = width;
    opt1.twidth = width;
    opt1.nchannels = nchannels;
    opt1.fill = localfill;
    if (missing[0] >= 0)
        opt1.missingcolor = (float *)&missing;
    TextureOpt::parse_wrapmodes (wrapmodes.c_str(), opt1.swrap, opt1.twrap);

    int shadepoints = blocksize*blocksize;
    float *s = ALLOCA (float, shadepoints);
    float *t = ALLOCA (float, shadepoints);
    Runflag *runflags = ALLOCA (Runflag, shadepoints);
    float *dsdx = ALLOCA (float, shadepoints);
    float *dtdx = ALLOCA (float, shadepoints);
    float *dsdy = ALLOCA (float, shadepoints);
    float *dtdy = ALLOCA (float, shadepoints);
    float *result = ALLOCA (float, shadepoints*nchannels);
    
    ustring filename = ustring (filenames[0]);
    TextureSystem::Perthread *perthread_info = texsys->get_perthread_info ();
    TextureSystem::TextureHandle *texture_handle = texsys->get_texture_handle (filename);

    for (int iter = 0;  iter < iters;  ++iter) {
        if (iters > 1 && filenames.size() > 1) {
            // Use a different filename for each iteration
            int texid = std::min (iter, (int)filenames.size()-1);
            filename = ustring (filenames[texid]);
            std::cerr << "iter " << iter << " file " << filename << "\n";
        }

        // Iterate over blocks
        for (int by = 0, b = 0;  by < output_yres;  by+=blocksize) {
            for (int bx = 0;  bx < output_xres;  bx+=blocksize, ++b) {
                // Trick: switch to other textures on later iterations, if any
                if (iters == 1 && filenames.size() > 1) {
                    // Use a different filename from block to block
                    filename = ustring (filenames[b % (int)filenames.size()]);
                }

                // Process pixels within a block.  First save the texture warp
                // (s,t) and derivatives into SIMD vectors.
                int idx = 0;
                for (int y = by; y < by+blocksize; ++y) {
                    for (int x = bx; x < bx+blocksize; ++x) {
                        if (x < output_xres && y < output_yres) {
                            if (nowarp) {
                                s[idx] = (float)x/output_xres * sscale + offset[0];
                                t[idx] = (float)y/output_yres * tscale + offset[1];
                                dsdx[idx] = 1.0f/output_xres * sscale;
                                dtdx[idx] = 0;
                                dsdy[idx] = 0;
                                dtdy[idx] = 1.0f/output_yres * tscale;
                            } else if (tube) {
                                float xt = float(x)/output_xres - 0.5f;
                                float dxt_dx = 1.0f/output_xres;
                                float yt = float(y)/output_yres - 0.5f;
                                float dyt_dy = 1.0f/output_yres;
                                float theta = atan2f (yt, xt);
                                // See OSL's Dual2 for partial derivs of
                                // atan2, hypot, and 1/x
                                float denom = 1.0f / (xt*xt + yt*yt);
                                float dtheta_dx = yt*dxt_dx * denom;
                                float dtheta_dy = -xt*dyt_dy * denom;
                                s[idx] = 4.0f * theta / (2.0f * M_PI);
                                dsdx[idx] = 4.0f * dtheta_dx / (2.0f * M_PI);
                                dsdy[idx] = 4.0f * dtheta_dy / (2.0f * M_PI);
                                float h = hypot(xt,yt);
                                float dh_dx = xt*dxt_dx / h;
                                float dh_dy = yt*dyt_dy / h;
                                h *= M_SQRT2;
                                dh_dx *= M_SQRT2; dh_dy *= M_SQRT2;
                                float hinv = 1.0f / h;
                                t[idx] = hinv;
                                dtdx[idx] = hinv * (-hinv * dh_dx);
                                dtdy[idx] = hinv * (-hinv * dh_dy);
                            } else {
                                Imath::V3f coord = warp ((float)x/output_xres,
                                                         (float)y/output_yres,
                                                         xform);
                                coord.x *= sscale;
                                coord.y *= tscale;
                                coord += offset;
                                Imath::V3f coordx = warp ((float)(x+1)/output_xres,
                                                          (float)y/output_yres,
                                                          xform);
                                coordx.x *= sscale;
                                coordx.y *= tscale;
                                coordx += offset;
                                Imath::V3f coordy = warp ((float)x/output_xres,
                                                          (float)(y+1)/output_yres,
                                                          xform);
                                coordy.x *= sscale;
                                coordy.y *= tscale;
                                coordy += offset;
                                s[idx] = coord[0];
                                t[idx] = coord[1];
                                dsdx[idx] = coordx[0] - coord[0];
                                dtdx[idx] = coordx[1] - coord[1];
                                dsdy[idx] = coordy[0] - coord[0];
                                dtdy[idx] = coordy[1] - coord[1];
                            }
                            runflags[idx] = RunFlagOn;
                        } else {
                            runflags[idx] = RunFlagOff;
                        }
                        ++idx;
                    }
                }

                // Call the texture system to do the filtering.
                bool ok;
                if (blocksize == 1) {
                    if (use_handle)
                        ok = texsys->texture (texture_handle, perthread_info, opt1,
                                              s[0], t[0], dsdx[0], dtdx[0],
                                              dsdy[0], dtdy[0], result);
                    else
                        ok = texsys->texture (filename, opt1,
                                              s[0], t[0], dsdx[0], dtdx[0],
                                              dsdy[0], dtdy[0], result);
                } else {
                    ok = texsys->texture (filename, opt, runflags, 0,
                                          shadepoints, Varying(s), Varying(t),
                                          Varying(dsdx), Varying(dtdx),
                                          Varying(dsdy), Varying(dtdy), result);
                }
                if (! ok) {
                    std::string e = texsys->geterror ();
                    if (! e.empty())
                        std::cerr << "ERROR: " << e << "\n";
                }
                for (int i = 0;  i < shadepoints*nchannels;  ++i)
                    result[i] *= scalefactor;

                // Save filtered pixels back to the image.
                idx = 0;
                for (int y = by; y < by+blocksize; ++y) {
                    for (int x = bx; x < bx+blocksize; ++x) {
                        if (runflags[idx]) {
                            image.setpixel (x, y, result + idx*nchannels);
                        }
                        ++idx;
                    }
                }
            }
        }

        if (resetstats) {
            std::cout << texsys->getstats(2) << "\n";
            texsys->reset_stats ();
        }
    }
    
    if (! image.save ()) 
        std::cerr << "Error writing " << output_filename 
                  << " : " << image.geterror() << "\n";
}