particle_cell_2D_memo.hpp 12 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
/*******************************************************************************
* 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                                        *
*                                                                              *
*******************************************************************************/
Pierre Kraemer's avatar
Pierre Kraemer committed
24

25 26 27 28 29 30 31 32 33 34 35 36 37
namespace CGoGN
{

namespace Algo
{

namespace Surface
{

namespace MovingObjects
{

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);


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

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

template <typename PFP>
Pierre Kraemer's avatar
Pierre Kraemer committed
69
std::vector<Dart> ParticleCell2DMemo<PFP>::move(const VEC3& goal, CellMarkerMemo<MAP, FACE>& memo_cross)
pitiot's avatar
pitiot committed
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
	this->crossCell = NO_CROSS ;
	if (!Geom::arePointsEquals(goal, this->getPosition()))
	{
		switch (this->getState())
		{
			case VERTEX :
				vertexState(goal,memo_cross) ;
				break ;
			case EDGE :
				edgeState(goal,memo_cross) ;
				break ;
			case FACE :
				faceState(goal,memo_cross) ;
				break ;
		}

		return memo_cross.get_markedCells();
	}
	else
		this->Algo::MovingObjects::ParticleBase<PFP>::move(goal) ;

	std::vector<Dart> res;
	res.push_back(this->d);
	return res;
pitiot's avatar
pitiot committed
95 96 97
}

template <typename PFP>
Pierre Kraemer's avatar
Pierre Kraemer committed
98
void ParticleCell2DMemo<PFP>::vertexState(const VEC3& current, CellMarkerMemo<MAP, FACE>& memo_cross)
Pierre Kraemer's avatar
Pierre Kraemer committed
99
{
David Cazier's avatar
David Cazier committed
100
#ifdef DEBUG
Jund Thomas's avatar
Jund Thomas committed
101
	CGoGNout << "vertexState" << this->d << CGoGNendl ;
David Cazier's avatar
David Cazier committed
102
#endif
David Cazier's avatar
David Cazier committed
103
	assert(std::isfinite(current[0]) && std::isfinite(current[1]) && std::isfinite(current[2])) ;
104
	memo_cross.mark(this->d);
David Cazier's avatar
David Cazier committed
105
	this->crossCell = CROSS_OTHER ;
pitiot's avatar
pitiot committed
106

107
	if (Geometry::isPointOnVertex < PFP > (this->m, this->d, this->positionAttribut, current))
David Cazier's avatar
David Cazier committed
108 109
	{
		this->setState(VERTEX) ;
Thomas Jund's avatar
Thomas Jund committed
110
		this->Algo::MovingObjects::ParticleBase<PFP>::move(current) ;
David Cazier's avatar
David Cazier committed
111
		return ;
Pierre Kraemer's avatar
Pierre Kraemer committed
112
	}
David Cazier's avatar
David Cazier committed
113 114
	else
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
115
		//orientation step
pitiot's avatar
pitiot committed
116 117
		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
118 119 120 121 122 123
		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
124 125 126 127
				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
128 129 130

			if (dd_vert == this->d)
			{
pitiot's avatar
pitiot committed
131
				//orbit with 2 edges : point on one edge
David Cazier's avatar
David Cazier committed
132
				if (this->m.phi2_1(this->m.phi2_1(this->d)) == this->d)
pitiot's avatar
pitiot committed
133
				{
134
					if (!Geometry::isPointOnHalfEdge<PFP>(this->m, this->d, this->positionAttribut, current))
pitiot's avatar
pitiot committed
135
						this->d = this->m.phi2_1(this->d) ;
pitiot's avatar
pitiot committed
136 137 138
				}
				else
				{
pitiot's avatar
pitiot committed
139 140 141
					//checking : case with 3 orthogonal darts and point on an edge
					do
					{
142
						if(Geometry::isPointOnHalfEdge<PFP>(this->m,this->d,this->positionAttribut,current)
pitiot's avatar
pitiot committed
143 144
								&& Geometry::isPointOnHalfEdge<PFP>(this->m,this->m.phi2(this->d),this->positionAttribut,current))
//								&& this->getOrientationEdge(current, this->d) == Geom::ALIGNED)
pitiot's avatar
pitiot committed
145
						{
Jund Thomas's avatar
Jund Thomas committed
146

pitiot's avatar
pitiot committed
147 148 149 150 151 152
							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
153
					this->Algo::MovingObjects::ParticleBase<PFP>::move(current) ;
David Cazier's avatar
David Cazier committed
154 155
					this->setState(VERTEX) ;
					return ;
pitiot's avatar
pitiot committed
156
				}
Pierre Kraemer's avatar
Pierre Kraemer committed
157 158
			}
		}
David Cazier's avatar
David Cazier committed
159 160
		else
		{
David Cazier's avatar
David Cazier committed
161 162
			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
163 164
			{
				this->d = this->m.phi12(this->d) ;
pitiot's avatar
pitiot committed
165 166 167
				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
168 169 170 171
			}
		}

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

David Cazier's avatar
David Cazier committed
173
		if (this->getOrientationEdge(current, this->d) == Geom::ALIGNED
174
				&& Geometry::isPointOnHalfEdge<PFP>(this->m, this->d, this->positionAttribut, current))
pitiot's avatar
pitiot committed
175
			edgeState(current,memo_cross) ;
David Cazier's avatar
David Cazier committed
176
		else
pitiot's avatar
pitiot committed
177
		{
David Cazier's avatar
David Cazier committed
178
			this->d = this->m.phi1(this->d) ;
pitiot's avatar
pitiot committed
179
			faceState(current,memo_cross) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
180
		}
David Cazier's avatar
David Cazier committed
181
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
182 183 184
}

template <typename PFP>
Pierre Kraemer's avatar
Pierre Kraemer committed
185
void ParticleCell2DMemo<PFP>::edgeState(const VEC3& current, CellMarkerMemo<MAP, FACE>& memo_cross, Geom::Orientation2D sideOfEdge)
Pierre Kraemer's avatar
Pierre Kraemer committed
186
{
David Cazier's avatar
David Cazier committed
187
#ifdef DEBUG
Jund Thomas's avatar
Jund Thomas committed
188
	CGoGNout << "edgeState" << this->d << CGoGNendl ;
David Cazier's avatar
David Cazier committed
189
#endif
pitiot's avatar
pitiot committed
190

David Cazier's avatar
David Cazier committed
191
	assert(std::isfinite(current[0]) && std::isfinite(current[1]) && std::isfinite(current[2])) ;
192
// 	assert(Geometry::isPointOnEdge<PFP>(m,d,m_positions,m_position));
193
	memo_cross.mark(this->d);
David Cazier's avatar
David Cazier committed
194
	if (this->crossCell == NO_CROSS)
pitiot's avatar
pitiot committed
195
	{
David Cazier's avatar
David Cazier committed
196 197
		this->crossCell = CROSS_EDGE ;
		this->lastCrossed = this->d ;
pitiot's avatar
pitiot committed
198 199
	}
	else
David Cazier's avatar
David Cazier committed
200
		this->crossCell = CROSS_OTHER ;
Pierre Kraemer's avatar
Pierre Kraemer committed
201

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

David Cazier's avatar
David Cazier committed
204 205
	switch (sideOfEdge)
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
206
		case Geom::LEFT :
David Cazier's avatar
David Cazier committed
207
			this->d = this->m.phi1(this->d) ;
pitiot's avatar
pitiot committed
208
			faceState(current,memo_cross) ;
David Cazier's avatar
David Cazier committed
209
			return ;
David Cazier's avatar
David Cazier committed
210
		case Geom::RIGHT :
David Cazier's avatar
David Cazier committed
211
			this->d = this->m.phi1(this->m.phi2(this->d)) ;
pitiot's avatar
pitiot committed
212
			faceState(current,memo_cross) ;
David Cazier's avatar
David Cazier committed
213
			return ;
David Cazier's avatar
David Cazier committed
214 215
		default :
			this->setState(EDGE) ;
David Cazier's avatar
David Cazier committed
216
			break ;
Pierre Kraemer's avatar
Pierre Kraemer committed
217 218
	}

219
	if (!Geometry::isPointOnHalfEdge < PFP
David Cazier's avatar
David Cazier committed
220
	    > (this->m, this->d, this->positionAttribut, current))
David Cazier's avatar
David Cazier committed
221
	{
Thomas Jund's avatar
Thomas Jund committed
222
		this->Algo::MovingObjects::ParticleBase<PFP>::move(this->positionAttribut[this->d]) ;
pitiot's avatar
pitiot committed
223
		vertexState(current,memo_cross) ;
David Cazier's avatar
David Cazier committed
224
		return ;
Pierre Kraemer's avatar
Pierre Kraemer committed
225
	}
226
	else if (!Geometry::isPointOnHalfEdge < PFP
David Cazier's avatar
David Cazier committed
227
	    > (this->m, this->m.phi2(this->d), this->positionAttribut, current))
David Cazier's avatar
David Cazier committed
228 229
	{
		this->d = this->m.phi2(this->d) ;
Thomas Jund's avatar
Thomas Jund committed
230
		this->Algo::MovingObjects::ParticleBase<PFP>::move(this->positionAttribut[this->d]) ;
pitiot's avatar
pitiot committed
231
		vertexState(current,memo_cross) ;
David Cazier's avatar
David Cazier committed
232
		return ;
Pierre Kraemer's avatar
Pierre Kraemer committed
233 234
	}

Thomas Jund's avatar
Thomas Jund committed
235
	this->Algo::MovingObjects::ParticleBase<PFP>::move(current) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
236 237 238
}

template <typename PFP>
Pierre Kraemer's avatar
Pierre Kraemer committed
239
void ParticleCell2DMemo<PFP>::faceState(const VEC3& current, CellMarkerMemo<MAP, FACE>& memo_cross)
Pierre Kraemer's avatar
Pierre Kraemer committed
240
{
David Cazier's avatar
David Cazier committed
241
#ifdef DEBUG
Jund Thomas's avatar
Jund Thomas committed
242
	CGoGNout << "faceState" << this->d << CGoGNendl ;
David Cazier's avatar
David Cazier committed
243
#endif
pitiot's avatar
pitiot committed
244

David Cazier's avatar
David Cazier committed
245 246 247 248
	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])) ;
249
// 	assert(Geometry::isPointInConvexFace2D<PFP>(m,d,m_positions,m_position,true));
250
	memo_cross.mark(this->d);
David Cazier's avatar
David Cazier committed
251
	Dart dd = this->d ;
David Cazier's avatar
David Cazier committed
252
	float wsoe = this->getOrientationFace(current, this->m.phi1(this->d)) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
253

David Cazier's avatar
David Cazier committed
254 255
// orientation step
	if (wsoe != Geom::RIGHT)
David Cazier's avatar
David Cazier committed
256 257
	{
		this->d = this->m.phi1(this->d) ;
David Cazier's avatar
David Cazier committed
258 259
		wsoe = this->getOrientationFace(current, this->m.phi1(this->d)) ;
		while (wsoe != Geom::RIGHT && dd != this->d)
pitiot's avatar
pitiot committed
260
		{
David Cazier's avatar
David Cazier committed
261
			this->d = this->m.phi1(this->d) ;
David Cazier's avatar
David Cazier committed
262
			wsoe = this->getOrientationFace(current, this->m.phi1(this->d)) ;
pitiot's avatar
pitiot committed
263
		}
David Cazier's avatar
David Cazier committed
264

David Cazier's avatar
David Cazier committed
265
		// 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
266 267 268 269 270 271 272 273 274 275
		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
276
						this->Algo::MovingObjects::ParticleBase<PFP>::move(current) ;
pitiot's avatar
pitiot committed
277
						edgeState(current,memo_cross) ;
David Cazier's avatar
David Cazier committed
278
						return ;
David Cazier's avatar
David Cazier committed
279
					case Geom::RIGHT :
pitiot's avatar
pitiot committed
280 281
//									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
282
					this->Algo::MovingObjects::ParticleBase<PFP>::move(this->intersectLineEdge(current, this->getPosition(), this->d)) ;
pitiot's avatar
pitiot committed
283 284
//									CGoGNout << " " << m_position << CGoGNendl;

pitiot's avatar
pitiot committed
285 286
					edgeState(current,memo_cross, Geom::RIGHT) ;
					return ;
Pierre Kraemer's avatar
Pierre Kraemer committed
287
				}
David Cazier's avatar
David Cazier committed
288
			} while (this->d != dd) ;
Thomas Jund's avatar
Thomas Jund committed
289
			this->Algo::MovingObjects::ParticleBase<PFP>::move(current);
David Cazier's avatar
David Cazier committed
290
			this->setState(FACE) ;
pitiot's avatar
pitiot committed
291

292
// 			m_position = Geometry::faceCentroid<PFP>(m,d,m_positions);
pitiot's avatar
pitiot committed
293 294 295 296 297 298
// 			d = m.phi1(d);
// 			m_position = pointInFace(d);
// 			faceState(current);

// 			m_position = m_positions[d];
// 			vertexState(current);
David Cazier's avatar
David Cazier committed
299
			return ;
Pierre Kraemer's avatar
Pierre Kraemer committed
300
		}
pitiot's avatar
pitiot committed
301
		// take the orientation with d1 : in case we are going through a vertex
David Cazier's avatar
David Cazier committed
302
		wsoe = this->getOrientationFace(current, this->d) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
303
	}
David Cazier's avatar
David Cazier committed
304 305
	else
	{
David Cazier's avatar
David Cazier committed
306 307
		wsoe = this->getOrientationFace(current, this->d) ;
		while (wsoe == Geom::RIGHT && this->m.phi_1(this->d) != dd)
pitiot's avatar
pitiot committed
308
		{
David Cazier's avatar
David Cazier committed
309
			this->d = this->m.phi_1(this->d) ;
David Cazier's avatar
David Cazier committed
310
			wsoe = this->getOrientationFace(current, this->d) ;
pitiot's avatar
pitiot committed
311
		}
Pierre Kraemer's avatar
Pierre Kraemer committed
312

pitiot's avatar
pitiot committed
313
		// in case of numerical incoherence
David Cazier's avatar
David Cazier committed
314
		if (this->m.phi_1(this->d) == dd && wsoe == Geom::RIGHT)
David Cazier's avatar
David Cazier committed
315 316 317 318 319 320 321 322 323 324
		{
			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
325
// 					CGoGNout << "pic" << CGoGNendl;
Thomas Jund's avatar
Thomas Jund committed
326
						this->Algo::MovingObjects::ParticleBase<PFP>::move(current) ;
pitiot's avatar
pitiot committed
327
						edgeState(current,memo_cross) ;
David Cazier's avatar
David Cazier committed
328
						return ;
David Cazier's avatar
David Cazier committed
329
					case Geom::RIGHT :
pitiot's avatar
pitiot committed
330
//					CGoGNout << "smthg went bad(2) " << m_position << CGoGNendl;
Thomas Jund's avatar
Thomas Jund committed
331
						this->Algo::MovingObjects::ParticleBase<PFP>::move(this->intersectLineEdge(current, this->getPosition(), this->d)) ;
pitiot's avatar
pitiot committed
332
// 					CGoGNout << " " << m_position << CGoGNendl;
pitiot's avatar
pitiot committed
333
						edgeState(current,memo_cross ,Geom::RIGHT) ;
David Cazier's avatar
David Cazier committed
334
						return ;
Pierre Kraemer's avatar
Pierre Kraemer committed
335
				}
David Cazier's avatar
David Cazier committed
336
			} while (this->d != dd) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
337

Thomas Jund's avatar
Thomas Jund committed
338
			this->Algo::MovingObjects::ParticleBase<PFP>::move(current) ;
David Cazier's avatar
David Cazier committed
339 340
			this->setState(FACE) ;
			return ;
Pierre Kraemer's avatar
Pierre Kraemer committed
341 342 343
		}
	}

David Cazier's avatar
David Cazier committed
344
//displacement step
David Cazier's avatar
David Cazier committed
345 346 347
	switch (this->getOrientationEdge(current, this->d))
	{
		case Geom::LEFT :
Thomas Jund's avatar
Thomas Jund committed
348
			this->Algo::MovingObjects::ParticleBase<PFP>::move(current) ;
David Cazier's avatar
David Cazier committed
349 350 351
			this->setState(FACE) ;
			;
			break ;
pitiot's avatar
pitiot committed
352 353 354 355 356 357 358 359 360 361 362
// 	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
363
		default :
David Cazier's avatar
David Cazier committed
364 365
			if (wsoe == Geom::ALIGNED)
			{
pitiot's avatar
pitiot committed
366

David Cazier's avatar
David Cazier committed
367
				this->d = this->m.phi1(this->d) ; //to check
Thomas Jund's avatar
Thomas Jund committed
368
				this->Algo::MovingObjects::ParticleBase<PFP>::move(this->positionAttribut[this->d]) ;
pitiot's avatar
pitiot committed
369
				vertexState(current,memo_cross) ;
David Cazier's avatar
David Cazier committed
370
			}
David Cazier's avatar
David Cazier committed
371
			else
David Cazier's avatar
David Cazier committed
372
			{
Thomas Jund's avatar
Thomas Jund committed
373
				this->Algo::MovingObjects::ParticleBase<PFP>::move(this->intersectLineEdge(current, this->getPosition(), this->d)) ;
pitiot's avatar
pitiot committed
374
				edgeState(current,memo_cross, Geom::RIGHT) ;
David Cazier's avatar
David Cazier committed
375
			}
Pierre Kraemer's avatar
Pierre Kraemer committed
376
	}
David Cazier's avatar
David Cazier committed
377

David Cazier's avatar
-  
David Cazier committed
378
}
379

Pierre Kraemer's avatar
Pierre Kraemer committed
380 381 382 383 384 385 386
} // namespace MovingObjects

} // namespace Surface

} // namespace Algo

} // namespace CGoGN