Salome HOME
d5a2addebf5fbce7d8d422a52256c507f95542e7
[modules/hexablock.git] / src / HEXABLOCK / HexEdge.cxx
1
2 // C++ : Gestion des aretes
3
4 // Copyright (C) 2009-2023  CEA, EDF
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 #include "HexEdge.hxx"
23 #include "HexVertex.hxx"
24 #include "HexQuad.hxx"
25
26 #include "HexPropagation.hxx"
27 #include "HexXmlWriter.hxx"
28 #include "HexNewShape.hxx"
29 #include "HexAssoEdge.hxx"
30 #include "HexVertexShape.hxx"
31
32 static int niveau = 0;
33
34 BEGIN_NAMESPACE_HEXA
35
36 static bool db = on_debug();
37
38 void geom_dump_asso (Edge* edge);
39
40 // ======================================================== Constructeur
41 Edge::Edge (Vertex* va, Vertex* vb)
42     : EltBase (va->dad(), EL_EDGE)
43 {
44    e_vertex [V_AMONT] = va;
45    e_vertex [V_AVAL ] = vb;
46
47    e_propag = NOTHING;
48    e_way    = true;
49    e_law    = NULL;
50    e_clone  = NULL;
51
52    if (isBad())
53       return;
54    else if (BadElement (va) || BadElement (vb))
55       {
56       setError ();
57       return;
58       }
59    else if (va == vb)
60       {
61       setError ();
62       return;
63       }
64
65    if (el_root != NULL)
66        el_root->addEdge (this);
67    majReferences ();
68 }
69 // ======================================================== Constructeur 2
70 Edge::Edge (Edge* other)
71     : EltBase (other->dad(), EL_EDGE)
72 {
73    e_vertex [V_AMONT] = e_vertex [V_AVAL ] = NULL;
74    if (BadElement (other))
75       setError ();
76
77    e_propag = NOTHING;
78    e_way    = true;
79    e_law    = NULL;
80    e_clone  = NULL;
81
82    if (el_root != NULL)
83        el_root->addEdge (this);
84 }
85 // ======================================================== majReferences
86 void Edge::majReferences ()
87 {
88    e_vertex [V_AMONT]->addParent (this);
89    e_vertex [V_AVAL ]->addParent (this);
90 }
91 // ======================================================== anaMerge
92 int Edge::anaMerge (Vertex* orig, Vertex* tv1[])
93 {
94    tv1 [0] = orig;
95
96    if (orig == e_vertex [V_AMONT])
97       tv1 [1] = e_vertex[V_AVAL];
98    else if (orig == e_vertex [V_AVAL])
99       tv1 [1] = e_vertex[V_AMONT];
100    else
101       return HERR;
102
103    return HOK;
104 }
105 // ========================================================= propager
106 void Edge::propager (Propagation* prop, int groupe, int sens)
107 {
108    setPropag (groupe, sens>0);
109    prop->addEdge (this);
110
111    niveau ++;
112    int nbquads = getNbrParents ();
113    for (int nq=0 ; nq<nbquads ; nq++)
114        {
115        Quad* quad = getParent (nq);
116        if (quad!=NULL && quad->hasParents())
117           {
118           if (debug (6))
119              {
120              printf ("Prop : niv=%d edge=", niveau);
121              printName ();
122              printf ("parent=%d quad=", nq);
123              quad->printName ("\n");
124              fflush(stdout);
125              }
126
127           int meme = 1;
128           Edge* arete = quad->getOpposEdge (this, meme);
129           if (arete != NULL && arete->getPropag () < 0)
130               arete->propager (prop, groupe, meme*sens);
131           }
132        }
133    niveau --;
134 }
135 // ========================================================= setPropag
136 void Edge::setPropag  (int nro, bool sens)
137 {
138    e_propag = nro;
139    e_way    = sens; 
140    if (NOT db || nro<0) 
141       return;
142
143    int prems  = sens ? 0 : 1;
144    Vertex* v1 = getVertex (  prems);
145    Vertex* v2 = getVertex (1-prems);
146
147    std::cout << " setPropag " << el_name
148              << " = "   << nro 
149              <<  " = (" << v1->getName() << ", "    << v2->getName()
150              << ") = (" << v2->getX() - v1->getX() 
151              << ", "    << v2->getY() - v1->getY() 
152              << ", "    << v2->getZ() - v1->getZ() 
153              << ")"     << std::endl;
154 }
155 // ========================================================= getParent
156 Quad* Edge::getParent  (int nro)
157 {
158    return static_cast <Quad*> (getFather (nro));
159 }
160 // ========================================================= saveXml
161 void Edge::saveXml (XmlWriter* xml)
162 {
163    char buffer[12];
164    std::string vertices = e_vertex [V_AMONT]->getName(buffer);
165    vertices += " ";
166    vertices       += e_vertex [V_AVAL ]->getName(buffer);
167
168    xml->openMark     ("Edge");
169    xml->addAttribute ("id",       getName (buffer));
170    xml->addAttribute ("vertices", vertices);
171    if (el_name!=buffer)
172        xml->addAttribute ("name", el_name);
173    xml->closeMark ();
174
175    int nbass = tab_assoc.size();
176    for (int nro=0 ; nro<nbass ; nro++)
177        if (tab_assoc[nro] != NULL)
178            tab_assoc[nro]->saveXml (xml);
179 }
180 // ======================================================== replaceVertex
181 void Edge::replaceVertex (Vertex* old, Vertex* par)
182 {
183    for (int nro=0 ; nro<QUAD4 ; nro++)
184        {
185        if (e_vertex[nro]==old)
186            {
187            e_vertex[nro] = par;
188            if (debug())
189               {
190               printf (" Dans ");
191               printName ();
192               printf (" [%d], ", nro);
193               old->printName (" est remplace par ");
194               par->printName ("\n");
195               }
196            }
197        }
198 }
199 // ======================================================== dump
200 void Edge::dump ()
201 {
202    printName(" = (");
203    if (NOT isHere ())
204       {
205       printf ("*** deleted ***)\n");
206       return;
207       }
208
209    e_vertex[V_AMONT]->printName(", ");
210    e_vertex[V_AVAL] ->printName(")");
211    if (e_propag>=0)
212       {
213       char signe = e_way ? '+' : '-';
214       printf (", Prop= %c%d", signe, e_propag);
215       }
216
217    dumpRef ();
218 }
219 // ======================================================== dumpAsso
220 void Edge::dumpAsso ()
221 {
222    if (NOT isHere ())
223       {
224       printName(" = *** deleted **\n");
225       return;
226       }
227
228    geom_dump_asso (this);
229 }
230 // ======================================================== dumpPlus
231 void Edge::dumpPlus ()
232 {
233    dump ();
234    for (int nro=0 ; nro < V_TWO ; nro++)
235        {
236        Vertex* pv = e_vertex[nro];
237        printf ( "    ");
238        if (pv!=NULL)
239           {
240           pv->printName ();
241           printf (" (%g, %g, %g)\n", pv->getX(),  pv->getY(),  pv->getZ());
242           }
243        else
244           {
245           printf (" NULL\n");
246           }
247        }
248 }
249 // ======================================================== makeDefinition
250 std::string Edge::makeDefinition ()
251 {
252    std::string definition = el_name;
253
254    definition += " = (";
255    definition += e_vertex [V_AMONT]->getName();
256    definition += ",";
257    definition += e_vertex [V_AVAL]->getName();
258    definition += ")";
259
260    return definition;
261 }
262 // ===================================================== addAssociation
263 int Edge::addAssociation (EdgeShape* gline, double deb, double fin)
264 {
265    if (gline == NULL)
266       return HERR;
267
268    gline->addAssociation (this);
269    AssoEdge*  asso  = new AssoEdge (gline, deb, fin);
270    tab_assoc.push_back (asso);
271
272    if (db)
273       {
274         std::cout << " Edge " << el_name
275                   << " = (" << e_vertex[V_AMONT]->getName()
276                   << " , "  << e_vertex[V_AVAL ]->getName()
277                   << ") addAssociation " << gline->getName ()
278                   << " (" << deb << ", " << fin << ")"
279                   << std::endl;
280       PutCoord (asso->getOrigin ());
281       PutCoord (asso->getExtrem ());
282       }
283    is_associated = true;
284    return HOK;
285 }
286 // ========================================================== addAssociation
287 int Edge::addAssociation (NewShape* geom, int subid, double deb, double fin)
288 {
289    if (geom == NULL)
290       {
291       if (el_root->debug ())
292         std::cout << "  Edge " << el_name << " addAssociation of NULL ignored"
293                   << std::endl;
294       return HERR;
295       }
296
297    EdgeShape* gline = geom->findEdge (subid);
298    int ier = addAssociation (gline, deb, fin);
299    return ier;
300 }
301 // ================================================== clearAssociation
302 void Edge::clearAssociation ()
303 {
304    int nombre = tab_assoc.size ();
305    for (int nro=0 ; nro<nombre ; nro++)
306        {
307        delete tab_assoc [nro];
308        }
309
310    tab_assoc .clear ();
311    is_associated = false;
312 }
313 // ================================================== getAssociation
314 AssoEdge* Edge::getAssociation (int nro)
315 {
316    if (nro<0 || nro >= (int)tab_assoc.size())
317       return NULL;
318
319    return tab_assoc [nro];
320 }
321 // =============================================================== getVertex
322 Vertex* Edge::getVertex(int nro)
323 {
324    Vertex* elt = NULL;
325    if (nro >=0 && nro < V_TWO  && el_status == HOK
326                && e_vertex [nro]->isValid())
327       elt = e_vertex [nro];
328
329    return elt;
330 }
331 // =============================================================== index
332 int Edge::index (Vertex* node)
333 {
334    return  node == NULL ? NOTHING
335          : node == e_vertex[V_AMONT] ? V_AMONT
336          : node == e_vertex[V_AVAL ] ? V_AVAL : NOTHING;
337 }
338 // ============================================================= opposedVertex
339 Vertex* Edge::opposedVertex (Vertex* sommet)
340 {
341    int nro = index (sommet);
342    return nro<0 ? NULL : e_vertex[1-nro];
343 }
344 // ============================================================= commonVertex
345 Vertex* Edge::commonVertex (Edge* other)
346 {
347    int nro = inter (other);
348    return nro<0 ? NULL : e_vertex[nro];
349 }
350 // ============================================================= commonPoint
351 double* Edge::commonPoint (Edge* other, double point[])
352 {
353    Vertex* commun = commonVertex (other);
354    if (commun==NULL)
355       {
356       point[dir_x] = point[dir_y] = point[dir_z] =  0;
357       return NULL;
358       }
359
360    commun->getPoint (point);
361    return point;
362 }
363 // =============================================================== inter
364 int Edge::inter (Edge* other)
365 {
366    int nro;
367    return inter (other, nro);
368 }
369 // =============================================================== inter
370 int Edge::inter (Edge* other, int& nother)
371 {
372    for (int ni=0 ; ni<V_TWO ; ni++)
373         for (int nj=0 ; nj<V_TWO ; nj++)
374             if (e_vertex[ni] == other->e_vertex[nj])
375                {
376                nother =  nj;
377                return ni;
378                }
379
380    nother = NOTHING;
381    return   NOTHING;
382 }
383 // =============================================================== definedBy
384 bool Edge::definedBy  (Vertex* v1, Vertex* v2)
385 {
386    bool   rep =    (v1 == e_vertex[V_AMONT] && v2 == e_vertex[V_AVAL ])
387                 || (v1 == e_vertex[V_AVAL ] && v2 == e_vertex[V_AMONT]);
388    return rep;
389 }
390 // =============================================================== setColor
391 void Edge::setColor  (double val)
392 {
393    e_vertex [V_AMONT]->setColor (val);
394    e_vertex [V_AVAL ]->setColor (val);
395 }
396 // =============================================================== duplicate
397 void Edge::duplicate  ()
398 {
399    e_clone = new Edge (GetClone (e_vertex [V_AMONT]),
400                        GetClone (e_vertex [V_AVAL ]));
401
402    // e_clone->tab_shapes = tab_shapes;
403    e_clone->tab_assoc  = tab_assoc;
404 }
405 // =============================================================== getVector
406 double* Edge::getVector (double vecteur[])
407 {
408
409    if (e_vertex[V_AMONT]==NULL ||  e_vertex[V_AVAL]==NULL)
410       {
411       vecteur [dir_x] = vecteur [dir_y] = vecteur [dir_z] = 0;
412       return NULL;
413       }
414
415    vecteur[dir_x] = e_vertex[V_AVAL]->getX() - e_vertex[V_AMONT]->getX();
416    vecteur[dir_y] = e_vertex[V_AVAL]->getY() - e_vertex[V_AMONT]->getY();
417    vecteur[dir_z] = e_vertex[V_AVAL]->getZ() - e_vertex[V_AMONT]->getZ();
418
419    return vecteur;
420 }
421 // ========================================================== checkAssociation
422 int Edge::checkAssociation ()
423 {
424    int nombre = tab_assoc.size();
425    if (nombre==0)
426       return HOK;
427
428    Real3 ver_assoc [V_TWO];
429    int arc [V_TWO], sens [V_TWO];
430    for (int nro=0 ; nro<V_TWO ; ++nro)
431        {
432        arc [nro] = sens [nro] = NOTHING;
433        e_vertex[nro]->getAssoCoord (ver_assoc[nro]);
434        }
435
436    int ier    = HOK;
437    for (int nass=0 ; nass<nombre ; ++nass)
438        {
439        AssoEdge*  asso = tab_assoc[nass];
440        for (int nro = V_AMONT ; nro<=V_AVAL ; ++nro)
441            {
442            int rep = asso->onExtremity (ver_assoc[nro]);
443            if (rep != NOTHING)
444               {
445               if (arc[nro] != NOTHING)
446                  {
447                  if (ier==HOK) std::cout << std::endl;
448                  std::cout << " Association Edge "  << el_name
449                            << " : Le vertex " << e_vertex[nro]->getName()
450                            << " : Le vertex " << e_vertex[nro]->getName()
451                            << " Touche les lignes " << arc [nro]
452                            << " et " << nass << std::endl;
453                  ier   = 112;
454                  }
455               arc  [nro] = nass;
456               sens [nro] = rep;
457               }
458           }
459        }
460
461    for (int nro=0 ; nro<V_TWO ; ++nro)
462        {
463        if (arc [nro] == NOTHING)
464           {
465           if (ier==HOK) std::cout << std::endl;
466           std::cout << " Association Edge " << el_name
467                     << " : Le vertex nro " << nro
468                     << " = " << e_vertex[nro]->getName()
469                     << " est isole" << std::endl;
470           PutCoord (ver_assoc[nro]);
471           ier = 111;
472           }
473        }
474    if (ier==HOK)
475        return ier;
476
477    std::cout << " ** Controle associations (" << nombre << ") edge " << el_name
478              << " = (" << e_vertex[V_AMONT]->getName()
479              << " , "  << e_vertex[V_AVAL ]->getName()
480              << ")" << std::endl;
481
482    for (int nv=0 ; nv<2 ; ++nv)
483        {
484        Vertex* node = e_vertex[nv];
485        std::cout << node->getName()         << " = (" << node->getX()
486                  << ", "   << node->getY() << ", "   << node->getZ()
487                  << ") -> "<< ver_assoc [nv][0] << ", " << ver_assoc [nv][1]
488                  << ", "   << ver_assoc [nv][2] << ")"  << std::endl;
489        }
490
491    for (int nass=0 ; nass<nombre ; ++nass)
492        {
493        AssoEdge*  asso = tab_assoc[nass];
494        std::cout << " " << nass << " :";
495        asso->dump ();
496        }
497
498    return ier;
499 }
500 // ========================================================== getAssoLen
501 double Edge::getAssoLen ()
502 {
503    int    nombre = tab_assoc.size();
504    double longueur = 0;
505    if (nombre==0)
506       {
507       Real3 p1, p2;
508       e_vertex [V_AMONT]-> getAssoCoord (p1);
509       e_vertex [V_AVAL ]-> getAssoCoord (p2);
510       longueur = calc_distance (p1, p2);
511       }
512    else
513       {
514       for (int nass=0 ; nass<nombre ; ++nass)
515           longueur += tab_assoc[nass]->length ();
516       }
517
518    return longueur;
519 }
520 // ========================================================= getLength
521 double Edge::getLength ()
522 {
523    Real3 p1, p2;
524    e_vertex [V_AMONT]-> getAssoCoord (p1);
525    e_vertex [V_AVAL ]-> getAssoCoord (p2);
526    double longueur = calc_distance (p1, p2);
527    return longueur;
528 }
529 // ========================================================= findAssociation
530 int Edge::findAssociation (NewShape* geom)
531 {
532    Real3 point, p2;
533    if (geom==NULL)
534       return NOTHING;
535
536    e_vertex [V_AMONT]-> getAssoCoord (point);
537    e_vertex [V_AVAL ]-> getAssoCoord (p2);
538
539    EdgeShape*  gline = geom->findEdge (point, p2);
540    if (gline==NULL)
541       { 
542       std::cout << " *** FindAssociation "  << el_name << std::endl;
543       for (int nv=0 ; nv < V_TWO ; ++nv)
544           {
545           e_vertex [nv]-> getAssoCoord (point);
546           VertexShape* shape = geom->findVertex (point);
547           std::cout << " *** Vertex nro "  << nv;
548           if (shape==NULL)
549              {
550              std::cout << " absent : ";
551              PutCoord (point);
552              }
553           else
554              {
555                std::cout << " : Subid = " << shape->getIdent() << std::endl;
556              }
557           }
558       return NOTHING;
559       }
560    
561    clearAssociation ();
562    addAssociation   (gline, 0, 1); 
563    return gline->getIdent();
564 }
565 // ========================================================= setAssociation
566 int Edge::setAssociation (NewShape* geom, int subid)
567 {
568    if (geom == NULL)
569       {
570       if (el_root->debug ())
571         std::cout << "  Edge " << el_name << " addAssociation of NULL ignored"
572                   << std::endl;
573       return HERR;
574       }
575
576    EdgeShape* gline = geom->findEdge (subid);
577    if (gline == NULL)
578       {
579       if (el_root->debug ())
580         std::cout << "  Edge " << el_name << " addAssociation bad subid : "
581                   << subid << std::endl;
582       return HERR;
583       }
584
585    Real3 p1, p2, pa, pb;
586    gline->getCoords (p1, p2);
587    e_vertex [V_AMONT]-> getAssoCoord (pa);
588    e_vertex [V_AVAL ]-> getAssoCoord (pb);
589
590    double da1 = calc_d2 (pa, p1);
591    double da2 = calc_d2 (pa, p2);
592    double db1 = calc_d2 (pb, p1);
593    double db2 = calc_d2 (pb, p2);
594    
595    std::cout << "setAssociation " << el_name << " :" <<std::endl;
596
597    if (da2 < da1 && db1 < db2) 
598       {
599       e_vertex [V_AMONT]->setAssociation (p2);
600       e_vertex [V_AVAL ]->setAssociation (p1);
601       }
602    else
603       {
604       e_vertex [V_AMONT]->setAssociation (p1);
605       e_vertex [V_AVAL ]->setAssociation (p2);
606       }
607
608    
609    clearAssociation ();
610    int ier = addAssociation   (gline, 0, 1); 
611    return ier;
612 }
613 END_NAMESPACE_HEXA