MAGiC  V5.0
Mailleurs Automatiques de Géometries intégrés à la Cao
CAD4FE_LocalEdgeCriteria.cpp
Aller à la documentation de ce fichier.
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"
37 #include "CAD4FE_Criteria.h"
38 #include "CAD4FE_ColorMap.h"
39 
40 #pragma hdrstop
41 
43 
44 
45 #pragma package(smart_init)
46 
47 using namespace CAD4FE;
48 
49 
51 : _seg(__seg), _mcaa(__mcaa), _mesh(__mesh), _startSeg(__startSeg), _normalOffset(NULL)
52 {
53  double x[2][3];
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 
77 {
78  delete _normalOffset;
79 }
80 
81 void
82 LocalEdgeCriteria::Update(bool __reconstructNormalOffset)
83 {
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 
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;
104  if ( topo && topo->get_dimension() == 1)
105  {
106  MCEdge * edge = (MCEdge*) topo;
107  _mcEdge = edge;
108  time = _mcEdge->time;
109  }
110  else
111  {
113  }
114  }
115 
116  for (unsigned i=0; i<2; i++)
117  {
118  _lengthToOppositeEdges[i] = 0;
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;
162  }
163  else
164  {
165  _oppositeEdges[j] = NULL;
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 
186  // Face width
188  // Epsilon (distance between the mesh and the geometry
190  // Angle between the 2 edge segments
191  if ( _segment [0] == _point || _segment [1] == _point )
192  _deviationAngle = 0;
193  else
195 }
196 
198 {
199  double criterionFaceWidth;
200  double limitFaceWidth = _meshSize / _mcaa->GetMaxOverdensity();
201 
202  if ( _oppositeEdges[0] || _oppositeEdges[1] )
203  {
204  if (_faceWidth < limitFaceWidth)
205  criterionFaceWidth = 1 - _faceWidth / limitFaceWidth;
206  else
207  criterionFaceWidth = .05 * (1 - _faceWidth / limitFaceWidth);
208  }
209  else
210  criterionFaceWidth = -.05;
211 
212  return criterionFaceWidth;
213 }
214 
216 {
217  double criterionAngle;
218  double limitAngle = _mcaa->GetLimitAngle();
219 
220  if (_deviationAngle < limitAngle)
221  criterionAngle = 1 - _deviationAngle / limitAngle;
222  else
223  criterionAngle = .2*(1 - _deviationAngle / limitAngle);
224 
225  return criterionAngle;
226 }
227 
229 {
230  int i, NB_CRITERIA = 0;
231  double score = 0;
232  double val[10];
233 
234  if (_mcaa->GetMCBody()->G21()->GetArc(_mcEdge->get_id())->Rank() != 2)
235  return 0;
236 
237  if (_mcEdge && _mcEdge->get_nb_ccf())
238  return 0;
239 
240  val[NB_CRITERIA++] = DeletionScore_FaceWidth();
241  val[NB_CRITERIA++] = DeletionScore_DeviationAngle();
242  // val[NB_CRITERIA++] = DeletionScore_OppositeEdge();
243 
244  for (i=0;i<NB_CRITERIA;i++)
245  {
246  if (score < val[i])
247  {
248  score = val[i];
249  }
250  }
251 
252  return score;
253 }
254 
255 void LocalEdgeCriteria::GetPolylineVertex(int i, float * __vec3f) const
256 {
257  const double * vec3d = _normalOffset->GetPolyline()[i].X;
258  for (int i=0; i<3; i++)
259  __vec3f[i] = vec3d[i];
260 }
261 
263 {
264  return _normalOffset->GetPolyline().size();
265 }
266 
267 std::string
269 {
270  std::ostringstream out;
271 
272  unsigned char rgb[3];
273  ColorMap::jetColorMap(rgb, 1-DeletionScore(), 0, 1);
274  _normalOffset->SetColor(rgb);
275  out << _normalOffset->InventorText();
276 
277  for (unsigned j=0; j<2; j++)
278  if (_oppositeEdgesPolylineIndices[j] != -1) {
280  std::vector <Intersection_Plane_MG_MAILLAGE::Vertex> & pl = _normalOffset->GetPolyline();
281  out << "\nSeparator { #sep1 \n";
282  out << "\n Coordinate3 {\n point [ \n";
283  out << pl[i].X[0] << " " <<pl[i].X[1] << " " << pl[i].X[2] << " \n";
284  out << "\n]\n}\n";
285  out << "PolygonOffset { \n";
286  out << "styles POINTS \n";
287  out << "factor 4.0 \n";
288  out << "units 1.0 \n";
289  out << "} \n";
290  out << "DrawStyle {\npointSize 4\n}\n";
291  out << "BaseColor { \n rgb 1.0 0.0 0.0\n }\n";
292  out << "PointSet {\nstartIndex "<<0<<"\nnumPoints "<<1<<"\n}\n";
293  out << "} # end Sep1 \n";
294  }
295 
296  return out.str();
297 }
298 
300 {
301  return _mcEdge;
302 }
303 
305 {
306  return _seg;
307 }
308 
310 {
311  return _faceWidth;
312 }
313 
315 {
316  return _epsilon;
317 }
318 
320 {
321  return _deviationAngle;
322 }
324 {
325  return _setTouchingEdge.find(__mcEdge) != _setTouchingEdge.end();
326 }
328 {
329  if (__segment == NULL)
330  return false;
331 
332  std::vector <Intersection_Plane_MG_MAILLAGE::Vertex> & pl = _normalOffset->GetPolyline();
333  unsigned nb_pts = pl.size();
334 
335  // Get the mc edge attached to the start segment
336  for (unsigned i = 0; i < nb_pts; i++)
337  {
338  MG_SEGMENT * seg = pl[i].E;
339 
340  if (seg == __segment)
341  return true;
342  }
343 
344  return false;
345 }
347 {
348  if (__segment == NULL)
349  return false;
350 
351  std::vector <Intersection_Plane_MG_MAILLAGE::Vertex> & pl = _normalOffset->GetPolyline();
352  unsigned int o = _normalOffset->GetOriginIndex();
353 
354  return (pl[o].E == __segment);
355 }
356 
358 {
359  if (__index >= 0 && __index < 2)
360  return _oppositeEdges[__index];
361  else
362  {
363  printf("Error GetTouchingEdge: __index = %d\n", __index);
364  return NULL;
365  }
366 }
367 
369 {
370  if (__index >= 0 && __index < 2)
371  return _lengthToOppositeEdges[__index];
372  else
373  {
374  printf("Error GetLengthToTouchingEdge: __index = %d\n", __index);
375  return -1;
376  }
377 }
379 {
381  ? _oppositeEdges[0]
382  : _oppositeEdges[1];
383 }
385 {
387  ? 0
388  : 1;
390 }
391 
393 {
394  if (__index >= 0 && __index < 2)
396  else
397  {
398  printf("Error GetLengthToTouchingEdge: __index = %d\n", __index);
399  return 0;
400  }
401 }
403 {
404  std::vector <Intersection_Plane_MG_MAILLAGE::Vertex> & pl = _normalOffset->GetPolyline();
405  int nb_pts = pl.size();
406  int o = _normalOffset->GetOriginIndex();
407 
408  for (int j = 0; j < 2; j++)
409  {
410  for (int i = 0; i+1 < nb_pts; i++)
411  {
412  int k[2];
413  if (j == 0)
414  {
415  k[0] = o - i;
416  k[1] = o - i - 1;
417  if (k[1] < 0 || k[1] >= nb_pts)
418  break;
419  }
420  else if (j == 1)
421  {
422  k[0] = o + i;
423  k[1] = o + i + 1;
424  if (k[1] < 0 || k[1] >= nb_pts)
425  break;
426  }
427 
428  MG_SEGMENT * Seg [2];
429  MG_NOEUD * No [2];
430  OT_VECTEUR_3D xyz[2];
431  double dl;
432 
433  for (unsigned l = 0; l < 2; l++)
434  {
435  xyz[l] = pl[k[l]].X;
436  Seg[l] = pl[k[l]].E;
437  No[l] = pl[k[l]].V;
438  }
439 
440  MG_ELEMENT_TOPOLOGIQUE * topo;
441  topo = Seg[1]->get_lien_topologie();
442 
443  if ( ! _mcaa->GetMCTess()->contient(Seg[1]))
444  printf("The MC Tessellation does not contains a segment crossed by LEC's polyline !\n");
445  _mcaa->CheckIfTopoExists(topo);
446  if (topo->get_dimension() < 2)
447  break;
448  }
449  }
450 }
451 
452 
453 
455 {
456  return _meshSize;
457 }
458 
460 {
461  std::vector <Intersection_Plane_MG_MAILLAGE::Vertex> & pl = _normalOffset->GetPolyline();
462  unsigned nb_pts = pl.size();
463 
464  _setTouchingEdge.clear();
465  for (unsigned i = 0; i < nb_pts; i++)
466  {
467  MG_SEGMENT * seg = pl[i].E;
469  if (topo && topo->get_dimension() == 1)
470  _setTouchingEdge.insert((MCEdge*)topo);
471  }
472 }
static void jetColorMap(unsigned char *rgb, double value, double min, double max)
void Update(bool __reconstructNormalOffset=true)
std::set< MCEdge * > _setTouchingEdge
void GetPolylineVertex(int i, float *__vec3f) const
bool IsTouchingEdge(MCEdge *__mcEdge)
LocalEdgeCriteria(MG_SEGMENT *, MCAA *__mcaa, MG_MAILLAGE *__mesh, MG_SEGMENT *__startSeg)
bool IsStartSegment(MG_SEGMENT *__segment)
bool IsTouchingSegment(MG_SEGMENT *__segment)
double * GetTouchingEdgePoint(int __index)
Intersection_Plane_MG_MAILLAGE * _normalOffset
MCBody * GetMCBody() const
double GetMaxOverdensity()
double GetSize(double xyz[3])
MG_MAILLAGE * GetMCTess() const
double GetLimitAngle()
bool CheckIfTopoExists(MG_ELEMENT_TOPOLOGIQUE *topo)
Graph::Graph * G21() const
MG_ELEMENT_TOPOLOGIQUE * get_lien_topologie(void)
virtual int get_dimension(void)=0
unsigned long get_id()
bool contient(MG_IDENTIFICATEUR *id)
virtual MG_NOEUD * get_noeud1(void)
Definition: mg_segment.cpp:108
virtual MG_NOEUD * get_noeud2(void)
Definition: mg_segment.cpp:113
static void MG_NOEUD_GET_XYZ(MG_NOEUD *node, double *xyz)
static double Angle3D_Segment_Segment(double __v0[3], double __v1[3], double __v2[3])
static double Dist3D_Point_Segment(double a[3], double b[3], double c[3])