ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/CAD4FE/src/CAD4FE_GlobalEdgeCriteria.cpp
Revision: 1158
Committed: Thu Jun 13 22:18:49 2024 UTC (11 months ago) by francois
File size: 15440 byte(s)
Log Message:
compatibilité Ubuntu 22.04
Suppression des refeences à Windows
Ajout d'une banière

File Contents

# User Rev Content
1 francois 1158 //####//------------------------------------------------------------
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 foucault 27
23    
24     #pragma hdrstop
25    
26 foucault 176 #include "gestionversion.h"
27    
28 foucault 27 #include "CAD4FE_GlobalEdgeCriteria.h"
29    
30    
31     #pragma package(smart_init)
32    
33     #include "gestionversion.h"
34 foucault 569 #include <mg_geometrie.h>
35     #include <mg_maillage.h>
36     #include <mg_maillage_outils.h>
37     #include <mg_gestionnaire.h>
38 foucault 27 #include <mailleur0d.h>
39     #include <mailleur1d.h>
40     #include <mailleur2d.h>
41     #include <fct_generateur_3d.h>
42 foucault 569 #include <fct_generateur_constante.h>
43 foucault 27 #include <fct_taille.h>
44     #include <ot_algorithme_geometrique.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"
53     #include "CAD4FE_LocalEdgeCriteria.h"
54     #include "CAD4FE_VertexCriteria.h"
55     #include "CAD4FE_mg_utils.h"
56     #include "CAD4FE_InventorText_MCAA.h"
57     #include "CAD4FE_Intersection_Plane_MG_MAILLAGE.h"
58     #include "CAD4FE_Intersection_Plane_MG_SEGMENT.h"
59     #include "ot_algorithme_geometrique.h"
60 foucault 569 #include "CAD4FE_ColorMap.h"
61 foucault 27 #include "CAD4FE_Criteria.h"
62    
63    
64     using namespace CAD4FE;
65    
66     GlobalEdgeCriteria::GlobalEdgeCriteria(MCEdge *__mcEdge, MCAA * __mcaa)
67     :
68     _mcEdge(__mcEdge), _mcaa(__mcaa)
69     {
70     }
71    
72     GlobalEdgeCriteria::~GlobalEdgeCriteria()
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    
83     LocalEdgeCriteria * GlobalEdgeCriteria::GetLocalEdgeCriteria(MG_SEGMENT * __seg)
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    
92     void GlobalEdgeCriteria::Init()
93     {
94     TPL_SET<MG_ELEMENT_MAILLAGE*> * lien_maillage2 = _mcEdge->get_lien_maillage();
95     TPL_SET<MG_ELEMENT_MAILLAGE*>::ITERATEUR it2;
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    
110     void GlobalEdgeCriteria::Init(MG_SEGMENT * __seg)
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    
119     LocalEdgeCriteria * lec = CreateLocalEdgeCriteria(__seg);
120    
121     _lec.insert ( std::make_pair(__seg,lec) );
122     }
123    
124     LocalEdgeCriteria * GlobalEdgeCriteria::CreateLocalEdgeCriteria(MG_SEGMENT* __seg)
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    
151     bool GlobalEdgeCriteria::Delete(MG_SEGMENT * __seg)
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    
213     void GlobalEdgeCriteria::ReInit(MG_SEGMENT * __touchingSeg)
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    
237     void GlobalEdgeCriteria::_Update()
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 foucault 569 printf("Warning: while updating local criteria of MCEdge %lu, local edge criteria's edge became null\n", _mcEdge->get_id());
248 foucault 27 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 foucault 569 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 foucault 27 }
267     }
268     }
269    
270     MCEdge * GlobalEdgeCriteria::GetEdge()
271     {
272     return _mcEdge;
273     }
274    
275     double GlobalEdgeCriteria::DeletionScore_EdgeLength() const
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();
425     TPL_SET<MG_ELEMENT_MAILLAGE*>::ITERATEUR it2;
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    
453     double GlobalEdgeCriteria::SplitScore(LocalEdgeCriteria * vecEC[2])
454     {
455     if ( vecEC[0] && vecEC[1]
456 foucault 569 && (vecEC[0]->DeletionScore() > 0.005) != (vecEC[1]->DeletionScore() > 0.005))
457 foucault 27 {
458     return 1.0;
459     }
460     else
461     return 0.0;
462     }
463    
464     double GlobalEdgeCriteria::GetLength() const
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    
480     double GlobalEdgeCriteria::DeletionScore()
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 foucault 569 {
491 foucault 27 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    
545     LocalEdgeCriteria * GlobalEdgeCriteria::GetFirstLocalEdgeCriteria(LEC_Iterator & __it)
546     {
547     __it = _lec.begin();
548     if (__it != _lec.end() )
549     return __it->second;
550     else
551     return NULL;
552     }
553    
554     LocalEdgeCriteria * GlobalEdgeCriteria::GetNextLocalEdgeCriteria(LEC_Iterator & __it)
555     {
556     __it ++;
557     if (__it != _lec.end() )
558     return __it->second;
559     else
560     return NULL;
561     }
562    
563     void
564     GlobalEdgeCriteria::ChangeTopo(GlobalEdgeCriteria * __src)
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    
581     void GlobalEdgeCriteria::CheckMCTess()
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