Salome HOME
ee4514e33bae99feed65d40afe772fc53fdf9569
[modules/hexablock.git] / src / HEXABLOCK / HexDocument.cxx
1
2 // C++ : La clase principale de Hexa
3
4 //  Copyright (C) 2009-2012  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 "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 #include "HexCrossElements.hxx"
33
34 #include "HexVector.hxx"
35 #include "HexCylinder.hxx"
36 #include "HexPipe.hxx"
37 #include "HexMatrix.hxx"
38 #include "HexCloner.hxx"
39 #include "HexPropagation.hxx"
40 #include "HexLaw.hxx"
41
42 #include "HexXmlWriter.hxx"
43 #include "HexXmlTree.hxx"
44 #include "HexGlobale.hxx"
45 #include "HexGroup.hxx"
46
47 BEGIN_NAMESPACE_HEXA
48
49 // ======================================================== Constructeur
50 Document::Document (cpchar name)
51 {
52    glob = Globale::getInstance ();
53
54    doc_db        = 0;
55    nbr_errors    = 0;
56    doc_modified  = true;
57    doc_saved     = false;
58    doc_name      = name;
59    doc_tolerance = 1e-6;
60    nbr_laws      = 0;
61    nbr_propagations = 0;
62    maj_propagation  = true;
63    doc_xml          = NULL;
64    doc_shape        = NULL;
65
66    defaultLaw = addLaw ("DefaultLaw", 0);
67    
68    nbr_used_hexas = nbr_used_quads = nbr_used_edges = nbr_used_vertex = 0;
69
70    for (EnumElt type = EL_NONE ; type < EL_MAXI ; type=(EnumElt) (type+1))
71        {
72        doc_first_elt [type] = doc_last_elt [type] = new EltBase (); 
73        doc_nbr_elt   [type] = 0;
74        }
75 }
76 // ======================================================== Destructeur
77 Document::~Document ()
78 {
79    delete doc_xml;
80
81    for (EnumElt type = EL_NONE ; type < EL_MAXI ; type=(EnumElt) (type+1))
82        {
83        //  printf ("____________________________ Type=%d\n", type);
84        EltBase* next = NULL;
85        for (EltBase* elt=doc_first_elt [type] ; elt != NULL ; elt=next) 
86            {
87            next = elt->next();
88            delete elt;
89            }
90        }
91 }
92 // ======================================================== addVector
93 Vector* Document::addVector (double dx, double dy, double dz)
94 {
95    Vector* pv = new Vector (this, dx, dy, dz); 
96    doc_vector.push_back (pv);
97    return  pv;
98 }
99 // ======================================================== addVectorVertices
100 Vector* Document::addVectorVertices (Vertex* va, Vertex* vb)
101 {
102    Vector* pv = addVector (vb->getX () - va->getX (),
103                            vb->getY () - va->getY (),
104                            vb->getZ () - va->getZ ());
105    return  pv;
106 }
107 // ======================================================== addVertex
108 Vertex* Document::addVertex (double x, double y, double z)
109 {
110    Vertex* pv   = new Vertex (this, x, y, z);
111    return pv;
112 }
113 // ======================================================== addEdge
114 Edge* Document::addEdge (Vertex* va, Vertex* vb)
115 {
116    if (va==NULL || vb==NULL) 
117       return NULL;
118
119    Edge* arete  = new Edge (va, vb);
120    return arete;
121 }
122 // ======================================================== addEdge (bis)
123 Edge* Document::addEdge (Vertex* va, Vector* vec)
124 {
125    Vertex* vb   = addVertex (va->getX () + vec->getDx(), 
126                              va->getY () + vec->getDy(), 
127                              va->getZ () + vec->getDz());
128
129    Edge*  arete = addEdge (va, vb);
130    return arete;
131 }
132 // ======================================================== addQuadVertices
133 Quad* Document::addQuadVertices (Vertex* va, Vertex* vb, Vertex* vc, Vertex* vd)
134 {
135    Quad*  face   = new Quad (va, vb, vc, vd);
136    return face;
137 }
138 // ======================================================== addQuad
139 Quad* Document::addQuad (Edge* ea, Edge* eb, Edge* ec, Edge* ed)
140 {
141    Quad*  face   = new Quad (ea, eb, ec, ed);
142    return face;
143 }
144 // ======================================================== addHexaVertices
145 Hexa* Document::addHexaVertices (Vertex* va, Vertex* vb, Vertex* vc, Vertex* vd,
146                                  Vertex* ve, Vertex* vf, Vertex* vg, Vertex* vh)
147 {
148    Hexa*  pave   = new Hexa (va, vb, vc, vd, ve, vf, vg, vh);
149    return pave;
150 }
151 // ======================================================== addHexa
152 Hexa* Document::addHexa (Quad* qa, Quad* qb, Quad* qc, Quad* qd, Quad* qe, 
153                          Quad* qf)
154 {
155    Hexa*  pave   = new Hexa (qa, qb, qc, qd, qe, qf);
156    return pave;
157 }
158 // ======================================================== addCylinder
159 Cylinder* Document::addCylinder (Vertex* b, Vector* d, double r,  double h)
160 {
161    Cylinder* cyl = new  Cylinder (b, d, r, h);
162    doc_cylinder.push_back (cyl);
163    return    cyl;
164 }
165 // ======================================================== addPipe
166 Pipe* Document::addPipe (Vertex* b, Vector* d, double ri, double re, double h)
167 {
168    Pipe*  tuyau = new  Pipe (b, d, ri, re, h);
169    doc_pipe.push_back (tuyau);
170    return tuyau;
171 }
172 // ======================================================== makeCartesian
173 Elements* Document::makeCartesian (Vertex* v, Vector* dir, 
174                             int px, int py, int pz, int mx, int my, int mz)
175 {
176    Vector* v1 = new Vector (this, dir->getDx(), 0, 0); 
177    Vector* v2 = new Vector (this, 0, dir->getDy(), 0); 
178    Vector* v3 = new Vector (this, 0,0,  dir->getDz()); 
179    Elements*  grille = new Elements (this);
180    grille->makeCartesianGrid (v, v1, v2, v3, px, py, pz, mx, my, mz);
181    return grille;
182 }
183 // ======================================================== makeCartesian
184 Elements* Document::makeCartesian (Vertex* v, Vector* v1, Vector* v2, 
185                     Vector* v3, int px, int py, int pz, int mx, int my, int mz)
186 {
187    Elements* grille = new Elements (this);
188    grille->makeCartesianGrid (v, v1, v2, v3, px, py, pz, mx, my, mz);
189    return grille;
190 }
191 // ======================================================== makeSpherical
192 Elements* Document::makeSpherical (Vertex* c, double rayon, int nb, double k)
193 {
194    Elements* grille = new Elements (this);
195    grille->makeSphericalGrid (c, rayon, nb, k);
196    return grille;
197 }
198 // ======================================================== makeCylindrical
199 Elements* Document::makeCylindrical (Vertex* c, Vector* b, Vector* h, 
200         double dr, double da, double dl, int nr, int na, int nl, bool fill)
201 {
202    Elements* grille = new Elements (this);
203    grille->makeCylindricalGrid (c, b, h, dr, da, dl, nr, na, nl, fill);
204    return grille;
205 }
206 // ======================================================== makeSphere
207 Elements* Document::makeSphere (Vertex* center, Vector* vx, Vector* vz, 
208                                 double radius, double radhole, Vertex* plorig, 
209                                 int nrad, int nang, int nhaut)
210 {
211    Elements* grille = new Elements (this);
212    double radint = (radhole + radius)*DEMI;
213    grille->makeRind (GR_HEMISPHERIC, center, vx, vz, radius, radint, radhole, 
214                      plorig, 360.0, nrad, nang, nhaut);
215    return grille;
216 }
217 // ======================================================== makePartSphere
218 Elements* Document::makePartSphere (Vertex* center, Vector* vx, Vector* vz, 
219                                  double  radius, double radhole,
220                                  Vertex* plorig, double angle,
221                                  int nrad, int nang, int nhaut)
222 {
223    Elements* grille = new Elements (this);
224    double radint = (radhole + radius)*DEMI;
225    grille->makeRind (GR_PART_SPHERIC, center, vx, vz, radius, radint, radhole, 
226                      plorig, angle, nrad, nang, nhaut);
227    return grille;
228 }
229 // ======================================================== makeRind 
230 Elements* Document::makeRind (Vertex* center, Vector* vx, Vector* vz, 
231                               double  radext, double radint, double radhole,
232                               Vertex* plorig, int nrad, int nang, int nhaut)
233 {
234    Elements* grille = new Elements (this);
235    grille->makeRind (GR_RIND, center, vx, vz, radext, radint, radhole, 
236                      plorig, 360.0, nrad, nang, nhaut);
237    return grille;
238 }
239 // ======================================================== makePartRind
240 Elements* Document::makePartRind (Vertex* center, Vector* vx, Vector* vz, 
241                            double  radext, double radint, double radhole,
242                            Vertex* plorig, double angle,
243                                int nrad, int nang, int nhaut)
244 {
245    Elements* grille = new Elements (this);
246    grille->makeRind (GR_PART_RIND, center, vx, vz, radext, radint, radhole, 
247                      plorig, angle, nrad, nang, nhaut);
248    return grille;
249 }
250 // ======================================================== findVertex
251 Vertex* Document::findVertex (double vx, double vy, double vz)
252 {
253    double xmin = vx - doc_tolerance;
254    double xmax = vx + doc_tolerance;
255    double ymin = vy - doc_tolerance;
256    double ymax = vy + doc_tolerance;
257    double zmin = vz - doc_tolerance;
258    double zmax = vz + doc_tolerance;
259
260    for (EltBase* elt = doc_first_elt[EL_VERTEX]->next (); elt!=NULL;
261                  elt = elt->next())
262        {
263        if (elt->isHere())
264           { 
265           Vertex* node = static_cast <Vertex*> (elt); 
266           if (node->isin (xmin, xmax, ymin, ymax, zmin, zmax))
267              return node;
268           }
269        }
270    return NULL;
271 }
272 // ======================================================== findEdge
273 Edge* Document::findEdge (Vertex* v1, Vertex* v2)
274 {
275    for (EltBase* elt = doc_first_elt[EL_EDGE]->next (); elt!=NULL;
276                  elt = elt->next())
277        {
278        Edge* candidat  = static_cast <Edge*> (elt); 
279        if (candidat->definedBy (v1, v2))
280           return candidat;
281        }
282    return NULL;
283 }
284 // ======================================================== findQuad
285 Quad* Document::findQuad (Vertex* v1, Vertex* v2)
286 {
287    for (EltBase* elt = doc_first_elt[EL_QUAD]->next (); elt!=NULL;
288                  elt = elt->next())
289        {
290        Quad* candidat  = static_cast <Quad*> (elt); 
291        if (candidat->definedBy (v1, v2))
292           return candidat;
293        }
294    return NULL;
295 }
296 // ======================================================== findHexa
297 Hexa* Document::findHexa (Vertex* v1, Vertex* v2)
298 {
299    for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); elt!=NULL;
300                  elt = elt->next())
301        {
302        Hexa* candidat  = static_cast <Hexa*> (elt); 
303        if (candidat->definedBy (v1, v2))
304           return candidat;
305        }
306    return NULL;
307 }
308
309 // ======================================================== findElement
310 EltBase* Document::findElement (EnumElt type, int ident)
311 {
312    for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
313                  elt = elt->next())
314        {
315        if (elt->isHere() && elt->getId()==ident)
316           return elt;
317        }
318    return NULL;
319 }
320 // ======================================================== findVertex
321 Vertex* Document::findVertex (int ident)
322 {
323    Vertex* node = static_cast <Vertex*> (findElement (EL_VERTEX, ident)); 
324    return  node;
325
326 }
327 // ======================================================== index_tv
328 int index_tv (Vertex* table[], Vertex* elt)
329 {
330    for (int nro=0; nro<QUAD4; nro++)
331         if (elt == table[nro])
332            return nro;
333
334    return NOTHING;
335 }
336 // ======================================================== mergeQuads
337 int Document::mergeQuads (Quad* dest, Quad* orig, Vertex* v1, Vertex* v2, 
338                                                 Vertex* v3, Vertex* v4)
339 {
340    update ();
341
342    if (dest==orig)
343       {
344       printf (" *** Quads identiques dans mergeQuads\n");
345       return HERR;
346       }
347    else if (dest==NULL || dest->isDeleted())
348       {
349       printf (" *** Quad nro 1 incorrect dans mergeQuads \n");
350       return HERR;
351       }
352    else if (orig==NULL || orig->isDeleted() )
353       {
354       printf (" *** Quad nro 2 incorrect dans mergeQuads \n");
355       return HERR;
356       }
357
358    int nbcomm = 0;
359    for (int nro=0 ; nro<QUAD4 ; nro++) 
360        {
361        int norig = orig->indexVertex (dest->getVertex(nro));
362        if (norig != NOTHING)
363           {
364           Vertex* uv = dest->getVertex(nro);
365           char nom[12];
366           nbcomm ++;
367           if (nbcomm==1)
368              {
369              printf ("  +++ Sommets communs dans mergeQuads");
370              printf (" (%s,",  dest->getName (nom));
371              printf (" %s)\n", orig->getName (nom));
372              }
373           printf ("  +++ quad1[%d] = quad2[%d] = %s\n", nro,  norig, 
374                                                         uv->getName (nom));
375           }
376        }
377
378    if (nbcomm == 2)
379       {
380       printf ("  +++ Les vertex passes en arguments sont ignores\n");
381       int ier = closeQuads (dest, orig);
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       return HERR;
389       }
390
391    if (   v1 ==NULL || v1 ->isDeleted() || v2 ==NULL || v2 ->isDeleted() 
392        || v3 ==NULL || v3 ->isDeleted() || v4 ==NULL || v4 ->isDeleted()) 
393       {
394       printf ("  *** _____________________ mergeQuads refuse: \n");
395       printf (" un sommet est incorrect\n");
396       return HERR;
397       }
398
399
400    if (debug())
401       {
402       printf ("  ----------------- mergeQuads : \n");
403       HexDump (orig);
404       HexDump (dest);
405       HexDump (v1);
406       HexDump (v2);
407       HexDump (v3);
408       HexDump (v4);
409       }
410
411    Vertex *tv1 [QUAD4], *tv2 [QUAD4];
412    Edge   *te1 [QUAD4], *te2 [QUAD4];
413
414    int ier1 = dest->ordoVertex (v1, v3, tv1);
415    int ier2 = orig->ordoVertex (v2, v4, tv2);
416    if (ier1 != HOK)      return ier1;
417    else if (ier2 != HOK) return ier2;
418
419    for (int nro=0 ; nro<QUAD4 ; nro++)
420        {
421        te1 [nro] = dest->getEdge(nro);
422        Vertex* va1 = te1[nro]->getVertex(V_AMONT);
423        Vertex* vb1 = te1[nro]->getVertex(V_AVAL);
424        int na = index_tv  (tv1, va1);
425        int nb = index_tv  (tv1, vb1);
426        if (na==NOTHING || nb==NOTHING)
427           return HERR;
428
429        te2 [nro] = orig->findEdge (tv2[na], tv2[nb]);
430        if (te2[nro]==NULL)
431           return HERR;
432        }
433
434    if (debug())
435       {
436       printf ("  ----------------- Correspondances mergeQuads : \n");
437       for (int nro=0 ; nro<QUAD4 ; nro++)
438           {
439           printf ("  %d  : ", nro);
440           tv2 [nro]->printName(" -> ");
441           tv1 [nro]->printName("\n");
442           }
443       for (int nro=0 ; nro<QUAD4 ; nro++)
444           {
445           printf ("  %d  : ", nro);
446           te2 [nro]->printName(" (");
447           te2 [nro]->getVertex(0)->printName(", ");
448           te2 [nro]->getVertex(1)->printName(") -> ");
449           te1 [nro]->printName(" (");
450           te1 [nro]->getVertex(0)->printName(", ");
451           te1 [nro]->getVertex(1)->printName(")\n");
452           }
453       }
454
455    replaceQuad (orig, dest);
456    for (int nro=0 ; nro<QUAD4 ; nro++) 
457        replaceEdge   (te2[nro], te1[nro]);
458    for (int nro=0 ; nro<QUAD4 ; nro++) 
459        replaceVertex (tv2[nro], tv1[nro]);
460
461    maj_connection = false;
462    purge_elements = false;
463    return HOK;
464 }
465 // ======================================================== closeQuads
466 int Document::closeQuads (Quad* dest, Quad* orig)
467 {
468    update ();
469    char nom[12];
470
471    if (dest==orig)
472       {
473       printf (" *** Quads identiques dans closeQuads : %s\n", 
474                  dest->getName(nom));
475       return HERR;
476       }
477    else if (dest==NULL || dest->isDeleted())
478       {
479       printf (" *** Quad nro 1 incorrect dans closeQuads \n");
480       return HERR;
481       }
482    else if (orig==NULL || orig->isDeleted() )
483       {
484       printf (" *** Quad nro 2 incorrect dans closeQuads \n");
485       return HERR;
486       }
487
488    Edge* edc = NULL;
489    for (int nro=0 ; nro<QUAD4 ; nro++) 
490        {
491        int norig = orig->indexEdge (dest->getEdge(nro));
492        if (norig != NOTHING)
493           {
494           if (edc != NULL) 
495              {
496              printf ("  *** Plus d'une arete commune dans closeQuads");
497              printf (" (%s,",  dest->getName (nom));
498              printf (" %s)\n", orig->getName (nom));
499              return HERR;
500              }
501           edc = dest->getEdge (nro);
502           printf ("  +++ quad1[%d] = quad2[%d] = %s\n", nro,  norig, 
503                                                         edc->getName (nom));
504           }
505        }
506
507    Vertex* va = edc->getVertex (V_AMONT);
508    Vertex* vb = edc->getVertex (V_AVAL);
509    Vertex *tv1 [QUAD4], *tv2 [QUAD4];
510    Edge   *te1 [QUAD4], *te2 [QUAD4];
511
512    int ier1 = dest->ordoVertex (va, vb, tv1);
513    int ier2 = orig->ordoVertex (va, vb, tv2);
514
515    if (ier1 != HOK)      return ier1;
516    else if (ier2 != HOK) return ier2;
517
518    for (int nro=0 ; nro<QUAD4 ; nro++)
519        {
520        te1 [nro] = dest->getEdge(nro);
521        Vertex* va1 = te1[nro]->getVertex(V_AMONT);
522        Vertex* vb1 = te1[nro]->getVertex(V_AVAL);
523        int na = index_tv  (tv1, va1);
524        int nb = index_tv  (tv1, vb1);
525        if (na==NOTHING || nb==NOTHING)
526           return HERR;
527
528        te2 [nro] = orig->findEdge (tv2[na], tv2[nb]);
529        if (te2[nro]==NULL)
530           return HERR;
531        }
532
533    if (debug())
534       {
535       printf ("  ----------------- Correspondances mergeQuads : \n");
536       for (int nro=0 ; nro<QUAD4 ; nro++)
537           {
538           printf ("  %d  : ", nro);
539           tv2 [nro]->printName(" -> ");
540           tv1 [nro]->printName("\n");
541           }
542       for (int nro=0 ; nro<QUAD4 ; nro++)
543           {
544           printf ("  %d  : ", nro);
545           te2 [nro]->printName(" (");
546           te2 [nro]->getVertex(0)->printName(", ");
547           te2 [nro]->getVertex(1)->printName(") -> ");
548           te1 [nro]->printName(" (");
549           te1 [nro]->getVertex(0)->printName(", ");
550           te1 [nro]->getVertex(1)->printName(")\n");
551           }
552       }
553
554    replaceQuad (orig, dest);
555    for (int nro=0 ; nro<QUAD4 ; nro++) 
556        replaceEdge   (te2[nro], te1[nro]);
557    for (int nro=0 ; nro<QUAD4 ; nro++) 
558        replaceVertex (tv2[nro], tv1[nro]);
559
560    maj_connection = false;
561    purge_elements = false;
562    return HOK;
563 }
564 // ======================================================== mergeEdges
565 int Document::mergeEdges (Edge* e1, Edge* e2, Vertex* v1, Vertex* v2)
566 {
567    if (e1==NULL || e1->isDeleted() || e2==NULL || e2->isDeleted()) 
568       return HERR;
569
570    for (int nro=0 ; nro<V_TWO ; nro++) 
571        if (e1->index (e2->getVertex(nro))!= NOTHING)
572           return HERR+nro+1;
573
574    Vertex *tv1 [V_TWO], *tv2 [V_TWO];
575
576    int ier1 = e1->anaMerge (v1, tv1);
577    int ier2 = e2->anaMerge (v2, tv2);
578
579    if (ier1 != HOK)      return ier1;
580    else if (ier2 != HOK) return ier2;
581
582    replaceEdge (e2, e1);
583    for (int nro=0 ; nro<V_TWO ; nro++) 
584        replaceVertex (tv2[nro], tv1[nro]);
585
586    maj_connection = false;
587    return HOK;
588 }
589 // ======================================================== mergeVertices
590 int Document::mergeVertices (Vertex* v1, Vertex* v2)
591 {
592    if (v1==v2 || v1==NULL || v1->isDeleted() 
593               || v2==NULL || v2->isDeleted())
594       return HERR;
595
596    replaceVertex (v2, v1);
597
598    maj_connection = false;
599    return HOK;
600 }
601 // ======================================================== replaceVertex
602 void Document::replaceVertex (Vertex* old, Vertex* par)
603 {
604    if (old==par)
605       return;
606
607    par->replaceAssociation (old);
608
609    for (int type=EL_EDGE ; type <= EL_HEXA ; type++)
610        {
611        for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
612                      elt = elt->next())
613            if (elt->isHere ())
614                elt->replaceVertex (old, par);
615        }
616    old->suppress ();
617 }
618 // ======================================================== replaceEdge
619 void Document::replaceEdge (Edge* old, Edge* par)
620 {
621    if (old==par)
622       return;
623
624    par->replaceAssociation (old);
625
626    for (int type=EL_QUAD ; type <= EL_HEXA ; type++)
627        {
628        for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
629                      elt = elt->next())
630            if (elt->isHere ())
631                elt->replaceEdge (old, par);
632        }
633    old->suppress ();
634 }
635 // ======================================================== replaceQuad
636 void Document::replaceQuad (Quad* old, Quad* par)
637 {
638    if (old==par)
639       return;
640
641    par->replaceAssociation (old);
642
643    for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); elt!=NULL;
644                  elt = elt->next())
645        if (elt->isHere ())
646           {
647           Hexa* cell = static_cast <Hexa*> (elt);
648           cell->replaceQuad (old, par);
649           }
650    old->suppress ();
651 }
652 // ======================================================== prismQuad
653 Elements* Document::prismQuad  (Quad* start, Vector* dir, int nb)
654 {
655    Quads  tstart;
656    tstart.push_back (start);
657
658    update ();
659    Elements* prisme = prismQuads (tstart, dir, nb);
660    return    prisme;
661 }
662 // ======================================================== prismQuads
663 Elements* Document::prismQuads (Quads& tstart, Vector* dir, int nb)
664 {
665    Elements*  prisme = new Elements (this);
666    if (nb<=0) return prisme;
667
668    prisme->prismQuads (tstart, dir, nb);
669    return prisme;
670 }
671 // ======================================================== prismQuadsVec
672 Elements* Document::prismQuadsVec (Quads& tstart, Vector* dir, RealVector& tlen,
673                                    int crit)
674 {
675    Elements*  prisme = new Elements (this);
676    if (tlen.size()<=0) return prisme;
677
678    prisme->prismQuadsVec (tstart, dir, tlen, crit);
679    return prisme;
680 }
681 // ======================================================== joinQuads
682 Elements* Document::joinQuads (Quads& start, Quad* dest, Vertex* v1, 
683                                Vertex* v2, Vertex* v3, Vertex* v4, int nb)
684 {
685    update ();
686    Elements*  joint = new Elements (this);
687    if (nb<=0)      return joint;
688
689    int ier = joint->joinQuads (start, nb, v1, v2, v3, v4, dest);
690    if (ier !=HOK)
691       printf ("\n ****\n **** Error in joinQuad(s)\n ****\n");
692    return joint;
693 }
694 // ======================================================== joinQuad
695 Elements* Document::joinQuad (Quad* start, Quad* dest, Vertex* v1, 
696                               Vertex* v2,  Vertex* v3, Vertex* v4, int nb)
697 {
698    Quads  tstart;
699    tstart.push_back (start);
700
701    Elements* joint = joinQuads (tstart, dest, v1, v2, v3, v4, nb);
702    return    joint;
703 }
704 // ========================================================== getHexa
705 Hexa* Document::getHexa (int nro) 
706 {
707    return static_cast <Hexa*> (getElement (EL_HEXA, nro));
708 }
709 // ========================================================== getQuad
710 Quad* Document::getQuad (int nro) 
711 {
712    return static_cast <Quad*> (getElement (EL_QUAD, nro));
713 }
714 // ========================================================== getEdge
715 Edge* Document::getEdge (int nro) 
716
717    return static_cast <Edge*> (getElement (EL_EDGE, nro));
718 }
719 // ========================================================== getVertex
720 Vertex* Document::getVertex (int nro) 
721
722    return static_cast <Vertex*> (getElement (EL_VERTEX, nro)); 
723 }
724 // ========================================================== countElement
725 int Document::countElement (EnumElt type)
726
727    int compteur = 0;
728    for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
729                  elt = elt->next())
730        if (elt->isHere())
731           compteur ++;
732
733    return compteur;
734 }
735 // ========================================================== getElement
736 EltBase* Document::getElement (EnumElt type, int nro) 
737
738    int compteur = 0;
739    for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
740                  elt = elt->next())
741        {
742        if (elt->isHere())
743           {
744           if (compteur>=nro)
745              return elt;
746           compteur ++;
747           }
748        }
749    return NULL;
750 }
751 // ========================================================= addLaw
752 Law* Document::addLaw (const char* name, int nbnodes)
753
754    Law* loi = new Law (name, nbnodes);
755    return addLaw (loi);
756 }
757 // ========================================================= addLaw
758 Law* Document::addLaw (Law* loi)
759
760    doc_laws.push_back (loi);
761    nbr_laws ++;
762    return loi;
763 }
764 // ========================================================= GetLaw
765 Law* Document::getLaw (int nro)
766
767    if (nro <0 || nro>= nbr_laws)
768       return NULL;
769
770    return doc_laws [nro];
771 }
772 // ========================================================= FindLaw
773 Law* Document::findLaw (const char* name)
774
775    std::string nom = name;
776    for (int nro=0 ; nro<nbr_laws; nro++)
777        if (doc_laws [nro]->getName() == nom)
778           return doc_laws [nro];
779
780    return NULL;
781 }
782 // ========================================================= removeLaw
783 int Document::removeLaw (Law* loi)
784
785    for (int nro=1 ; nro<nbr_laws; nro++)
786        if (doc_laws [nro] == loi)
787           {
788           //All propagations having this law should now have the default law.
789
790           for (int nl=0 ; nl<nbr_propagations ; nl++)
791               {
792               if ( doc_propagation [nl]->getLaw() == loi )
793                    doc_propagation [nl]->setLaw(defaultLaw);
794               }
795
796            delete doc_laws [nro];
797            doc_laws.erase (doc_laws.begin()+nro);
798            nbr_laws= doc_laws.size();
799            return HOK;
800            }
801
802    return HERR;
803 }
804 // ========================================================= majPropagation
805 void Document::majPropagation ()
806
807    majReferences ();
808    update ();
809    // if (purge_elements)
810        // purge ();
811
812    for (int nro=0 ; nro<nbr_propagations ; nro++)
813        {
814        delete doc_propagation [nro];
815        }
816
817    doc_propagation.clear ();
818    nbr_propagations = 0;
819    maj_propagation  = false;
820
821    for (EltBase* elt = doc_first_elt[EL_EDGE]->next (); elt!=NULL;
822                  elt = elt->next())
823        {
824        Edge* arete = static_cast <Edge*> (elt);
825        if (arete!=NULL)
826            arete->setPropag (NOTHING, true);
827        }
828
829    //  markAll (NO_COUNTED, EL_EDGE);
830
831    for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); elt!=NULL;
832                  elt = elt->next())
833        {
834        Hexa* cell = static_cast <Hexa*> (elt);
835        if (cell!=NULL && cell->isHere())
836           {
837           for (int ne=0 ; ne<HE_MAXI ; ne++)
838               {
839               Edge* arete = cell->getEdge(ne);
840               if (arete->getPropag()<0)
841                  {
842                  Propagation* prop = new Propagation (); 
843                  doc_propagation.push_back (prop);
844                  arete->propager (prop, nbr_propagations);
845                  nbr_propagations ++;
846                  prop->majLaw();
847                  }
848               }
849           }
850        }
851 }
852 // ======================================================== countPropagation
853 int Document::countPropagation ()
854 {
855    if (maj_propagation)
856        majPropagation ();
857
858    return nbr_propagations;
859 }
860 // ======================================================== getPropagation
861 Propagation* Document::getPropagation (int nro)
862 {
863    if (maj_propagation)
864        majPropagation ();
865
866    if (nro < 0 || nro >= nbr_propagations)
867        return NULL;
868
869    return doc_propagation [nro];
870 }
871 // ======================================================== findPropagation
872 Propagation* Document::findPropagation (Edge* arete)
873 {
874    if (arete==NULL) 
875        return NULL;
876
877    if (maj_propagation)
878        majPropagation ();
879
880    return getPropagation (arete->getPropag ());
881 }
882 // ======================================================== disconnectQuad
883 Elements* Document::disconnectQuad (Hexa* cell, Quad* element)
884 {
885    if (cell==NULL || element==NULL) 
886       return NULL;
887
888    update ();
889    Elements* crees = cell->disconnectQuad (element);
890
891    if (crees!=NULL) 
892        majReferences ();
893
894    return crees;
895 }
896 // ======================================================== disconnectEdge
897 Elements* Document::disconnectEdge (Hexa* cell, Edge* element)
898 {
899    if (cell==NULL || element==NULL) 
900       return NULL;
901
902    update ();
903    Elements* crees = cell->disconnectEdge (element);
904
905    if (crees!=NULL)
906        majReferences ();
907    return crees;
908 }
909 // ======================================================== disconnectVertex
910 Elements* Document::disconnectVertex (Hexa* cell, Vertex* element)
911 {
912    if (cell==NULL || element==NULL) 
913       return NULL;
914
915    update ();
916    Elements* crees = cell->disconnectVertex (element);
917
918    if (crees!=NULL) 
919        majReferences ();
920    return crees;
921 }
922 // ======================================================== cut
923 Elements* Document::cut (Edge* edge, int nbcuts)
924 {
925    Elements* t_hexas = new Elements (this);
926
927    if (edge==NULL || nbcuts<=0)
928       return t_hexas;
929
930    Propagation* prop    = findPropagation (edge);
931    const Edges& t_edges = prop->getEdges ();
932
933    t_hexas->cutHexas (t_edges, nbcuts);
934
935    majPropagation ();
936    return t_hexas;
937 }
938 // ======================================================== addGroup
939 Group* Document::addGroup    (cpchar name, EnumGroup kind)
940 {
941    Group* grp = new Group (name, kind);
942    doc_group.push_back (grp);
943    return grp;
944 }
945 // ======================================================== findGroup
946 Group* Document::findGroup   (cpchar name)
947 {
948    int nbre = doc_group.size();
949
950    for (int ng=0 ; ng<nbre ; ng++) 
951        if (Cestegal (doc_group [ng]->getName(), name))
952           return doc_group [ng];
953
954    return NULL;
955 }
956 // ======================================================== removeGroup
957 int Document::removeGroup (Group* grp)
958 {
959    int nbre = doc_group.size();
960    for (int ng=0 ; ng<nbre ; ng++) 
961        {
962        if (grp == doc_group [ng])
963           {
964           doc_group.erase (doc_group.begin() + ng);
965           delete grp;
966           return HOK;
967           }
968        }
969                       // Pas trouve dans la liste. On detruit quand meme
970    delete grp;
971    return HERR;
972 }// ======================================================== makeCylinder
973 Elements* Document::makeCylinder (Cylinder* cyl, Vector* base, int nr, int na, 
974                                                                        int nl)
975 {
976    Elements* grille = new Elements (this);
977    grille->makeCylinder (cyl, base, nr, na, nl);
978    return grille;
979 }
980 // ======================================================== makeCylinders
981 CrossElements* Document::makeCylinders (Cylinder* cyl1, Cylinder* cyl2)
982 {
983    CrossElements* grille = new CrossElements (this, GR_BICYL);
984    grille->crossCylinders (cyl1, cyl2, true);
985    return grille;
986 }
987
988 // ======================================================== makePipe
989 Elements* Document::makePipe (Pipe* pipe, Vector* bx, int nr, int na, int nl)
990 {
991    Elements* grille = new Elements (this);
992    grille->makePipe (pipe, bx, nr, na, nr);
993    return grille;
994 }
995 // ======================================================== makePipes
996 CrossElements* Document::makePipes (Pipe* pipe1, Pipe* pipe2)
997 {
998    CrossElements* grille = new CrossElements (this, GR_BIPIPE);
999    grille->crossCylinders (pipe1, pipe2, false);
1000    return grille;
1001 }
1002 // ======================================================== setName
1003 int Document::setName (const char* name)
1004 {
1005    doc_name = name ;
1006    return HOK ;
1007 }
1008
1009 // ======================================================== setLevel
1010
1011 #ifdef  NO_CASCADE
1012 #define _TEST_BIC
1013 #endif
1014
1015 class BiCylinder;
1016
1017 BiCylinder* test_bicylinder (Document* docu, int option);
1018 void        set_debug_asso  (bool boule);
1019
1020 void Document::setLevel (int niv)
1021 {
1022    if (niv == 747)
1023       clearAssociation ();
1024    else if (niv == 777)
1025       set_special_option (true);
1026    else if (niv == 778)
1027       set_special_option (false);
1028 #ifdef _TEST_BICYL
1029    else if (niv >=90 && niv <=99)
1030       test_bicylinder (this, niv-90);
1031 #endif
1032    else
1033       {
1034       doc_db = niv;
1035       set_debug_asso (niv>0);
1036       }
1037 }
1038 // ======================================================== getAssoVertices
1039 void Document::getAssoVertices (Vertices& tabelt)
1040 {
1041    tabelt.clear ();
1042    for (EltBase* elt = doc_first_elt[EL_VERTEX]->next (); elt!=NULL;
1043                  elt = elt->next())
1044        if (elt->isHere() && elt->getAssociation()!=NULL)
1045           tabelt.push_back (static_cast <Vertex*> (elt)); 
1046 }
1047 // ======================================================== getAssoEdges
1048 void Document::getAssoEdges (Edges& tabelt)
1049 {
1050    tabelt.clear ();
1051    for (EltBase* elt = doc_first_elt[EL_EDGE]->next (); elt!=NULL;
1052                  elt = elt->next())
1053        if (elt->isHere())
1054           { 
1055           Edge* edge = static_cast <Edge*> (elt); 
1056           int nbass  = edge->getAssociations().size();
1057           if (nbass>0)
1058               tabelt.push_back (edge);
1059           }
1060 }
1061 END_NAMESPACE_HEXA