particle_cell_2D_memo.hpp 11.6 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 35
/*******************************************************************************
* 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 Surface
{

namespace MovingObjects
{

pitiot's avatar
pitiot committed
36

37
template <typename PFP>
38
std::vector<Dart> ParticleCell2DMemo<PFP>::move(const VEC3& goal)
Pierre Kraemer's avatar
Pierre Kraemer committed
39
{
pitiot's avatar
pitiot committed
40
	this->crossCell = NO_CROSS ;
David Cazier's avatar
David Cazier committed
41
	if (!Geom::arePointsEquals(goal, this->getPosition()))
David Cazier's avatar
David Cazier committed
42
	{
43 44 45
		CellMarkerMemo<FACE> memo_cross(this->m);
		memo_cross.mark(this->d);

David Cazier's avatar
David Cazier committed
46 47 48
		switch (this->getState())
		{
			case VERTEX :
pitiot's avatar
pitiot committed
49
				vertexState(goal,memo_cross) ;
David Cazier's avatar
David Cazier committed
50 51
				break ;
			case EDGE :
pitiot's avatar
pitiot committed
52
				edgeState(goal,memo_cross) ;
David Cazier's avatar
David Cazier committed
53 54
				break ;
			case FACE :
pitiot's avatar
pitiot committed
55
				faceState(goal,memo_cross) ;
David Cazier's avatar
David Cazier committed
56 57
				break ;
		}
58 59

		return memo_cross.get_markedCells();
Pierre Kraemer's avatar
Pierre Kraemer committed
60
	}
David Cazier's avatar
David Cazier committed
61
	else
Thomas Jund's avatar
Thomas Jund committed
62
		this->Algo::MovingObjects::ParticleBase<PFP>::move(goal) ;
63 64 65 66

	std::vector<Dart> res;
	res.push_back(this->d);
	return res;
Pierre Kraemer's avatar
Pierre Kraemer committed
67 68 69
}

template <typename PFP>
70
std::vector<Dart> ParticleCell2DMemo<PFP>::move(const VEC3& goal, CellMarkerMemo<FACE>& memo_cross)
pitiot's avatar
pitiot committed
71 72
{
	memo_cross.mark(this->d);
73
	this->move(goal,memo_cross);
pitiot's avatar
pitiot committed
74 75 76 77
	return memo_cross.get_markedCells();
}

template <typename PFP>
78
void ParticleCell2DMemo<PFP>::vertexState(const VEC3& current, CellMarkerMemo<FACE>& memo_cross)
Pierre Kraemer's avatar
Pierre Kraemer committed
79
{
David Cazier's avatar
David Cazier committed
80
#ifdef DEBUG
Jund Thomas's avatar
Jund Thomas committed
81
	CGoGNout << "vertexState" << this->d << CGoGNendl ;
David Cazier's avatar
David Cazier committed
82
#endif
David Cazier's avatar
David Cazier committed
83
	assert(std::isfinite(current[0]) && std::isfinite(current[1]) && std::isfinite(current[2])) ;
84
	memo_cross.mark(this->d);
David Cazier's avatar
David Cazier committed
85
	this->crossCell = CROSS_OTHER ;
pitiot's avatar
pitiot committed
86

87
	if (Geometry::isPointOnVertex < PFP > (this->m, this->d, this->positionAttribut, current))
David Cazier's avatar
David Cazier committed
88 89
	{
		this->setState(VERTEX) ;
Thomas Jund's avatar
Thomas Jund committed
90
		this->Algo::MovingObjects::ParticleBase<PFP>::move(current) ;
David Cazier's avatar
David Cazier committed
91
		return ;
Pierre Kraemer's avatar
Pierre Kraemer committed
92
	}
David Cazier's avatar
David Cazier committed
93 94
	else
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
95
		//orientation step
pitiot's avatar
pitiot committed
96 97
		if (this->positionAttribut[this->d][0] == this->positionAttribut[this->m.phi1(this->d)][0] && this->positionAttribut[this->d][1] == this->positionAttribut[this->m.phi1(this->d)][1])
			this->d = this->m.phi2_1(this->d) ;
David Cazier's avatar
David Cazier committed
98 99 100 101 102 103
		if (this->getOrientationEdge(current, this->m.phi2_1(this->d)) != Geom::RIGHT)
		{
			Dart dd_vert = this->d ;
			do
			{
				this->d = this->m.phi2_1(this->d) ;
pitiot's avatar
pitiot committed
104 105 106 107
				if (this->positionAttribut[this->d][0] == this->positionAttribut[this->m.phi1(this->d)][0]
					&& this->positionAttribut[this->d][1]== this->positionAttribut[this->m.phi1(this->d)][1])
					this->d = this->m.phi2_1(this->d) ;
			} while (this->getOrientationEdge(current, this->m.phi2_1(this->d)) != Geom::RIGHT && dd_vert != this->d) ;
David Cazier's avatar
David Cazier committed
108 109 110

			if (dd_vert == this->d)
			{
pitiot's avatar
pitiot committed
111
				//orbit with 2 edges : point on one edge
David Cazier's avatar
David Cazier committed
112
				if (this->m.phi2_1(this->m.phi2_1(this->d)) == this->d)
pitiot's avatar
pitiot committed
113
				{
114
					if (!Geometry::isPointOnHalfEdge<PFP>(this->m, this->d, this->positionAttribut, current))
pitiot's avatar
pitiot committed
115
						this->d = this->m.phi2_1(this->d) ;
pitiot's avatar
pitiot committed
116 117 118
				}
				else
				{
pitiot's avatar
pitiot committed
119 120 121
					//checking : case with 3 orthogonal darts and point on an edge
					do
					{
122 123
						if(Geometry::isPointOnHalfEdge<PFP>(this->m,this->d,this->positionAttribut,current)
								&& Geometry::isPointOnHalfEdge<PFP>(this->m,this->m.phi2(this->d),this->positionAttribut,current)
Jund Thomas's avatar
Jund Thomas committed
124
								&& this->getOrientationEdge(current, this->d) == Geom::ALIGNED)
pitiot's avatar
pitiot committed
125
						{
Jund Thomas's avatar
Jund Thomas committed
126

pitiot's avatar
pitiot committed
127 128 129 130 131 132
							this->edgeState(current,memo_cross) ;
							return;
						}
						this->d = this->m.phi2_1(this->d) ;
					} while (this->getOrientationEdge(current, this->m.phi2_1(this->d)) != Geom::RIGHT && dd_vert != this->d) ;

Thomas Jund's avatar
Thomas Jund committed
133
					this->Algo::MovingObjects::ParticleBase<PFP>::move(current) ;
David Cazier's avatar
David Cazier committed
134 135
					this->setState(VERTEX) ;
					return ;
pitiot's avatar
pitiot committed
136
				}
Pierre Kraemer's avatar
Pierre Kraemer committed
137 138
			}
		}
David Cazier's avatar
David Cazier committed
139 140
		else
		{
David Cazier's avatar
David Cazier committed
141 142
			Dart dd_vert = this->m.phi2_1(this->d) ;
			while (this->getOrientationEdge(current, this->d) == Geom::RIGHT && dd_vert != this->d)
David Cazier's avatar
David Cazier committed
143 144
			{
				this->d = this->m.phi12(this->d) ;
pitiot's avatar
pitiot committed
145 146 147
				if (this->positionAttribut[this->d][0] == this->positionAttribut[this->m.phi1(this->d)][0]
				    && this->positionAttribut[this->d][1] == this->positionAttribut[this->m.phi1(this->d)][1])
					this->d = this->m.phi12(this->d) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
148 149 150 151
			}
		}

		//displacement step
Jund Thomas's avatar
Jund Thomas committed
152

David Cazier's avatar
David Cazier committed
153
		if (this->getOrientationEdge(current, this->d) == Geom::ALIGNED
154
				&& Geometry::isPointOnHalfEdge<PFP>(this->m, this->d, this->positionAttribut, current))
pitiot's avatar
pitiot committed
155
			edgeState(current,memo_cross) ;
David Cazier's avatar
David Cazier committed
156
		else
pitiot's avatar
pitiot committed
157
		{
David Cazier's avatar
David Cazier committed
158
			this->d = this->m.phi1(this->d) ;
pitiot's avatar
pitiot committed
159
			faceState(current,memo_cross) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
160
		}
David Cazier's avatar
David Cazier committed
161
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
162 163 164
}

template <typename PFP>
165
void ParticleCell2DMemo<PFP>::edgeState(const VEC3& current, CellMarkerMemo<FACE>& memo_cross, Geom::Orientation2D sideOfEdge)
Pierre Kraemer's avatar
Pierre Kraemer committed
166
{
David Cazier's avatar
David Cazier committed
167
#ifdef DEBUG
Jund Thomas's avatar
Jund Thomas committed
168
	CGoGNout << "edgeState" << this->d << CGoGNendl ;
David Cazier's avatar
David Cazier committed
169
#endif
pitiot's avatar
pitiot committed
170

David Cazier's avatar
David Cazier committed
171
	assert(std::isfinite(current[0]) && std::isfinite(current[1]) && std::isfinite(current[2])) ;
172
// 	assert(Geometry::isPointOnEdge<PFP>(m,d,m_positions,m_position));
173
	memo_cross.mark(this->d);
David Cazier's avatar
David Cazier committed
174
	if (this->crossCell == NO_CROSS)
pitiot's avatar
pitiot committed
175
	{
David Cazier's avatar
David Cazier committed
176 177
		this->crossCell = CROSS_EDGE ;
		this->lastCrossed = this->d ;
pitiot's avatar
pitiot committed
178 179
	}
	else
David Cazier's avatar
David Cazier committed
180
		this->crossCell = CROSS_OTHER ;
Pierre Kraemer's avatar
Pierre Kraemer committed
181

David Cazier's avatar
David Cazier committed
182
	if (sideOfEdge == Geom::ALIGNED) sideOfEdge = this->getOrientationEdge(current, this->d) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
183

David Cazier's avatar
David Cazier committed
184 185
	switch (sideOfEdge)
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
186
		case Geom::LEFT :
David Cazier's avatar
David Cazier committed
187
			this->d = this->m.phi1(this->d) ;
pitiot's avatar
pitiot committed
188
			faceState(current,memo_cross) ;
David Cazier's avatar
David Cazier committed
189
			return ;
David Cazier's avatar
David Cazier committed
190
		case Geom::RIGHT :
David Cazier's avatar
David Cazier committed
191
			this->d = this->m.phi1(this->m.phi2(this->d)) ;
pitiot's avatar
pitiot committed
192
			faceState(current,memo_cross) ;
David Cazier's avatar
David Cazier committed
193
			return ;
David Cazier's avatar
David Cazier committed
194 195
		default :
			this->setState(EDGE) ;
David Cazier's avatar
David Cazier committed
196
			break ;
Pierre Kraemer's avatar
Pierre Kraemer committed
197 198
	}

199
	if (!Geometry::isPointOnHalfEdge < PFP
David Cazier's avatar
David Cazier committed
200
	    > (this->m, this->d, this->positionAttribut, current))
David Cazier's avatar
David Cazier committed
201
	{
Thomas Jund's avatar
Thomas Jund committed
202
		this->Algo::MovingObjects::ParticleBase<PFP>::move(this->positionAttribut[this->d]) ;
pitiot's avatar
pitiot committed
203
		vertexState(current,memo_cross) ;
David Cazier's avatar
David Cazier committed
204
		return ;
Pierre Kraemer's avatar
Pierre Kraemer committed
205
	}
206
	else if (!Geometry::isPointOnHalfEdge < PFP
David Cazier's avatar
David Cazier committed
207
	    > (this->m, this->m.phi2(this->d), this->positionAttribut, current))
David Cazier's avatar
David Cazier committed
208 209
	{
		this->d = this->m.phi2(this->d) ;
Thomas Jund's avatar
Thomas Jund committed
210
		this->Algo::MovingObjects::ParticleBase<PFP>::move(this->positionAttribut[this->d]) ;
pitiot's avatar
pitiot committed
211
		vertexState(current,memo_cross) ;
David Cazier's avatar
David Cazier committed
212
		return ;
Pierre Kraemer's avatar
Pierre Kraemer committed
213 214
	}

Thomas Jund's avatar
Thomas Jund committed
215
	this->Algo::MovingObjects::ParticleBase<PFP>::move(current) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
216 217 218
}

template <typename PFP>
219
void ParticleCell2DMemo<PFP>::faceState(const VEC3& current, CellMarkerMemo<FACE>& memo_cross)
Pierre Kraemer's avatar
Pierre Kraemer committed
220
{
David Cazier's avatar
David Cazier committed
221
#ifdef DEBUG
Jund Thomas's avatar
Jund Thomas committed
222
	CGoGNout << "faceState" << this->d << CGoGNendl ;
David Cazier's avatar
David Cazier committed
223
#endif
pitiot's avatar
pitiot committed
224

David Cazier's avatar
David Cazier committed
225 226 227 228
	assert(
	    std::isfinite(this->getPosition()[0]) && std::isfinite(this->getPosition()[1])
	        && std::isfinite(this->getPosition()[2])) ;
	assert(std::isfinite(current[0]) && std::isfinite(current[1]) && std::isfinite(current[2])) ;
229
// 	assert(Geometry::isPointInConvexFace2D<PFP>(m,d,m_positions,m_position,true));
230
	memo_cross.mark(this->d);
David Cazier's avatar
David Cazier committed
231
	Dart dd = this->d ;
David Cazier's avatar
David Cazier committed
232
	float wsoe = this->getOrientationFace(current, this->m.phi1(this->d)) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
233

David Cazier's avatar
David Cazier committed
234 235
// orientation step
	if (wsoe != Geom::RIGHT)
David Cazier's avatar
David Cazier committed
236 237
	{
		this->d = this->m.phi1(this->d) ;
David Cazier's avatar
David Cazier committed
238 239
		wsoe = this->getOrientationFace(current, this->m.phi1(this->d)) ;
		while (wsoe != Geom::RIGHT && dd != this->d)
pitiot's avatar
pitiot committed
240
		{
David Cazier's avatar
David Cazier committed
241
			this->d = this->m.phi1(this->d) ;
David Cazier's avatar
David Cazier committed
242
			wsoe = this->getOrientationFace(current, this->m.phi1(this->d)) ;
pitiot's avatar
pitiot committed
243
		}
David Cazier's avatar
David Cazier committed
244

David Cazier's avatar
David Cazier committed
245
		// source and position to reach are the same : verify if no edge is crossed due to numerical approximation
David Cazier's avatar
David Cazier committed
246 247 248 249 250 251 252 253 254 255
		if (dd == this->d)
		{
			do
			{
				switch (this->getOrientationEdge(current, this->d))
				{
					case Geom::LEFT :
						this->d = this->m.phi1(this->d) ;
						break ;
					case Geom::ALIGNED :
Thomas Jund's avatar
Thomas Jund committed
256
						this->Algo::MovingObjects::ParticleBase<PFP>::move(current) ;
pitiot's avatar
pitiot committed
257
						edgeState(current,memo_cross) ;
David Cazier's avatar
David Cazier committed
258
						return ;
David Cazier's avatar
David Cazier committed
259
					case Geom::RIGHT :
pitiot's avatar
pitiot committed
260 261
//									CGoGNout << "smthg went bad " << m_position << " " << current << CGoGNendl;
//									CGoGNout << "d1 " << m_positions[d] << " d2 " << m_positions[m.phi1(d)] << CGoGNendl;
Thomas Jund's avatar
Thomas Jund committed
262
					this->Algo::MovingObjects::ParticleBase<PFP>::move(this->intersectLineEdge(current, this->getPosition(), this->d)) ;
pitiot's avatar
pitiot committed
263 264
//									CGoGNout << " " << m_position << CGoGNendl;

pitiot's avatar
pitiot committed
265 266
					edgeState(current,memo_cross, Geom::RIGHT) ;
					return ;
Pierre Kraemer's avatar
Pierre Kraemer committed
267
				}
David Cazier's avatar
David Cazier committed
268
			} while (this->d != dd) ;
Thomas Jund's avatar
Thomas Jund committed
269
			this->Algo::MovingObjects::ParticleBase<PFP>::move(current);
David Cazier's avatar
David Cazier committed
270
			this->setState(FACE) ;
pitiot's avatar
pitiot committed
271

272
// 			m_position = Geometry::faceCentroid<PFP>(m,d,m_positions);
pitiot's avatar
pitiot committed
273 274 275 276 277 278
// 			d = m.phi1(d);
// 			m_position = pointInFace(d);
// 			faceState(current);

// 			m_position = m_positions[d];
// 			vertexState(current);
David Cazier's avatar
David Cazier committed
279
			return ;
Pierre Kraemer's avatar
Pierre Kraemer committed
280
		}
pitiot's avatar
pitiot committed
281
		// take the orientation with d1 : in case we are going through a vertex
David Cazier's avatar
David Cazier committed
282
		wsoe = this->getOrientationFace(current, this->d) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
283
	}
David Cazier's avatar
David Cazier committed
284 285
	else
	{
David Cazier's avatar
David Cazier committed
286 287
		wsoe = this->getOrientationFace(current, this->d) ;
		while (wsoe == Geom::RIGHT && this->m.phi_1(this->d) != dd)
pitiot's avatar
pitiot committed
288
		{
David Cazier's avatar
David Cazier committed
289
			this->d = this->m.phi_1(this->d) ;
David Cazier's avatar
David Cazier committed
290
			wsoe = this->getOrientationFace(current, this->d) ;
pitiot's avatar
pitiot committed
291
		}
Pierre Kraemer's avatar
Pierre Kraemer committed
292

pitiot's avatar
pitiot committed
293
		// in case of numerical incoherence
David Cazier's avatar
David Cazier committed
294
		if (this->m.phi_1(this->d) == dd && wsoe == Geom::RIGHT)
David Cazier's avatar
David Cazier committed
295 296 297 298 299 300 301 302 303 304
		{
			this->d = this->m.phi_1(this->d) ;
			do
			{
				switch (this->getOrientationEdge(current, this->d))
				{
					case Geom::LEFT :
						this->d = this->m.phi1(this->d) ;
						break ;
					case Geom::ALIGNED :
pitiot's avatar
pitiot committed
305
// 					CGoGNout << "pic" << CGoGNendl;
Thomas Jund's avatar
Thomas Jund committed
306
						this->Algo::MovingObjects::ParticleBase<PFP>::move(current) ;
pitiot's avatar
pitiot committed
307
						edgeState(current,memo_cross) ;
David Cazier's avatar
David Cazier committed
308
						return ;
David Cazier's avatar
David Cazier committed
309
					case Geom::RIGHT :
pitiot's avatar
pitiot committed
310
//					CGoGNout << "smthg went bad(2) " << m_position << CGoGNendl;
Thomas Jund's avatar
Thomas Jund committed
311
						this->Algo::MovingObjects::ParticleBase<PFP>::move(this->intersectLineEdge(current, this->getPosition(), this->d)) ;
pitiot's avatar
pitiot committed
312
// 					CGoGNout << " " << m_position << CGoGNendl;
pitiot's avatar
pitiot committed
313
						edgeState(current,memo_cross ,Geom::RIGHT) ;
David Cazier's avatar
David Cazier committed
314
						return ;
Pierre Kraemer's avatar
Pierre Kraemer committed
315
				}
David Cazier's avatar
David Cazier committed
316
			} while (this->d != dd) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
317

Thomas Jund's avatar
Thomas Jund committed
318
			this->Algo::MovingObjects::ParticleBase<PFP>::move(current) ;
David Cazier's avatar
David Cazier committed
319 320
			this->setState(FACE) ;
			return ;
Pierre Kraemer's avatar
Pierre Kraemer committed
321 322 323
		}
	}

David Cazier's avatar
David Cazier committed
324
//displacement step
David Cazier's avatar
David Cazier committed
325 326 327
	switch (this->getOrientationEdge(current, this->d))
	{
		case Geom::LEFT :
Thomas Jund's avatar
Thomas Jund committed
328
			this->Algo::MovingObjects::ParticleBase<PFP>::move(current) ;
David Cazier's avatar
David Cazier committed
329 330 331
			this->setState(FACE) ;
			;
			break ;
pitiot's avatar
pitiot committed
332 333 334 335 336 337 338 339 340 341 342
// 	case Geom::ALIGNED :
//		if(wsoe==Geom::ALIGNED) {
// 			m_position = m_positions[d];
// 			vertexState(current);
// 		}
// 		else {
// 			CGoGNout << "poc" << CGoGNendl;
// 			m_position = current;
// 			state = EDGE;
// 		}
// 		break;
David Cazier's avatar
David Cazier committed
343
		default :
David Cazier's avatar
David Cazier committed
344 345
			if (wsoe == Geom::ALIGNED)
			{
pitiot's avatar
pitiot committed
346

David Cazier's avatar
David Cazier committed
347
				this->d = this->m.phi1(this->d) ; //to check
Thomas Jund's avatar
Thomas Jund committed
348
				this->Algo::MovingObjects::ParticleBase<PFP>::move(this->positionAttribut[this->d]) ;
pitiot's avatar
pitiot committed
349
				vertexState(current,memo_cross) ;
David Cazier's avatar
David Cazier committed
350
			}
David Cazier's avatar
David Cazier committed
351
			else
David Cazier's avatar
David Cazier committed
352
			{
Thomas Jund's avatar
Thomas Jund committed
353
				this->Algo::MovingObjects::ParticleBase<PFP>::move(this->intersectLineEdge(current, this->getPosition(), this->d)) ;
pitiot's avatar
pitiot committed
354
				edgeState(current,memo_cross, Geom::RIGHT) ;
David Cazier's avatar
David Cazier committed
355
			}
Pierre Kraemer's avatar
Pierre Kraemer committed
356
	}
David Cazier's avatar
David Cazier committed
357

David Cazier's avatar
-  
David Cazier committed
358
}
359 360 361 362 363

}
}
} //namespaces
}