2 // C++ : Associations dans le document
4 // Copyright (C) 2009-2014 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, or (at your option) any later version.
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 "HexDocument.hxx"
23 #include "HexEdge.hxx"
24 #include "HexQuad.hxx"
25 #include "HexDiagnostics.hxx"
26 #include "HexNewShape.hxx"
27 #include "HexEdgeShape.hxx"
28 #include "HexPropagation.hxx"
34 static bool db = on_debug (); // == getenv ("HEXA_DB") > 0
37 int vertexInLine (Vertex* vfirst, Edges& mline, vector<int> &tsens);
38 // ====================================================== vertexInLine
39 int vertexInLine (Vertex* vfirst, Edges& mline, vector<int> &tsens)
41 int nbseg = mline.size ();
43 for (int ned = 0 ; ned<nbseg ; ned++)
45 if (tsens [ned] == V_TWO)
46 for (int ns=V_AMONT; ns<=V_AVAL ; ns++)
48 if (mline[ned]->getVertex (ns) == vfirst)
58 // ====================================================== clearAssociation
59 void Document::clearAssociation ()
65 // ====================================================== clearAssociation (t)
66 int Document::clearAssociation (EnumElt type)
79 default : return HERR;
84 // ====================================================== clearAssoVertices
85 void Document::clearAssoVertices ()
87 for (EltBase* elt = doc_first_elt[EL_VERTEX]->next (); elt!=NULL;
90 Vertex* elem = static_cast <Vertex*> (elt);
92 elem->clearAssociation ();
95 // ====================================================== clearAssoEdges
96 void Document::clearAssoEdges ()
98 for (EltBase* elt = doc_first_elt[EL_EDGE]->next (); elt!=NULL;
101 Edge* elem = static_cast <Edge*> (elt);
102 if (elem->isValid ())
103 elem->clearAssociation ();
106 // ====================================================== clearAssoQuads
107 void Document::clearAssoQuads ()
109 for (EltBase* elt = doc_first_elt[EL_QUAD]->next (); elt!=NULL;
112 Quad* elem = static_cast <Quad*> (elt);
113 if (elem->isValid ())
114 elem->clearAssociation ();
117 // ====================================================== addShape (1)
118 NewShape* Document::addShape (TopoDS_Shape& topo, cpchar name)
120 NewShape* shape = new NewShape (this);
121 doc_tab_shape.push_back (shape);
123 shape->setName (name);
124 shape->setShape (topo);
127 // ====================================================== addShape (2)
128 NewShape* Document::addShape (cpchar name, EnumShape type)
130 NewShape* shape = new NewShape (this, type);
131 doc_tab_shape.push_back (shape);
133 shape->setName (name);
136 // ====================================================== addCloud
137 void Document::addCloud ()
139 doc_cloud = new NewShape (this, SH_CLOUD);
140 doc_cloud->setName ("cloud");
142 doc_tab_shape.push_back (doc_cloud);
144 // ====================================================== getShape
145 NewShape* Document::getShape (int nro)
147 int nbre = doc_tab_shape.size ();
148 if (nro < 0 || nro >= nbre)
151 return doc_tab_shape [nro];
153 // ====================================================== getFirstExplicitShape
154 cpchar Document::getFirstExplicitShape()
156 int nbre = doc_tab_shape.size ();
157 for (int nro=0 ; nro < nbre ; ++nro)
159 NewShape* shape = doc_tab_shape [nro];
160 if (shape!= NULL && shape->getOrigin()==SH_IMPORT)
161 return shape->getBrep ();
166 // ====================================================== findShape
167 NewShape* Document::findShape (rcstring nom)
169 int nbre = doc_tab_shape.size ();
170 for (int nro=0 ; nro<nbre ; ++nro)
171 if (nom == doc_tab_shape [nro]->getName())
172 return doc_tab_shape [nro];
176 // ====================================================== find_line
177 EdgeShape* find_line (EdgeShapes& gline, double* point, int& sens)
179 int nbseg = gline.size ();
181 for (int ned = 0 ; ned<nbseg ; ned++)
183 EdgeShape* edge = gline [ned];
186 sens = edge->onExtremity (point);
196 // ====================================================== find_edge
197 Edge* find_edge (Edges& mline, Vertex* vfirst, int& sens)
199 int nbseg = mline.size ();
201 for (int ned = 0 ; ned<nbseg ; ned++)
203 Edge* edge = mline [ned];
206 sens = edge->index (vfirst);
216 // ====================================================== associateOpenedLine
217 int Document::associateOpenedLine (Edges mline, NewShapes gline,
219 double pstart, double pend)
221 cout << "_________________________________ Asso Open Line"
222 << " ed=" << mline.size()
223 << " sh=" << tabid.size()
225 int ier = associateLine (NULL, mline, gline, tabid, pstart, pend, false);
228 // ====================================================== associateClosedLine
229 int Document::associateClosedLine (Vertex* vfirst, Edges mline,
230 NewShapes gline, IntVector tabid,
231 double pstart, bool inv)
235 putError (W_ASSO_LINE3);
239 cout << "_________________________________ Asso Closed Line"
240 << " first=" << vfirst->getName()
241 << " ed=" << mline.size()
242 << " sh=" << tabid.size()
245 int ier = associateLine (vfirst, mline, gline, tabid, pstart, 1.0, inv);
249 // ====================================================== associateLine
250 int Document::associateLine (Vertex* vfirst, Edges& mline,
251 NewShapes& tshapes, IntVector& subid,
252 double pstart, double pend, bool inv)
256 IntVector gsens, tsens;
259 bool closed = vfirst!=NULL;
260 int ier = sortShapes (tshapes, subid, closed, inv, pstart, pend,
261 glines, gsens, lgtotale);
265 ier = sortEdges (vfirst, mline, tedges, tsens);
269 int nbedges = tedges.size();
270 int nblines = glines.size();
272 EdgeShape* gstart = glines [0];
273 EdgeShape* gend = glines [nblines-1];
274 bool boucle = closed && nblines==1;
276 double abstart = inv ? (1-pstart) : pstart;
279 bool rev = gsens [nblines-1]!=0;
280 double abend = rev ? pend : (1-pend);
281 lgtotale = lgtotale - abstart * gstart->getLength()
282 - abend * gend ->getLength();
286 gstart->getPoint (pstart, point);
287 int vsid = doc_cloud->addPoint (point);
288 Vertex* node = tedges[0]->getVertex (tsens[0]);
289 node->setAssociation (doc_cloud, vsid);
291 double lgedge = lgtotale/nbedges;
292 double smax = gstart->getLength()*(1-abstart);
293 double emax = lgedge;
294 double pdeb = pstart;
300 while (ned < nbedges && nsh < nblines)
302 EdgeShape* shape = glines [nsh];
303 Edge* edge = tedges [ned];
304 bool grev = gsens [nsh]==1;
305 bool av_shape = smax < emax + tol;
306 bool av_edge = emax < smax + tol;
307 bool vassoc = av_edge && NOT (closed && ned == nbedges-1);
309 double lgshape = shape->getLength ();
311 double abscisse = std::min (emax, smax);
312 double decal = (abscisse-ablast) / lgshape;
316 if (pfin < 0.0) pfin = 0;
321 if (pfin > 1.0) pfin = 1;
324 edge->addAssociation (shape, pdeb, pfin);
328 shape->getPoint (pfin, point);
329 vsid = doc_cloud->addPoint (point);
330 node = edge ->getVertex (1-tsens[ned]);
332 node->setAssociation (doc_cloud, vsid);
336 // On incremente les edges
342 // On incremente les shapes
347 smax = shape->getLength ();
352 smax += glines[nsh]->getLength();
359 // ====================================================== sortShapes
360 int Document::sortShapes (NewShapes& tshapes, IntVector& subid, bool closed,
361 bool inv, double pstart, double pend,
362 EdgeShapes& glines, IntVector& gsens, double& lgtotale)
365 int nblines = subid.size ();
366 int nombre = tshapes.size ();
368 if (nblines==0 || nombre==0)
371 if (nombre != 1 && nombre != nblines)
374 for (int ns = 0 ; ns < nombre ; ns++)
376 if (tshapes[ns] == NULL)
378 sprintf (cnum, "%d", ns);
379 putError (W_ASSO_LINE5, cnum);
384 NewShape* geom = tshapes [0];
385 EdgeShapes buf_lines;
388 for (int ns = 0 ; ns < nblines ; ns++)
392 EdgeShape* shape = geom->findEdge (subid[ns]);
395 sprintf (cnum, "%d", ns);
396 putError (W_ASSO_LINE5, cnum);
399 buf_lines.push_back (shape);
403 EdgeShape* gnext = buf_lines[0];
405 int reste = nblines - 1;
408 lgtotale = gnext->getLength();
409 glines.push_back (gnext);
410 gsens .push_back (inv);
412 for (int nro = 0 ; nro < reste ; nro++)
414 double param = 1-rev;
415 gnext->getPoint (param, pnext);
416 gnext = find_line (buf_lines, pnext, rev);
419 lgtotale += gnext->getLength();
420 glines.push_back (gnext);
421 gsens .push_back (rev);
426 EdgeShape* gfirst = glines[0];
427 gfirst->getPoint (1-inv, pnext);
428 int ext = gnext->onExtremity (pnext);
434 // ====================================================== sortEdges
435 int Document::sortEdges (Vertex* vfirst, Edges& mline, Edges& tab_edge,
439 bool closed = vfirst!=NULL;
441 int nbedges = mline.size ();
445 Edge* mstart = mline[0]; // Coherence ancienne version
447 // Le vertex de depart n'appartient pas a l'edge de depart
448 int istart = mstart->index (vfirst);
449 if (closed && istart == NOTHING)
451 putError (W_ASSO_LINE2, vfirst->getName());
458 for (int nro = 0 ; nro < nbedges ; nro++)
460 Edge* edge = mline[nro];
463 sprintf (cnum, "%d", nro);
464 putError (W_ASSO_LINE5, cnum);
467 buf_edge.push_back (edge);
470 Vertex* vnext = NULL;
471 Edge* enext = mstart;
473 int reste = nbedges - 1;
474 tab_edge.push_back (mstart);
479 tab_sens.push_back (istart);
484 vnext = mstart->getVertex (1-istart);
485 enext = find_edge (buf_edge, vnext, sens);
489 vnext = mstart->getVertex (1-istart);
490 enext = find_edge (buf_edge, vnext, sens);
494 tab_sens.push_back (istart);
495 tab_edge.push_back (enext);
496 tab_sens.push_back (sens);
500 for (int nro = 0 ; nro < reste ; nro++)
502 vnext = enext->getVertex (1 - sens);
503 enext = find_edge (buf_edge, vnext, sens);
506 tab_edge.push_back (enext);
507 tab_sens.push_back (sens);
510 istart = tab_edge [nbedges-1]->index (vfirst);
511 if (closed && istart == NOTHING)
513 putError (W_ASSO_LINE2, vfirst->getName());
519 // ====================================================== checkAssociations
520 int Document::checkAssociations ()
522 int nombre = countUsedEdge();
524 for (int ned=0 ; ned<nombre ; ++ned)
526 Edge* edge = getUsedEdge (ned);
527 int ier = edge->checkAssociation ();
528 if (ier != HOK) nberrors ++;
531 cout << " ... Check edges assotiations : " << nberrors
532 << " error(s)." << endl;
534 if (nberrors>0) return HERR;
537 // ====================================================== addLaws
538 int Document::addLaws (double lgmoy, bool usemax)
540 const double Epsilon = 1e-6;
541 const double Precision = 1e-2;
542 const double BigNumber = 1e+36;
544 std::map <int, Law*> existing_law;
545 std::map <int, Law*> :: iterator iter;
550 int nbprop = countPropagation();
551 for (int np=0 ; np<nbprop ; ++np)
553 Propagation* prop = getPropagation (np);
554 const Edges& tab_edges = prop->getEdges ();
555 double lgref = usemax ? 0 : BigNumber;
556 int nbedges = tab_edges.size();
557 for (int ned=0 ; ned<nbedges ; ++ned)
559 Edge* edge = tab_edges [ned];
560 double lg = edge->getAssoLen ();
562 lgref = std::max (lgref, lg);
564 lgref = std::min (lgref, lg);
566 lgref = lgref / lgmoy;
567 int nbcut = (int) lgref;
568 double delta = lgref - (double) nbcut;
569 if (NOT usemax || (delta < Precision))
572 iter = existing_law.find (nbcut);
573 if (iter == existing_law.end())
576 sprintf (name, "u_%02d", nbcut);
577 existing_law [nbcut] = addLaw (name, nbcut);
579 prop->setLaw (existing_law [nbcut]);