ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/CAD4FE/src/CAD4FE_GlobalEdgeCriteria.cpp
Revision: 27
Committed: Thu Jul 5 15:26:40 2007 UTC (17 years, 10 months ago) by foucault
Original Path: magic/lib/CAD4FE/CAD4FE/src/CAD4FE_GlobalEdgeCriteria.cpp
File size: 17429 byte(s)
Log Message:

File Contents

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