Пример #1
0
void DumpData(Ptex::DataType dt, int nchan, PtexFaceData* dh, std::string prefix)
{
    void* dpixel = malloc(Ptex::DataSize(dt)*nchan);
    float* pixel = (float*) malloc(sizeof(float)*nchan);
    uint8_t* cpixel = (uint8_t*) malloc(sizeof(uint8_t)*nchan);
    Ptex::Res res = dh->res();
    printf("%sdata (%d x %d)", prefix.c_str(), res.u(), res.v());
    if (dh->isTiled()) {
	Ptex::Res tileres = dh->tileRes();
	printf(", tiled (%d x %d):\n", tileres.u(), tileres.v());
	int n = res.ntiles(tileres);
	for (int i = 0; i < n; i++) {
	    PtexFaceData* t = dh->getTile(i);
	    std::cout << prefix << "  tile " << i;
	    if (!t) {
		std::cout << " NULL!" << std::endl;
	    } else {
		DumpData(dt, nchan, t, prefix + "  ");
		t->release();
	    }
	}
    } else {
	int ures, vres;
	if (dh->isConstant()) { ures = vres = 1; std::cout << ", const: "; }
	else { ures = res.u(); vres = res.v(); std::cout << ":\n"; }
	
	int vimax = vres;// if (vimax > 16) vimax = 16;
	for (int vi = 0; vi < vimax; vi++) {
	    if (vi == 8 && vres > 16) { vi = vres-8; std::cout << prefix << "  ..." << std::endl; }
	    std::cout << prefix << "  ";
	    int uimax = ures;// if (uimax > 16) uimax = 16;
	    for (int ui = 0; ui < uimax; ui++) {
		if (ui == 8 && ures > 16) { ui = ures-8; std::cout << "... "; }
		dh->getPixel(ui, vi, dpixel);
		Ptex::ConvertToFloat(pixel, dpixel, dt, nchan);
		Ptex::ConvertFromFloat(cpixel, pixel, Ptex::dt_uint8, nchan);
		for (int c=0; c < nchan; c++) {
		    printf("%02x", cpixel[c]);
		}
		printf(" ");
	    }
	    if (uimax != ures) printf(" ...");
	    printf("\n");
	}
	if (vimax != vres) std::cout << prefix << "  ..." << std::endl;
    }
    free(cpixel);
    free(pixel);
    free(dpixel);
}
Пример #2
0
void DumpData(PtexTexture* r, int faceid, bool dumpall)
{
    int levels = 1;
    if (dumpall) {
        PtexReader* R = static_cast<PtexReader*> (r);
        if (R) levels = R->header().nlevels;
    }

    const Ptex::FaceInfo& f = r->getFaceInfo(faceid);
    int nchan = r->numChannels();
    float* pixel = (float*) malloc(sizeof(float)*nchan);
    Ptex::Res res = f.res;
    while (levels && res.ulog2 >= 1 && res.vlog2 >= 1) {
        int ures = res.u(), vres = res.v();
        std::cout << "  data (" << ures << " x " << vres << ")";
        if (f.isConstant()) { ures = vres = 1; }
        bool isconst = (ures == 1 && vres == 1);
        if (isconst) std::cout << ", const: ";
        else std::cout << ":";
        for (int vi = 0; vi < vres; vi++) {
            for (int ui = 0; ui < ures; ui++) {
                if (!isconst) std::cout << "\n    (" << ui << ", " << vi << "): ";
                r->getPixel(faceid, ui, vi, pixel, 0, nchan, res);
                for (int c=0; c < nchan; c++) {
                    printf(" %.3f", pixel[c]);
                }
            }
        }
        std::cout << std::endl;
        res.ulog2--;
        res.vlog2--;
        levels--;
    }
    free(pixel);
}
Пример #3
0
void DumpFaceInfo(const Ptex::FaceInfo& f)
{
    Ptex::Res res = f.res;
    std::cout << "  res: " << int(res.ulog2) << ' ' << int(res.vlog2)
              << " (" << res.u() << " x " << res.v() << ")"
              << "  adjface: " 
              << f.adjfaces[0] << ' '
              << f.adjfaces[1] << ' '
              << f.adjfaces[2] << ' '
              << f.adjfaces[3]
              << "  adjedge: " 
              << f.adjedge(0) << ' '
              << f.adjedge(1) << ' '
              << f.adjedge(2) << ' '
              << f.adjedge(3)
              << "  flags:";
    // output flag names
    if (f.flags == 0) std::cout << " (none)";
    else {
        if (f.isSubface()) std::cout << " subface";
        if (f.isConstant()) std::cout << " constant";
        if (f.isNeighborhoodConstant()) std::cout << " nbconstant";
        if (f.hasEdits()) std::cout << " hasedits";
    }
    std::cout << std::endl;
}
void PtexSeparableFilter::apply(PtexSeparableKernel& k, int faceid, const Ptex::FaceInfo& f)
{
    assert(k.u >= 0 && k.u + k.uw <= k.res.u());
    assert(k.v >= 0 && k.v + k.vw <= k.res.v());

    if (k.uw <= 0 || k.vw <= 0) return;

    // downres kernel if needed
    while (k.res.u() > f.res.u()) k.downresU();
    while (k.res.v() > f.res.v()) k.downresV();

    // get face data, and apply
    PtexPtr<PtexFaceData> dh ( _tx->getData(faceid, k.res) );
    if (!dh) return;

    if (dh->isConstant()) {
	k.applyConst(_result, (char*)dh->getData()+_firstChanOffset, _dt, _nchan);
    }
    else if (dh->isTiled()) {
	Ptex::Res tileres = dh->tileRes();
	PtexSeparableKernel kt;
	kt.res = tileres;
	int tileresu = tileres.u();
	int tileresv = tileres.v();
	int ntilesu = k.res.u() / tileresu;
	for (int v = k.v, vw = k.vw; vw > 0; vw -= kt.vw, v += kt.vw) {
	    int tilev = v / tileresv;
	    kt.v = v % tileresv;
	    kt.vw = PtexUtils::min(vw, tileresv - kt.v);
	    kt.kv = k.kv + v - k.v;
	    for (int u = k.u, uw = k.uw; uw > 0; uw -= kt.uw, u += kt.uw) {
		int tileu = u / tileresu;
		kt.u = u % tileresu;
		kt.uw = PtexUtils::min(uw, tileresu - kt.u);
		kt.ku = k.ku + u - k.u;
		PtexPtr<PtexFaceData> th ( dh->getTile(tilev * ntilesu + tileu) );
		if (th) {
		    if (th->isConstant())
			kt.applyConst(_result, (char*)th->getData()+_firstChanOffset, _dt, _nchan);
		    else
			kt.apply(_result, (char*)th->getData()+_firstChanOffset, _dt, _nchan, _ntxchan);
		}
	    }
	}
    }
    else {
	k.apply(_result, (char*)dh->getData()+_firstChanOffset, _dt, _nchan, _ntxchan);
    }
}
Пример #5
0
void DumpTiling(PtexFaceData* dh)
{
    std::cout << "  tiling: ";
    if (dh->isTiled()) {
        Ptex::Res res = dh->tileRes();
        std::cout << "ntiles = " << dh->res().ntiles(res)
                  << ", res = "
                  << int(res.ulog2) << ' ' << int(res.vlog2)
                  << " (" << res.u() << " x " << res.v() << ")\n";
    }
    else if (dh->isConstant()) {
        std::cout << "  (constant)" << std::endl;
    }
    else {
        std::cout << "  (untiled)" << std::endl;
    }
}
Пример #6
0
void PtexTriangleFilter::applyIter(PtexTriangleKernelIter& k, PtexFaceData* dh)
{
    if (dh->isConstant()) {
        k.applyConst(_result, (char*)dh->getData()+_firstChanOffset, _dt, _nchan);
        _weight += k.weight;
    }
    else if (dh->isTiled()) {
        Ptex::Res tileres = dh->tileRes();
        PtexTriangleKernelIter kt = k;
        int tileresu = tileres.u();
        int tileresv = tileres.v();
        kt.rowlen = tileresu;
        int ntilesu = k.rowlen / kt.rowlen;
        int wOffsetBase = k.rowlen - tileresu;
        for (int tilev = k.v1 / tileresv, tilevEnd = (k.v2-1) / tileresv; tilev <= tilevEnd; tilev++) {
            int vOffset = tilev * tileresv;
            kt.v = k.v - (float)vOffset;
            kt.v1 = PtexUtils::max(0, k.v1 - vOffset);
            kt.v2 = PtexUtils::min(k.v2 - vOffset, tileresv);
            for (int tileu = k.u1 / tileresu, tileuEnd = (k.u2-1) / tileresu; tileu <= tileuEnd; tileu++) {
                int uOffset = tileu * tileresu;
                int wOffset = wOffsetBase - uOffset - vOffset;
                kt.u = k.u - (float)uOffset;
                kt.u1 = PtexUtils::max(0, k.u1 - uOffset);
                kt.u2 = PtexUtils::min(k.u2 - uOffset, tileresu);
                kt.w1 = k.w1 - wOffset;
                kt.w2 = k.w2 - wOffset;
                PtexPtr<PtexFaceData> th ( dh->getTile(tilev * ntilesu + tileu) );
                if (th) {
                    kt.weight = 0;
                    if (th->isConstant())
                        kt.applyConst(_result, (char*)th->getData()+_firstChanOffset, _dt, _nchan);
                    else
                        kt.apply(_result, (char*)th->getData()+_firstChanOffset, _dt, _nchan, _ntxchan);
                    _weight += kt.weight;
                }
            }
        }
    }
    else {
        k.apply(_result, (char*)dh->getData()+_firstChanOffset, _dt, _nchan, _ntxchan);
        _weight += k.weight;
    }
}
Пример #7
0
void IBLWidget::loadIBL( const char* filename )
{
    printf( "opening %s... ", filename );

    // try and load it
    Ptex::String error;
    PtexTexture* tx = PtexTexture::open(filename, error);
    if (!tx) {
        printf( "failed\n");
        return;
    }

    CKGL();

    Ptex::DataType dataType = tx->dataType();
    int numChannels = tx->numChannels();
    int numFaces=tx->numFaces();
    int faceWidth=0, faceHeight=0;

    if( dataType != Ptex::dt_float || numChannels != 3 || numFaces != 6 )
    {
        printf( "not the right kind\n" );
        return;
    }

    for( int i = 0; i < numFaces; i++ )
    {
        int face = i;


        Ptex::Res res = tx->getFaceInfo(i).res;
        if( i == 0 )
        {
            faceWidth = res.u();
            faceHeight = res.v();

            // printf( "size: %dx%d    (%dx%d)\n", faceWidth, faceHeight, faceWidth*6, faceHeight );

            envTex.create( faceWidth*6, faceHeight );
        }

        if( faceWidth != res.u() || faceHeight != res.v() )
        {
            printf( "error loading ptex file\n" );
            return;
        }

        float* faceData = (float*)malloc( faceWidth*faceHeight*numChannels*sizeof(float) );
        tx->getData( i, faceData, 0 );

        // copy the data into the envmap texture
        for( int j = 0; j < faceHeight * faceWidth; j++ )
        {
            color3 c( faceData[j*3+0], faceData[j*3+1], faceData[j*3+2] );
            envTex.setPixel( faceWidth*face + j % faceWidth, j / faceWidth, c );
        }

        free( faceData );

    }
    tx->release();
    printf( "success\n");

    // allocate texture names (if we haven't before)
    if( envTexID == 0 ) {
        glf->glGenTextures( 1, &envTexID );
        glf->glGenTextures( 1, &probTexID );
        glf->glGenTextures( 1, &marginalProbTexID );
    }

    CKGL();

    // now that the envmap tex is loaded, compute the sampling data
    computeEnvMapSamplingData();
    createGLSamplingTextures();

    CKGL();

    glf->glGenTextures(1, &envTexID);
    glf->glBindTexture( GL_TEXTURE_CUBE_MAP, envTexID );
    glf->glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);


    BitmapContainer<color3> flip;
    flip.create(envTex.w, envTex.h);//get face flipped to match GL thinking!
    for (int y=0; y < envTex.h; y++){
        color3* in = &envTex.data[y*envTex.w];
        color3* out = &flip.data[(envTex.h-y-1)*envTex.w];
        for (int x=0; x < envTex.w; x++)
            out[x] = in[x];
    }

    BitmapContainer<color3> tmp;
    tmp.create(envTex.h, envTex.h);

    CKGL();

    for (int y=0; y < tmp.h; y++)
        for (int x=0; x < tmp.w; x++)
            tmp.setPixel(x, y,flip.getPixel(x+tmp.w*0, y));
    glf->glTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_X , 0,GL_R11F_G11F_B10F, tmp.w, tmp.h, 0, GL_RGB, GL_FLOAT, tmp.getPtr() );


    for (int y=0; y < tmp.h; y++)
        for (int x=0; x < tmp.w; x++)
            tmp.setPixel(x, y,flip.getPixel(x+tmp.w*1, y));
    glf->glTexImage2D( GL_TEXTURE_CUBE_MAP_NEGATIVE_X , 0,GL_R11F_G11F_B10F, tmp.w, tmp.h, 0, GL_RGB, GL_FLOAT, tmp.getPtr() );

    for (int y=0; y < tmp.h; y++)
        for (int x=0; x < tmp.w; x++)
            tmp.setPixel(x, y,flip.getPixel(x+tmp.w*2, y));
    glf->glTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_Y , 0,GL_R11F_G11F_B10F, tmp.w, tmp.h, 0, GL_RGB, GL_FLOAT, tmp.getPtr() );

    for (int y=0; y < tmp.h; y++)
        for (int x=0; x < tmp.w; x++)
            tmp.setPixel(x, y,flip.getPixel(x+tmp.w*3, y));
    glf->glTexImage2D( GL_TEXTURE_CUBE_MAP_NEGATIVE_Y , 0,GL_R11F_G11F_B10F, tmp.w, tmp.h, 0, GL_RGB, GL_FLOAT, tmp.getPtr() );

    for (int y=0; y < tmp.h; y++)
        for (int x=0; x < tmp.w; x++)
            tmp.setPixel(x, y,flip.getPixel(x+tmp.w*4, y));
    glf->glTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_Z , 0,GL_R11F_G11F_B10F, tmp.w, tmp.h, 0, GL_RGB, GL_FLOAT, tmp.getPtr() );


    CKGL();

    for (int y=0; y < tmp.h; y++)
        for (int x=0; x < tmp.w; x++)
            tmp.setPixel(x, y,flip.getPixel(x+tmp.w*5, y));
    glf->glTexImage2D( GL_TEXTURE_CUBE_MAP_NEGATIVE_Z , 0,GL_R11F_G11F_B10F, tmp.w, tmp.h, 0, GL_RGB, GL_FLOAT, tmp.getPtr() );

    CKGL();

    glf->glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
    glf->glBindTexture( GL_TEXTURE_CUBE_MAP, 0 );

    CKGL();
}
Пример #8
0
  OBJScene::Texture *loadPtexTexture(const FileName& filename)
  {
#if defined(USE_PTEX)
    std::string fn = filename.str();
    Ptex::String error;
    std::cout << "opening " << fn << " ... " << std::flush;
    PtexTexture* tex = PtexTexture::open(fn.c_str(),error);
    if (!tex) {
      std::cout << "[FAILED]" << std::endl;
      THROW_RUNTIME_ERROR("cannot open ptex file: "+fn);
    }
    
    PtexMetaData *metadata = tex->getMetaData();
    const int32_t *vertices_per_face = nullptr;
    int geom_faces = 0;
    metadata->getValue("PtexFaceVertCounts", vertices_per_face, geom_faces);

    OBJScene::Texture **face_textures = new OBJScene::Texture *[geom_faces];
    for (size_t i=0;i<geom_faces;i++)
      face_textures[i] = nullptr;

    OBJScene::Texture *texture = new OBJScene::Texture();
    texture->width         = 0;
    texture->height        = 0;    
    texture->format        = OBJScene::Texture::PTEX_RGBA8;
    texture->faceTextures  = geom_faces;
    texture->data          = face_textures;
    texture->width_mask    = 0;
    texture->height_mask   = 0;

    int nchan = tex->numChannels();
    if (nchan != 3 && nchan != 1) 
      {
	std::cout << "[FAILED]" << std::endl;
	THROW_RUNTIME_ERROR(fn+": ptex file with other than 1 or 3 channels found!");
      }

    if (nchan == 1)
      texture->format = OBJScene::Texture::PTEX_FLOAT32;

    float px[3];
    int ptex_face_id = 0;

    for (size_t geom_face_id=0;geom_face_id<geom_faces;geom_face_id++)
      {
	face_textures[geom_face_id] = nullptr;
	const Ptex::FaceInfo &fi = tex->getFaceInfo(ptex_face_id);

	int n = vertices_per_face[geom_face_id];
	if (n == 4) /* ptex data only for quads */
	  {
	    Ptex::Res res = fi.res;
			  
	    OBJScene::Texture *face_txt = new OBJScene::Texture();
	    face_txt->width         = res.u();
	    face_txt->height        = res.v();    
	    face_txt->width_mask    =  0;
	    face_txt->height_mask   =  0;
	    face_txt->data          = nullptr;
	    face_textures[geom_face_id] = face_txt;
	  
	    if (nchan == 3) /* rgb color data */
	      {
		face_txt->format        = OBJScene::Texture::RGBA8;
		face_txt->bytesPerTexel = 4;
		unsigned char *data     = new unsigned char[face_txt->bytesPerTexel*face_txt->width*face_txt->height];
		face_txt->data          = data;

		for (int vi = 0; vi < face_txt->height; vi++) {
		  for (int ui = 0; ui < face_txt->width; ui++) {
		    tex->getPixel(ptex_face_id, ui, vi, px, 0, nchan, res);
		    data[(vi*face_txt->width+ui)*4+0] = (unsigned char)(px[0]*255.0f);
		    data[(vi*face_txt->width+ui)*4+1] = (unsigned char)(px[1]*255.0f);
		    data[(vi*face_txt->width+ui)*4+2] = (unsigned char)(px[2]*255.0f);
		  }
		}
	      }
	    else if (nchan == 1) /* displacement data */
	      {
		face_txt->format        = OBJScene::Texture::FLOAT32;
		face_txt->bytesPerTexel = 4;
		float*data              = new float[face_txt->width*face_txt->height];
		face_txt->data          = data;

		for (int vi = 0; vi < face_txt->height; vi++) {
		  for (int ui = 0; ui < face_txt->width; ui++) {
		    tex->getPixel(ptex_face_id, ui, vi, px, 0, nchan, res);
		    if (!isfinite(px[0]))
		      px[0] = 0.0f;
		    data[vi*face_txt->width+ui] = px[0];
		  }
		}
	      }
	    ptex_face_id++;
	  }
	else 
	    ptex_face_id += 3;
      }
    std::cout << "done" << std::endl << std::flush;
    return texture;	
#else
    return nullptr;
#endif
  }
Пример #9
0
void PtexSeparableFilter::apply(PtexSeparableKernel& k, int faceid, const Ptex::FaceInfo& f)
{
    assert(k.u >= 0 && k.u + k.uw <= k.res.u());
    assert(k.v >= 0 && k.v + k.vw <= k.res.v());

    if (k.uw <= 0 || k.vw <= 0) return;

    // downres kernel if needed
    while (k.res.u() > f.res.u()) k.downresU();
    while (k.res.v() > f.res.v()) k.downresV();

    // get face data, and apply
    PtexPtr<PtexFaceData> dh ( _tx->getData(faceid, k.res) );
    if (!dh) return;

    if (dh->isConstant()) {
        k.applyConst(_result, (char*)dh->getData()+_firstChanOffset, _dt, _nchan);
        return;
    }

    // allocate temporary result for tanvec mode (if needed)
    bool tanvecMode = (_efm == efm_tanvec) && (_nchan >= 2) && (k.rot > 0);
    float* result = tanvecMode ? (float*) alloca(sizeof(float)*_nchan) : _result;
    if (tanvecMode) memset(result, 0, sizeof(float)*_nchan);

    if (dh->isTiled()) {
        Ptex::Res tileres = dh->tileRes();
        PtexSeparableKernel kt;
        kt.res = tileres;
        int tileresu = tileres.u();
        int tileresv = tileres.v();
        int ntilesu = k.res.u() / tileresu;
        for (int v = k.v, vw = k.vw; vw > 0; vw -= kt.vw, v += kt.vw) {
            int tilev = v / tileresv;
            kt.v = v % tileresv;
            kt.vw = PtexUtils::min(vw, tileresv - kt.v);
            kt.kv = k.kv + v - k.v;
            for (int u = k.u, uw = k.uw; uw > 0; uw -= kt.uw, u += kt.uw) {
                int tileu = u / tileresu;
                kt.u = u % tileresu;
                kt.uw = PtexUtils::min(uw, tileresu - kt.u);
                kt.ku = k.ku + u - k.u;
                PtexPtr<PtexFaceData> th ( dh->getTile(tilev * ntilesu + tileu) );
                if (th) {
                    if (th->isConstant())
                        kt.applyConst(result, (char*)th->getData()+_firstChanOffset, _dt, _nchan);
                    else
                        kt.apply(result, (char*)th->getData()+_firstChanOffset, _dt, _nchan, _ntxchan);
                }
            }
        }
    }
    else {
        k.apply(result, (char*)dh->getData()+_firstChanOffset, _dt, _nchan, _ntxchan);
    }

    if (tanvecMode) {
        // rotate tangent-space vector data and update main result
        switch (k.rot) {
            case 0: // rot==0 included for completeness, but tanvecMode should be false in this case
                _result[0] += result[0];
                _result[1] += result[1];
                break;
            case 1:
                _result[0] -= result[1];
                _result[1] += result[0];
                break;
            case 2:
                _result[0] -= result[0];
                _result[1] -= result[1];
                break;
            case 3:
                _result[0] += result[1];
                _result[1] -= result[0];
                break;
        }
        for (int i = 2; i < _nchan; i++) _result[i] += result[i];
    }
}