ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/CAD4FE/src/CAD4FE_GlobalEdgeCriteria.cpp
Revision: 569
Committed: Thu Oct 16 14:36:31 2014 UTC (10 years, 6 months ago) by foucault
File size: 14834 byte(s)
Log Message:
Mise à jour pour CAD4FE (Gilles) : operation 1 (tentative)

File Contents

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