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