2 // C++ : Associations dans le document
4 // Copyright (C) 2009-2013 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/
21 // or email : webmaster.salome@opencascade.com
23 #include "HexDocument.hxx"
24 #include "HexEdge.hxx"
25 #include "HexQuad.hxx"
26 #include "HexDiagnostics.hxx"
27 #include "HexNewShape.hxx"
28 #include "HexEdgeShape.hxx"
29 #include "HexPropagation.hxx"
35 static bool db = on_debug (); // == getenv ("HEXA_DB") > 0
38 int vertexInLine (Vertex* vfirst, Edges& mline, vector<int> &tsens);
39 // ====================================================== vertexInLine
40 int vertexInLine (Vertex* vfirst, Edges& mline, vector<int> &tsens)
42 int nbseg = mline.size ();
44 for (int ned = 0 ; ned<nbseg ; ned++)
46 if (tsens [ned] == V_TWO)
47 for (int ns=V_AMONT; ns<=V_AVAL ; ns++)
49 if (mline[ned]->getVertex (ns) == vfirst)
59 // ====================================================== clearAssociation
60 void Document::clearAssociation ()
66 // ====================================================== clearAssociation (t)
67 int Document::clearAssociation (EnumElt type)
80 default : return HERR;
85 // ====================================================== clearAssoVertices
86 void Document::clearAssoVertices ()
88 for (EltBase* elt = doc_first_elt[EL_VERTEX]->next (); elt!=NULL;
91 Vertex* elem = static_cast <Vertex*> (elt);
93 elem->clearAssociation ();
96 // ====================================================== clearAssoEdges
97 void Document::clearAssoEdges ()
99 for (EltBase* elt = doc_first_elt[EL_EDGE]->next (); elt!=NULL;
102 Edge* elem = static_cast <Edge*> (elt);
103 if (elem->isValid ())
104 elem->clearAssociation ();
107 // ====================================================== clearAssoQuads
108 void Document::clearAssoQuads ()
110 for (EltBase* elt = doc_first_elt[EL_QUAD]->next (); elt!=NULL;
113 Quad* elem = static_cast <Quad*> (elt);
114 if (elem->isValid ())
115 elem->clearAssociation ();
118 // ====================================================== addShape (1)
119 NewShape* Document::addShape (TopoDS_Shape& topo, cpchar name)
121 NewShape* shape = new NewShape (this);
122 doc_tab_shape.push_back (shape);
124 shape->setName (name);
125 shape->setShape (topo);
128 // ====================================================== addShape (2)
129 NewShape* Document::addShape (cpchar name, EnumShape type)
131 NewShape* shape = new NewShape (this, type);
132 doc_tab_shape.push_back (shape);
134 shape->setName (name);
137 // ====================================================== addCloud
138 void Document::addCloud ()
140 doc_cloud = new NewShape (this, SH_CLOUD);
141 doc_cloud->setName ("cloud");
143 doc_tab_shape.push_back (doc_cloud);
145 // ====================================================== getShape
146 NewShape* Document::getShape (int nro)
148 int nbre = doc_tab_shape.size ();
149 if (nro < 0 || nro >= nbre)
152 return doc_tab_shape [nro];
154 // ====================================================== getFirstExplicitShape
155 cpchar Document::getFirstExplicitShape()
157 int nbre = doc_tab_shape.size ();
158 for (int nro=0 ; nro < nbre ; ++nro)
160 NewShape* shape = doc_tab_shape [nro];
161 if (shape!= NULL && shape->getOrigin()==SH_IMPORT)
162 return shape->getBrep ();
167 // ====================================================== findShape
168 NewShape* Document::findShape (rcstring nom)
170 int nbre = doc_tab_shape.size ();
171 for (int nro=0 ; nro<nbre ; ++nro)
172 if (nom == doc_tab_shape [nro]->getName())
173 return doc_tab_shape [nro];
177 // ====================================================== find_line
178 EdgeShape* find_line (EdgeShapes& gline, double* point, int& sens)
180 int nbseg = gline.size ();
182 for (int ned = 0 ; ned<nbseg ; ned++)
184 EdgeShape* edge = gline [ned];
187 sens = edge->onExtremity (point);
197 // ====================================================== find_edge
198 Edge* find_edge (Edges& mline, Vertex* vfirst, int& sens)
200 int nbseg = mline.size ();
202 for (int ned = 0 ; ned<nbseg ; ned++)
204 Edge* edge = mline [ned];
207 sens = edge->index (vfirst);
217 // ====================================================== associateOpenedLine
218 int Document::associateOpenedLine (Edges mline, NewShapes gline,
220 double pstart, double pend)
222 cout << "_________________________________ Asso Open Line"
223 << " ed=" << mline.size()
224 << " sh=" << tabid.size()
226 int ier = associateLine (NULL, mline, gline, tabid, pstart, pend, false);
229 // ====================================================== associateClosedLine
230 int Document::associateClosedLine (Vertex* vfirst, Edges mline,
231 NewShapes gline, IntVector tabid,
232 double pstart, bool inv)
236 putError (W_ASSO_LINE3);
240 cout << "_________________________________ Asso Closed Line"
241 << " first=" << vfirst->getName()
242 << " ed=" << mline.size()
243 << " sh=" << tabid.size()
246 int ier = associateLine (vfirst, mline, gline, tabid, pstart, 1.0, inv);
250 // ====================================================== associateLine
251 int Document::associateLine (Vertex* vfirst, Edges& mline,
252 NewShapes& tshapes, IntVector& subid,
253 double pstart, double pend, bool inv)
257 IntVector gsens, tsens;
260 bool closed = vfirst!=NULL;
261 int ier = sortShapes (tshapes, subid, closed, inv, pstart, pend,
262 glines, gsens, lgtotale);
266 ier = sortEdges (vfirst, mline, tedges, tsens);
270 int nbedges = tedges.size();
271 int nblines = glines.size();
273 EdgeShape* gstart = glines [0];
274 EdgeShape* gend = glines [nblines-1];
275 bool boucle = closed && nblines==1;
277 double abstart = inv ? (1-pstart) : pstart;
280 bool rev = gsens [nblines-1]!=0;
281 double abend = rev ? pend : (1-pend);
282 lgtotale = lgtotale - abstart * gstart->getLength()
283 - abend * gend ->getLength();
287 gstart->getPoint (pstart, point);
288 int vsid = doc_cloud->addPoint (point);
289 Vertex* node = tedges[0]->getVertex (tsens[0]);
290 node->setAssociation (doc_cloud, vsid);
292 double lgedge = lgtotale/nbedges;
293 double smax = gstart->getLength()*(1-abstart);
294 double emax = lgedge;
295 double pdeb = pstart;
301 while (ned < nbedges && nsh < nblines)
303 EdgeShape* shape = glines [nsh];
304 Edge* edge = tedges [ned];
305 bool grev = gsens [nsh]==1;
306 bool av_shape = smax < emax + tol;
307 bool av_edge = emax < smax + tol;
308 bool vassoc = av_edge && NOT (closed && ned == nbedges-1);
310 double lgshape = shape->getLength ();
312 double abscisse = std::min (emax, smax);
313 double decal = (abscisse-ablast) / lgshape;
317 if (pfin < 0.0) pfin = 0;
322 if (pfin > 1.0) pfin = 1;
325 edge->addAssociation (shape, pdeb, pfin);
329 shape->getPoint (pfin, point);
330 vsid = doc_cloud->addPoint (point);
331 node = edge ->getVertex (1-tsens[ned]);
333 node->setAssociation (doc_cloud, vsid);
337 // On incremente les edges
343 // On incremente les shapes
348 smax = shape->getLength ();
353 smax += glines[nsh]->getLength();
360 // ====================================================== sortShapes
361 int Document::sortShapes (NewShapes& tshapes, IntVector& subid, bool closed,
362 bool inv, double pstart, double pend,
363 EdgeShapes& glines, IntVector& gsens, double& lgtotale)
366 int nblines = subid.size ();
367 int nombre = tshapes.size ();
369 if (nblines==0 || nombre==0)
372 if (nombre != 1 && nombre != nblines)
375 for (int ns = 0 ; ns < nombre ; ns++)
377 if (tshapes[ns] == NULL)
379 sprintf (cnum, "%d", ns);
380 putError (W_ASSO_LINE5, cnum);
385 NewShape* geom = tshapes [0];
386 EdgeShapes buf_lines;
389 for (int ns = 0 ; ns < nblines ; ns++)
393 EdgeShape* shape = geom->findEdge (subid[ns]);
396 sprintf (cnum, "%d", ns);
397 putError (W_ASSO_LINE5, cnum);
400 buf_lines.push_back (shape);
404 EdgeShape* gnext = buf_lines[0];
406 int reste = nblines - 1;
409 lgtotale = gnext->getLength();
410 glines.push_back (gnext);
411 gsens .push_back (inv);
413 for (int nro = 0 ; nro < reste ; nro++)
415 double param = 1-rev;
416 gnext->getPoint (param, pnext);
417 gnext = find_line (buf_lines, pnext, rev);
420 lgtotale += gnext->getLength();
421 glines.push_back (gnext);
422 gsens .push_back (rev);
427 EdgeShape* gfirst = glines[0];
428 gfirst->getPoint (1-inv, pnext);
429 int ext = gnext->onExtremity (pnext);
435 // ====================================================== sortEdges
436 int Document::sortEdges (Vertex* vfirst, Edges& mline, Edges& tab_edge,
440 bool closed = vfirst!=NULL;
442 int nbedges = mline.size ();
446 Edge* mstart = mline[0]; // Coherence ancienne version
448 // Le vertex de depart n'appartient pas a l'edge de depart
449 int istart = mstart->index (vfirst);
450 if (closed && istart == NOTHING)
452 putError (W_ASSO_LINE2, vfirst->getName());
459 for (int nro = 0 ; nro < nbedges ; nro++)
461 Edge* edge = mline[nro];
464 sprintf (cnum, "%d", nro);
465 putError (W_ASSO_LINE5, cnum);
468 buf_edge.push_back (edge);
471 Vertex* vnext = NULL;
472 Edge* enext = mstart;
474 int reste = nbedges - 1;
475 tab_edge.push_back (mstart);
480 tab_sens.push_back (istart);
485 vnext = mstart->getVertex (1-istart);
486 enext = find_edge (buf_edge, vnext, sens);
490 vnext = mstart->getVertex (1-istart);
491 enext = find_edge (buf_edge, vnext, sens);
495 tab_sens.push_back (istart);
496 tab_edge.push_back (enext);
497 tab_sens.push_back (sens);
501 for (int nro = 0 ; nro < reste ; nro++)
503 vnext = enext->getVertex (1 - sens);
504 enext = find_edge (buf_edge, vnext, sens);
507 tab_edge.push_back (enext);
508 tab_sens.push_back (sens);
511 istart = tab_edge [nbedges-1]->index (vfirst);
512 if (closed && istart == NOTHING)
514 putError (W_ASSO_LINE2, vfirst->getName());
520 // ====================================================== checkAssociations
521 int Document::checkAssociations ()
523 int nombre = countUsedEdge();
525 for (int ned=0 ; ned<nombre ; ++ned)
527 Edge* edge = getUsedEdge (ned);
528 int ier = edge->checkAssociation ();
529 if (ier != HOK) nberrors ++;
532 cout << " ... Check edges assotiations : " << nberrors
533 << " error(s)." << endl;
535 if (nberrors>0) return HERR;
538 // ====================================================== addLaws
539 int Document::addLaws (double lgmoy, bool usemax)
541 const double Epsilon = 1e-6;
542 const double Precision = 1e-2;
543 const double BigNumber = 1e+36;
545 std::map <int, Law*> existing_law;
546 std::map <int, Law*> :: iterator iter;
551 int nbprop = countPropagation();
552 for (int np=0 ; np<nbprop ; ++np)
554 Propagation* prop = getPropagation (np);
555 const Edges& tab_edges = prop->getEdges ();
556 double lgref = usemax ? 0 : BigNumber;
557 int nbedges = tab_edges.size();
558 for (int ned=0 ; ned<nbedges ; ++ned)
560 Edge* edge = tab_edges [ned];
561 double lg = edge->getAssoLen ();
563 lgref = std::max (lgref, lg);
565 lgref = std::min (lgref, lg);
567 lgref = lgref / lgmoy;
568 int nbcut = (int) lgref;
569 double delta = lgref - (double) nbcut;
570 if (NOT usemax || (delta < Precision))
573 iter = existing_law.find (nbcut);
574 if (iter == existing_law.end())
577 sprintf (name, "u_%02d", nbcut);
578 existing_law [nbcut] = addLaw (name, nbcut);
580 prop->setLaw (existing_law [nbcut]);