Création d'un compte pour un collaborateur extérieur au laboratoire depuis l'intranet ICube : https://intranet.icube.unistra.fr/fr/labs/member/profile

volume.hpp 4.68 KB
Newer Older
Pierre Kraemer's avatar
Pierre Kraemer committed
1
2
3
/*******************************************************************************
 * CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps  *
 * version 0.1                                                                  *
4
 * Copyright (C) 2009-2012, IGG Team, LSIIT, University of Strasbourg           *
Pierre Kraemer's avatar
Pierre Kraemer committed
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 *                                                                              *
 * 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.           *
 *                                                                              *
20
 * Web site: http://cgogn.unistra.fr/                                           *
Pierre Kraemer's avatar
Pierre Kraemer committed
21
22
23
24
 * Contact information: cgogn@unistra.fr                                        *
 *                                                                              *
 *******************************************************************************/

25
#include "Topology/generic/traversorCell.h"
Pierre Kraemer's avatar
Pierre Kraemer committed
26
#include "Algo/Geometry/centroid.h"
Thomas's avatar
Thomas committed
27
#include "Algo/Modelisation/tetrahedralization.h"
Pierre Kraemer's avatar
Pierre Kraemer committed
28
29
30
31
32
33
34
35
36
37
38

namespace CGoGN
{

namespace Algo
{

namespace Geometry
{

template <typename PFP>
39
typename PFP::REAL tetrahedronSignedVolume(typename PFP::MAP& map, Dart d, const VertexAttribute<typename PFP::VEC3>& position)
Pierre Kraemer's avatar
Pierre Kraemer committed
40
41
42
43
44
45
46
47
48
49
{
	typename PFP::VEC3 p1 = position[d] ;
	typename PFP::VEC3 p2 = position[map.phi1(d)] ;
	typename PFP::VEC3 p3 = position[map.phi_1(d)] ;
	typename PFP::VEC3 p4 = position[map.phi_1(map.phi2(d))] ;

	return Geom::tetraSignedVolume(p1, p2, p3, p4) ;
}

template <typename PFP>
50
typename PFP::REAL tetrahedronVolume(typename PFP::MAP& map, Dart d, const VertexAttribute<typename PFP::VEC3>& position)
Pierre Kraemer's avatar
Pierre Kraemer committed
51
52
53
54
55
56
57
58
59
60
{
	typename PFP::VEC3 p1 = position[d] ;
	typename PFP::VEC3 p2 = position[map.phi1(d)] ;
	typename PFP::VEC3 p3 = position[map.phi_1(d)] ;
	typename PFP::VEC3 p4 = position[map.phi_1(map.phi2(d))] ;

	return Geom::tetraVolume(p1, p2, p3, p4) ;
}

template <typename PFP>
61
typename PFP::REAL convexPolyhedronVolume(typename PFP::MAP& map, Dart d, const VertexAttribute<typename PFP::VEC3>& position)
Pierre Kraemer's avatar
Pierre Kraemer committed
62
63
64
{
	typedef typename PFP::VEC3 VEC3;

Thomas's avatar
Thomas committed
65
	if(Modelisation::Tetrahedralization::isTetrahedron<PFP>(map,d))
Pierre Kraemer's avatar
Pierre Kraemer committed
66
67
68
69
70
71
72
73
74
75
76
		return tetrahedronVolume<PFP>(map,d,position) ;
	else
	{
		typename PFP::REAL vol = 0 ;
		VEC3 vCentroid = Algo::Geometry::volumeCentroid<PFP>(map, d, position) ;

		DartMarkerStore mark(map);		// Lock a marker

		std::vector<Dart> visitedFaces ;
		visitedFaces.reserve(100) ;
		visitedFaces.push_back(d) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
77
		mark.markOrbit<FACE>(d) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
78
79
80
81

		for(typename std::vector<Dart>::iterator face = visitedFaces.begin(); face != visitedFaces.end(); ++face)
		{
			Dart e = *face ;
82
			if(map.isCycleTriangle(e))
Pierre Kraemer's avatar
Pierre Kraemer committed
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
			{
				VEC3 p1 = position[e] ;
				VEC3 p2 = position[map.phi1(e)] ;
				VEC3 p3 = position[map.phi_1(e)] ;
				vol += Geom::tetraVolume(p1, p2, p3, vCentroid) ;
			}
			else
			{
				VEC3 fCentroid = Algo::Geometry::faceCentroid<PFP>(map, e, position) ;
				Dart f = e ;
				do
				{
					VEC3 p1 = position[f] ;
					VEC3 p2 = position[map.phi1(f)] ;
					vol += Geom::tetraVolume(p1, p2, fCentroid, vCentroid) ;
					f = map.phi1(f) ;
				} while(f != e) ;
			}
			do	// add all face neighbours to the table
			{
				Dart ee = map.phi2(e) ;
				if(!mark.isMarked(ee)) // not already marked
				{
					visitedFaces.push_back(ee) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
107
					mark.markOrbit<FACE>(e) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
108
109
110
111
112
113
114
115
116
117
				}
				e = map.phi1(e) ;
			} while(e != *face) ;
		}

		return vol ;
	}
}

template <typename PFP>
118
float totalVolume(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& position, const FunctorSelect& select)
Pierre Kraemer's avatar
Pierre Kraemer committed
119
120
{
	typename PFP::REAL vol = 0 ;
Pierre Kraemer's avatar
Pierre Kraemer committed
121
	TraversorW<typename PFP::MAP> t(map, select) ;
122
	for(Dart d = t.begin(); d != t.end(); d = t.next())
Pierre Kraemer's avatar
Pierre Kraemer committed
123
		vol += convexPolyhedronVolume<PFP>(map, d, position) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
124
125
126
127
128
129
130
131
	return vol ;
}

} // namespace Geometry

} // namespace Algo

} // namespace CGoGN