예제 #1
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
  }
예제 #2
0
bool mesh::loadFromMetaData(PtexTexture* r)
{
    PtexMetaData* meta = r->getMetaData();
    if (meta->numKeys()<3) return false;
    
    triangles = r->meshType()==Ptex::mt_triangle;

    const float* vf;
    const int *vif, *fvc;
    int vertcount, indexcount, facevertcount;

    meta->getValue("PtexFaceVertCounts",fvc,facevertcount);
    if (facevertcount==0) return false;
    meta->getValue("PtexVertPositions",vf,vertcount);
    if (vertcount==0) return false;
    meta->getValue("PtexFaceVertIndices",vif,indexcount);
    if (indexcount==0) return false;
    
    for (int i=0; i<vertcount; i+=3) addVertex(&vf[i]);
        
    int* fviptr = (int*) vif;
    int* nvptr = (int*) fvc;
    for (int i=0; i<facevertcount; i++)
    {
        int nverts = *nvptr;
        if (triangles)
        {
            if (nverts!=3) return false;
            polygon q;
            q.indices[0] = fviptr[0];
            q.indices[1] = fviptr[1];
            q.indices[2] = fviptr[2];
            q.indices[3] = -1;
            addFace(q);
        }
        else if (nverts==4)
        {
            polygon q;
            q.indices[0] = fviptr[0];
            q.indices[1] = fviptr[1];
            q.indices[2] = fviptr[2];
            q.indices[3] = fviptr[3];
            addFace(q);
        }
        else
        {
            int vib = verts.size();

            // Add new vertices at edge midpoints and polygon center
            Vec3f cp = Vec3f(0,0,0);
            for (int v=0; v<nverts; v++)
            {
                verts.push_back((verts[fviptr[v]] + verts[fviptr[(v+1)%nverts]])/2);
                cp += verts[fviptr[v]];
            }
            verts.push_back(cp/nverts);

            // Add the new sub-faces
            for (int v=0; v<nverts; v++)
            {
                polygon q;
                q.indices[0] = fviptr[v];
                q.indices[1] = vib+v;
                q.indices[2] = verts.size()-1;
                q.indices[3] = vib+(v+nverts-1)%nverts;
                addFace(q);
            }
        }
        fviptr+=nverts;
        nvptr++;
    }
    
    if ((int)polys.size()!=r->numFaces())
    {
        verts.clear();
        polys.clear();
        return false;
    }
    
    return true;
}
예제 #3
0
OpenSubdiv::HbrMesh<T> * createPTexGeo(PtexTexture * r)
{
  PtexMetaData* meta = r->getMetaData();
  if(meta->numKeys()<3) return NULL;

  const float* vp;
  const int *vi, *vc;
  int nvp, nvi, nvc;

  meta->getValue("PtexFaceVertCounts", vc, nvc);
  if (nvc==0)
      return NULL;

  meta->getValue("PtexVertPositions", vp, nvp);
  if (nvp==0)
      return NULL;

  meta->getValue("PtexFaceVertIndices", vi, nvi);
  if (nvi==0)
      return NULL;

  static OpenSubdiv::HbrCatmarkSubdivision<T>  _catmark;
  static OpenSubdiv::HbrBilinearSubdivision<T>  _bilinear;
  OpenSubdiv::HbrMesh<T> * mesh;
  if(g_scheme == 0)
      mesh = new OpenSubdiv::HbrMesh<T>(&_catmark);
  else
      mesh = new OpenSubdiv::HbrMesh<T>(&_bilinear);

  g_positions.clear();
  g_positions.reserve(nvp);

  // compute model bounding
  float min[3] = {vp[0], vp[1], vp[2]};
  float max[3] = {vp[0], vp[1], vp[2]};
  for (int i=0; i<nvp/3; ++i) {
      for(int j=0; j<3; ++j) {
          float v = vp[i*3+j];
          g_positions.push_back(v);
          min[j] = std::min(min[j], v);
          max[j] = std::max(max[j], v);
      }
      mesh->NewVertex(i, T());
  }
  for (int j=0; j<3; ++j) {
      g_center[j] = (min[j] + max[j]) * 0.5f;
      g_size += (max[j]-min[j])*(max[j]-min[j]);
  }
  g_size = sqrtf(g_size);

  const int *fv = vi;
  for (int i=0, ptxidx=0; i<nvc; ++i) {
      int nv = vc[i];
      OpenSubdiv::HbrFace<T> * face = mesh->NewFace(nv, (int *)fv, 0);

      face->SetPtexIndex(ptxidx);
      if(nv != 4)
          ptxidx+=nv;
      else
          ptxidx++;

      fv += nv;
  }
  mesh->SetInterpolateBoundaryMethod( OpenSubdiv::HbrMesh<T>::k_InterpolateBoundaryEdgeOnly );
//  set creases here
//  applyTags<T>( mesh, sh );
  mesh->Finish();

  return mesh;
}