MAGiC  V5.0
Mailleurs Automatiques de Géometries intégrés à la Cao
CAD4FE_GlobalEdgeCriteria.cpp
Aller à la documentation de ce fichier.
1 //####//------------------------------------------------------------
2 //####//------------------------------------------------------------
3 //####// MAGiC
4 //####// Jean Christophe Cuilliere et Vincent FRANCOIS
5 //####// Departement de Genie Mecanique - UQTR
6 //####//------------------------------------------------------------
7 //####// MAGIC est un projet de recherche de l equipe ERICCA
8 //####// du departement de genie mecanique de l Universite du Quebec a Trois Rivieres
9 //####// http://www.uqtr.ca/ericca
10 //####// http://www.uqtr.ca/
11 //####//------------------------------------------------------------
12 //####//------------------------------------------------------------
13 //####//
14 //####// CAD4FE_GlobalEdgeCriteria.cpp
15 //####//
16 //####//------------------------------------------------------------
17 //####//------------------------------------------------------------
18 //####// COPYRIGHT 2000-2024
19 //####// jeu 13 jun 2024 11:58:56 EDT
20 //####//------------------------------------------------------------
21 //####//------------------------------------------------------------
22 
23 
24 #pragma hdrstop
25 
26 #include "gestionversion.h"
27 
29 
30 
31 #pragma package(smart_init)
32 
33 #include "gestionversion.h"
34 #include <mg_geometrie.h>
35 #include <mg_maillage.h>
36 #include <mg_maillage_outils.h>
37 #include <mg_gestionnaire.h>
38 #include <mailleur0d.h>
39 #include <mailleur1d.h>
40 #include <mailleur2d.h>
41 #include <fct_generateur_3d.h>
43 #include <fct_taille.h>
45 
46 #include "CAD4FE_MCBody.h"
47 #include "CAD4FE_MCAA.h"
48 #include "CAD4FE_PolyCurve.h"
49 #include "CAD4FE_PolySurface.h"
50 #include "CAD4FE_MCFace.h"
51 #include "CAD4FE_MCEdge.h"
52 #include "CAD4FE_MCVertex.h"
54 #include "CAD4FE_VertexCriteria.h"
55 #include "CAD4FE_mg_utils.h"
60 #include "CAD4FE_ColorMap.h"
61 #include "CAD4FE_Criteria.h"
62 
63 
64 using namespace CAD4FE;
65 
67 :
68 _mcEdge(__mcEdge), _mcaa(__mcaa)
69 {
70 }
71 
73 {
74  for ( LEC_Iterator it_lec = _lec.begin();
75  it_lec != _lec.end();
76  it_lec ++ )
77  {
78  LocalEdgeCriteria * ec = it_lec->second;
79  delete ec;
80  }
81 }
82 
84 {
85  LEC_Iterator it_lec = _lec.find(__seg);
86  if (it_lec != _lec.end())
87  return it_lec->second;
88  else
89  return NULL;
90 }
91 
93 {
96  MG_ELEMENT_MAILLAGE* element2;
97  for (element2 = lien_maillage2->get_premier(it2); element2; element2 = lien_maillage2->get_suivant(it2) )
98  {
99  MG_SEGMENT * seg = (MG_SEGMENT *)element2;
100 
101  if (seg == NULL)
102  continue;
103  if ( ! _mcaa->GetFEMesh()->contient(seg) )
104  continue;
105 
106  Init(seg);
107  }
108 }
109 
111 {
112  LEC_Iterator it_lec = _lec.find(__seg);
113  if (it_lec != _lec.end() )
114  {
115  delete it_lec->second;
116  _lec.erase (it_lec);
117  }
118 
120 
121  _lec.insert ( std::make_pair(__seg,lec) );
122 }
123 
125 {
126 
127  double point[3], normal[3];
128  double x[2][3];
129  MG_UTILS::MG_NOEUD_GET_XYZ(__seg->get_noeud1(), x[0]);
130  MG_UTILS::MG_NOEUD_GET_XYZ(__seg->get_noeud2(), x[1]);
131 
132  for (unsigned i=0; i<3; i++)
133  {
134  point[i] = .5*(x[0][i]+x[1][i]);
135  normal[i] = x[1][i] - point[i];
136  }
137 
138  MG_SEGMENT * startSeg = _mcaa->FindClosestSeg(_mcEdge, point, normal);
139 
140  if (startSeg == NULL)
141  {
142  startSeg = _mcaa->FindClosestSeg(_mcEdge, point, normal);
143  }
144 
145  return new LocalEdgeCriteria ( __seg,
146  _mcaa,
147  _mcaa->GetMCTess(),
148  startSeg);
149 }
150 
152 {
153  LEC_Iterator it_lec = _lec.find(__seg);
154  if (it_lec != _lec.end() )
155  {
156  delete it_lec->second;
157  _lec.erase (it_lec);
158  return true;
159  }
160  else
161  {
162  return false;
163  }
164 }
165 
166 void GlobalEdgeCriteria::Update(bool __reconstructNormalOffsets)
167 {
168  LEC_Iterator it_lec;
169 
170  for ( it_lec = _lec.begin();
171  it_lec != _lec.end();
172  it_lec ++ )
173  {
174  LocalEdgeCriteria * lec = it_lec->second;
175  lec->Update(__reconstructNormalOffsets);
176  }
177 
178  _Update();
179 }
180 
181 void GlobalEdgeCriteria::Update(MCEdge * __touchingEdge, bool __reconstructNormalOffsets)
182 {
183  LEC_Iterator it_lec;
184 
185  for ( it_lec = _lec.begin();
186  it_lec != _lec.end();
187  it_lec ++ )
188  {
189  LocalEdgeCriteria * lec = it_lec->second;
190  if (lec->IsTouchingEdge(__touchingEdge))
191  lec->Update(__reconstructNormalOffsets);
192  }
193 
194  _Update();
195 }
196 
197 void GlobalEdgeCriteria::Update(MG_SEGMENT * __touchingSeg, bool __reconstructNormalOffsets)
198 {
199  LEC_Iterator it_lec;
200 
201  for ( it_lec = _lec.begin();
202  it_lec != _lec.end();
203  it_lec ++ )
204  {
205  LocalEdgeCriteria * ec = it_lec->second;
206  if (ec->IsTouchingSegment(__touchingSeg))
207  ec->Update(__reconstructNormalOffsets);
208  }
209 
210  _Update();
211 }
212 
214 {
215  int touchingSegCount;
216  LEC_Iterator it_lec;
217 
218  touchingSegCount = 0;
219  for ( it_lec = _lec.begin();
220  it_lec != _lec.end();
221  it_lec ++ )
222  {
223  LocalEdgeCriteria * ec = it_lec->second;
224  if (ec->IsTouchingSegment(__touchingSeg))
225  {
226  MG_SEGMENT * seg = ec->GetSegment();
227  delete ec;
228  it_lec->second = CreateLocalEdgeCriteria ( seg );
229  touchingSegCount++;
230  }
231  }
232 
233  if (touchingSegCount > 1)
234  _Update();
235 }
236 
238 {
239  LEC_Iterator it_lec;
240  for ( it_lec = _lec.begin();
241  it_lec != _lec.end();
242  it_lec ++ )
243  {
244  LocalEdgeCriteria * lec = it_lec->second;
245  if (lec->GetEdge() == NULL)
246  {
247  printf("Warning: while updating local criteria of MCEdge %lu, local edge criteria's edge became null\n", _mcEdge->get_id());
248  lec->Update();
249  delete lec;
250  _lec.erase(it_lec);
251  }
252  }
253 
254  it_lec = _lec.begin();
255  LocalEdgeCriteria * ec = it_lec->second;
256  _mcEdge = ec->GetEdge();
257 
258  for ( LEC_Iterator it_lec = _lec.begin();
259  it_lec != _lec.end();
260  it_lec ++ )
261  {
262  LocalEdgeCriteria * lec = it_lec->second;
263  if (lec->GetEdge() != _mcEdge)
264  {
265  printf("Warning: while updating local criteria of MCEdge %lu, the MCEdge %lu is different than the first one\n", _mcEdge->get_id(), ec->GetEdge()->get_id() );
266  }
267  }
268 }
269 
271 {
272  return _mcEdge;
273 }
274 
276 {
277  MCVertex * mcVertexRank1 = NULL;
278  MCVertex * otherVertex = NULL;
279  std::vector < MCVertex * > mcVertices;
280 
281  _mcaa->GetMCBody()->Edge_GetVertices(_mcEdge, mcVertices);
282 
283  double xyz[2][3 ];
284  int i;
285  mcVertices[0]->get_point()->evaluer(xyz[0]);
286  mcVertices[1]->get_point()->evaluer(xyz[1]);
287  double meshSize = .5*(_mcaa->GetSize(xyz[0])+_mcaa->GetSize(xyz[1]));
288 
289  double criterionEdgeLength;
290  double limitLength = meshSize / _mcaa->GetMaxOverdensity();
291 
292 
293  // Requirement 1
294  // length < limit
295  double length = _mcEdge->GetPolyCurve()->get_longueur();
296  if (length > limitLength)
297  {
298  return 0;
299  }
300 
301 
302  // requirements :
303  // at least one vertex has rank = 1
304  // the other vertex must have deletion score = 0
305  if (mcVertices.size() == 2 && mcVertices[0] != mcVertices[1] )
306  {
307  for (i=0;i<2;i++)
308  {
309  MCVertex * v = mcVertices[i];
310  std::set < MCEdge * > vertex_edges;
311  _mcaa->GetMCBody()->Vertex_GetAdjacentEdges(v,vertex_edges);
312  if (vertex_edges.size() == 1)
313  {
314  mcVertexRank1 = v;
315  break;
316  }
317  }
318 
319  if (mcVertexRank1 == NULL)
320  {
321  return -1; // DO NOT DELETE SMALL EDGES THAT HAVE UNDELETABLE EXTREMITIES
322  }
323 
324  if (mcVertexRank1 == mcVertices[0] )
325  otherVertex = mcVertices[1];
326  else
327  otherVertex = mcVertices[0];
328 
329  return ( -1 + length / limitLength );
330 
331  /* if (_mcaa->VC_Get(otherVertex)->GetScore() <= 0)
332  {
333  return 0;
334  }
335  else
336  {
337  return 1 - length / limitLength;
338  }*/
339  }
340  else
341  {
342  mcVertexRank1 = mcVertices[0];
343 
344  return ( -1 + length / limitLength );
345  }
346 
347 
348 
349  return 0;
350 }
351 
352 double GlobalEdgeCriteria::SplitScore(double __splitPoint[3])
353 {
354  int i;
355  // for each node of the 1D FE mesh :
356  // if the node is on a edge (not on a vertex)
357  // if the 2 adjacent segments have incompatible suppression
358  // criteria ie. 1st edge non-suppressable, 2nd suppressable
359  // then split the MCEdge at the node's position
360 
361 
362  /* LEC_Iterator it_lec;
363  std::set<MG_NOEUD*> nodes;
364 
365  for ( it_lec = _lec.begin();
366  it_lec != _lec.end();
367  it_lec ++ )
368  {
369  MG_SEGMENT * seg = it_lec->first;
370 
371  MG_NOEUD * no[2];
372  MG_SEGMENT_GET_NOEUDS(seg, no);
373  for (i=0;i<2;i++)
374  {
375  nodes.insert(no[i]);
376  }
377  }
378 
379  LISTE_MG_NOEUD::iterator itNode;
380  for ( std::set<MG_NOEUD*>::iterator it_nodes = nodes.begin();
381  it_nodes != nodes.end();
382  it_nodes++ )
383  {
384  MG_NOEUD * node = *it_nodes;*/
385 
386  LEC_Iterator it_lec;
387  std::set<MG_NOEUD*> nodes;
388 
389  for ( it_lec = _lec.begin();
390  it_lec != _lec.end();
391  it_lec ++ )
392  {
393  MG_SEGMENT * seg = it_lec->first;
394  MG_NOEUD * node = seg->get_noeud1();
395 
396  if (node->get_lien_topologie()
397  && node->get_lien_topologie()->get_dimension() == 1
398  && node->get_lien_segment()->get_nb() == 2 )
399  {
400  MG_SEGMENT * segs[2];
401  segs[0] = node->get_lien_segment()->get(0);
402  segs[1] = node->get_lien_segment()->get(1);
403  LocalEdgeCriteria * vecEC[2];
404  for (i=0;i<2;i++)
405  vecEC[i]=GetLocalEdgeCriteria(segs[i]);
406 
407  MG_UTILS::MG_NOEUD_GET_XYZ(node, __splitPoint);
408 
409  double score = SplitScore(vecEC);
410  if (score > 0)
411  return score;
412  }
413  }
414 
415  return 0;
416 }
417 
418 double GlobalEdgeCriteria::SplitScore(MCAA * __mcaa, MCVertex * __mcVertex)
419 {
420  int i;
421  MG_NOEUD * node;
422  MG_MAILLAGE * feMesh = __mcaa->GetFEMesh();
423 
424  TPL_SET<MG_ELEMENT_MAILLAGE*> * lien_maillage2 = __mcVertex->get_lien_maillage();
426  MG_ELEMENT_MAILLAGE* element2;
427  for (element2 = lien_maillage2->get_premier(it2); element2; element2 = lien_maillage2->get_suivant(it2) )
428  {
429  if (feMesh->contient(element2))
430  {
431  node = (MG_NOEUD*) element2;
432  break;
433  }
434  }
435 
436  if (node->get_lien_segment()->get_nb() != 2 )
437  return 0;
438 
439  MG_SEGMENT * segs[2];
440  segs[0] = node->get_lien_segment()->get(0);
441  segs[1] = node->get_lien_segment()->get(1);
442  LocalEdgeCriteria * vecEC[2];
443  for (i=0;i<2;i++)
444  {
445  MCEdge * mcEdge = (MCEdge*) segs[i]->get_lien_topologie();
446  GlobalEdgeCriteria * gec = __mcaa->GetGlobalEdgeCriteria(mcEdge);
447  vecEC[i] = gec->GetLocalEdgeCriteria(segs[i]);
448  }
449 
450  return SplitScore(vecEC);
451 }
452 
454 {
455  if ( vecEC[0] && vecEC[1]
456  && (vecEC[0]->DeletionScore() > 0.005) != (vecEC[1]->DeletionScore() > 0.005))
457  {
458  return 1.0;
459  }
460  else
461  return 0.0;
462 }
463 
465 {
466  double edge_length=0;
467  LEC_CIterator it_lec;
468  for ( it_lec = _lec.begin();
469  it_lec != _lec.end();
470  it_lec ++ )
471  {
472  MG_SEGMENT * seg = it_lec->first;
473  LocalEdgeCriteria * lec = it_lec->second;
474  double length = seg->get_longueur();
475  edge_length += length;
476  }
477  return edge_length;
478 }
479 
481 {
482  double result;
483  LEC_Iterator it_lec;
484 
485  result = 0;
486  double edge_length = 0;
487 
488  // Deny deletion of there exist some boundary conditions on the edge
489  if (_mcEdge->get_nb_ccf())
490  {
491  return 0;
492  }
493 
494  for ( it_lec = _lec.begin();
495  it_lec != _lec.end();
496  it_lec ++ )
497  {
498  MG_SEGMENT * seg = it_lec->first;
499  LocalEdgeCriteria * lec = it_lec->second;
500  if (lec->GetEdge() != _mcEdge)
501  continue;
502  double length = seg->get_longueur();
503  if (length == 0.0)
504  result += lec->DeletionScore();
505  else
506  {
507  result += length*lec->DeletionScore();
508  edge_length += length;
509  }
510  }
511 
512  if (edge_length != 0.0)
513  result /= edge_length;
514 
515  double lengthScore = DeletionScore_EdgeLength();
516 
517  if (lengthScore < 0)
518  result = std::min(result, .01);
519  else if (lengthScore > result)
520  result = lengthScore;
521 
522  if (edge_length == 0.0)
523  result = 1;
524 
525  return result;
526 }
527 
528 std::vector <LocalEdgeCriteria*> GlobalEdgeCriteria::GetLocalEdgeCriteria()
529 {
530  std::vector <LocalEdgeCriteria*> result;
531 
532  LEC_Iterator it_lec;
533 
534  for ( it_lec = _lec.begin();
535  it_lec != _lec.end();
536  it_lec ++ )
537  {
538  LocalEdgeCriteria * lec = it_lec->second;
539  result.push_back(lec);
540  }
541 
542  return result;
543 }
544 
546 {
547  __it = _lec.begin();
548  if (__it != _lec.end() )
549  return __it->second;
550  else
551  return NULL;
552 }
553 
555 {
556  __it ++;
557  if (__it != _lec.end() )
558  return __it->second;
559  else
560  return NULL;
561 }
562 
563 void
565 {
566  LEC_Iterator it_lec;
567 
568  for ( it_lec = __src->_lec.begin();
569  it_lec != __src->_lec.end();
570  it_lec ++ )
571  {
572  LocalEdgeCriteria * lec = it_lec->second;
573  MG_SEGMENT * seg = it_lec->first;
574  _lec.insert(std::make_pair(seg,lec));
575  }
576 
577  __src->_lec.clear();
578 }
579 
580 
582 {
583  LEC_Iterator it_lec;
584 
585  for ( it_lec = _lec.begin();
586  it_lec != _lec.end();
587  it_lec ++ )
588  {
589  LocalEdgeCriteria * lec = it_lec->second;
590  lec->CheckMCTess();
591  }
592 }
593 
#define node(i, j)
std::map< MG_SEGMENT *, LocalEdgeCriteria * >::iterator LEC_Iterator
LocalEdgeCriteria * CreateLocalEdgeCriteria(MG_SEGMENT *__seg)
double GetLength() const
total length of all local segments
void ReInit(MG_SEGMENT *__touchingSeg)
double DeletionScore()
score of MCT operators
void Update(MG_SEGMENT *__touchingSeg, bool __reconstructNormalOffsets)
std::vector< LocalEdgeCriteria * > GetLocalEdgeCriteria()
std::map< MG_SEGMENT *, LocalEdgeCriteria * >::const_iterator LEC_CIterator
LocalEdgeCriteria * GetFirstLocalEdgeCriteria(LEC_Iterator &__it)
double SplitScore(double __splitPoint[3])
void ChangeTopo(GlobalEdgeCriteria *__src)
LocalEdgeCriteria * GetNextLocalEdgeCriteria(LEC_Iterator &__it)
void Update(bool __reconstructNormalOffset=true)
bool IsTouchingEdge(MCEdge *__mcEdge)
bool IsTouchingSegment(MG_SEGMENT *__segment)
MG_MAILLAGE * GetFEMesh() const
MCBody * GetMCBody() const
double GetMaxOverdensity()
double GetSize(double xyz[3])
GlobalEdgeCriteria * GetGlobalEdgeCriteria(MCEdge *__mcEdge)
MG_MAILLAGE * GetMCTess() const
MG_SEGMENT * FindClosestSeg(MCEdge *__mcEdge, double __P[3], double __N[3])
void Vertex_GetAdjacentEdges(MCVertex *__mcVertex, std::vector< MCEdge * > &__list)
void Edge_GetVertices(MCEdge *, std::vector< MCVertex * > &__mcVertices)
PolyCurve * GetPolyCurve()
double get_longueur(double __s_min=-1, double __s_max=-1, double precision=1E-6)
virtual TPL_SET< MG_ELEMENT_MAILLAGE * > * get_lien_maillage(void)
unsigned long get_id()
bool contient(MG_IDENTIFICATEUR *id)
virtual MG_NOEUD * get_noeud1(void)
Definition: mg_segment.cpp:108
virtual double get_longueur(void)
Definition: mg_segment.cpp:125
virtual MG_NOEUD * get_noeud2(void)
Definition: mg_segment.cpp:113
static void MG_NOEUD_GET_XYZ(MG_NOEUD *node, double *xyz)
X get_premier(ITERATEUR &it)
Definition: tpl_set.h:99
X get_suivant(ITERATEUR &it)
Definition: tpl_set.h:107