2 // C++ : Gestion des Quadrangles
4 // Copyright (C) 2009-2012 CEA/DEN, EDF R&D
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 #include "HexQuad.hxx"
24 #include "HexDocument.hxx"
25 #include "HexHexa.hxx"
26 #include "HexElements.hxx"
28 #include "HexXmlWriter.hxx"
29 #include "HexShape.hxx"
33 // ======================================================== Constructeur
34 Quad::Quad (Vertex* va, Vertex* vb, Vertex* vc, Vertex* vd)
35 : EltBase (va->dad(), EL_QUAD)
42 q_orientation = Q_UNDEFINED;
44 for (int nro=0 ; nro<QUAD4 ; nro++)
46 q_edge [nro] = new Edge (q_vertex[nro],
47 q_vertex[(nro+1) MODULO QUAD4]);
52 // ======================================================== Constructeur bis
53 Quad::Quad (Edge* ea, Edge* eb, Edge* ec, Edge* ed)
54 : EltBase (ea->dad(), EL_QUAD)
61 q_orientation = Q_UNDEFINED;
63 for (int nro=0 ; nro<QUAD4 ; nro++)
65 int prec = (nro+1) MODULO QUAD4;
67 int nc = q_edge[nro] -> inter (q_edge[prec]);
69 node = q_edge[nro]->getVertex (nc);
72 q_vertex [prec] = node;
77 printf (" +++++++++++++++++++++++++++++++++++++++++++ \n");
78 printf (" +++ Quadrangle impossible \n");
79 printf (" +++++++++++++++++++++++++++++++++++++++++++ \n");
81 printf (" +++++++++++++++++++++++++++++++++++++++++++ \n");
83 for (int ned=0; ned<QUAD4; ned++)
85 q_edge[ned]->dumpPlus ();
87 HexDump (q_vertex[0]);
88 HexDump (q_vertex[1]);
89 HexDump (q_vertex[2]);
90 HexDump (q_vertex[3]);
92 printf (" +++++++++++++++++++++++++++++++++++++++++++ \n");
93 fatal_error ("Quadrangle impossible");
98 // ======================================================== Constructeur bis
99 Quad::Quad (Quad* other)
100 : EltBase (other->dad(), EL_QUAD)
102 for (int nro=0 ; nro<QUAD4 ; nro++)
105 q_vertex [nro] = NULL;
107 q_orientation = Q_UNDEFINED;
110 // ========================================================= majReferences
111 void Quad::majReferences ()
113 for (int nro=0 ; nro<QUAD4 ; nro++)
114 q_edge [nro] -> addParent (this);
116 // ========================================================= getParent
117 Hexa* Quad::getParent (int nro)
119 return static_cast <Hexa*> (getFather (nro));
121 // ======================================================== anaMerge
122 int Quad::anaMerge (Vertex* v1, Vertex* v2, Vertex* tv1[], Edge* te1[])
125 for (int nro=0 ; orig == NOTHING && nro < QUAD4 ; nro++)
126 if (q_vertex [nro] == v1)
132 int nsp1 = (orig+1) MODULO QUAD4;
133 int nsm1 = (orig+QUAD4-1) MODULO QUAD4;
135 if (q_vertex [nsp1] == v2)
137 for (int nro=0 ; nro < QUAD4 ; nro++)
139 tv1 [nro] = q_vertex [(orig+nro) MODULO QUAD4];
140 te1 [nro] = q_edge [(orig+nro) MODULO QUAD4];
143 else if (q_vertex [nsm1] == v2)
145 for (int nro=0 ; nro < QUAD4 ; nro++)
147 tv1 [nro] = q_vertex [(orig+QUAD4-nro) MODULO QUAD4];
148 te1 [nro] = q_edge [(orig+QUAD4-nro) MODULO QUAD4];
156 // ======================================================== ordoVertex
157 int Quad::ordoVertex (Vertex* v1, Vertex* v2, Vertex* tv1[])
160 for (int nro=0 ; orig == NOTHING && nro < QUAD4 ; nro++)
161 if (q_vertex [nro] == v1)
167 int nsp1 = (orig+1) MODULO QUAD4;
168 int nsm1 = (orig+QUAD4-1) MODULO QUAD4;
170 if (q_vertex [nsp1] == v2)
172 for (int nro=0 ; nro < QUAD4 ; nro++)
173 tv1 [nro] = q_vertex [(orig+nro) MODULO QUAD4];
175 else if (q_vertex [nsm1] == v2)
177 for (int nro=0 ; nro < QUAD4 ; nro++)
178 tv1 [nro] = q_vertex [(orig+QUAD4-nro) MODULO QUAD4];
185 // ======================================================== getBrother
186 Quad* Quad::getBrother (StrOrient* orient)
188 /* *****************************
189 printf (" getBrother ");
191 printf (" .. Base : ");
192 orient->v21->printName();
193 orient->v22->printName();
194 printf ("dir=%d, arete=", orient->dir);
195 ***************************** */
197 int n21 = indexVertex (orient->v21);
198 int n22 = indexVertex (orient->v22);
200 int sens = n22 - n21;
201 if (sens > 1) sens -= QUAD4;
202 if (sens < -1) sens += QUAD4;
203 if (sens*sens !=1) return NULL;
207 case OR_LEFT : n22 = n21 - sens;
209 case OR_RIGHT : n21 = n22 + sens;
211 case OR_FRONT : n21 += 2;
217 n21 = (n21 + QUAD4) MODULO QUAD4;
218 n22 = (n22 + QUAD4) MODULO QUAD4;
220 orient->v21 = q_vertex [n21];
221 orient->v22 = q_vertex [n22];
223 Edge* arete = findEdge (orient->v21, orient->v22);
224 // arete->printName("\n");
226 int nbfreres = arete->getNbrParents ();
228 for (int nq = 0 ; nq < nbfreres ; nq++)
230 Quad* next = arete->getParent (nq);
231 if (next!=NULL && next != this )
233 int nbp = next->getNbrParents();
234 Hexa* dad = next->getParent(0);
235 int mark = next->getMark();
236 int mark2 = dad ? dad->getMark() : IS_NONE;
238 if (nbp <= 1 && mark2 != IS_MARRIED && mark == IS_NONE)
240 // if (nbp <= 1 && mark == IS_NONE)
246 // ======================================================== coupler
247 int Quad::coupler (Quad* other, StrOrient* orient, Elements* table)
252 Hexa* hexa = other->getParent(0);
254 setMark (IS_MARRIED);
255 other->setMark (IS_MARRIED);
257 hexa->setMark (IS_MARRIED);
259 for (int ned = 0 ; ned < QUAD4 ; ned++)
261 Edge* arete = q_edge[ned];
262 int nbfreres = arete ->getNbrParents ();
263 for (int nq = 0 ; nq < nbfreres ; nq++)
265 Quad* next = arete->getParent (nq);
266 if (next!=NULL && next != this && next->getMark() > 0)
268 StrOrient new_ori (orient);
269 new_ori.dir = OR_FRONT;
270 Vertex* va = arete->getVertex (V_AMONT);
271 Vertex* vb = arete->getVertex (V_AVAL);
273 // On voit si un point de repere est conserve
274 if (va == orient->v11)
277 new_ori.dir += OR_LEFT;
279 else if (vb == orient->v11)
282 new_ori.dir += OR_LEFT;
285 if (va == orient->v12)
288 new_ori.dir += OR_RIGHT;
290 else if (vb == orient->v12)
293 new_ori.dir += OR_RIGHT;
296 if (new_ori.dir == OR_FRONT)
298 if (definedBy (va, orient->v11))
310 int nro = next->getMark ();
311 Quad* beauf = other->getBrother (&new_ori);
312 int ier = table->coupler (nro, beauf, &new_ori);
315 ier = next->coupler (beauf, &new_ori, table);
323 // ======================================================== getOpposVertex
324 Vertex* Quad::getOpposVertex (Vertex* start)
326 int na = indexVertex (start);
329 return q_vertex [(na+2) MODULO QUAD4];
331 // ======================================================== getOpposEdge
332 Edge* Quad::getOpposEdge (Edge* start, int& sens)
335 int na = indexVertex (start->getVertex (V_AMONT));
336 int nb = indexVertex (start->getVertex (V_AVAL));
338 Vertex* vaprim = q_vertex [(nb+2) MODULO QUAD4];
339 Vertex* vbprim = q_vertex [(na+2) MODULO QUAD4];
341 for (int ned = 0 ; ned < QUAD4 ; ned++)
343 if ( q_edge[ned]->getVertex(V_AMONT) == vaprim
344 && q_edge[ned]->getVertex(V_AVAL ) == vbprim)
349 else if ( q_edge[ned]->getVertex(V_AMONT) == vbprim
350 && q_edge[ned]->getVertex(V_AVAL ) == vaprim)
356 // TODO : traiter l'erreur
357 cout << " ... Probleme dans Quad::getOpposedEdge :" << endl;
365 for (int ned = 0 ; ned < QUAD4 ; ned++)
370 // ========================================================= saveXml
371 void Quad::saveXml (XmlWriter* xml)
376 for (int nro=0 ; nro<QUAD4 ; nro++)
378 if (nro>0) edges += " ";
379 edges += q_edge[nro]->getName(buffer);
382 xml->openMark ("Quad");
383 xml->addAttribute ("id", getName (buffer));
384 xml->addAttribute ("edges", edges);
386 xml->addAttribute ("name", el_name);
389 int nbass = tab_assoc.size();
390 for (int nro=0 ; nro<nbass ; nro++)
391 if (tab_assoc[nro] != NULL)
392 tab_assoc[nro]->saveXml (xml);
394 // ======================================================== replaceEdge
395 void Quad::replaceEdge (Edge* old, Edge* par)
397 for (int nro=0 ; nro<QUAD4 ; nro++)
399 if (q_edge[nro]==old)
406 printf (" [%d], ", nro);
407 old->printName (" est remplace par ");
408 par->printName ("\n");
413 // ======================================================== replaceVertex
414 void Quad::replaceVertex (Vertex* old, Vertex* par)
416 for (int nro=0 ; nro<QUAD4 ; nro++)
418 if (q_vertex [nro]==old)
420 q_vertex [nro] = par;
425 printf (" [%d], ", nro);
426 old->printName (" est remplace par ");
427 par->printName ("\n");
432 // ======================================================== dump
438 printf ("*** deleted ***)\n");
442 for (int nro=0 ; nro<QUAD4 ; nro++)
443 PrintName (q_edge[nro]);
447 for (int nro=0 ; nro<QUAD4 ; nro++)
448 PrintName (q_vertex[nro]);
453 // ======================================================== dumpPlus
454 void Quad::dumpPlus ()
460 for (int nro=0 ; nro < QUAD4 ; nro++)
462 Vertex* pv = q_vertex[nro];
467 printf ( " (%g, %g, %g)\n", pv->getX(), pv->getY(), pv->getZ());
475 // ======================================================== getOpposEdge (2)
476 Edge* Quad::getOpposEdge (Edge* start)
478 int na = indexEdge (start);
481 return q_edge [(na+2) MODULO QUAD4];
483 // ======================================================== getPerpendicular
484 Edge* Quad::getPerpendicular (Edge* arete, Vertex* node)
486 int na = indexEdge (arete);
490 int nv = arete->index (node);
493 Edge* perp = q_edge [(na+1) MODULO QUAD4];
495 nv = perp->index (node);
499 perp = q_edge [(na+3) MODULO QUAD4];
500 nv = perp->index (node);
506 static cpchar t_ori[] = {"Q_INSIDE", "Q_DIRECT", "Q_INVERSE", "Q_UNDEF"};
507 // ======================================================== setOrientation
508 void Quad::setOrientation (int ori)
511 if (ori==Q_DIRECT || ori==Q_INVERSE)
512 printf (" %s = %s\n", el_name.c_str(), t_ori [ q_orientation ]);
514 // ======================================================== setOrientation
515 int Quad::setOrientation ()
517 q_orientation = Q_INSIDE;
518 if (getNbrParents() != 1)
519 return q_orientation;
521 Real3 cg, orig, pi, pj, vi, vj, vk;
523 Hexa* hexa = getParent(0);
524 hexa->getCenter (cg);
526 /********************************************************************
529 for (int np=0 ; np < QUAD4 ; np++)
531 q_vertex [np ] -> getPoint (orig);
532 q_vertex [(np+1) % 4] -> getPoint (pi);
533 q_vertex [(np+3) % 4] -> getPoint (pj);
535 calc_vecteur (orig, pi, vi);
536 calc_vecteur (orig, pj, vj);
537 calc_vecteur (orig, cg, vk);
538 double pmixte = prod_mixte (vi, vj, vk);
539 q_orientation = pmixte > ZEROR ? Q_DIRECT : Q_INVERSE;
540 if (pmixte>0) printf (">");
546 ******************************************************************* */
547 q_vertex [0] -> getPoint (orig);
548 q_vertex [1] -> getPoint (pi);
549 q_vertex [3] -> getPoint (pj);
551 calc_vecteur (orig, pi, vi);
552 calc_vecteur (orig, pj, vj);
553 calc_vecteur (cg, orig, vk);
555 double pmixte = prod_mixte (vi, vj, vk);
556 q_orientation = pmixte > ZEROR ? Q_DIRECT : Q_INVERSE;
557 printf (" %s = %s\n", el_name.c_str(), t_ori [ q_orientation ]);
558 return q_orientation;