ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/CAD4FE/src/CAD4FE_LocalEdgeCriteria.cpp
Revision: 253
Committed: Tue Jul 13 19:40:46 2010 UTC (14 years, 10 months ago) by francois
File size: 16509 byte(s)
Error occurred while calculating annotation data.
Log Message:
changement de hiearchie et utilisation de ccmake + mise a jour

File Contents

# Content
1 //---------------------------------------------------------------------------
2 #include <fstream>
3 #include <sstream>
4
5 //---------------------------------------------------------------------------
6 // include MAGIC Headers
7 #include "gestionversion.h"
8 #include <MG_GEOMETRIE.h>
9 #include <MG_MAILLAGE.h>
10 #include <MG_MAILLAGE_OUTILS.h>
11 #include <ot_mathematique.h>
12
13 #include "CAD4FE_MCEdge.h"
14 #include "CAD4FE_MCAA.h"
15 #include "CAD4FE_MCBody.h"
16 #include "CAD4FE_mg_utils.h"
17 #include "CAD4FE_Intersection_Plane_MG_MAILLAGE.h"
18 #include "OT_ALGORITHME_GEOMETRIQUE.h"
19 #include "CAD4FE_Criteria.h"
20 #include "CAD4FE_ColorMap.h"
21
22 #pragma hdrstop
23
24 #include "CAD4FE_LocalEdgeCriteria.h"
25
26 //---------------------------------------------------------------------------
27
28 #pragma package(smart_init)
29
30 using namespace CAD4FE;
31
32 //------------------------------------------------------------------------------
33 // Edge Local Properties
34
35 LocalEdgeCriteria::LocalEdgeCriteria(MG_SEGMENT * __seg, MCAA * __mcaa, MG_MAILLAGE * __mesh, MG_SEGMENT * __startSeg)
36 : _seg(__seg), _mcaa(__mcaa), _mesh(__mesh), _startSeg(__startSeg), _normalOffset(NULL)
37 {
38 double x[2][3];
39 MG_UTILS::MG_NOEUD_GET_XYZ(_seg->get_noeud1(), x[0]);
40 MG_UTILS::MG_NOEUD_GET_XYZ(_seg->get_noeud2(), x[1]);
41 // _deletionScoreOppositeEdge = 0;
42
43 for (unsigned i=0; i<3; i++)
44 {
45 _P[i] = .5*(x[0][i]+x[1][i]);
46 _N[i] = x[1][i]-_P[i];
47 }
48
49 _meshSize = 0;
50 _normalOffset = 0;
51
52 _mcEdge = NULL;
53
54 Update();
55 if (_mcEdge) time = _mcEdge->time;
56 }
57 //------------------------------------------------------------------------------
58
59 LocalEdgeCriteria::~LocalEdgeCriteria()
60 {
61 delete _normalOffset;
62 }
63 //------------------------------------------------------------------------------
64
65 void
66 LocalEdgeCriteria::Update(bool __reconstructNormalOffset)
67 {
68 _meshSize = _mcaa->GetSize(_P);
69
70 double targetLength = .86*_meshSize;
71 if ( __reconstructNormalOffset
72 ||!_normalOffset )
73 // inutile? || fabs ( 1 - 2*targetLength/_normalOffset->GetTargetLength()) > .1)
74 {
75 if (_normalOffset) delete _normalOffset;
76 _normalOffset = new Intersection_Plane_MG_MAILLAGE(_P, _N, _mesh, targetLength, _startSeg, NULL);
77 }
78
79 InitSetOfTouchingEdges();
80
81 std::vector <Intersection_Plane_MG_MAILLAGE::Vertex> & pl = _normalOffset->GetPolyline();
82 int nb_pts = pl.size();
83 int o = _normalOffset->GetOriginIndex();
84
85 // Get the mc edge attached to the start segment
86 {
87 MG_SEGMENT * seg = pl[o].E;
88 MG_ELEMENT_TOPOLOGIQUE * topo = seg->get_lien_topologie();
89 if ( topo && topo->get_dimension() == 1)
90 {
91 MCEdge * edge = (MCEdge*) topo;
92 _mcEdge = edge;
93 time = _mcEdge->time;
94 }
95 else
96 {
97 _mcEdge = (MCEdge*)_seg->get_lien_topologie();
98 }
99 }
100
101 for (unsigned i=0; i<2; i++)
102 {
103 _lengthToOppositeEdges[i] = 0;
104 _oppositeEdgesPolylineIndices[i] = -1;
105 _oppositeEdges[i] = NULL;
106 }
107
108 for (int j = 0; j < 2; j++)
109 {
110 for (int i = 0; i+1 < nb_pts; i++)
111 {
112 int k[2];
113 if (j == 0)
114 {
115 k[0] = o - i;
116 k[1] = o - i - 1;
117 if (k[1] < 0 || k[1] >= nb_pts)
118 break;
119 }
120 else if (j == 1)
121 {
122 k[0] = o + i;
123 k[1] = o + i + 1;
124 if (k[1] < 0 || k[1] >= nb_pts)
125 break;
126 }
127
128 MG_SEGMENT * Seg [2];
129 MG_NOEUD * No [2];
130 OT_VECTEUR_3D xyz[2];
131 double dl;
132
133 for (unsigned l = 0; l < 2; l++)
134 {
135 xyz[l] = pl[k[l]].X;
136 Seg[l] = pl[k[l]].E;
137 No[l] = pl[k[l]].V;
138 }
139
140 MG_ELEMENT_TOPOLOGIQUE * topo;
141 topo = Seg[1]->get_lien_topologie();
142
143 if (topo && topo->get_dimension() == 1 )
144 {
145 _oppositeEdges[j] = (MCEdge *) topo;
146 _oppositeEdgesPolylineIndices[j] = k[1];
147 }
148 else
149 {
150 _oppositeEdges[j] = NULL;
151 _oppositeEdgesPolylineIndices[j] = -1;
152 }
153
154 dl = (xyz[0] - xyz[1]).get_longueur();
155 _lengthToOppositeEdges[j] += dl;
156
157 if ( _oppositeEdges[j] )
158 break;
159 }
160 }
161
162 _point = pl[o].X;
163 double * segStart = pl[0].X, * segEnd = pl[nb_pts-1].X;
164 for (unsigned i=0;i<3;i++)
165 {
166 _segment [0][i] = segStart[i];
167 _segment [1][i] = segEnd[i];
168 }
169
170 /** Compute the local edge properties */
171 // Face width
172 _faceWidth = std::min( _lengthToOppositeEdges[0], _lengthToOppositeEdges[1] );
173 // Epsilon (distance between the mesh and the geometry
174 _epsilon = OT_ALGORITHME_GEOMETRIQUE::Dist3D_Point_Segment( _segment [0], _segment [1], _point); // Angle between the 2 edge segments
175 if ( _segment [0] == _point || _segment [1] == _point )
176 _deviationAngle = 0;
177 else
178 _deviationAngle = OT_ALGORITHME_GEOMETRIQUE::Angle3D_Segment_Segment( _segment [0], _point, _segment [1] );
179 }
180 //------------------------------------------------------------------------------
181
182 double LocalEdgeCriteria::DeletionScore_FaceWidth() const
183 {
184 double criterionFaceWidth;
185 double limitFaceWidth = _meshSize / _mcaa->GetMaxOverdensity();
186
187 if ( _oppositeEdges[0] || _oppositeEdges[1] )
188 {
189 if (_faceWidth < limitFaceWidth)
190 criterionFaceWidth = 1 - _faceWidth / limitFaceWidth;
191 else
192 criterionFaceWidth = .05 * (1 - _faceWidth / limitFaceWidth);
193 }
194 else
195 criterionFaceWidth = -.05;
196
197 return criterionFaceWidth;
198 }
199 //------------------------------------------------------------------------------
200
201 double LocalEdgeCriteria::DeletionScore_DeviationAngle() const
202 {
203 double criterionAngle;
204 double limitAngle = _mcaa->GetLimitAngle();
205
206 if (_deviationAngle < limitAngle)
207 criterionAngle = 1 - _deviationAngle / limitAngle;
208 else
209 criterionAngle = .2*(1 - _deviationAngle / limitAngle);
210
211 return criterionAngle;
212 }
213 //------------------------------------------------------------------------------
214
215 double LocalEdgeCriteria::DeletionScore() const
216 {
217 int i, NB_CRITERIA = 0;
218 double score = 0;
219 double val[10];
220
221 if (_mcaa->GetMCBody()->G21()->GetArc(_mcEdge->get_id())->Rank() != 2)
222 return 0;
223
224 if (_mcEdge && _mcEdge->get_nb_ccf())
225 return 0;
226
227 val[NB_CRITERIA++] = DeletionScore_FaceWidth();
228 val[NB_CRITERIA++] = DeletionScore_DeviationAngle();
229 // val[NB_CRITERIA++] = DeletionScore_OppositeEdge();
230
231 for (i=0;i<NB_CRITERIA;i++)
232 {
233 if (score < val[i])
234 {
235 score = val[i];
236 }
237 }
238
239 return score;
240 }
241 //------------------------------------------------------------------------------
242
243 void LocalEdgeCriteria::GetPolylineVertex(int i, float * __vec3f) const
244 {
245 const double * vec3d = _normalOffset->GetPolyline()[i].X;
246 for (int i=0; i<3; i++)
247 __vec3f[i] = vec3d[i];
248 }
249 //------------------------------------------------------------------------------
250
251 unsigned LocalEdgeCriteria::GetPolylineVerticesCount() const
252 {
253 return _normalOffset->GetPolyline().size();
254 }
255 //------------------------------------------------------------------------------
256
257 std::string
258 LocalEdgeCriteria::InventorText()
259 {
260 std::ostringstream out;
261
262 unsigned char rgb[3];
263 ColorMap::jetColorMap(rgb, 1-DeletionScore(), 0, 1);
264 _normalOffset->SetColor(rgb);
265 out << _normalOffset->InventorText();
266
267 for (unsigned j=0; j<2; j++)
268 if (_oppositeEdgesPolylineIndices[j] != -1) {
269 int i = _oppositeEdgesPolylineIndices[j];
270 std::vector <Intersection_Plane_MG_MAILLAGE::Vertex> & pl = _normalOffset->GetPolyline();
271 out << "\nSeparator { #sep1 \n";
272 out << "\n Coordinate3 {\n point [ \n";
273 out << pl[i].X[0] << " " <<pl[i].X[1] << " " << pl[i].X[2] << " \n";
274 out << "\n]\n}\n";
275 out << "PolygonOffset { \n";
276 out << "styles POINTS \n";
277 out << "factor 4.0 \n";
278 out << "units 1.0 \n";
279 out << "} \n";
280 out << "DrawStyle {\npointSize 4\n}\n";
281 out << "BaseColor { \n rgb 1.0 0.0 0.0\n }\n";
282 out << "PointSet {\nstartIndex "<<0<<"\nnumPoints "<<1<<"\n}\n";
283 out << "} # end Sep1 \n";
284 }
285
286 return out.str();
287 }
288 //------------------------------------------------------------------------------
289
290 MCEdge * LocalEdgeCriteria::GetEdge()
291 {
292 return _mcEdge;
293 }
294 //------------------------------------------------------------------------------
295
296 MG_SEGMENT * LocalEdgeCriteria::GetSegment()
297 {
298 return _seg;
299 }
300 //------------------------------------------------------------------------------
301
302 double LocalEdgeCriteria::GetFaceWidth()
303 {
304 return _faceWidth;
305 }
306 //------------------------------------------------------------------------------
307
308 double LocalEdgeCriteria::GetEpsilon()
309 {
310 return _epsilon;
311 }
312 //------------------------------------------------------------------------------
313
314 double LocalEdgeCriteria::GetDeviationAngle()
315 {
316 return _deviationAngle;
317 }
318 //------------------------------------------------------------------------------
319 bool LocalEdgeCriteria::IsTouchingEdge(MCEdge * __mcEdge)
320 {
321 return _setTouchingEdge.find(__mcEdge) != _setTouchingEdge.end();
322 }
323 //------------------------------------------------------------------------------
324 bool LocalEdgeCriteria::IsTouchingSegment(MG_SEGMENT * __segment)
325 {
326 if (__segment == NULL)
327 return false;
328
329 std::vector <Intersection_Plane_MG_MAILLAGE::Vertex> & pl = _normalOffset->GetPolyline();
330 unsigned nb_pts = pl.size();
331
332 // Get the mc edge attached to the start segment
333 for (unsigned i = 0; i < nb_pts; i++)
334 {
335 MG_SEGMENT * seg = pl[i].E;
336
337 if (seg == __segment)
338 return true;
339 }
340
341 return false;
342 }
343 //------------------------------------------------------------------------------
344 bool LocalEdgeCriteria::IsStartSegment(MG_SEGMENT * __segment)
345 {
346 if (__segment == NULL)
347 return false;
348
349 std::vector <Intersection_Plane_MG_MAILLAGE::Vertex> & pl = _normalOffset->GetPolyline();
350 unsigned int o = _normalOffset->GetOriginIndex();
351
352 return (pl[o].E == __segment);
353 }
354 //------------------------------------------------------------------------------
355
356 MCEdge * LocalEdgeCriteria::GetTouchingEdge(int __index)
357 {
358 if (__index >= 0 && __index < 2)
359 return _oppositeEdges[__index];
360 else
361 {
362 printf("Error GetTouchingEdge: __index = %d\n", __index);
363 return NULL;
364 }
365 }
366 //------------------------------------------------------------------------------
367
368 double LocalEdgeCriteria::GetLengthToTouchingEdge(int __index)
369 {
370 if (__index >= 0 && __index < 2)
371 return _lengthToOppositeEdges[__index];
372 else
373 {
374 printf("Error GetLengthToTouchingEdge: __index = %d\n", __index);
375 return NULL;
376 }
377 }
378 //------------------------------------------------------------------------------
379 MCEdge * LocalEdgeCriteria::GetClosestTouchingEdge()
380 {
381 return (_lengthToOppositeEdges[0] < _lengthToOppositeEdges[1])
382 ? _oppositeEdges[0]
383 : _oppositeEdges[1];
384 }
385 //------------------------------------------------------------------------------
386 double * LocalEdgeCriteria::GetClosestTouchingEdgePoint()
387 {
388 int i = (_lengthToOppositeEdges[0] < _lengthToOppositeEdges[1])
389 ? 0
390 : 1;
391 return _normalOffset->GetPolyline()[ _oppositeEdgesPolylineIndices [i] ].X;
392 }
393
394 double * LocalEdgeCriteria::GetTouchingEdgePoint(int __index)
395 {
396 if (__index >= 0 && __index < 2)
397 return _normalOffset->GetPolyline()[ _oppositeEdgesPolylineIndices [__index] ].X;
398 else
399 {
400 printf("Error GetLengthToTouchingEdge: __index = %d\n", __index);
401 return 0;
402 }
403 }
404 //------------------------------------------------------------------------------
405 void LocalEdgeCriteria::CheckMCTess()
406 {
407 std::vector <Intersection_Plane_MG_MAILLAGE::Vertex> & pl = _normalOffset->GetPolyline();
408 int nb_pts = pl.size();
409 int o = _normalOffset->GetOriginIndex();
410
411 for (int j = 0; j < 2; j++)
412 {
413 for (int i = 0; i+1 < nb_pts; i++)
414 {
415 int k[2];
416 if (j == 0)
417 {
418 k[0] = o - i;
419 k[1] = o - i - 1;
420 if (k[1] < 0 || k[1] >= nb_pts)
421 break;
422 }
423 else if (j == 1)
424 {
425 k[0] = o + i;
426 k[1] = o + i + 1;
427 if (k[1] < 0 || k[1] >= nb_pts)
428 break;
429 }
430
431 MG_SEGMENT * Seg [2];
432 MG_NOEUD * No [2];
433 OT_VECTEUR_3D xyz[2];
434 double dl;
435
436 for (unsigned l = 0; l < 2; l++)
437 {
438 xyz[l] = pl[k[l]].X;
439 Seg[l] = pl[k[l]].E;
440 No[l] = pl[k[l]].V;
441 }
442
443 MG_ELEMENT_TOPOLOGIQUE * topo;
444 topo = Seg[1]->get_lien_topologie();
445
446 if ( ! _mcaa->GetMCTess()->contient(Seg[1]))
447 printf("The MC Tessellation does not contains a segment crossed by LEC's polyline !\n");
448 _mcaa->CheckIfTopoExists(topo);
449 if (topo->get_dimension() < 2)
450 break;
451 }
452 }
453 }
454
455 // void LocalEdgeCriteria::Set_DeletionScore_OppositeEdge(double __value)
456 // {
457 // _deletionScoreOppositeEdge = __value;
458 // }
459
460 // double LocalEdgeCriteria::DeletionScore_OppositeEdge() const
461 // {
462 // if (_deletionScoreOppositeEdge>0)
463 // printf("ha!\n");
464 // return _deletionScoreOppositeEdge;
465 // }
466
467 double LocalEdgeCriteria::GetMeshSize()
468 {
469 return _meshSize;
470 }
471
472 void LocalEdgeCriteria::InitSetOfTouchingEdges()
473 {
474 std::vector <Intersection_Plane_MG_MAILLAGE::Vertex> & pl = _normalOffset->GetPolyline();
475 unsigned nb_pts = pl.size();
476
477 _setTouchingEdge.clear();
478 for (unsigned i = 0; i < nb_pts; i++)
479 {
480 MG_SEGMENT * seg = pl[i].E;
481 MG_ELEMENT_TOPOLOGIQUE * topo = seg->get_lien_topologie();
482 if (topo && topo->get_dimension() == 1)
483 _setTouchingEdge.insert((MCEdge*)topo);
484 }
485 }