colorPerVertexApproximator.hpp 5.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps  *
* version 0.1                                                                  *
* Copyright (C) 2009-2012, IGG Team, LSIIT, University of Strasbourg           *
*                                                                              *
* This library is free software; you can redistribute it and/or modify it      *
* under the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, or (at your     *
* option) any later version.                                                   *
*                                                                              *
* This library is distributed in the hope that it will be useful, but WITHOUT  *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or        *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License  *
* for more details.                                                            *
*                                                                              *
* You should have received a copy of the GNU Lesser General Public License     *
* along with this library; if not, write to the Free Software Foundation,      *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.           *
*                                                                              *
* Web site: http://cgogn.unistra.fr/                                           *
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/

namespace CGoGN
{

namespace Algo
{

namespace Decimation
{

/************************************************************************************
35
 *                      NAIVE COLOR METRIC                                          *
36 37 38
 ************************************************************************************/

template <typename PFP>
39
void Approximator_ColorNaive<PFP>::approximate(Dart d)
40 41 42
{
	Dart dd = this->m_map.phi1(d) ;

43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
	const VEC3& p1 = m_position.operator[](d) ;
	const VEC3& p2 = m_position.operator[](dd) ;
	const VEC3& p = m_approxposition.operator[](d) ;

	const VEC3& edge = p2 - p1 ;
	const REAL& ratio = std::max(std::min(((p - p1) * edge) / edge.norm2(),REAL(1)),REAL(0)) ;

	this->m_approx[0][d] = m_color->operator[](d)*ratio + m_color->operator[](dd)*(1-ratio) ;
}

/************************************************************************************
 *                            EXTENDED QUADRIC ERROR METRIC                         *
 ************************************************************************************/
template <typename PFP>
bool Approximator_ColorQEMext<PFP>::init()
{
	m_quadric = this->m_map.template getAttribute<QuadricNd<REAL,6>, VERTEX>("QEMext-quadric") ;

	if(this->m_predictor)
	{
		return false ;
	}
	return true ;
}

template <typename PFP>
void Approximator_ColorQEMext<PFP>::approximate(Dart d)
{
	MAP& m = this->m_map ;

	// get some darts
	Dart dd = m.phi2(d) ;

	QuadricNd<REAL,6> q1, q2 ;
	if(!m_quadric.isValid()) // if the selector is not QEM, compute local error quadrics
	{
		// compute the error quadric associated to v1
		Dart it = d ;
		do
		{
			VEC6 p0,p1,p2 ;
			for (unsigned int i = 0 ; i < 3 ; ++i)
			{
				p0[i] = this->m_attrV[0]->operator[](it)[i] ;
				p0[i+3] = this->m_attrV[1]->operator[](it)[i] ;
				p1[i] = this->m_attrV[0]->operator[](m.phi1(it))[i] ;
				p1[i+3] = this->m_attrV[1]->operator[](m.phi1(it))[i] ;
				p2[i] = this->m_attrV[0]->operator[](m.phi_1(it))[i] ;
				p2[i+3] = this->m_attrV[1]->operator[](m.phi_1(it))[i] ;
			}

			QuadricNd<REAL,6> q(p0,p1,p2) ;
			q1 += q ;
			it = m.phi2_1(it) ;
		} while(it != d) ;

		// compute the error quadric associated to v2
		it = dd ;
		do
		{
			VEC6 p0,p1,p2 ;
			for (unsigned int i = 0 ; i < 3 ; ++i)
			{
				p0[i] = this->m_attrV[0]->operator[](it)[i] ;
				p0[i+3] = this->m_attrV[1]->operator[](it)[i] ;
				p1[i] = this->m_attrV[0]->operator[](m.phi1(it))[i] ;
				p1[i+3] = this->m_attrV[1]->operator[](m.phi1(it))[i] ;
				p2[i] = this->m_attrV[0]->operator[](m.phi_1(it))[i] ;
				p2[i+3] = this->m_attrV[1]->operator[](m.phi_1(it))[i] ;
			}

			QuadricNd<REAL,6> q(p0,p1,p2) ;
			q2 += q ;
			it = m.phi2_1(it) ;
		} while(it != dd) ;
	}
	else // if the selector is QEM, use the error quadrics computed by the selector
	{
		q1 = m_quadric[d] ;
		q2 = m_quadric[dd] ;
	}

	QuadricNd<REAL,6> quad ;
	quad += q1 ;	// compute the sum of the
	quad += q2 ;	// two vertices quadrics

	VEC6 res ;
130
	bool opt = quad.findOptimizedVec(res) ;	// try to compute an optimized position for the contraction of this edge
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
	if(!opt)
	{
		VEC6 p1, p2 ;
		for (unsigned int i = 0 ; i < 3; ++i)
		{
			p1[i] = this->m_attrV[0]->operator[](d)[i] ;	// let the new vertex lie
			p1[i+3] = this->m_attrV[1]->operator[](d)[i] ; // on either one
			p2[i] = this->m_attrV[0]->operator[](dd)[i] ;	// of the two
			p2[i+3] = this->m_attrV[1]->operator[](dd)[i] ; // endpoints
		}
		VEC6 p12 = (p1 + p2) / 2.0f ;	// or the middle of the edge

		REAL e1 = quad(p1) ;
		REAL e2 = quad(p2) ;
		REAL e12 = quad(p12) ;
		REAL minerr = std::min(std::min(e1, e2), e12) ;	// consider only the one for
		if(minerr == e12)
			res = p12 ;		// which the error is minimal
		else if(minerr == e1)
			res = p1 ;
		else
			res = p2 ;
	}

	// copy res into m_approx
	for (unsigned int i = 0 ; i < 3 ; ++i)
	{
158 159
		this->m_approx[0][d][i] = res[i] ;
		this->m_approx[1][d][i] = res[i+3] ;
160
	}
161 162 163 164 165 166 167
}

} //namespace Decimation

} //namespace Algo

} //namespace CGoGN