ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/CAD4FE/src/CAD4FE_GlobalEdgeCriteria.cpp
Revision: 176
Committed: Tue May 19 20:56:11 2009 UTC (15 years, 11 months ago) by foucault
Original Path: magic/lib/CAD4FE/CAD4FE/src/CAD4FE_GlobalEdgeCriteria.cpp
File size: 17458 byte(s)
Log Message:
Mise à jour :
* CAD4FE
* outil : HypergraphLib qui est maintenant compilable sous Linux (essais mois aout 2008)
* outil : ot_mathematique.cpp suppression d'une méthode de classe inutile nécessaire pour compiler avec CodeGear Builder 2006 OT_VECTEUR_3D::OT_VECTEUR_3D(OT_VECTEUR_3D& mdd)

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     #include <MG_GEOMETRIE.h>
18     #include <MG_MAILLAGE.h>
19     #include <MG_MAILLAGE_OUTILS.h>
20     #include <MG_GESTIONNAIRE.h>
21     #include <mailleur0d.h>
22     #include <mailleur1d.h>
23     #include <mailleur2d.h>
24     #include <fct_generateur_3d.h>
25     #include <FCT_GENERATEUR_CONSTANTE.h>
26     #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     #include "CAD4FE_Colormap.h"
44     #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     printf("Warning: while updating local criteria of MCEdge %d, local edge criteria's edge became null\n", _mcEdge->get_id());
234     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     printf("Warning: while updating local criteria of MCEdge %d, the MCEdge %d is different than the first one\n", _mcEdge->get_id(), ec->GetEdge()->get_id() );
252     }
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     && (vecEC[0]->DeletionScore() > 0.005) != (vecEC[1]->DeletionScore() > 0.005) )
444     {
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     {
478    
479    
480     // for ( it_lec = _lec.begin();
481     // it_lec != _lec.end();
482     // it_lec ++ )
483     // {
484     // MG_SEGMENT * seg = it_lec->first;
485     // LocalEdgeCriteria * lec = it_lec->second;
486    
487     // for (int j=0; j<2; j++)
488     // {
489     // double limitLength = lec->GetMeshSize() / _mcaa->GetMaxOverdensity();
490    
491     // if (lec->GetLengthToTouchingEdge(j) > limitLength)
492     // continue;
493    
494    
495    
496     // if (lec->DeletionScore_FaceWidth() > 0.01)
497     // {
498     // MCEdge * touchingEdge = lec->GetTouchingEdge(j);
499     // double * P = lec->GetTouchingEdgePoint(j);
500     // MG_SEGMENT * closestSegment = NULL;
501     // double shorstestDistance = 1E99;
502     // MG_MAILLAGE * feMesh = _mcaa->GetFEMesh();
503     // TPL_SET<MG_ELEMENT_MAILLAGE*>::ITERATEUR it_seg;
504     // TPL_SET<MG_ELEMENT_MAILLAGE*> * lien_maillage = touchingEdge->get_lien_maillage();
505     // for (MG_SEGMENT* seg = (MG_SEGMENT*)lien_maillage->get_premier(it_seg);
506     // seg; seg = (MG_SEGMENT*)lien_maillage->get_suivant(it_seg))
507     // {
508     // if (feMesh->contient(seg) )
509     // {
510     // double a[3],b[3];
511     // a[0]=seg->get_noeud1()->get_x(); b[0]=seg->get_noeud2()->get_x();
512     // a[1]=seg->get_noeud1()->get_y(); b[1]=seg->get_noeud2()->get_y();
513     // a[2]=seg->get_noeud1()->get_z(); b[2]=seg->get_noeud2()->get_z();
514    
515     // double distance = OT_ALGORITHME_GEOMETRIQUE::Dist3D_Point_Segment(a,b,P);
516    
517     // if (distance < shorstestDistance)
518     // {
519     // shorstestDistance = distance;
520     // closestSegment = seg;
521     // }
522     // }
523     // }
524    
525     // _mcaa->GetGlobalEdgeCriteria(touchingEdge)->GetLocalEdgeCriteria(closestSegment)->Set_DeletionScore_OppositeEdge(1);
526     // }
527     // }
528     // }
529    
530     return 0;
531     }
532    
533    
534     for ( it_lec = _lec.begin();
535     it_lec != _lec.end();
536     it_lec ++ )
537     {
538     MG_SEGMENT * seg = it_lec->first;
539     LocalEdgeCriteria * lec = it_lec->second;
540     if (lec->GetEdge() != _mcEdge)
541     continue;
542     double length = seg->get_longueur();
543     if (length == 0.0)
544     result += lec->DeletionScore();
545     else
546     {
547     result += length*lec->DeletionScore();
548     edge_length += length;
549     }
550     }
551    
552     if (edge_length != 0.0)
553     result /= edge_length;
554    
555     double lengthScore = DeletionScore_EdgeLength();
556    
557     if (lengthScore < 0)
558     result = std::min(result, .01);
559     else if (lengthScore > result)
560     result = lengthScore;
561    
562     if (edge_length == 0.0)
563     result = 1;
564    
565     return result;
566     }
567    
568     std::vector <LocalEdgeCriteria*> GlobalEdgeCriteria::GetLocalEdgeCriteria()
569     {
570     std::vector <LocalEdgeCriteria*> result;
571    
572     LEC_Iterator it_lec;
573    
574     for ( it_lec = _lec.begin();
575     it_lec != _lec.end();
576     it_lec ++ )
577     {
578     LocalEdgeCriteria * lec = it_lec->second;
579     result.push_back(lec);
580     }
581    
582     return result;
583     }
584    
585     LocalEdgeCriteria * GlobalEdgeCriteria::GetFirstLocalEdgeCriteria(LEC_Iterator & __it)
586     {
587     __it = _lec.begin();
588     if (__it != _lec.end() )
589     return __it->second;
590     else
591     return NULL;
592     }
593    
594     LocalEdgeCriteria * GlobalEdgeCriteria::GetNextLocalEdgeCriteria(LEC_Iterator & __it)
595     {
596     __it ++;
597     if (__it != _lec.end() )
598     return __it->second;
599     else
600     return NULL;
601     }
602    
603     void
604     GlobalEdgeCriteria::ChangeTopo(GlobalEdgeCriteria * __src)
605     {
606     LEC_Iterator it_lec;
607    
608     for ( it_lec = __src->_lec.begin();
609     it_lec != __src->_lec.end();
610     it_lec ++ )
611     {
612     LocalEdgeCriteria * lec = it_lec->second;
613     MG_SEGMENT * seg = it_lec->first;
614     _lec.insert(std::make_pair(seg,lec));
615     }
616    
617     __src->_lec.clear();
618     }
619    
620    
621     void GlobalEdgeCriteria::CheckMCTess()
622     {
623     LEC_Iterator it_lec;
624    
625     for ( it_lec = _lec.begin();
626     it_lec != _lec.end();
627     it_lec ++ )
628     {
629     LocalEdgeCriteria * lec = it_lec->second;
630     lec->CheckMCTess();
631     }
632     }
633