Salome HOME
Updated copyright comment
[modules/hexablock.git] / src / HEXABLOCK / HexDocument.cxx
1
2 // C++ : La clase principale de Hexa
3
4 // Copyright (C) 2009-2024  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
23 #include "HexDocument.hxx"
24
25 #include "HexEltBase.hxx"
26 #include "HexVertex.hxx"
27 #include "HexEdge.hxx"
28 #include "HexQuad.hxx"
29 #include "HexHexa.hxx"
30
31 #include "HexElements.hxx"
32
33 #include "HexVector.hxx"
34 #include "HexMatrix.hxx"
35 #include "HexCloner.hxx"
36 #include "HexPropagation.hxx"
37 #include "HexLaw.hxx"
38
39 #include "HexXmlWriter.hxx"
40 #include "HexXmlTree.hxx"
41 #include "HexGlobale.hxx"
42 #include "HexGroup.hxx"
43 #include "Hex.hxx"
44 #include "HexNewShape.hxx"
45
46 void test_six (Hex::Document* docu, int option);
47
48 BEGIN_NAMESPACE_HEXA
49
50 int Document::doc_number = 0;
51
52 // ======================================================== Constructeur
53 Document::Document (cpchar name, Hex* dad)
54 {
55    el_name    = name;
56    hex_parent = dad;
57    glob       = Globale::getInstance ();
58    el_root    = this;
59
60    doc_db        = 0;
61    nbr_errors    = 0;
62    doc_modified  = true;
63    doc_saved     = false;
64    doc_tolerance = 1e-6;
65    nbr_laws      = 0;
66    nbr_propagations = 0;
67    maj_propagation  = true;
68    doc_xml          = NULL;
69
70    nbr_used_hexas = nbr_used_quads = nbr_used_edges = nbr_used_vertex = 0;
71
72    for (EnumElt type = EL_NONE ; type < EL_MAXI ; type=(EnumElt) (type+1))
73        {
74        doc_first_elt [type] = doc_last_elt [type] = new EltBase ();
75        doc_nbr_elt   [type] = 0;
76        }
77
78    if (doc_number == 0)
79       strcpy (doc_ident, "doc");
80    else
81       sprintf (doc_ident, "doc%02d", doc_number);
82    doc_number++;
83
84    DumpLock;
85    defaultLaw = addLaw ("DefaultLaw", 0);
86    DumpRestore;
87
88    maj_connection = false;
89    purge_elements = false;
90    holes_elements = false;
91    addCloud ();
92 }
93 // ======================================================== Destructeur
94 Document::~Document ()
95 {
96    delete doc_xml;
97
98    for (EnumElt type = EL_NONE ; type < EL_MAXI ; type=(EnumElt) (type+1))
99        {
100        //  printf ("____________________________ Type=%d\n", type);
101        EltBase* next = NULL;
102        for (EltBase* elt=doc_first_elt [type] ; elt != NULL ; elt=next)
103            {
104            next = elt->next();
105            delete elt;
106            }
107        }
108 }
109 // ======================================================== addVector
110 Vector* Document::addVector (double dx, double dy, double dz)
111 {
112    DumpStart ("addVector", dx  << dy  << dz);
113    Vector* pv = new Vector (this, dx, dy, dz);
114    doc_vector.push_back (pv);
115
116    DumpReturn (pv);
117    return  pv;
118 }
119 // ======================================================== addVectorVertices
120 Vector* Document::addVectorVertices (Vertex* va, Vertex* vb)
121 {
122    DumpStart ("addVectorVertices", va  << vb);
123
124    Vector* pv = addVector (vb->getX () - va->getX (),
125                            vb->getY () - va->getY (),
126                            vb->getZ () - va->getZ ());
127
128    DumpReturn (pv);
129    return  pv;
130 }
131 // ======================================================== addVertex
132 Vertex* Document::addVertex (double x, double y, double z)
133 {
134    DumpStart ("addVertex", x  << y  << z);
135
136    Vertex* pv   = new Vertex (this, x, y, z);
137    DumpReturn (pv);
138    return pv;
139 }
140 // ======================================================== addEdge
141 Edge* Document::addEdge (Vertex* va, Vertex* vb)
142 {
143    DumpStart ("addEdge", va  << vb );
144
145    if (va==NULL || vb==NULL)
146       return NULL;
147
148    Edge* arete  = new Edge (va, vb);
149    DumpReturn (arete);
150    return arete;
151 }
152 // ======================================================== addEdgeVector
153 Edge* Document::addEdgeVector (Vertex* va, Vector* vec)
154 {
155    DumpStart ("addEdgeVector", va  << vec );
156
157    Vertex* vb   = addVertex (va->getX () + vec->getDx(),
158                              va->getY () + vec->getDy(),
159                              va->getZ () + vec->getDz());
160
161    Edge*  arete = addEdge (va, vb);
162    DumpReturn (arete);
163    return arete;
164 }
165 // ======================================================== addQuadVertices
166 Quad* Document::addQuadVertices (Vertex* va, Vertex* vb, Vertex* vc, Vertex* vd)
167 {
168    DumpStart ("addQuadVertices", va << vb << vc << vd );
169
170    Quad*  face   = new Quad (va, vb, vc, vd);
171    DumpReturn (face);
172    return face;
173 }
174 // ======================================================== addQuad
175 Quad* Document::addQuad (Edge* ea, Edge* eb, Edge* ec, Edge* ed)
176 {
177    DumpStart ("addQuad", ea << eb << ec << ed );
178
179    Quad*  face   = new Quad (ea, eb, ec, ed);
180    DumpReturn (face);
181    return face;
182 }
183 // ======================================================== addHexaVertices
184 Hexa* Document::addHexaVertices (Vertex* va, Vertex* vb, Vertex* vc, Vertex* vd,
185                                  Vertex* ve, Vertex* vf, Vertex* vg, Vertex* vh)
186 {
187    DumpStart ("addHexaVertices", va << vb << vc << vd << ve << vf << vg << vh);
188
189    Hexa*  pave   = new Hexa (va, vb, vc, vd, ve, vf, vg, vh);
190    DumpReturn (pave);
191    return pave;
192 }
193 // ======================================================== addHexa
194 Hexa* Document::addHexa (Quad* qa, Quad* qb, Quad* qc, Quad* qd, Quad* qe,
195                          Quad* qf)
196 {
197    DumpStart ("addHexa", qa << qb << qc << qd << qe << qf );
198
199    Hexa*  pave   = new Hexa (qa, qb, qc, qd, qe, qf);
200    DumpReturn (pave);
201    return pave;
202 }
203 // ======================================================== findVertex
204 Vertex* Document::findVertex (double vx, double vy, double vz)
205 {
206    DumpStart ("findVertex", vx << vy << vz);
207    Vertex* found = NULL;
208
209    double xmin = vx - doc_tolerance;
210    double xmax = vx + doc_tolerance;
211    double ymin = vy - doc_tolerance;
212    double ymax = vy + doc_tolerance;
213    double zmin = vz - doc_tolerance;
214    double zmax = vz + doc_tolerance;
215  
216    for (EltBase* elt = doc_first_elt[EL_VERTEX]->next (); 
217                  elt!= NULL && found == NULL ;
218                  elt = elt->next())
219        {
220        if (elt->isHere())
221           {
222           Vertex* candidat = static_cast <Vertex*> (elt);
223           if (candidat->isin (xmin, xmax, ymin, ymax, zmin, zmax))
224              found = candidat;
225           }
226        }
227
228    DumpReturn (found);
229    return found;
230 }
231 // ======================================================== findEdge
232 Edge* Document::findEdge (Vertex* v1, Vertex* v2)
233 {
234    DumpStart ("findEdge", v1 << v2);
235    Edge* found = NULL;
236
237    for (EltBase* elt = doc_first_elt[EL_EDGE]->next (); 
238                  elt!= NULL && found == NULL ;
239                  elt = elt->next())
240        {
241        Edge* candidat  = static_cast <Edge*> (elt);
242        if (candidat->definedBy (v1, v2))
243           found = candidat;
244        }
245
246    DumpReturn (found);
247    return found;
248 }
249 // ======================================================== findQuad
250 Quad* Document::findQuad (Vertex* v1, Vertex* v2)
251 {
252    DumpStart ("findQuad", v1 << v2);
253    Quad* found = NULL;
254
255    for (EltBase* elt = doc_first_elt[EL_QUAD]->next (); 
256                  elt!= NULL && found == NULL ;
257                  elt = elt->next())
258        {
259        Quad* candidat  = static_cast <Quad*> (elt);
260        if (candidat->definedBy (v1, v2))
261           found = candidat;
262        }
263
264    DumpReturn (found);
265    return found;
266 }
267 // ======================================================== findQuad
268 Quad* Document::findQuad (Edge* e1, Edge* e2)
269 {
270    DumpStart ("findQuad", e1 << e2);
271    Quad* found = NULL;
272
273    for (EltBase* elt = doc_first_elt[EL_QUAD]->next (); 
274                  elt!= NULL && found == NULL ;
275                  elt = elt->next())
276        {
277        Quad* candidat  = static_cast <Quad*> (elt);
278        if (candidat->definedBy (e1, e2))
279           found = candidat;
280        }
281
282    DumpReturn (found);
283    return found;
284 }
285 // ======================================================== findHexa
286 Hexa* Document::findHexa (Vertex* v1, Vertex* v2)
287 {
288    DumpStart ("findHexa", v1 << v2);
289    Hexa* found = NULL;
290
291    for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); 
292                  elt!= NULL && found == NULL ;
293                  elt = elt->next())
294        {
295        Hexa* candidat  = static_cast <Hexa*> (elt);
296        if (candidat->definedBy (v1, v2))
297           found = candidat;
298        }
299
300    DumpReturn (found);
301    return found;
302 }
303 // ======================================================== findElement
304 EltBase* Document::findElement (EnumElt type, int ident)
305 {
306    for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
307                  elt = elt->next())
308        {
309        if (elt->isHere() && elt->getId()==ident)
310           return elt;
311        }
312    return NULL;
313 }
314 // ======================================================== findVertex
315 Vertex* Document::findVertex (int ident)
316 {
317    Vertex* node = static_cast <Vertex*> (findElement (EL_VERTEX, ident));
318    return  node;
319
320 }
321 // ======================================================== index_tv
322 int index_tv (Vertex* table[], Vertex* elt)
323 {
324    for (int nro=0; nro<QUAD4; nro++)
325         if (elt == table[nro])
326            return nro;
327
328    return NOTHING;
329 }
330 // ======================================================== mergeQuads
331 int Document::mergeQuads (Quad* dest, Quad* orig, Vertex* v1, Vertex* v2,
332                                                 Vertex* v3, Vertex* v4)
333 {
334    DumpStart ("mergeQuads", dest << orig << v1 << v2  << v3 << v4);
335
336    update ();
337
338    if (dest==orig)
339       {
340       printf (" *** Quads identiques dans mergeQuads\n");
341       DumpEnd;
342       return HERR;
343       }
344    else if (dest==NULL || dest->isDeleted())
345       {
346       printf (" *** Quad nro 1 incorrect dans mergeQuads \n");
347       DumpEnd;
348       return HERR;
349       }
350    else if (orig==NULL || orig->isDeleted() )
351       {
352       printf (" *** Quad nro 2 incorrect dans mergeQuads \n");
353       DumpEnd;
354       return HERR;
355       }
356
357    int nbcomm = 0;
358    for (int nro=0 ; nro<QUAD4 ; nro++)
359        {
360        int norig = orig->indexVertex (dest->getVertex(nro));
361        if (norig != NOTHING)
362           {
363           Vertex* uv = dest->getVertex(nro);
364           char nom[12];
365           nbcomm ++;
366           if (nbcomm==1)
367              {
368              printf ("  +++ Sommets communs dans mergeQuads");
369              printf (" (%s,",  dest->getName (nom));
370              printf (" %s)\n", orig->getName (nom));
371              }
372           printf ("  +++ quad1[%d] = quad2[%d] = %s\n", nro,  norig,
373                                                         uv->getName (nom));
374           }
375        }
376
377    if (nbcomm == 2)
378       {
379       printf ("  +++ Les vertex passes en arguments sont ignores\n");
380       int ier = closeQuads (dest, orig);
381       DumpEnd;
382       return ier;
383       }
384    else if (nbcomm != 0)
385       {
386       printf ("  *** _____________________ mergeQuads refuse: \n");
387       printf (" il y a %d sommet(s) sont commun(s)\n", nbcomm);
388       DumpEnd;
389       return HERR;
390       }
391
392    if (   v1 ==NULL || v1 ->isDeleted() || v2 ==NULL || v2 ->isDeleted()
393        || v3 ==NULL || v3 ->isDeleted() || v4 ==NULL || v4 ->isDeleted())
394       {
395       printf ("  *** _____________________ mergeQuads refuse: \n");
396       printf (" un sommet est incorrect\n");
397       DumpEnd;
398       return HERR;
399       }
400
401
402    if (debug())
403       {
404       printf ("  ----------------- mergeQuads : \n");
405       HexDump (orig);
406       HexDump (dest);
407       HexDump (v1);
408       HexDump (v2);
409       HexDump (v3);
410       HexDump (v4);
411       }
412
413    Vertex *tv1 [QUAD4], *tv2 [QUAD4];
414    Edge   *te1 [QUAD4], *te2 [QUAD4];
415
416    int ier1 = dest->ordoVertex (v1, v3, tv1);
417    int ier2 = orig->ordoVertex (v2, v4, tv2);
418    if (ier1 != HOK)
419       {
420       DumpEnd;
421       return ier1;
422       }
423    else if (ier2 != HOK)
424       {
425       DumpEnd;
426       return ier2;
427       }
428
429    for (int nro=0 ; nro<QUAD4 ; nro++)
430        {
431        te1 [nro] = dest->getEdge(nro);
432        Vertex* va1 = te1[nro]->getVertex(V_AMONT);
433        Vertex* vb1 = te1[nro]->getVertex(V_AVAL);
434        int na = index_tv  (tv1, va1);
435        int nb = index_tv  (tv1, vb1);
436        if (na==NOTHING || nb==NOTHING)
437           {
438           DumpEnd;
439           return HERR;
440           }
441
442        te2 [nro] = orig->findEdge (tv2[na], tv2[nb]);
443        if (te2[nro]==NULL)
444           {
445           DumpEnd;
446           return HERR;
447           }
448        }
449
450    if (debug())
451       {
452       printf ("  ----------------- Correspondances mergeQuads : \n");
453       for (int nro=0 ; nro<QUAD4 ; nro++)
454           {
455           printf ("  %d  : ", nro);
456           tv2 [nro]->printName(" -> ");
457           tv1 [nro]->printName("\n");
458           }
459       for (int nro=0 ; nro<QUAD4 ; nro++)
460           {
461           printf ("  %d  : ", nro);
462           te2 [nro]->printName(" (");
463           te2 [nro]->getVertex(0)->printName(", ");
464           te2 [nro]->getVertex(1)->printName(") -> ");
465           te1 [nro]->printName(" (");
466           te1 [nro]->getVertex(0)->printName(", ");
467           te1 [nro]->getVertex(1)->printName(")\n");
468           }
469       }
470
471    replaceQuad (orig, dest);
472    for (int nro=0 ; nro<QUAD4 ; nro++)
473        replaceEdge   (te2[nro], te1[nro]);
474    for (int nro=0 ; nro<QUAD4 ; nro++)
475        replaceVertex (tv2[nro], tv1[nro]);
476
477    maj_connection = false;
478    purge_elements = false;
479
480    DumpEnd;
481    return HOK;
482 }
483 // ======================================================== closeQuads
484 int Document::closeQuads (Quad* dest, Quad* orig)
485 {
486    DumpStart ("closeQuads", dest << orig);
487
488    update ();
489    char nom[12];
490
491    if (dest==orig)
492       {
493       printf (" *** Quads identiques dans closeQuads : %s\n",
494                  dest->getName(nom));
495       DumpEnd;
496       return HERR;
497       }
498    else if (dest==NULL || dest->isDeleted())
499       {
500       printf (" *** Quad nro 1 incorrect dans closeQuads \n");
501       DumpEnd;
502       return HERR;
503       }
504    else if (orig==NULL || orig->isDeleted() )
505       {
506       printf (" *** Quad nro 2 incorrect dans closeQuads \n");
507       DumpEnd;
508       return HERR;
509       }
510
511    Edge* edc = NULL;
512    for (int nro=0 ; nro<QUAD4 ; nro++)
513        {
514        int norig = orig->indexEdge (dest->getEdge(nro));
515        if (norig != NOTHING)
516           {
517           if (edc != NULL)
518              {
519              printf ("  *** Plus d'une arete commune dans closeQuads");
520              printf (" (%s,",  dest->getName (nom));
521              printf (" %s)\n", orig->getName (nom));
522              DumpEnd;
523              return HERR;
524              }
525           edc = dest->getEdge (nro);
526           printf ("  +++ quad1[%d] = quad2[%d] = %s\n", nro,  norig,
527                                                         edc->getName (nom));
528           }
529        }
530
531    Vertex* va = edc->getVertex (V_AMONT);
532    Vertex* vb = edc->getVertex (V_AVAL);
533    Vertex *tv1 [QUAD4], *tv2 [QUAD4];
534    Edge   *te1 [QUAD4], *te2 [QUAD4];
535
536    int ier1 = dest->ordoVertex (va, vb, tv1);
537    int ier2 = orig->ordoVertex (va, vb, tv2);
538
539    if (ier1 != HOK)
540       {
541       DumpEnd;
542       return ier1;
543       }
544    else if (ier2 != HOK)
545       {
546       DumpEnd;
547       return ier2;
548       }
549
550    for (int nro=0 ; nro<QUAD4 ; nro++)
551        {
552        te1 [nro] = dest->getEdge(nro);
553        Vertex* va1 = te1[nro]->getVertex(V_AMONT);
554        Vertex* vb1 = te1[nro]->getVertex(V_AVAL);
555        int na = index_tv  (tv1, va1);
556        int nb = index_tv  (tv1, vb1);
557        if (na==NOTHING || nb==NOTHING)
558           {
559           DumpEnd;
560           return HERR;
561           }
562
563        te2 [nro] = orig->findEdge (tv2[na], tv2[nb]);
564        if (te2[nro]==NULL)
565           {
566           DumpEnd;
567           return HERR;
568           }
569        }
570
571    if (debug())
572       {
573       printf ("  ----------------- Correspondances mergeQuads : \n");
574       for (int nro=0 ; nro<QUAD4 ; nro++)
575           {
576           printf ("  %d  : ", nro);
577           tv2 [nro]->printName(" -> ");
578           tv1 [nro]->printName("\n");
579           }
580       for (int nro=0 ; nro<QUAD4 ; nro++)
581           {
582           printf ("  %d  : ", nro);
583           te2 [nro]->printName(" (");
584           te2 [nro]->getVertex(0)->printName(", ");
585           te2 [nro]->getVertex(1)->printName(") -> ");
586           te1 [nro]->printName(" (");
587           te1 [nro]->getVertex(0)->printName(", ");
588           te1 [nro]->getVertex(1)->printName(")\n");
589           }
590       }
591
592    replaceQuad (orig, dest);
593    for (int nro=0 ; nro<QUAD4 ; nro++)
594        replaceEdge   (te2[nro], te1[nro]);
595    for (int nro=0 ; nro<QUAD4 ; nro++)
596        replaceVertex (tv2[nro], tv1[nro]);
597
598    maj_connection = false;
599    purge_elements = false;
600
601    DumpEnd;
602    return HOK;
603 }
604 // ======================================================== mergeEdges
605 int Document::mergeEdges (Edge* e1, Edge* e2, Vertex* v1, Vertex* v2)
606 {
607    DumpStart ("mergeEdges", e1 << e2 << v1 << v2);
608
609    if (e1==NULL || e1->isDeleted() || e2==NULL || e2->isDeleted())
610       {
611       DumpEnd;
612       return HERR;
613       }
614
615    for (int nro=0 ; nro<V_TWO ; nro++)
616        if (e1->index (e2->getVertex(nro))!= NOTHING)
617           {
618           DumpEnd;
619           return HERR+nro+1;
620           }
621
622    Vertex *tv1 [V_TWO], *tv2 [V_TWO];
623
624    int ier1 = e1->anaMerge (v1, tv1);
625    int ier2 = e2->anaMerge (v2, tv2);
626
627    if (ier1 != HOK)
628       {
629       DumpEnd;
630       return ier1;
631       }
632    else if (ier2 != HOK)
633       {
634       DumpEnd;
635       return ier2;
636       }
637
638    replaceEdge (e2, e1);
639    for (int nro=0 ; nro<V_TWO ; nro++)
640        replaceVertex (tv2[nro], tv1[nro]);
641
642    maj_connection = false;
643    DumpEnd;
644    return HOK;
645 }
646 // ======================================================== mergeVertices
647 int Document::mergeVertices (Vertex* vpar, Vertex* vold)
648 {
649    DumpStart ("mergeVertices", vpar << vold);
650
651    int ier = HOK;
652    if (BadElement (vpar))
653       {
654       Mess << "First vertex is not valid";
655       ier = HERR;
656       }
657    else if (BadElement (vold))
658       {
659       Mess << "Second vertex is not valid";
660       ier = HERR;
661       }
662    else if (vpar==vold)
663       {
664       Mess << "Vertices are identical";
665       ier = HERR;
666       }
667    else if (EltIsValid (findEdge (vpar, vold)))
668       {
669       Mess << "Theese vertices are connected by an edge";
670       ier = HERR;
671       }
672
673    if (ier != HOK)
674       {
675       DumpEnd;
676       return ier;
677       }
678
679    std::map <Quad*,   Quad*>   rep_quad;
680    std::map <Edge*,   Edge*>   rep_edge;
681    std::map <Vertex*, Vertex*> rep_vertex;
682
683    std::map <Quad*,   Quad*>   :: iterator itq;
684    std::map <Edge*,   Edge*>   :: iterator ited;
685    std::map <Vertex*, Vertex*> :: iterator itv;
686    
687    rep_vertex [vold] = vpar;
688    int nbparv  = vold->getNbrParents ();
689
690    for (int ned=0 ; ned<nbparv ; ++ned)
691        {
692        Edge* edold = vold->getParent (ned);
693        if (edold->isHere())
694           {
695           Vertex* vopp  = edold->opposedVertex (vold);
696           Edge*   edpar = findEdge (vpar, vopp);
697           if (edpar != NULL)
698              rep_edge [edold] = edpar;
699           }
700        }
701
702    Quad *qold=NULL,  *qpar=NULL;
703
704    for (ited=rep_edge.begin(); ited!=rep_edge.end() ; ++ited)
705        {
706        Edge* edold = ited->first;
707        Edge* edpar = ited->second;
708        int nbpared = edold->getNbrParents ();
709        for (int nq=0 ; nq<nbpared ; ++nq)
710            {
711            qold = edold->getParent (nq);
712            if (qold->isHere())
713               {
714               for (int ned=0 ; ned<QUAD4 ; ned++)
715                   {
716                   // Edge* edge = quad->getEdge(ned);
717                   Edge* edge = qold->getEdge (ned);
718                   if (edge != edold)
719                      {
720                      qpar = findQuad (edpar, edge);
721                      if (qpar != NULL)
722                         rep_quad [qold] = qpar;
723                      }
724                   }
725               }
726            }
727        }
728
729    std::cout << " +++ Intersection : veq = "   << rep_vertex.size() 
730              << " " << rep_edge.size() <<  " " << rep_quad.size()
731              << std::endl;
732
733    for (itq=rep_quad.begin(); itq!=rep_quad.end() ; ++itq)
734       {
735       qold = itq->first;
736       qpar = itq->second;
737       Vertex *tv1[QUAD4], *tv2[QUAD4];
738       Edge   *te1[QUAD4], *te2[QUAD4];
739       Edge*  einter = qpar->inter (qold);
740       if (einter!=NULL)
741          {
742          Vertex* va = einter->getVertex (V_AMONT);
743          Vertex* vb = einter->getVertex (V_AVAL);
744          qpar->ordonner (va, vb, tv1, te1); 
745          qold->ordonner (va, vb, tv2, te2); 
746          for (int nro=0 ; nro<QUAD4 ; nro++)
747              {
748              rep_edge   [te2[nro]] =  te1[nro];
749              rep_vertex [tv2[nro]] =  tv1[nro];
750              }
751          }
752       replaceQuad (qold, qpar);
753       }
754
755    for (ited=rep_edge.begin(); ited!=rep_edge.end() ; ++ited)
756         replaceEdge (ited->first, ited->second);
757        
758    for (itv=rep_vertex.begin(); itv!=rep_vertex.end() ; ++itv)
759         replaceVertex (itv->first, itv->second);
760        
761    maj_connection = false;
762    DumpEnd;
763    return HOK;
764 }
765 // ======================================================== replaceVertex
766 void Document::replaceVertex (Vertex* old, Vertex* par)
767 {
768    if (BadElement(old) || BadElement(par) ||  old==par)
769       return ;
770
771    // par->replaceAssociation (old);   TODO
772
773    for (int type=EL_EDGE ; type <= EL_HEXA ; type++)
774        {
775        for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
776                      elt = elt->next())
777            if (elt->isHere ())
778                elt->replaceVertex (old, par);
779        }
780    old->suppress ();
781 }
782 // ======================================================== replaceEdge
783 void Document::replaceEdge (Edge* old, Edge* par)
784 {
785    if (BadElement(old) || BadElement(par) ||  old==par)
786       return;
787
788    // par->replaceAssociation (old);   TODO
789
790    for (int type=EL_QUAD ; type <= EL_HEXA ; type++)
791        {
792        for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
793                      elt = elt->next())
794            if (elt->isHere ())
795                elt->replaceEdge (old, par);
796        }
797
798    old->suppress ();
799 }
800 // ======================================================== replaceQuad
801 int Document::replaceQuad (Quad* old, Quad* par)
802 {
803    if (BadElement(old) || BadElement(par) ||  old==par)
804       return HERR;
805
806    // par->replaceAssociation (old);   TODO
807
808    for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); elt!=NULL;
809                  elt = elt->next())
810        if (elt->isHere ())
811           {
812           Hexa* cell = static_cast <Hexa*> (elt);
813           cell->replaceQuad (old, par);
814           }
815    old->suppress ();
816    return HOK;
817 }
818 // ========================================================== countElement
819 int Document::countElement (EnumElt type)
820 {
821    int compteur = 0;
822    for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
823                  elt = elt->next())
824        if (elt->isHere())
825           compteur ++;
826
827    return compteur;
828 }
829 // ========================================================== getElement
830 EltBase* Document::getElement (EnumElt type, int nro)
831 {
832    int compteur = 0;
833    for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
834                  elt = elt->next())
835        {
836        if (elt->isHere())
837           {
838           if (compteur>=nro)
839              return elt;
840           compteur ++;
841           }
842        }
843    return NULL;
844 }
845 // ========================================================= addLaw
846 Law* Document::addLaw (const char* name, int nbnodes)
847 {
848    DumpStart ("addLaw", name << nbnodes);
849    Law* loi = new Law (this, name, nbnodes);
850    addLaw (loi);
851    DumpReturn (loi);
852    return loi;
853 }
854 // ========================================================= addLaw
855 Law* Document::addLaw (Law* loi)
856 {
857    doc_laws.push_back (loi);
858    nbr_laws ++;
859    return loi;
860 }
861 // ========================================================= getLaw
862 Law* Document::getLaw (int nro)
863 {
864    DumpStart ("getLaw", nro);
865    Law* loi = NULL;
866
867    if (nro >= 0 && nro < nbr_laws)
868        loi =  doc_laws [nro];
869
870    DumpReturn (loi);
871    return loi;
872 }
873 // ========================================================= findLaw
874 Law* Document::findLaw (const char* name)
875 {
876    DumpStart ("findLaw", name);
877
878    std::string nom = name;
879    Law*   loi = NULL;
880
881    for (int nro=0 ;loi==NULL &&  nro<nbr_laws; nro++)
882        if (doc_laws [nro]->getName() == nom)
883           loi = doc_laws [nro];
884
885    DumpReturn (loi);
886    return loi;
887 }
888 // ========================================================= removeLaw
889 int Document::removeLaw (Law* loi)
890 {
891    DumpStart ("removeLaw", loi);
892
893    for (int nro=1 ; nro<nbr_laws; nro++)
894        if (doc_laws [nro] == loi)
895           {
896           //All propagations having this law should now have the default law.
897           for (int nl=0 ; nl<nbr_propagations ; nl++)
898               {
899               if ( doc_propagation [nl]->getLaw() == loi )
900                    doc_propagation [nl]->setLaw(defaultLaw);
901               }
902
903           // delete doc_laws [nro];
904           doc_laws [nro]->suppress ();
905           doc_laws.erase (doc_laws.begin()+nro);
906           nbr_laws = doc_laws.size();
907
908           DumpReturn (HOK);
909           return HOK;
910           }
911
912    DumpReturn (HERR);
913    return HERR;
914 }
915 // ========================================================= majPropagation
916 void Document::majPropagation ()
917 {
918    DumpLock;
919    majReferences ();
920    update ();
921    // if (purge_elements)
922        // purge ();
923
924    for (int nro=0 ; nro<nbr_propagations ; nro++)
925        {
926        // delete doc_propagation [nro];
927        // doc_propagation [nro]->suppress();
928        ;
929        }
930
931    doc_propagation.clear ();
932    nbr_propagations = 0;
933    maj_propagation  = false;
934
935    for (EltBase* elt = doc_first_elt[EL_EDGE]->next (); elt!=NULL;
936                  elt = elt->next())
937        {
938        Edge* arete = static_cast <Edge*> (elt);
939        if (arete!=NULL)
940            arete->setPropag (NOTHING, true);
941        }
942
943    //  markAll (NO_COUNTED, EL_EDGE);
944
945    for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); elt!=NULL;
946                  elt = elt->next())
947        {
948        Hexa* cell = static_cast <Hexa*> (elt);
949        if (cell!=NULL && cell->isHere())
950           {
951           for (int ne=0 ; ne<HE_MAXI ; ne++)
952               {
953               Edge* arete = cell->getEdge(ne);
954               if (arete->getPropag()<0)
955                  {
956                  Propagation* prop = new Propagation (this);
957                  doc_propagation.push_back (prop);
958                  arete->propager (prop, nbr_propagations);
959                  nbr_propagations ++;
960                  prop->majLaw();
961                  }
962               }
963           }
964        }
965    maj_propagation  = false;
966    DumpRestore;
967 }
968 // ======================================================== countPropagation
969 int Document::countPropagation ()
970 {
971    if (maj_propagation)
972        majPropagation ();
973
974    return nbr_propagations;
975 }
976 // ======================================================== getPropagation
977 Propagation* Document::getPropagation (int nro)
978 {
979    DumpStart ("getPropagation", nro);
980
981    if (maj_propagation)
982        majPropagation ();
983
984    Propagation* prop = NULL;
985    if (nro >= 0 && nro < nbr_propagations)
986        prop = doc_propagation [nro];
987
988    DumpReturn (prop);
989    return prop;
990 }
991 // ======================================================== findPropagation
992 Propagation* Document::findPropagation (Edge* arete)
993 {
994    DumpStart ("findPropagation", arete);
995
996    Propagation* prop = NULL;
997    if (arete!=NULL)
998       {
999       if (maj_propagation)
1000           majPropagation ();
1001       prop = getPropagation (arete->getPropag ());
1002       }
1003
1004    DumpReturn (prop);
1005    return  prop;
1006 }
1007 // ======================================================== disconnectQuad
1008 Elements* Document::disconnectQuad (Hexa* cell, Quad* element)
1009 {
1010    DumpStart ("disconnectQuad", cell << element);
1011
1012    Elements* grid = new Elements (this);
1013    grid->checkDisco (cell, element);
1014
1015    if (grid->isValid())
1016       {
1017       update ();
1018       cell->disconnectQuad (element, grid);
1019       majReferences ();
1020       }
1021
1022    DumpReturn (grid);
1023    return grid;
1024 }
1025 // ======================================================== disconnectEdge
1026 Elements* Document::disconnectEdge (Hexa* cell, Edge* element)
1027 {
1028    DumpStart ("disconnectEdge", cell << element);
1029
1030    Elements* grid = new Elements (this);
1031    grid->checkDisco (cell, element);
1032
1033    if (grid->isValid())
1034       {
1035       update ();
1036       cell->disconnectEdge (element, grid);
1037       majReferences ();
1038       }
1039
1040    DumpReturn (grid);
1041    return grid;
1042 }
1043 // ======================================================== disconnectVertex
1044 Elements* Document::disconnectVertex (Hexa* cell, Vertex* element)
1045 {
1046    DumpStart ("disconnectVertex", cell << element);
1047
1048    Elements* grid = new Elements (this);
1049    grid->checkDisco (cell, element);
1050
1051    if (grid->isValid())
1052       {
1053       update ();
1054       cell->disconnectVertex (element, grid);
1055       majReferences ();
1056       }
1057
1058    DumpReturn (grid);
1059    return grid;
1060 }
1061 // ======================================================== setName
1062 int Document::setName (cpchar prefix)
1063 {
1064    DumpStart ("setName", prefix);
1065
1066    int ier = HOK;
1067    if (Cestvide (prefix) || el_name==prefix)
1068        ier = HERR;
1069    else
1070        {
1071        std::string name = prefix;
1072        if (hex_parent != NULL)
1073            hex_parent->makeName (prefix, name);
1074        el_name = name;
1075        }
1076
1077    DumpReturn (ier);
1078    return ier ;
1079 }
1080 // ======================================================== setLevel
1081
1082 #ifdef  NO_CASCADE
1083 #define _TEST_BICYL
1084 #endif
1085
1086 void Document::setLevel (int niv)
1087 {
1088    DumpStart ("setLevel", niv);
1089
1090    if (niv == 747)
1091       checkAssociations ();
1092    else if (niv == 748)
1093       {
1094       int nbshapes = countShape ();
1095       for (int nsh=0 ; nsh < nbshapes ; nsh++)
1096           {
1097           doc_tab_shape[nsh]->saveBrep();
1098           }
1099       }
1100    else if (niv == 777)
1101       set_special_option (true);
1102    else if (niv == 778)
1103       set_special_option (false);
1104
1105    else if (niv >=100 && niv <=200)
1106       test_six (this, niv);
1107    else
1108       {
1109       doc_db = niv;
1110       }
1111
1112    DumpEnd;
1113 }
1114 // ======================================================== makeVarName
1115 char* Document::makeVarName (char* name)
1116 {
1117    strcpy (name, doc_ident);
1118    return doc_ident ;
1119 }
1120 // ======================================================== isEmpty
1121 bool Document::isEmpty ()
1122 {
1123    int nombre = countVertex () + countVector ();
1124    return nombre <= 0 && countLaw  () <= 1;
1125 }
1126 // ======================================================== getNextName
1127 cpchar Document::getNextName (EnumElt type, std::string& buff)
1128 {
1129    char name [8];
1130    EltBase::makeName (type, doc_nbr_elt [type], name);
1131
1132    buff = name;
1133    return buff.c_str();
1134 }
1135
1136 // ======================================================== getNextName
1137 std::string Document::getNextName (EnumElt type)
1138 {
1139    char name [8];
1140    EltBase::makeName (type, doc_nbr_elt [type], name);
1141
1142    return std::string(name);
1143 }
1144
1145 // ======================================================== lockDump
1146 void Document::lockDump ()
1147 {
1148    glob->dump.lock ();
1149 }
1150 // ======================================================== restoreDump
1151 void Document::restoreDump ()
1152 {
1153    glob->dump.restore (DumpActif);
1154 }
1155 // ======================================================== getGroup
1156 Group* Document::getGroup (int nro)
1157 {
1158    int size = doc_group.size();
1159    if (nro>=0 && nro<size)
1160       return doc_group [nro];
1161    else
1162       return NULL;
1163 }
1164 // ======================================================== getVector
1165 Vector* Document::getVector (int nro)
1166 {
1167    int size = doc_vector.size();
1168    if (nro>=0 && nro<size)
1169       return doc_vector [nro];
1170    else
1171       return NULL;
1172 }
1173 END_NAMESPACE_HEXA