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

File Contents

# Content
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_LocalEdgeCriteria.cpp
15 //####//
16 //####//------------------------------------------------------------
17 //####//------------------------------------------------------------
18 //####// COPYRIGHT 2000-2024
19 //####// jeu 13 jun 2024 11:58:56 EDT
20 //####//------------------------------------------------------------
21 //####//------------------------------------------------------------
22 #include <fstream>
23 #include <sstream>
24
25 #include "gestionversion.h"
26 #include <mg_geometrie.h>
27 #include <mg_maillage.h>
28 #include <mg_maillage_outils.h>
29 #include <ot_mathematique.h>
30
31 #include "CAD4FE_MCEdge.h"
32 #include "CAD4FE_MCAA.h"
33 #include "CAD4FE_MCBody.h"
34 #include "CAD4FE_mg_utils.h"
35 #include "CAD4FE_Intersection_Plane_MG_MAILLAGE.h"
36 #include "ot_algorithme_geometrique.h"
37 #include "CAD4FE_Criteria.h"
38 #include "CAD4FE_ColorMap.h"
39
40 #pragma hdrstop
41
42 #include "CAD4FE_LocalEdgeCriteria.h"
43
44
45 #pragma package(smart_init)
46
47 using namespace CAD4FE;
48
49
50 LocalEdgeCriteria::LocalEdgeCriteria(MG_SEGMENT * __seg, MCAA * __mcaa, MG_MAILLAGE * __mesh, MG_SEGMENT * __startSeg)
51 : _seg(__seg), _mcaa(__mcaa), _mesh(__mesh), _startSeg(__startSeg), _normalOffset(NULL)
52 {
53 double x[2][3];
54 MG_UTILS::MG_NOEUD_GET_XYZ(_seg->get_noeud1(), x[0]);
55 MG_UTILS::MG_NOEUD_GET_XYZ(_seg->get_noeud2(), x[1]);
56 // _deletionScoreOppositeEdge = 0;
57
58 /* GF Debug int nb_triangles_adj_start_segment = __startSeg->get_lien_triangle()->get_nb();
59 printf("start seg %ld : %d triangles adjacents\n", __startSeg->get_id(), nb_triangles_adj_start_segment);*/
60
61 for (unsigned i=0; i<3; i++)
62 {
63 _P[i] = .5*(x[0][i]+x[1][i]);
64 _N[i] = x[1][i]-_P[i];
65 }
66
67 _meshSize = 0;
68 _normalOffset = 0;
69
70 _mcEdge = NULL;
71
72 Update();
73 if (_mcEdge) time = _mcEdge->time;
74 }
75
76 LocalEdgeCriteria::~LocalEdgeCriteria()
77 {
78 delete _normalOffset;
79 }
80
81 void
82 LocalEdgeCriteria::Update(bool __reconstructNormalOffset)
83 {
84 _meshSize = _mcaa->GetSize(_P);
85
86 double targetLength = .86*_meshSize;
87 if ( __reconstructNormalOffset
88 ||!_normalOffset )
89 {
90 if (_normalOffset) delete _normalOffset;
91 _normalOffset = new Intersection_Plane_MG_MAILLAGE(_P, _N, _mesh, targetLength, _startSeg, NULL);
92 }
93
94 InitSetOfTouchingEdges();
95
96 std::vector <Intersection_Plane_MG_MAILLAGE::Vertex> & pl = _normalOffset->GetPolyline();
97 int nb_pts = pl.size();
98 int o = _normalOffset->GetOriginIndex();
99
100 // Get the mc edge attached to the start segment
101 {
102 MG_SEGMENT * seg = pl[o].E;
103 MG_ELEMENT_TOPOLOGIQUE * topo = seg->get_lien_topologie();
104 if ( topo && topo->get_dimension() == 1)
105 {
106 MCEdge * edge = (MCEdge*) topo;
107 _mcEdge = edge;
108 time = _mcEdge->time;
109 }
110 else
111 {
112 _mcEdge = (MCEdge*)_seg->get_lien_topologie();
113 }
114 }
115
116 for (unsigned i=0; i<2; i++)
117 {
118 _lengthToOppositeEdges[i] = 0;
119 _oppositeEdgesPolylineIndices[i] = -1;
120 _oppositeEdges[i] = NULL;
121 }
122
123 for (int j = 0; j < 2; j++)
124 {
125 for (int i = 0; i+1 < nb_pts; i++)
126 {
127 int k[2];
128 if (j == 0)
129 {
130 k[0] = o - i;
131 k[1] = o - i - 1;
132 if (k[1] < 0 || k[1] >= nb_pts)
133 break;
134 }
135 else if (j == 1)
136 {
137 k[0] = o + i;
138 k[1] = o + i + 1;
139 if (k[1] < 0 || k[1] >= nb_pts)
140 break;
141 }
142
143 MG_SEGMENT * Seg [2];
144 MG_NOEUD * No [2];
145 OT_VECTEUR_3D xyz[2];
146 double dl;
147
148 for (unsigned l = 0; l < 2; l++)
149 {
150 xyz[l] = pl[k[l]].X;
151 Seg[l] = pl[k[l]].E;
152 No[l] = pl[k[l]].V;
153 }
154
155 MG_ELEMENT_TOPOLOGIQUE * topo;
156 topo = Seg[1]->get_lien_topologie();
157
158 if (topo && topo->get_dimension() == 1 )
159 {
160 _oppositeEdges[j] = (MCEdge *) topo;
161 _oppositeEdgesPolylineIndices[j] = k[1];
162 }
163 else
164 {
165 _oppositeEdges[j] = NULL;
166 _oppositeEdgesPolylineIndices[j] = -1;
167 }
168
169 dl = (xyz[0] - xyz[1]).get_longueur();
170 _lengthToOppositeEdges[j] += dl;
171
172 if ( _oppositeEdges[j] )
173 break;
174 }
175 }
176
177 _point = pl[o].X;
178 double * segStart = pl[0].X, * segEnd = pl[nb_pts-1].X;
179 for (unsigned i=0;i<3;i++)
180 {
181 _segment [0][i] = segStart[i];
182 _segment [1][i] = segEnd[i];
183 }
184
185 /** Compute the local edge properties */
186 // Face width
187 _faceWidth = std::min( _lengthToOppositeEdges[0], _lengthToOppositeEdges[1] );
188 // Epsilon (distance between the mesh and the geometry
189 _epsilon = OT_ALGORITHME_GEOMETRIQUE::Dist3D_Point_Segment( _segment [0], _segment [1], _point); // Angle between the 2 edge segments
190 if ( _segment [0] == _point || _segment [1] == _point )
191 _deviationAngle = 0;
192 else
193 _deviationAngle = OT_ALGORITHME_GEOMETRIQUE::Angle3D_Segment_Segment( _segment [0], _point, _segment [1] );
194 }
195
196 double LocalEdgeCriteria::DeletionScore_FaceWidth() const
197 {
198 double criterionFaceWidth;
199 double limitFaceWidth = _meshSize / _mcaa->GetMaxOverdensity();
200
201 if ( _oppositeEdges[0] || _oppositeEdges[1] )
202 {
203 if (_faceWidth < limitFaceWidth)
204 criterionFaceWidth = 1 - _faceWidth / limitFaceWidth;
205 else
206 criterionFaceWidth = .05 * (1 - _faceWidth / limitFaceWidth);
207 }
208 else
209 criterionFaceWidth = -.05;
210
211 return criterionFaceWidth;
212 }
213
214 double LocalEdgeCriteria::DeletionScore_DeviationAngle() const
215 {
216 double criterionAngle;
217 double limitAngle = _mcaa->GetLimitAngle();
218
219 if (_deviationAngle < limitAngle)
220 criterionAngle = 1 - _deviationAngle / limitAngle;
221 else
222 criterionAngle = .2*(1 - _deviationAngle / limitAngle);
223
224 return criterionAngle;
225 }
226
227 double LocalEdgeCriteria::DeletionScore() const
228 {
229 int i, NB_CRITERIA = 0;
230 double score = 0;
231 double val[10];
232
233 if (_mcaa->GetMCBody()->G21()->GetArc(_mcEdge->get_id())->Rank() != 2)
234 return 0;
235
236 if (_mcEdge && _mcEdge->get_nb_ccf())
237 return 0;
238
239 val[NB_CRITERIA++] = DeletionScore_FaceWidth();
240 val[NB_CRITERIA++] = DeletionScore_DeviationAngle();
241 // val[NB_CRITERIA++] = DeletionScore_OppositeEdge();
242
243 for (i=0;i<NB_CRITERIA;i++)
244 {
245 if (score < val[i])
246 {
247 score = val[i];
248 }
249 }
250
251 return score;
252 }
253
254 void LocalEdgeCriteria::GetPolylineVertex(int i, float * __vec3f) const
255 {
256 const double * vec3d = _normalOffset->GetPolyline()[i].X;
257 for (int i=0; i<3; i++)
258 __vec3f[i] = vec3d[i];
259 }
260
261 unsigned LocalEdgeCriteria::GetPolylineVerticesCount() const
262 {
263 return _normalOffset->GetPolyline().size();
264 }
265
266 std::string
267 LocalEdgeCriteria::InventorText()
268 {
269 std::ostringstream out;
270
271 unsigned char rgb[3];
272 ColorMap::jetColorMap(rgb, 1-DeletionScore(), 0, 1);
273 _normalOffset->SetColor(rgb);
274 out << _normalOffset->InventorText();
275
276 for (unsigned j=0; j<2; j++)
277 if (_oppositeEdgesPolylineIndices[j] != -1) {
278 int i = _oppositeEdgesPolylineIndices[j];
279 std::vector <Intersection_Plane_MG_MAILLAGE::Vertex> & pl = _normalOffset->GetPolyline();
280 out << "\nSeparator { #sep1 \n";
281 out << "\n Coordinate3 {\n point [ \n";
282 out << pl[i].X[0] << " " <<pl[i].X[1] << " " << pl[i].X[2] << " \n";
283 out << "\n]\n}\n";
284 out << "PolygonOffset { \n";
285 out << "styles POINTS \n";
286 out << "factor 4.0 \n";
287 out << "units 1.0 \n";
288 out << "} \n";
289 out << "DrawStyle {\npointSize 4\n}\n";
290 out << "BaseColor { \n rgb 1.0 0.0 0.0\n }\n";
291 out << "PointSet {\nstartIndex "<<0<<"\nnumPoints "<<1<<"\n}\n";
292 out << "} # end Sep1 \n";
293 }
294
295 return out.str();
296 }
297
298 MCEdge * LocalEdgeCriteria::GetEdge()
299 {
300 return _mcEdge;
301 }
302
303 MG_SEGMENT * LocalEdgeCriteria::GetSegment()
304 {
305 return _seg;
306 }
307
308 double LocalEdgeCriteria::GetFaceWidth()
309 {
310 return _faceWidth;
311 }
312
313 double LocalEdgeCriteria::GetEpsilon()
314 {
315 return _epsilon;
316 }
317
318 double LocalEdgeCriteria::GetDeviationAngle()
319 {
320 return _deviationAngle;
321 }
322 bool LocalEdgeCriteria::IsTouchingEdge(MCEdge * __mcEdge)
323 {
324 return _setTouchingEdge.find(__mcEdge) != _setTouchingEdge.end();
325 }
326 bool LocalEdgeCriteria::IsTouchingSegment(MG_SEGMENT * __segment)
327 {
328 if (__segment == NULL)
329 return false;
330
331 std::vector <Intersection_Plane_MG_MAILLAGE::Vertex> & pl = _normalOffset->GetPolyline();
332 unsigned nb_pts = pl.size();
333
334 // Get the mc edge attached to the start segment
335 for (unsigned i = 0; i < nb_pts; i++)
336 {
337 MG_SEGMENT * seg = pl[i].E;
338
339 if (seg == __segment)
340 return true;
341 }
342
343 return false;
344 }
345 bool LocalEdgeCriteria::IsStartSegment(MG_SEGMENT * __segment)
346 {
347 if (__segment == NULL)
348 return false;
349
350 std::vector <Intersection_Plane_MG_MAILLAGE::Vertex> & pl = _normalOffset->GetPolyline();
351 unsigned int o = _normalOffset->GetOriginIndex();
352
353 return (pl[o].E == __segment);
354 }
355
356 MCEdge * LocalEdgeCriteria::GetTouchingEdge(int __index)
357 {
358 if (__index >= 0 && __index < 2)
359 return _oppositeEdges[__index];
360 else
361 {
362 printf("Error GetTouchingEdge: __index = %d\n", __index);
363 return NULL;
364 }
365 }
366
367 double LocalEdgeCriteria::GetLengthToTouchingEdge(int __index)
368 {
369 if (__index >= 0 && __index < 2)
370 return _lengthToOppositeEdges[__index];
371 else
372 {
373 printf("Error GetLengthToTouchingEdge: __index = %d\n", __index);
374 return -1;
375 }
376 }
377 MCEdge * LocalEdgeCriteria::GetClosestTouchingEdge()
378 {
379 return (_lengthToOppositeEdges[0] < _lengthToOppositeEdges[1])
380 ? _oppositeEdges[0]
381 : _oppositeEdges[1];
382 }
383 double * LocalEdgeCriteria::GetClosestTouchingEdgePoint()
384 {
385 int i = (_lengthToOppositeEdges[0] < _lengthToOppositeEdges[1])
386 ? 0
387 : 1;
388 return _normalOffset->GetPolyline()[ _oppositeEdgesPolylineIndices [i] ].X;
389 }
390
391 double * LocalEdgeCriteria::GetTouchingEdgePoint(int __index)
392 {
393 if (__index >= 0 && __index < 2)
394 return _normalOffset->GetPolyline()[ _oppositeEdgesPolylineIndices [__index] ].X;
395 else
396 {
397 printf("Error GetLengthToTouchingEdge: __index = %d\n", __index);
398 return 0;
399 }
400 }
401 void LocalEdgeCriteria::CheckMCTess()
402 {
403 std::vector <Intersection_Plane_MG_MAILLAGE::Vertex> & pl = _normalOffset->GetPolyline();
404 int nb_pts = pl.size();
405 int o = _normalOffset->GetOriginIndex();
406
407 for (int j = 0; j < 2; j++)
408 {
409 for (int i = 0; i+1 < nb_pts; i++)
410 {
411 int k[2];
412 if (j == 0)
413 {
414 k[0] = o - i;
415 k[1] = o - i - 1;
416 if (k[1] < 0 || k[1] >= nb_pts)
417 break;
418 }
419 else if (j == 1)
420 {
421 k[0] = o + i;
422 k[1] = o + i + 1;
423 if (k[1] < 0 || k[1] >= nb_pts)
424 break;
425 }
426
427 MG_SEGMENT * Seg [2];
428 MG_NOEUD * No [2];
429 OT_VECTEUR_3D xyz[2];
430 double dl;
431
432 for (unsigned l = 0; l < 2; l++)
433 {
434 xyz[l] = pl[k[l]].X;
435 Seg[l] = pl[k[l]].E;
436 No[l] = pl[k[l]].V;
437 }
438
439 MG_ELEMENT_TOPOLOGIQUE * topo;
440 topo = Seg[1]->get_lien_topologie();
441
442 if ( ! _mcaa->GetMCTess()->contient(Seg[1]))
443 printf("The MC Tessellation does not contains a segment crossed by LEC's polyline !\n");
444 _mcaa->CheckIfTopoExists(topo);
445 if (topo->get_dimension() < 2)
446 break;
447 }
448 }
449 }
450
451
452
453 double LocalEdgeCriteria::GetMeshSize()
454 {
455 return _meshSize;
456 }
457
458 void LocalEdgeCriteria::InitSetOfTouchingEdges()
459 {
460 std::vector <Intersection_Plane_MG_MAILLAGE::Vertex> & pl = _normalOffset->GetPolyline();
461 unsigned nb_pts = pl.size();
462
463 _setTouchingEdge.clear();
464 for (unsigned i = 0; i < nb_pts; i++)
465 {
466 MG_SEGMENT * seg = pl[i].E;
467 MG_ELEMENT_TOPOLOGIQUE * topo = seg->get_lien_topologie();
468 if (topo && topo->get_dimension() == 1)
469 _setTouchingEdge.insert((MCEdge*)topo);
470 }
471 }