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]);
49 if (BadElement (q_vertex [nro]) || BadElement (q_edge [nro]))
52 for (int nv=nro+1 ; nv<QUAD4 ; nv++)
53 if (q_vertex[nv] == q_vertex[nro])
59 // ======================================================== Constructeur bis
60 Quad::Quad (Edge* ea, Edge* eb, Edge* ec, Edge* ed)
61 : EltBase (ea->dad(), EL_QUAD)
68 q_orientation = Q_UNDEFINED;
70 for (int nro=0 ; nro<QUAD4 ; nro++)
72 int prec = (nro+1) MODULO QUAD4;
75 if (BadElement (q_edge[nro]))
79 for (int nv=nro+1 ; nv<QUAD4 ; nv++)
80 if (q_edge[nv] == q_edge[nro])
82 int nc = q_edge[nro] -> inter (q_edge[prec]);
84 node = q_edge[nro]->getVertex (nc);
88 q_vertex [prec] = node;
93 printf (" +++++++++++++++++++++++++++++++++++++++++++ \n");
94 printf (" +++ Quadrangle impossible \n");
95 printf (" +++++++++++++++++++++++++++++++++++++++++++ \n");
97 printf (" +++++++++++++++++++++++++++++++++++++++++++ \n");
99 for (int ned=0; ned<QUAD4; ned++)
101 q_edge[ned]->dumpPlus ();
103 HexDump (q_vertex[0]);
104 HexDump (q_vertex[1]);
105 HexDump (q_vertex[2]);
106 HexDump (q_vertex[3]);
108 printf (" +++++++++++++++++++++++++++++++++++++++++++ \n");
109 fatal_error ("Quadrangle impossible");
114 // ======================================================== Constructeur bis
115 Quad::Quad (Quad* other)
116 : EltBase (other->dad(), EL_QUAD)
118 for (int nro=0 ; nro<QUAD4 ; nro++)
121 q_vertex [nro] = NULL;
123 q_orientation = Q_UNDEFINED;
126 // ========================================================= majReferences
127 void Quad::majReferences ()
129 for (int nro=0 ; nro<QUAD4 ; nro++)
130 q_edge [nro] -> addParent (this);
132 // ========================================================= getParent
133 Hexa* Quad::getParent (int nro)
135 return static_cast <Hexa*> (getFather (nro));
137 // ======================================================== anaMerge
138 int Quad::anaMerge (Vertex* v1, Vertex* v2, Vertex* tv1[], Edge* te1[])
141 for (int nro=0 ; orig == NOTHING && nro < QUAD4 ; nro++)
142 if (q_vertex [nro] == v1)
148 int nsp1 = (orig+1) MODULO QUAD4;
149 int nsm1 = (orig+QUAD4-1) MODULO QUAD4;
151 if (q_vertex [nsp1] == v2)
153 for (int nro=0 ; nro < QUAD4 ; nro++)
155 tv1 [nro] = q_vertex [(orig+nro) MODULO QUAD4];
156 te1 [nro] = q_edge [(orig+nro) MODULO QUAD4];
159 else if (q_vertex [nsm1] == v2)
161 for (int nro=0 ; nro < QUAD4 ; nro++)
163 tv1 [nro] = q_vertex [(orig+QUAD4-nro) MODULO QUAD4];
164 te1 [nro] = q_edge [(orig+QUAD4-nro) MODULO QUAD4];
172 // ======================================================== ordoVertex
173 int Quad::ordoVertex (Vertex* v1, Vertex* v2, Vertex* tv1[])
176 for (int nro=0 ; orig == NOTHING && nro < QUAD4 ; nro++)
177 if (q_vertex [nro] == v1)
183 int nsp1 = (orig+1) MODULO QUAD4;
184 int nsm1 = (orig+QUAD4-1) MODULO QUAD4;
186 if (q_vertex [nsp1] == v2)
188 for (int nro=0 ; nro < QUAD4 ; nro++)
189 tv1 [nro] = q_vertex [(orig+nro) MODULO QUAD4];
191 else if (q_vertex [nsm1] == v2)
193 for (int nro=0 ; nro < QUAD4 ; nro++)
194 tv1 [nro] = q_vertex [(orig+QUAD4-nro) MODULO QUAD4];
201 // ======================================================== getBrother
202 Quad* Quad::getBrother (StrOrient* orient)
204 /* *****************************
205 printf (" getBrother ");
207 printf (" .. Base : ");
208 orient->v21->printName();
209 orient->v22->printName();
210 printf ("dir=%d, arete=", orient->dir);
211 ***************************** */
213 int n21 = indexVertex (orient->v21);
214 int n22 = indexVertex (orient->v22);
216 int sens = n22 - n21;
217 if (sens > 1) sens -= QUAD4;
218 if (sens < -1) sens += QUAD4;
219 if (sens*sens !=1) return NULL;
223 case OR_LEFT : n22 = n21 - sens;
225 case OR_RIGHT : n21 = n22 + sens;
227 case OR_FRONT : n21 += 2;
233 n21 = (n21 + QUAD4) MODULO QUAD4;
234 n22 = (n22 + QUAD4) MODULO QUAD4;
236 orient->v21 = q_vertex [n21];
237 orient->v22 = q_vertex [n22];
239 Edge* arete = findEdge (orient->v21, orient->v22);
240 // arete->printName("\n");
242 int nbfreres = arete->getNbrParents ();
244 for (int nq = 0 ; nq < nbfreres ; nq++)
246 Quad* next = arete->getParent (nq);
247 if (next!=NULL && next != this )
249 int nbp = next->getNbrParents();
250 Hexa* dad = next->getParent(0);
251 int mark = next->getMark();
252 int mark2 = dad ? dad->getMark() : IS_NONE;
254 if (nbp <= 1 && mark2 != IS_MARRIED && mark == IS_NONE)
256 // if (nbp <= 1 && mark == IS_NONE)
262 // ======================================================== coupler
263 int Quad::coupler (Quad* other, StrOrient* orient, Elements* table)
268 Hexa* hexa = other->getParent(0);
270 setMark (IS_MARRIED);
271 other->setMark (IS_MARRIED);
273 hexa->setMark (IS_MARRIED);
275 for (int ned = 0 ; ned < QUAD4 ; ned++)
277 Edge* arete = q_edge[ned];
278 int nbfreres = arete ->getNbrParents ();
279 for (int nq = 0 ; nq < nbfreres ; nq++)
281 Quad* next = arete->getParent (nq);
282 if (next!=NULL && next != this && next->getMark() > 0)
284 StrOrient new_ori (orient);
285 new_ori.dir = OR_FRONT;
286 Vertex* va = arete->getVertex (V_AMONT);
287 Vertex* vb = arete->getVertex (V_AVAL);
289 // On voit si un point de repere est conserve
290 if (va == orient->v11)
293 new_ori.dir += OR_LEFT;
295 else if (vb == orient->v11)
298 new_ori.dir += OR_LEFT;
301 if (va == orient->v12)
304 new_ori.dir += OR_RIGHT;
306 else if (vb == orient->v12)
309 new_ori.dir += OR_RIGHT;
312 if (new_ori.dir == OR_FRONT)
314 if (definedBy (va, orient->v11))
326 int nro = next->getMark ();
327 Quad* beauf = other->getBrother (&new_ori);
328 int ier = table->coupler (nro, beauf, &new_ori);
331 ier = next->coupler (beauf, &new_ori, table);
339 // ======================================================== getOpposVertex
340 Vertex* Quad::getOpposVertex (Vertex* start)
342 int na = indexVertex (start);
345 return q_vertex [(na+2) MODULO QUAD4];
347 // ======================================================== getOpposEdge
348 Edge* Quad::getOpposEdge (Edge* start, int& sens)
351 int na = indexVertex (start->getVertex (V_AMONT));
352 int nb = indexVertex (start->getVertex (V_AVAL));
354 Vertex* vaprim = q_vertex [(nb+2) MODULO QUAD4];
355 Vertex* vbprim = q_vertex [(na+2) MODULO QUAD4];
357 for (int ned = 0 ; ned < QUAD4 ; ned++)
359 if ( q_edge[ned]->getVertex(V_AMONT) == vaprim
360 && q_edge[ned]->getVertex(V_AVAL ) == vbprim)
365 else if ( q_edge[ned]->getVertex(V_AMONT) == vbprim
366 && q_edge[ned]->getVertex(V_AVAL ) == vaprim)
372 // TODO : traiter l'erreur
373 cout << " ... Probleme dans Quad::getOpposedEdge :" << endl;
381 for (int ned = 0 ; ned < QUAD4 ; ned++)
386 // ========================================================= saveXml
387 void Quad::saveXml (XmlWriter* xml)
392 for (int nro=0 ; nro<QUAD4 ; nro++)
394 if (nro>0) edges += " ";
395 edges += q_edge[nro]->getName(buffer);
398 xml->openMark ("Quad");
399 xml->addAttribute ("id", getName (buffer));
400 xml->addAttribute ("edges", edges);
402 xml->addAttribute ("name", el_name);
405 int nbass = tab_assoc.size();
406 for (int nro=0 ; nro<nbass ; nro++)
407 if (tab_assoc[nro] != NULL)
408 tab_assoc[nro]->saveXml (xml);
410 // ======================================================== replaceEdge
411 void Quad::replaceEdge (Edge* old, Edge* par)
413 for (int nro=0 ; nro<QUAD4 ; nro++)
415 if (q_edge[nro]==old)
422 printf (" [%d], ", nro);
423 old->printName (" est remplace par ");
424 par->printName ("\n");
429 // ======================================================== replaceVertex
430 void Quad::replaceVertex (Vertex* old, Vertex* par)
432 for (int nro=0 ; nro<QUAD4 ; nro++)
434 if (q_vertex [nro]==old)
436 q_vertex [nro] = par;
441 printf (" [%d], ", nro);
442 old->printName (" est remplace par ");
443 par->printName ("\n");
448 // ======================================================== dump
454 printf ("*** deleted ***)\n");
458 for (int nro=0 ; nro<QUAD4 ; nro++)
459 PrintName (q_edge[nro]);
463 for (int nro=0 ; nro<QUAD4 ; nro++)
464 PrintName (q_vertex[nro]);
469 // ======================================================== dumpPlus
470 void Quad::dumpPlus ()
476 for (int nro=0 ; nro < QUAD4 ; nro++)
478 Vertex* pv = q_vertex[nro];
483 printf ( " (%g, %g, %g)\n", pv->getX(), pv->getY(), pv->getZ());
491 // ======================================================== getOpposEdge (2)
492 Edge* Quad::getOpposEdge (Edge* start)
494 int na = indexEdge (start);
497 return q_edge [(na+2) MODULO QUAD4];
499 // ======================================================== getPerpendicular
500 Edge* Quad::getPerpendicular (Edge* arete, Vertex* node)
502 int na = indexEdge (arete);
506 int nv = arete->index (node);
509 Edge* perp = q_edge [(na+1) MODULO QUAD4];
511 nv = perp->index (node);
515 perp = q_edge [(na+3) MODULO QUAD4];
516 nv = perp->index (node);
522 static cpchar t_ori[] = {"Q_INSIDE", "Q_DIRECT", "Q_INVERSE", "Q_UNDEF"};
523 // ======================================================== setOrientation
524 void Quad::setOrientation (int ori)
527 if (ori==Q_DIRECT || ori==Q_INVERSE)
528 printf (" %s = %s\n", el_name.c_str(), t_ori [ q_orientation ]);
530 // ======================================================== setOrientation
531 int Quad::setOrientation ()
533 q_orientation = Q_INSIDE;
534 if (getNbrParents() != 1)
535 return q_orientation;
537 Real3 cg, orig, pi, pj, vi, vj, vk;
539 Hexa* hexa = getParent(0);
540 hexa->getCenter (cg);
542 /********************************************************************
545 for (int np=0 ; np < QUAD4 ; np++)
547 q_vertex [np ] -> getPoint (orig);
548 q_vertex [(np+1) % 4] -> getPoint (pi);
549 q_vertex [(np+3) % 4] -> getPoint (pj);
551 calc_vecteur (orig, pi, vi);
552 calc_vecteur (orig, pj, vj);
553 calc_vecteur (orig, cg, vk);
554 double pmixte = prod_mixte (vi, vj, vk);
555 q_orientation = pmixte > ZEROR ? Q_DIRECT : Q_INVERSE;
556 if (pmixte>0) printf (">");
562 ******************************************************************* */
563 q_vertex [0] -> getPoint (orig);
564 q_vertex [1] -> getPoint (pi);
565 q_vertex [3] -> getPoint (pj);
567 calc_vecteur (orig, pi, vi);
568 calc_vecteur (orig, pj, vj);
569 calc_vecteur (cg, orig, vk);
571 double pmixte = prod_mixte (vi, vj, vk);
572 q_orientation = pmixte > ZEROR ? Q_DIRECT : Q_INVERSE;
573 printf (" %s = %s\n", el_name.c_str(), t_ori [ q_orientation ]);
574 return q_orientation;
576 // ========================================================== setAssociation
577 void Quad::setAssociation (Shape* forme)
580 addAssociation (forme);