Salome HOME
Mise a jour source recette Hexablock 6
[modules/hexablock.git] / src / HEXABLOCK / HexQuad.cxx
1
2 // C++ : Gestion des Quadrangles
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/ or email : webmaster.salome@opencascade.com
21 //
22 #include "HexQuad.hxx"
23
24 #include "HexDocument.hxx"
25 #include "HexHexa.hxx"
26 #include "HexElements.hxx"
27 #include "HexGlobale.hxx"
28
29 #include "HexXmlWriter.hxx"
30 #include "HexNewShape.hxx"
31 #include "HexFaceShape.hxx"
32
33 BEGIN_NAMESPACE_HEXA
34
35 bool db = false;
36
37 // ======================================================== Constructeur
38 Quad::Quad (Vertex* va, Vertex* vb, Vertex* vc, Vertex* vd)
39     : EltBase (va->dad(), EL_QUAD)
40 {
41    q_vertex [E_A] = va;
42    q_vertex [E_B] = vb;
43    q_vertex [E_C] = vc;
44    q_vertex [E_D] = vd;
45    q_clone        = NULL;
46    q_orientation  = Q_UNDEFINED;
47
48    for (int nro=0 ; nro<QUAD4 ; nro++)
49        {
50        q_edge [nro] = new Edge (q_vertex[nro],
51                                 q_vertex[(nro+1) MODULO QUAD4]);
52
53        if (BadElement (q_vertex [nro]) || BadElement (q_edge [nro]))
54           setError ();
55        else
56           for (int nv=nro+1 ; nv<QUAD4 ; nv++)
57               if (q_vertex[nv] == q_vertex[nro])
58                  setError ();
59        }
60
61    if (el_root != NULL && el_status==HOK)
62        el_root->addQuad (this);
63    majReferences ();
64 }
65 // ======================================================== Constructeur bis
66 Quad::Quad (Edge* ea, Edge* eb, Edge* ec, Edge* ed)
67     : EltBase (ea->dad(), EL_QUAD)
68 {
69    q_edge [E_A] = ea;
70    q_edge [E_B] = eb;
71    q_edge [E_C] = ec;
72    q_edge [E_D] = ed;
73    q_clone       = NULL;
74    q_orientation = Q_UNDEFINED;
75
76    for (int nro=0 ; nro<QUAD4 ; nro++)
77        {
78        int prec = (nro+1) MODULO QUAD4;
79        Vertex* node = NULL;
80
81        if (BadElement (q_edge[nro]))
82           setError ();
83        else
84           {
85           for (int nv=nro+1 ; nv<QUAD4 ; nv++)
86               if (q_edge[nv] == q_edge[nro])
87                   setError ();
88           int nc  = q_edge[nro] -> inter (q_edge[prec]);
89           if (nc>=0)
90              node = q_edge[nro]->getVertex (nc);
91           else
92              setError (888);
93           }
94        q_vertex [prec] = node;
95        }
96
97    if (isBad())
98       {
99       printf (" +++++++++++++++++++++++++++++++++++++++++++ \n");
100       printf (" +++ Quadrangle impossible \n");
101       printf (" +++++++++++++++++++++++++++++++++++++++++++ \n");
102       dump ();
103       printf (" +++++++++++++++++++++++++++++++++++++++++++ \n");
104       // el_root->dump ();
105       for (int ned=0; ned<QUAD4; ned++)
106           {
107           q_edge[ned]->dumpPlus ();
108           }
109       HexDump (q_vertex[0]);
110       HexDump (q_vertex[1]);
111       HexDump (q_vertex[2]);
112       HexDump (q_vertex[3]);
113
114       printf (" +++++++++++++++++++++++++++++++++++++++++++ \n");
115       fatal_error ("Quadrangle impossible");
116       }
117
118    if (el_root != NULL && el_status==HOK)
119        el_root->addQuad (this);
120    majReferences ();
121 }
122 // ======================================================== Constructeur ter
123 Quad::Quad (Quad* other)
124     : EltBase (other->dad(), EL_QUAD)
125 {
126    for (int nro=0 ; nro<QUAD4 ; nro++)
127        {
128        q_edge   [nro] = NULL;
129        q_vertex [nro] = NULL;
130        }
131    q_orientation = Q_UNDEFINED;
132    q_clone       = NULL;
133
134    if (el_root != NULL && el_status==HOK)
135        el_root->addQuad (this);
136 }
137 // ============================================================  getEdge
138 Edge* Quad::getEdge (int nro)
139 {
140    Edge* elt = NULL;
141    if (nro >=0 && nro < QUAD4 && el_status == HOK && q_edge [nro]->isValid())
142       elt = q_edge [nro];
143
144    DumpStart  ("getEdge", nro);
145    DumpReturn (elt);
146    return elt;
147 }
148 // ============================================================  getVertex
149 Vertex* Quad::getVertex (int nro)
150 {
151    Vertex* elt = NULL;
152    if (nro >=0 && nro < QUAD4 && el_status == HOK && q_vertex [nro]->isValid())
153       elt = q_vertex [nro];
154
155    DumpStart  ("getVertex", nro);
156    DumpReturn (elt);
157    return elt;
158 }
159 // ========================================================= majReferences
160 void Quad::majReferences ()
161 {
162    for (int nro=0 ; nro<QUAD4 ; nro++)
163        q_edge [nro] -> addParent (this);
164 }
165 // ========================================================= getParent
166 Hexa* Quad::getParent  (int nro)
167 {
168    return static_cast <Hexa*> (getFather (nro));
169 }
170 // ======================================================== anaMerge
171 int Quad::anaMerge (Vertex* v1, Vertex* v2, Vertex* tv1[], Edge* te1[])
172 {
173    int orig = NOTHING;
174    for (int nro=0 ; orig == NOTHING && nro < QUAD4 ; nro++)
175        if (q_vertex [nro] == v1)
176            orig = nro;
177
178    if (orig==NOTHING)
179       return HERR;
180
181    int nsp1 = (orig+1)       MODULO QUAD4;
182    int nsm1 = (orig+QUAD4-1) MODULO QUAD4;
183
184    if (q_vertex [nsp1] == v2)
185       {
186       for (int nro=0 ; nro < QUAD4 ; nro++)
187           {
188           tv1 [nro] = q_vertex [(orig+nro) MODULO QUAD4];
189           te1 [nro] = q_edge   [(orig+nro) MODULO QUAD4];
190           }
191       }
192    else if (q_vertex [nsm1] == v2)
193       {
194       for (int nro=0 ; nro < QUAD4 ; nro++)
195           {
196           tv1 [nro] = q_vertex [(orig+QUAD4-nro) MODULO QUAD4];
197           te1 [nro] = q_edge   [(orig+QUAD4-nro) MODULO QUAD4];
198           }
199       }
200    else
201       return 588;
202
203    return HOK;
204 }
205 // ======================================================== ordoVertex
206 int Quad::ordoVertex (Vertex* v1, Vertex* v2, Vertex* tver[])
207 {
208    int orig = NOTHING;
209    for (int nro=0 ; orig == NOTHING && nro < QUAD4 ; nro++)
210        if (q_vertex [nro] == v1)
211            orig = nro;
212
213    if (orig==NOTHING)
214       return HERR;
215
216    int nsp1 = (orig+1)       MODULO QUAD4;
217    int nsm1 = (orig+QUAD4-1) MODULO QUAD4;
218
219    if (q_vertex [nsp1] == v2)
220       {
221       for (int nro=0 ; nro < QUAD4 ; nro++)
222           tver [nro] = q_vertex [(orig+nro) MODULO QUAD4];
223       }
224    else if (q_vertex [nsm1] == v2)
225       {
226       for (int nro=0 ; nro < QUAD4 ; nro++)
227           tver [nro] = q_vertex [(orig+QUAD4-nro) MODULO QUAD4];
228       }
229    else
230       return 588;
231
232    return HOK;
233 }
234 // ======================================================== ordonner
235 int Quad::ordonner (Vertex* v1, Vertex* v2, Vertex* tver[], Edge* ted[])
236 {
237    tver [0] = tver [1] = tver [2] = tver [3] = NULL;
238    ted  [0] = ted  [1] = ted  [2] = ted  [3] = NULL;
239
240    int ier = ordoVertex (v1, v2, tver);
241    if (ier != HOK)
242        return ier;
243
244    for (int nro=0 ; nro < QUAD4 ; nro++)
245        ted [nro] = findEdge (tver[nro], tver [(nro+1) MODULO QUAD4]);
246
247    return HOK;
248 }
249 // ======================================================== getBrother
250 Quad* Quad::getBrother (StrOrient* orient)
251 {
252 /* *****************************
253    printf (" getBrother ");
254    dump ();
255    printf (" .. Base  : ");
256    orient->v21->printName();
257    orient->v22->printName();
258    printf ("dir=%d, arete=", orient->dir);
259   ***************************** */
260
261    int n21 = indexVertex (orient->v21);
262    int n22 = indexVertex (orient->v22);
263
264    int sens  = n22 - n21;
265    if (sens >  1) sens -= QUAD4;
266    if (sens < -1) sens += QUAD4;
267    if (sens*sens !=1) return NULL;
268
269    switch (orient->dir)
270       {
271       case OR_LEFT  : n22 = n21 - sens;
272            break;
273       case OR_RIGHT : n21 = n22 + sens;
274            break;
275       case OR_FRONT : n21 += 2;
276                       n22 += 2;
277            break;
278       default : ;
279       }
280
281    n21 = (n21 + QUAD4) MODULO QUAD4;
282    n22 = (n22 + QUAD4) MODULO QUAD4;
283
284    orient->v21 = q_vertex [n21];
285    orient->v22 = q_vertex [n22];
286
287    Edge* arete  = findEdge (orient->v21, orient->v22);
288    // arete->printName("\n");
289
290    int nbfreres = arete->getNbrParents ();
291
292    for (int nq = 0 ; nq < nbfreres ; nq++)
293        {
294        Quad* next = arete->getParent (nq);
295        if (next!=NULL && next != this )
296           {
297           int   nbp   = next->getNbrParents();
298           Hexa* dad   = next->getParent(0);
299           int   mark  = next->getMark();
300           int   mark2 = dad ? dad->getMark() : IS_NONE;
301
302           if (nbp  <= 1  && mark2 != IS_MARRIED && mark == IS_NONE)
303              return next;
304           // if (nbp  <= 1  && mark == IS_NONE)
305              // return next;
306           }
307        }
308    return NULL;
309 }
310 // ======================================================== coupler
311 int Quad::coupler (Quad* other, StrOrient* orient, Elements* table)
312 {
313    if (other==NULL)
314       return HERR;
315
316    Hexa* hexa = other->getParent(0);
317
318    setMark (IS_MARRIED);
319    other->setMark (IS_MARRIED);
320    if (hexa != NULL)
321        hexa->setMark (IS_MARRIED);
322
323    for (int ned = 0 ; ned < QUAD4 ; ned++)
324        {
325        Edge* arete  = q_edge[ned];
326        int nbfreres = arete ->getNbrParents ();
327        for (int nq = 0 ; nq < nbfreres ; nq++)
328            {
329            Quad* next = arete->getParent (nq);
330            if (next!=NULL && next != this && next->getMark() > 0)
331               {
332               StrOrient new_ori (orient);
333               new_ori.dir = OR_FRONT;
334               Vertex* va  = arete->getVertex (V_AMONT);
335               Vertex* vb  = arete->getVertex (V_AVAL);
336
337 //    On voit si un point de repere est conserve
338               if (va == orient->v11)
339                  {
340                  new_ori.v12 = vb;
341                  new_ori.dir += OR_LEFT;
342                  }
343               else if (vb == orient->v11)
344                  {
345                  new_ori.v12 = va;
346                  new_ori.dir += OR_LEFT;
347                  }
348
349               if (va == orient->v12)
350                  {
351                  new_ori.v11 = vb;
352                  new_ori.dir += OR_RIGHT;
353                  }
354               else if (vb == orient->v12)
355                  {
356                  new_ori.v11 = va;
357                  new_ori.dir += OR_RIGHT;
358                  }
359
360               if (new_ori.dir == OR_FRONT)
361                  {
362                  if (definedBy (va, orient->v11))
363                     {
364                     new_ori.v11 = va;
365                     new_ori.v12 = vb;
366                     }
367                  else
368                     {
369                     new_ori.v11 = vb;
370                     new_ori.v12 = va;
371                     }
372                  }
373
374               int nro = next->getMark ();
375               Quad* beauf = other->getBrother (&new_ori);
376               int ier = table->coupler (nro, beauf, &new_ori);
377               if (ier != HOK)
378                  return ier;
379               ier = next->coupler (beauf, &new_ori, table);
380               if (ier != HOK)
381                  return ier;
382               }
383            }
384        }
385    return HOK;
386 }
387 // ======================================================== getOpposVertex
388 Vertex* Quad::getOpposVertex (Vertex* start)
389 {
390    int  na = indexVertex (start);
391    if (na==NOTHING)
392       return NULL;
393    return  q_vertex [(na+2) MODULO QUAD4];
394 }
395 // ======================================================== getOpposEdge
396 Edge* Quad::getOpposEdge (Edge* start, int& sens)
397 {
398    sens = 1;
399    int  na = indexVertex (start->getVertex (V_AMONT));
400    int  nb = indexVertex (start->getVertex (V_AVAL));
401
402    Vertex* vaprim = q_vertex [(nb+2) MODULO QUAD4];
403    Vertex* vbprim = q_vertex [(na+2) MODULO QUAD4];
404
405    for (int ned = 0 ; ned < QUAD4 ; ned++)
406        {
407        if (   q_edge[ned]->getVertex(V_AMONT) == vaprim
408            && q_edge[ned]->getVertex(V_AVAL ) == vbprim)
409            {
410            sens = 1;
411            return q_edge[ned];
412            }
413        else if (   q_edge[ned]->getVertex(V_AMONT) == vbprim
414                 && q_edge[ned]->getVertex(V_AVAL ) == vaprim)
415            {
416            sens = -1;
417            return q_edge[ned];
418            }
419        }
420    //             TODO : traiter l'erreur
421    cout << " ... Probleme dans Quad::getOpposedEdge :" << endl;
422    HexDisplay (el_name);
423    PutName (start);
424    PutName (vaprim);
425    PutName (vbprim);
426    HexDisplay (na);
427    HexDisplay (nb);
428    dumpPlus ();
429
430    for (int ned = 0 ; ned < QUAD4 ; ned++)
431        q_edge[ned]->dump();
432
433    return NULL;
434 }
435 // ========================================================= saveXml
436 void Quad::saveXml (XmlWriter* xml)
437 {
438    char buffer[12];
439    string edges;
440
441    for (int nro=0 ; nro<QUAD4 ; nro++)
442        {
443        if (nro>0) edges += " ";
444        edges += q_edge[nro]->getName(buffer);
445        }
446
447    xml->openMark     ("Quad");
448    xml->addAttribute ("id",    getName (buffer));
449    xml->addAttribute ("edges", edges);
450    if (el_name!=buffer)
451        xml->addAttribute ("name", el_name);
452    xml->closeMark ();
453
454    int nbass = tab_assoc.size();
455    for (int nro=0 ; nro<nbass ; nro++)
456        if (tab_assoc[nro] != NULL)
457            tab_assoc[nro]->saveXml (xml);
458 }
459 // ======================================================== replaceEdge
460 void Quad::replaceEdge (Edge* old, Edge* par)
461 {
462    for (int nro=0 ; nro<QUAD4 ; nro++)
463        {
464        if (q_edge[nro]==old)
465            {
466            q_edge[nro] = par;
467            if (debug())
468               {
469               printf (" Dans ");
470               printName ();
471               printf (" [%d], ", nro);
472               old->printName (" est remplace par ");
473               par->printName ("\n");
474               }
475            }
476        }
477 }
478 // ======================================================== replaceVertex
479 void Quad::replaceVertex (Vertex* old, Vertex* par)
480 {
481    for (int nro=0 ; nro<QUAD4 ; nro++)
482        {
483        if (q_vertex [nro]==old)
484           {
485           q_vertex [nro] = par;
486            if (debug())
487               {
488               printf (" Dans ");
489               printName ();
490               printf (" [%d], ", nro);
491               old->printName (" est remplace par ");
492               par->printName ("\n");
493               }
494           }
495        }
496 }
497 // ======================================================== dump
498 void Quad::dump ()
499 {
500    printName(" = (");
501    if (NOT isHere ())
502       {
503       printf ("*** deleted ***)\n");
504       return;
505       }
506
507    for (int nro=0 ; nro<QUAD4 ; nro++)
508         PrintName (q_edge[nro]);
509    printf (")\n");
510
511    printf ("        (");
512    for (int nro=0 ; nro<QUAD4 ; nro++)
513         PrintName (q_vertex[nro]);
514    printf (")");
515
516    dumpRef ();
517 }
518 // ======================================================== dumpPlus
519 void Quad::dumpPlus ()
520 {
521    dump ();
522    if (NOT isHere ())
523       return;
524
525    for (int nro=0 ; nro < QUAD4 ; nro++)
526        {
527        Vertex* pv = q_vertex[nro];
528        printf ( "    ");
529        if (pv!=NULL)
530           {
531           pv->printName ("");
532           printf ( " (%g, %g, %g)\n", pv->getX(),  pv->getY(),  pv->getZ());
533           }
534        else
535           {
536           printf ( "NULL\n");
537           }
538        }
539 }
540 // ======================================================== getOpposEdge (2)
541 Edge* Quad::getOpposEdge (Edge* start)
542 {
543    int  na = indexEdge (start);
544    if (na<0)
545       return NULL;
546    return q_edge [(na+2) MODULO QUAD4];
547 }
548 // ======================================================== getPerpendicular
549 Edge* Quad::getPerpendicular (Edge* arete, Vertex* node)
550 {
551    int na = indexEdge (arete);
552    if (na<0)
553       return NULL;
554
555    int nv = arete->index (node);
556    if (nv<0)
557       return NULL;
558    Edge* perp = q_edge [(na+1) MODULO QUAD4];
559
560    nv = perp->index (node);
561    if (nv>=0)
562       return perp;
563
564    perp = q_edge [(na+3) MODULO QUAD4];
565    nv   = perp->index (node);
566    if (nv>=0)
567       return perp;
568    else
569       return NULL;
570 }
571 static cpchar t_ori[] = {"Q_INSIDE", "Q_DIRECT", "Q_INVERSE", "Q_UNDEF"};
572 // ======================================================== setOrientation
573 void Quad::setOrientation (int ori)
574 {
575     q_orientation = ori;
576     if (db && (ori==Q_DIRECT || ori==Q_INVERSE))
577        printf (" %s = %s\n", el_name.c_str(), t_ori [ q_orientation ]);
578 }
579 // ======================================================== setOrientation
580 int Quad::setOrientation ()
581 {
582     q_orientation = Q_INSIDE;
583     if (getNbrParents() != 1)
584        return q_orientation;
585
586     Real3 cg, orig, pi, pj, vi, vj, vk;
587
588     Hexa* hexa = getParent(0);
589     hexa->getCenter (cg);
590
591 /********************************************************************
592     printName (" = ");
593
594     for (int np=0 ; np < QUAD4 ; np++)
595         {
596         q_vertex [np        ] -> getPoint (orig);
597         q_vertex [(np+1) % 4] -> getPoint (pi);
598         q_vertex [(np+3) % 4] -> getPoint (pj);
599
600         calc_vecteur (orig, pi, vi);
601         calc_vecteur (orig, pj, vj);
602         calc_vecteur (orig, cg, vk);
603         double pmixte = prod_mixte (vi, vj, vk);
604         q_orientation = pmixte > ZEROR ? Q_DIRECT : Q_INVERSE;
605         if (pmixte>0) printf (">");
606            else       printf ("<");
607         }
608
609     printf ("\n");
610     return;
611   ******************************************************************* */
612     q_vertex [0] -> getPoint (orig);
613     q_vertex [1] -> getPoint (pi);
614     q_vertex [3] -> getPoint (pj);
615
616     calc_vecteur (orig, pi, vi);
617     calc_vecteur (orig, pj, vj);
618     calc_vecteur (cg, orig, vk);
619
620     double pmixte = prod_mixte (vi, vj, vk);
621     q_orientation = pmixte > ZEROR ? Q_DIRECT : Q_INVERSE;
622     if (db)
623        printf (" %s := %s\n", el_name.c_str(), t_ori [ q_orientation ]);
624     return q_orientation;
625 }
626 // ========================================================== clearAssociation
627 void Quad::clearAssociation ()
628 {
629    tab_assoc.clear ();
630    is_associated = false;
631 }
632 // ========================================================== addAssociation
633 int Quad::addAssociation (NewShape* geom, int subid)
634 {
635    if (geom == NULL)
636       return HERR;
637
638    FaceShape* face = geom->findFace (subid);
639    int ier = addAssociation (face);
640
641    return ier;
642 }
643 // ========================================================== addAssociation
644 int Quad::addAssociation (FaceShape* face)
645 {
646    if (face == NULL)
647       return HERR;
648
649    face->addAssociation (this);
650    tab_assoc.push_back (face);
651    is_associated = true;
652    return HOK;
653 }
654 // ========================================================== getAssociation
655 FaceShape* Quad::getAssociation (int nro)
656 {
657    if (nro < 0 || nro >= (int)tab_assoc.size())
658       return NULL;
659
660    return tab_assoc [nro];
661 }
662 // ======================================================== commonEdge
663 Edge* Quad::commonEdge (Quad* other)
664 {
665    for (int ne1=0 ; ne1<QUAD4 ; ne1++)
666        for (int ne2=0 ; ne2<QUAD4 ; ne2++)
667            if (q_edge [ne1] == other->q_edge [ne2])
668               return q_edge [ne1];
669
670    return NULL;
671 }
672 // ======================================================== Inter
673 int Quad::inter (Quad* other, int& nother)
674 {
675    for (int ne1=0 ; ne1<QUAD4 ; ne1++)
676        for (int ne2=0 ; ne2<QUAD4 ; ne2++)
677            if (q_edge [ne1] == other->q_edge [ne2])
678               {
679               nother = ne2;
680               return  ne1;
681               }
682
683    nother = NOTHING;
684    return NOTHING;
685 }
686 // ======================================================== Inter (2)
687 Edge* Quad::inter (Quad* other)
688 {
689    for (int ne1=0 ; ne1<QUAD4 ; ne1++)
690        for (int ne2=0 ; ne2<QUAD4 ; ne2++)
691            if (q_edge [ne1] == other->q_edge [ne2])
692               return  q_edge [ne1];
693    return NULL;
694 }
695 // ============================================================ definedBy (v)
696 bool Quad::definedBy  (Vertex* v1, Vertex* v2)
697 {
698    for (int n1=0 ; n1< QUAD4 ; n1++)
699        if (v1 == q_vertex[n1] && v2 == q_vertex[(n1+2) MODULO QUAD4])
700           return true;
701
702    return false;
703 }
704 // ============================================================ definedBy (e)
705 bool Quad::definedBy  (Edge* e1, Edge* e2)
706 {
707    if (e1==e2 || BadElement (e1) || BadElement (e2))
708       return false;
709
710    bool f1=false, f2=false;
711    for (int ned=0 ; ned< QUAD4 ; ned++)
712        if      (e1 == q_edge[ned]) f1 = true;
713        else if (e2 == q_edge[ned]) f2 = true;
714     // if (e1 == q_edge[ned] && e2 == q_edge[(ned+2) MODULO QUAD4]) return true;
715
716    return f1 && f2;
717 }
718 // =============================================================== findEdge
719 Edge* Quad::findEdge (Vertex* v1, Vertex* v2)
720 {
721    for (int nro=0 ; nro< QUAD4 ; nro++)
722        {
723        Vertex* va = q_edge[nro]->getVertex(V_AMONT) ;
724        Vertex* vb = q_edge[nro]->getVertex(V_AVAL) ;
725        if ((v1==va && v2==vb) || (v1==vb && v2==va))
726            return q_edge [nro];
727        }
728
729    return NULL;
730 }
731 // =============================================================== indexVertex
732 int Quad::indexVertex  (Vertex* elt)
733 {
734    for (int n1=0 ; n1< QUAD4 ; n1++)
735        if (elt == q_vertex[n1])
736           return n1;
737
738    return NOTHING;
739 }
740 // =============================================================== indexEdge
741 int Quad::indexEdge  (Edge* elt)
742 {
743    for (int n1=0 ; n1< QUAD4 ; n1++)
744        if (elt == q_edge[n1])
745           return n1;
746
747    return NOTHING;
748 }
749 // =============================================================== setColor
750 void Quad::setColor  (double val)
751 {
752    for (int n1=0 ; n1< QUAD4 ; n1++)
753        q_vertex[n1] -> setColor (val);
754 }
755 // =============================================================== duplicate
756 void Quad::duplicate  ()
757 {
758    q_orientation  = Q_UNDEFINED;
759    q_clone = new Quad (GetClone (q_edge [E_A]),
760                        GetClone (q_edge [E_B]),
761                        GetClone (q_edge [E_C]),
762                        GetClone (q_edge [E_D]));
763    q_clone->tab_assoc  = tab_assoc;
764 }
765 // ============================================================ nearestVertex
766 Vertex* Quad::nearestVertex (Vertex* other)
767 {
768    if (BadElement (other))
769       return NULL;
770  
771    Vertex* vsol = NULL;
772    double  dmin = 1e+77;
773    int nbre = countVertex ();
774    for (int nro=0 ; nro<nbre ; nro++)
775        {
776        Vertex* vert = getVertex (nro);
777        double  dist = other->dist2 (vert);
778        if (dist < dmin)
779           {
780           dmin = dist;
781           vsol = vert; 
782           }
783        }
784    return vsol;
785 }
786 // =============================================================== reorienter
787 void Quad::reorienter  ()
788 {
789    if (q_orientation != Q_INVERSE)
790          return;
791
792    Edge* edge   = q_edge [E_B];
793    q_edge [E_B] = q_edge [E_D];
794    q_edge [E_B] = edge;
795
796    q_vertex [E_A] = q_edge [E_D]->commonVertex(q_edge [E_A]);
797    q_vertex [E_B] = q_edge [E_A]->commonVertex(q_edge [E_B]);
798    q_vertex [E_C] = q_edge [E_B]->commonVertex(q_edge [E_C]);
799    q_vertex [E_D] = q_edge [E_C]->commonVertex(q_edge [E_D]);
800
801    if (db)
802        printf (" %s est reoriente\n", el_name.c_str());
803    q_orientation = Q_DIRECT;
804 }
805 // =============================================================== getCenter
806 double* Quad::getCenter (double* center)
807 {
808    center[dir_x] = center[dir_y] = center[dir_z] =  0;
809    if (BadElement (this))
810       return NULL;
811
812    for (int nv=0 ; nv<QUAD4 ; nv++)
813        {
814        if (BadElement (q_vertex [nv]))
815            return NULL;
816        center [dir_x] += q_vertex[nv]->getX();
817        center [dir_y] += q_vertex[nv]->getY();
818        center [dir_z] += q_vertex[nv]->getZ();
819        }
820     return center;
821 }
822 // =============================================================== getCenter
823 double Quad::dist2 (double* point)
824 {
825    Real3 center;
826    getCenter (center);
827    double d2 = carre (point[dir_x] - center[dir_x]) 
828              + carre (point[dir_y] - center[dir_y]) 
829              + carre (point[dir_z] - center[dir_z]) ;
830    return d2;
831 }
832 END_NAMESPACE_HEXA