/*! end current facegroup and append to mesh */
  void OBJLoader::flushFaceGroup()
  {
    if (curGroup.empty()) return;
    
    if (subdivMode)
    {
      Ref<SceneGraph::SubdivMeshNode> mesh = new SceneGraph::SubdivMeshNode(curMaterial);
      group->add(mesh.cast<SceneGraph::Node>());

      for (size_t i=0; i<v.size();  i++) mesh->positions.push_back(v[i]);
      for (size_t i=0; i<vn.size(); i++) mesh->normals  .push_back(vn[i]);
      for (size_t i=0; i<vt.size(); i++) mesh->texcoords.push_back(vt[i]);
      
      for (size_t i=0; i<ec.size(); ++i) {
        assert(ec[i].a < v.size() && ec[i].b < v.size());
        mesh->edge_creases.push_back(Vec2i(ec[i].a, ec[i].b));
        mesh->edge_crease_weights.push_back(ec[i].w);
      }
      
      for (size_t j=0; j<curGroup.size(); j++)
      {
        const std::vector<Vertex>& face = curGroup[j];
        mesh->verticesPerFace.push_back(face.size());
        for (size_t i=0; i<face.size(); i++)
          mesh->position_indices.push_back(face[i].v);
      }
    }
    else
    {
      Ref<SceneGraph::TriangleMeshNode> mesh = new SceneGraph::TriangleMeshNode(curMaterial);
      group->add(mesh.cast<SceneGraph::Node>());
      
      // merge three indices into one
      std::map<Vertex, uint32_t> vertexMap;
      for (size_t j=0; j<curGroup.size(); j++)
      {
        /* iterate over all faces */
        const std::vector<Vertex>& face = curGroup[j];
        
        /* triangulate the face with a triangle fan */
        Vertex i0 = face[0], i1 = Vertex(-1), i2 = face[1];
        for (size_t k=2; k < face.size(); k++) 
        {
          i1 = i2; i2 = face[k];
          uint32_t v0,v1,v2;
          v0 = getVertex(vertexMap, mesh, i0);
          v1 = getVertex(vertexMap, mesh, i1);
          v2 = getVertex(vertexMap, mesh, i2);
          assert(v0 < mesh->v.size());
          assert(v1 < mesh->v.size());
          assert(v2 < mesh->v.size());
          mesh->triangles.push_back(SceneGraph::TriangleMeshNode::Triangle(v0,v1,v2));
        }
      }
    }
    curGroup.clear();
    ec.clear();
  }
Ejemplo n.º 2
0
 void build_sah(avector<PrimRef>& prims, isa::PrimInfo& pinfo)
 {
   size_t N = pinfo.size();
   
   /* fast allocator that supports thread local operation */
   FastAllocator allocator(nullptr);
   
   for (size_t i=0; i<2; i++)
   {
     std::cout << "iteration " << i << ": building BVH over " << N << " primitives, " << std::flush;
     double t0 = getSeconds();
     
     allocator.reset();
     
     Node* root;
     isa::BVHBuilderBinnedSAH::build<Node*>(
       root,
       /* thread local allocator for fast allocations */
       [&] () -> FastAllocator::ThreadLocal* { 
         return allocator.threadLocal(); 
       },
       
       /* lambda function that creates BVH nodes */
       [&](const isa::BVHBuilderBinnedSAH::BuildRecord& current, isa::BVHBuilderBinnedSAH::BuildRecord* children, const size_t N, FastAllocator::ThreadLocal* alloc) -> int
       {
         assert(N <= 2);
         InnerNode* node = new (alloc->malloc(sizeof(InnerNode))) InnerNode;
         for (size_t i=0; i<N; i++) {
           node->bounds[i] = children[i].pinfo.geomBounds;
           children[i].parent = (size_t*) &node->children[i];
         }
         *current.parent = (size_t) node;
         return 0;
       },
       
       /* lambda function that creates BVH leaves */
       [&](const isa::BVHBuilderBinnedSAH::BuildRecord& current, FastAllocator::ThreadLocal* alloc) -> int
       {
         assert(current.prims.size() == 1);
         Node* node = new (alloc->malloc(sizeof(LeafNode))) LeafNode(prims[current.prims.begin()].ID(),prims[current.prims.begin()].bounds());
         *current.parent = (size_t) node;
         return 0;
       },
       
       /* progress monitor function */
       [&] (size_t dn) { 
         // throw an exception here to cancel the build operation
       },
       
       prims.data(),pinfo,2,1024,1,1,1,1.0f,1.0f);
     
     double t1 = getSeconds();
     
     std::cout << 1000.0f*(t1-t0) << "ms, " << 1E-6*double(N)/(t1-t0) << " Mprims/s, sah = " << root->sah() << " [DONE]" << std::endl;
   }
 }
 int OBJLoader::fix_vn(int index) { return (index > 0 ? index - 1 : (index == 0 ? 0 : (int) vn.size() + index)); }
Ejemplo n.º 4
0
 void build_morton(avector<PrimRef>& prims, isa::PrimInfo& pinfo)
 {
   unsigned N = unsigned(pinfo.size());
   /* array for morton builder */
   avector<isa::MortonID32Bit> morton_src(N);
   avector<isa::MortonID32Bit> morton_tmp(N);
   for (unsigned i=0; i<N; i++) 
     morton_src[i].index = i;
   
   /* fast allocator that supports thread local operation */
   FastAllocator allocator(nullptr);
   
   for (size_t i=0; i<2; i++)
   {
     std::cout << "iteration " << i << ": building BVH over " << N << " primitives, " << std::flush;
     double t0 = getSeconds();
     
     allocator.reset();
     
     std::pair<Node*,BBox3fa> node_bounds = isa::bvh_builder_morton<Node*>(
       
       /* thread local allocator for fast allocations */
       [&] () -> FastAllocator::ThreadLocal* { 
         return allocator.threadLocal(); 
       },
       
       BBox3fa(empty),
       
       /* lambda function that allocates BVH nodes */
       [&] ( isa::MortonBuildRecord<Node*>& current, isa::MortonBuildRecord<Node*>* children, size_t N, FastAllocator::ThreadLocal* alloc ) -> InnerNode*
       {
         assert(N <= 2);
         InnerNode* node = new (alloc->malloc(sizeof(InnerNode))) InnerNode;
         *current.parent = node;
         for (size_t i=0; i<N; i++) 
           children[i].parent = &node->children[i];
         return node;
       },
       
       /* lambda function that sets bounds */
       [&] (InnerNode* node, const BBox3fa* bounds, size_t N) -> BBox3fa
       {
         BBox3fa res = empty;
         for (size_t i=0; i<N; i++) {
           const BBox3fa b = bounds[i];
           res.extend(b);
           node->bounds[i] = b;
         }
         return res;
       },
       
       /* lambda function that creates BVH leaves */
       [&]( isa::MortonBuildRecord<Node*>& current, FastAllocator::ThreadLocal* alloc, BBox3fa& box_o) -> Node*
       {
         assert(current.size() == 1);
         const size_t id = morton_src[current.begin].index;
         const BBox3fa bounds = prims[id].bounds(); 
         Node* node = new (alloc->malloc(sizeof(LeafNode))) LeafNode(id,bounds);
         *current.parent = node;
         box_o = bounds;
         return node;
       },
       
       /* lambda that calculates the bounds for some primitive */
       [&] (const isa::MortonID32Bit& morton) -> BBox3fa {
         return prims[morton.index].bounds();
       },
       
       /* progress monitor function */
       [&] (size_t dn) { 
         // throw an exception here to cancel the build operation
       },
       
       morton_src.data(),morton_tmp.data(),prims.size(),2,1024,1,1);
     
     Node* root = node_bounds.first;
     
     double t1 = getSeconds();
     
     std::cout << 1000.0f*(t1-t0) << "ms, " << 1E-6*double(N)/(t1-t0) << " Mprims/s, sah = " << root->sah() << " [DONE]" << std::endl;
   }
 }