Esempio n. 1
0
void SimplifTrian<PFP>::simplifUntil(unsigned int nbWantedTriangles)
{
    m_nbWanted = nbWantedTriangles;

    bool notFinished = true;
    while (notFinished)
    {
        // TODO optimiser la calcul de diff
        int diff = (m_nbTriangles - m_nbWanted) / 8;
        if (diff < 128)
            diff = 128;

        int collapsed = 0;
        CRIT_IT it = m_edgeCrit.begin();
        // traverse the criteria map until diff collapse & enough triangles
        while ( (it != m_edgeCrit.end()) /*&& (collapsed < diff)*/ && (m_nbWanted < m_nbTriangles) )
        {
            // get the criteria
            CRIT* cr = it->second;
//			 if criteria invalid then remove it and step to next
            if (cr->isDirty())
            {
                CRIT_IT jt = it++;
                delete jt->second;
                m_edgeCrit.erase(jt);
            }
            else
            {
                Dart d = cr->getDart();
                if (cr->removingAllowed())
                {
                    if (edgeIsCollapsible(d))
                    {
                        // compute new position
                        typename PFP::VEC3 np = cr->newPosition(m_map, m_positions);
                        // and collapse edge
                        Dart dd = edgeCollapse(d, np);
                        // update criterias
                        updateCriterias(dd);
                        m_nbTriangles -= 2;
                        ++collapsed;
                    }
                }
                ++it;
            }
        }
        // test finish condition
        if ((collapsed == 0) || (m_nbWanted >= m_nbTriangles))
            notFinished = false;

        m_protectMarker.unmarkAll();
    }
}
Esempio n. 2
0
void VolumetricProgressiveMesh<PFP>::coarsen()
{
	if(m_cur == m_splits.size())
		return ;

	VSplit<PFP>* vs = m_splits[m_cur] ; // get the split node
	++m_cur ;

	Dart d = vs->getEdge() ;
	Dart dd = m_map.phi2(d) ;		// get some darts
	Dart d2 = vs->getLeftEdge() ;
	Dart dd2 = vs->getRightEdge() ;

	edgeCollapse(vs) ;	// collapse edge

	m_map.template setOrbitEmbedding<VERTEX>(d2, vs->getApproxV()) ;
	m_map.template setOrbitEmbedding<EDGE>(d2, vs->getApproxE1()) ;
	m_map.template setOrbitEmbedding<EDGE>(dd2, vs->getApproxE2()) ;
}
Esempio n. 3
0
bool BuilderTerrain::simplifyTriangle(runnel::Triangle* triangle, Terrain* ter){
    assert(("Triangle to simplify was not part of the terrain",ter->struct_triangle.find(triangle) != ter->struct_triangle.end()));
    runnel::Edge* shortestEdge = triangle->getShortestEdge();
    bool edgeWasCollapsed = edgeCollapse(shortestEdge, ter);
    return edgeWasCollapsed;
}
Esempio n. 4
0
void Mesh<VertData, TriData>::remesh()
{
    //std::cout << "remesh initial tri count: " << tris.size() << std::endl;
    if(verts.size() == 0)   return; // pathology guard
    
    /*{ // dump out mesh before performing re-mesh
        Files::FileMesh filemesh;
        filemesh = transduce<Files::FileVertex, Files::FileTriangle,
                             VertData, TriData>
        (raw(),
        [](Files::FileVertex &out, const VertData &in) {
            out.pos = in.pos;
        },
        [](Files::FileTriangle &out, const TriData &in) {
            out.a = in.a; out.b = in.b; out.c = in.c;
        });
        if(Files::writeTriMesh("remesh_in.off", &filemesh) > 0) {
            CORK_ERROR("Unable to write out remesh input to remesh_in.off");
        }
    }*/
    
    // create a scratchpad and set it up
    RemeshScratchpad scratchpad(this);
    
    // compute which vertices are boundary or not
    for(VertData &v : verts) {
        v.manifold = true;
    }
    scratchpad.cache.edges.for_each([this, &scratchpad](Eptr edge) {
        if(edge->tris.size() != 2) {
            verts[edge->verts[0]->ref].manifold = false;
            verts[edge->verts[1]->ref].manifold = false;
        }
    });
    
    // Then, we set up the priority queue
    // (allocating auxiliary data as we go)
    scratchpad.cache.edges.for_each([this, &scratchpad](Eptr edge) {
        edge->data = scratchpad.edge_data.alloc();
        scoreAndEnqueue(scratchpad.queue, edge);
    });
    
    int cutoff = 10000;
    // now let's go into a loop pulling work off of the queue
    while(scratchpad.queue.size() > 0) {
        // pop the end of the queue
        auto        it_top          = scratchpad.queue.end();
                    it_top--;
        //double      top_score       = it_top->first;
        Eptr        top_edge        = it_top->second;
                    scratchpad.queue.erase(it_top);
        
        // Which operation should be performed to this edge?
        EdgeRemeshOperation         op =
                reinterpret_cast<RemeshEdgeAuxiliary*>(top_edge->data)->op;
        if(op == EDGE_SPLIT) {
                    //std::cout << "edge split" << std::endl;
                    edgeSplit(scratchpad, top_edge);
        } else if (op == EDGE_COLLAPSE) {
                    //std::cout << "edge collapse" << std::endl;
                    edgeCollapse(scratchpad, top_edge, true);
        } // else do nothing (should have score <= 0.0 then...)
        cutoff--;
        if(cutoff < 0)
            break;
    }
    
    //std::cout << " cache.tris is "
    //          << scratchpad.cache.tris.size() << std::endl;
    //std::cout << "prefinalize tri count: " << tris.size() << std::endl;
    
    // finally, we commit all of the results of this remeshing operation
    // causing the data storage to defrag and clean out dead items
    scratchpad.cache.commit();
    
    //std::cout << "remesh final tri count: " << tris.size() << std::endl;
}
Esempio n. 5
0
void VolumetricProgressiveMesh<PFP>::createPM(unsigned int percentWantedVertices)
{
	unsigned int nbVertices = m_map.template getNbOrbits<VERTEX>() ;
	unsigned int nbWantedVertices = nbVertices * percentWantedVertices / 100 ;
	CGoGNout << "  creating PM (" << nbVertices << " vertices).." << /* flush */ CGoGNendl ;

	bool finished = false ;
	Dart d ;
	while(!finished)
	{
		if(!m_selector->nextEdge(d))
			break ;

		--nbVertices ;
		Dart d2 = m_map.phi2(m_map.phi_1(d)) ;
		Dart dd2 = m_map.phi2(m_map.phi_1(m_map.phi2(d))) ;

		VSplit<PFP>* vs = new VSplit<PFP>(m_map, d, dd2, d2) ;	// create new VSplit node
		m_splits.push_back(vs) ;								// and store it

		for(typename std::vector<Algo::Decimation::ApproximatorGen<PFP>*>::iterator it = m_approximators.begin(); it != m_approximators.end(); ++it)
		{
			(*it)->approximate(d) ;					// compute approximated attributes with its associated detail
			(*it)->saveApprox(d) ;
		}

		m_selector->updateBeforeCollapse(d) ;		// update selector

		edgeCollapse(vs) ;							// collapse edge

		unsigned int newV = m_map.template setOrbitEmbeddingOnNewCell<VERTEX>(d2) ;
		unsigned int newE1 = m_map.template setOrbitEmbeddingOnNewCell<EDGE>(d2) ;
		unsigned int newE2 = m_map.template setOrbitEmbeddingOnNewCell<EDGE>(dd2) ;
		vs->setApproxV(newV) ;
		vs->setApproxE1(newE1) ;
		vs->setApproxE2(newE2) ;

		for(typename std::vector<Algo::Decimation::ApproximatorGen<PFP>*>::iterator it = m_approximators.begin(); it != m_approximators.end(); ++it)
			(*it)->affectApprox(d2);				// affect data to the resulting vertex

		m_selector->updateAfterCollapse(d2, dd2) ;	// update selector

		if(nbVertices <= nbWantedVertices)
			finished = true ;
	}
	delete m_selector ;
	m_selector = NULL ;

	m_cur = m_splits.size() ;
	CGoGNout << "..done (" << nbVertices << " vertices)" << CGoGNendl ;






//	unsigned int nbVertices = m_map.template getNbOrbits<VERTEX>() ;
//	unsigned int nbWantedVertices = nbVertices * percentWantedVertices / 100 ;
//	CGoGNout << "  creating PM (" << nbVertices << " vertices).." << /* flush */ CGoGNendl ;
//
//	bool finished = false ;
//	Dart d ;
//	while(!finished)
//	{
//		//Next Operator to perform
//		Algo::DecimationVolumes::Operator<PFP> *op;
//
//		if((op = m_selector->nextOperator()) == NULL)
//			break;
//
//		m_nodes->add(op);
//
//		for(typename std::vector<Algo::DecimationVolumes::ApproximatorGen<PFP>*>::iterator it = m_approximators.begin(); it != m_approximators.end(); ++it)
//		{
//			(*it)->approximate(op) ;					// compute approximated attributes with its associated detail
//			(*it)->saveApprox(op) ;
//		}
//
//		//Update the selector before performing operation
//		if(!m_selector->updateBeforeOperation(op))
//			break;
//
//		nbVertices -= op->collapse(m_map, positionsTable);
//
//		for(typename std::vector<Algo::DecimationVolumes::ApproximatorGen<PFP>*>::iterator it = m_approximators.begin(); it != m_approximators.end(); ++it)
//			(*it)->affectApprox(op);				// affect data to the resulting vertex
//
//		m_selector->updateAfterOperation(op) ;	// update selector
//
//		if(nbVertices <= 3) //<= nbWantedVertices)
//			finished = true ;
//	}
//
//	m_selector->finish() ;
//
//	delete m_selector ;
//	m_selector = NULL ;
//
//	m_level = m_nodes->size() ;
//	CGoGNout << "..done (" << nbVertices << " vertices)" << CGoGNendl ;
}