Version: 9.16.0
LinkMatrix.cxx
Go to the documentation of this file.
1// Copyright (C) 2006-2026 CEA, EDF
2//
3// This library is free software; you can redistribute it and/or
4// modify it under the terms of the GNU Lesser General Public
5// License as published by the Free Software Foundation; either
6// version 2.1 of the License, or (at your option) any later version.
7//
8// This library is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11// Lesser General Public License for more details.
12//
13// You should have received a copy of the GNU Lesser General Public
14// License along with this library; if not, write to the Free Software
15// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16//
17// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18//
19
20#include "LinkMatrix.hxx"
21#include "Scene.hxx"
24#include "SceneHeaderItem.hxx"
26#include "SceneCtrlPortItem.hxx"
27#include "SceneLinkItem.hxx"
28#include "QtGuiContext.hxx"
29#include "InPort.hxx"
30#include "OutPort.hxx"
31#include "Resource.hxx"
32
33#include <cmath>
34
35//#define _DEVDEBUG_
36#include "YacsTrace.hxx"
37
38using namespace std;
39using namespace YACS::ENGINE;
40using namespace YACS::HMI;
41
42double LNode::distance(const LNode& o) const
43{
44 int dx = _x -o._x;
45 int dy = _y -o._y;
46 return sqrt(double(dx*dx +dy*dy));
47}
48
49
51{
52 _im=0;
53 _jm=0;
54 _pas=10;
55 _sxm.clear();
56 _sym.clear();
57 _xm.clear();
58 _ym.clear();
59 _x2i.clear();
60 _y2j.clear();
61 _cost.clear();
63}
64
66{
67}
68
70{
72 explore(_bloc); // --- define the boundaries _xm[i] and _ym[j]
74 _im = _sxm.size();
75 _xm.resize(_im);
76 DEBTRACE("_sxm.size()=" << _im);
77 int i =0;
78 for(std::set<double>::iterator it = _sxm.begin(); it != _sxm.end(); ++it)
79 {
80 _xm[i] = *it;
81 _x2i[*it] = i;
82 DEBTRACE("_xm[" << i << "] = " << _xm[i]);
83 i++;
84 }
85 _jm = _sym.size();
86 _ym.resize(_jm);
87 DEBTRACE("_sym.size()=" << _jm);
88 i =0;
89 for(std::set<double>::iterator it = _sym.begin(); it != _sym.end(); ++it)
90 {
91 _ym[i] = *it;
92 _y2j[*it] = i;
93 DEBTRACE("_ym[" << i << "] = " << _ym[i]);
94 i++;
95 }
96 _cost.resize(_im*_jm);
97 for (int ij=0; ij < _im*_jm; ij++)
98 _cost[ij] = 1; // --- set the _cost matrix open everywhere (no obstacles)
99 explore(_bloc, true); // --- fill the cells cost(i,j) with obstacles
100
101 for (int j=0; j<_jm; j++)
102 {
103 char* m = new char[_im+1];
104 for (int i=0; i<_im; i++)
105 if (cost(i,j))
106 m[i] = ' ';
107 else
108 m[i] = 'X';
109 m[_im] = 0;
110 DEBTRACE(m);
111 delete [] m;
112 }
113}
114
116{
118 SceneItem* item = _context->_mapOfSceneItem[subDP];
119 QRectF bb = (item->mapToScene(item->boundingRect())).boundingRect();
120 qreal xp = bb.right();
121 qreal yp = (bb.top() + bb.bottom())*0.5;
122 DEBTRACE("xp,yp:"<<xp<<","<<yp);
123 int ifrom = -1;
124 for (int i=0; i<_im-1; i++)
125 if (_xm[i+1] >= xp && xp > _xm[i])
126 {
127 ifrom = i;
128 break;
129 }
130 int jfrom = -1;
131 for (int j=0; j<_jm-1; j++)
132 if (_ym[j+1] >= yp && yp > _ym[j])
133 {
134 jfrom = j;
135 break;
136 }
137 //if ifrom or jfrom == -1 the port is outside the matrix
138 if(ifrom < 0 || jfrom < 0)return pair<int,int>(ifrom,jfrom);
139 while (ifrom < _im && !cost(ifrom,jfrom)) ifrom++; // --- from point is inside an obstacle
140
141 return pair<int,int>(ifrom,jfrom);
142}
143
145{
146 SubjectNode* subNode = _context->_mapOfSubjectNode[outp->getNode()];
147 SceneNodeItem* itemNode = dynamic_cast<SceneNodeItem*>(_context->_mapOfSceneItem[subNode]);
148 YASSERT(itemNode);
149 SceneHeaderNodeItem* itemHeader = dynamic_cast<SceneHeaderNodeItem*>(itemNode->getHeader());
150 YASSERT(itemHeader);
151 SceneCtrlPortItem *item = itemHeader->getCtrlOutPortItem();
152 YASSERT(item);
153 QRectF bb = (item->mapToScene(item->boundingRect())).boundingRect();
154 qreal xp = bb.right();
155 qreal yp = (bb.top() + bb.bottom())*0.5;
156 DEBTRACE("xp,yp:"<<xp<<","<<yp);
157 int ifrom = -1;
158 for (int i=0; i<_im-1; i++)
159 if (_xm[i+1] >= xp && xp > _xm[i])
160 {
161 ifrom = i;
162 break;
163 }
164 int jfrom = -1;
165 for (int j=0; j<_jm-1; j++)
166 if (_ym[j+1] >= yp && yp > _ym[j])
167 {
168 jfrom = j;
169 break;
170 }
171 //if ifrom or jfrom == -1 the port is outside the matrix
172 if(ifrom < 0 || jfrom < 0)return pair<int,int>(ifrom,jfrom);
173 while (ifrom < _im && !cost(ifrom,jfrom)) ifrom++; // --- from point is inside an obstacle
174
175 return pair<int,int>(ifrom,jfrom);
176}
177
179{
181 SceneItem* item = _context->_mapOfSceneItem[subDP];
182 QRectF bb = (item->mapToScene(item->boundingRect())).boundingRect();
183 qreal xp = bb.left();
184 qreal yp = (bb.top() + bb.bottom())*0.5;
185 DEBTRACE("xp,yp:"<<xp<<","<<yp);
186 int ito = -1;
187 for (int i=0; i<_im-1; i++)
188 if (_xm[i+1] >= xp && xp > _xm[i])
189 {
190 ito = i;
191 break;
192 }
193 int jto = -1;
194 for (int j=0; j<_jm-1; j++)
195 if (_ym[j+1] >= yp && yp > _ym[j])
196 {
197 jto = j;
198 break;
199 }
200 //if ito or jto == -1 the port is outside the matrix
201 if(ito < 0 || jto < 0)return pair<int,int>(ito,jto);
202 while (ito >0 && !cost(ito,jto)) ito--; // --- to point is inside an obstacle
203
204 return pair<int,int>(ito,jto);
205}
206
208{
209 SubjectNode* subNode = _context->_mapOfSubjectNode[inp->getNode()];
210 SceneNodeItem* itemNode = dynamic_cast<SceneNodeItem*>(_context->_mapOfSceneItem[subNode]);
211 YASSERT(itemNode);
212 SceneHeaderNodeItem* itemHeader = dynamic_cast<SceneHeaderNodeItem*>(itemNode->getHeader());
213 YASSERT(itemHeader);
214 SceneCtrlPortItem *item = itemHeader->getCtrlInPortItem();
215 YASSERT(item);
216 QRectF bb = (item->mapToScene(item->boundingRect())).boundingRect();
217 qreal xp = bb.left();
218 qreal yp = (bb.top() + bb.bottom())*0.5;
219 DEBTRACE("xp,yp:"<<xp<<","<<yp);
220 int ito = -1;
221 for (int i=0; i<_im-1; i++)
222 if (_xm[i+1] >= xp && xp > _xm[i])
223 {
224 ito = i;
225 break;
226 }
227 int jto = -1;
228 for (int j=0; j<_jm-1; j++)
229 if (_ym[j+1] >= yp && yp > _ym[j])
230 {
231 jto = j;
232 break;
233 }
234 //if ito or jto == -1 the port is outside the matrix
235 if(ito < 0 || jto < 0)return pair<int,int>(ito,jto);
236 while (ito > 0 && !cost(ito,jto)) ito--; // --- to point is inside an obstacle
237
238 return pair<int,int>(ito,jto);
239}
240
242{
243 list<linkdef> alist;
244 map<pair<Node*, Node*>, SubjectControlLink*>::const_iterator it;
245 for (it = _context->_mapOfSubjectControlLink.begin();
246 it != _context->_mapOfSubjectControlLink.end(); ++it)
247 {
248 linkdef ali;
249 pair<Node*, Node*> outin = it->first;
250 SubjectControlLink* sub = it->second;
251 ali.from = cellFrom(outin.first->getOutGate());
252 ali.to = cellTo(outin.second->getInGate());
253 ali.item = dynamic_cast<SceneLinkItem*>(_context->_mapOfSceneItem[sub]);
254 alist.push_back(ali);
255 DEBTRACE("from("<<ali.from.first<<","<<ali.from.second
256 <<") to ("<<ali.to.first<<","<<ali.to.second
257 <<") " << ali.item->getLabel().toStdString());
258 }
259 return alist;
260}
261
263{
264 list<linkdef> alist;
265 map<pair<OutPort*, InPort*>, SubjectLink*>::const_iterator it;
266 for (it = _context->_mapOfSubjectLink.begin();
267 it != _context->_mapOfSubjectLink.end(); ++it)
268 {
269 linkdef ali;
270 pair<OutPort*, InPort*> outin = it->first;
271 SubjectLink* sub = it->second;
272 ali.from = cellFrom(outin.first);
273 ali.to = cellTo(outin.second);
274 ali.item = dynamic_cast<SceneLinkItem*>(_context->_mapOfSceneItem[sub]);
275 alist.push_back(ali);
276 DEBTRACE("from("<<ali.from.first<<","<<ali.from.second
277 <<") to ("<<ali.to.first<<","<<ali.to.second
278 <<") " << ali.item->getLabel().toStdString());
279 }
280 return alist;
281}
282
284{
285 DEBTRACE("LinkMatrix::getPath " << lnp.size());
286 LinkPath lp;
287 lp.clear();
288 int dim = lnp.size();
289 //use a random coefficient between 0.25 and 0.75 to try to separate links
290 double coef=-0.25+rand()%101*0.005;
291 coef=0.5 + coef* Resource::link_separation_weight/10.;
292 LNodePath::const_iterator it = lnp.begin();
293 for (int k=0; k<dim; k++)
294 {
295 int i = it->getX();
296 int j = it->getY();
297 DEBTRACE("i, j: " << i << " " << j << " Xmax, Ymax: " << _im << " " << _jm);
298 linkPoint a;
299
300 if ( (i+1)==_im ) {
301 a.x = _xm[i];
302 } else {
303 a.x = coef*_xm[i] + (1.-coef)*_xm[i+1];
304 };
305
306 if ( (j+1)==_jm ) {
307 a.y = _ym[j];
308 } else {
309 a.y = coef*_ym[j] + (1.-coef)*_ym[j+1];
310 };
311
312 lp.push_back(a);
313 DEBTRACE(a.x << " " << a.y);
314 ++it;
315 }
316 return lp;
317}
318
320{
321 int dim = lnp.size();
322 LNodePath::const_iterator it = lnp.begin();
323 for (; it != lnp.end(); ++it)
324 {
325 int i = it->getX();
326 int j = it->getY();
327 int ij = i*_jm +j;
328 _cost[ij] += Resource::link_separation_weight; // --- big cost, because distance is x2+y2
329
330 }
331}
332
333
340void LinkMatrix::explore(AbstractSceneItem *child, bool setObstacle)
341{
342 SceneComposedNodeItem *cnItem = dynamic_cast<SceneComposedNodeItem*>(child);
343 if (cnItem)
344 {
345 SceneHeaderItem *obstacle = cnItem->getHeader();
346 if (obstacle) getBoundingBox(obstacle, 0, setObstacle);
347 list<AbstractSceneItem*> children = cnItem->getChildren();
348 for (list<AbstractSceneItem*>::const_iterator it = children.begin(); it != children.end(); ++it)
349 explore(*it, setObstacle);
350 }
351 SceneElementaryNodeItem *ceItem = dynamic_cast<SceneElementaryNodeItem*>(child);
352 if (ceItem)
353 {
354 getBoundingBox(ceItem, 1, setObstacle);
355 }
356}
357
364void LinkMatrix::getBoundingBox(SceneItem *obstacle, int margin, bool setObstacle)
365{
366 QRectF bb = (obstacle->mapToScene(obstacle->boundingRect())).boundingRect();
367 if (setObstacle)
368 {
369 int imin = _x2i[bb.left() + margin];
370 int imax = _x2i[bb.right() - margin];
371 int jmin = _y2j[bb.top() + margin];
372 int jmax = _y2j[bb.bottom() - margin];
373 DEBTRACE(bb.left() << " " << bb.right() << " " << bb.top() << " " << bb.bottom() );
374 DEBTRACE(imin << " " << imax << " " << jmin << " " << jmax);
375 for (int j=jmin; j<jmax; j++)
376 for (int i=imin; i<imax; i++)
377 {
378 int ij = i*_jm +j;
379 _cost[ij] = 0; // --- obstacle
380 }
381 }
382 else
383 {
384 _sxm.insert(bb.left() + margin);
385 _sxm.insert(bb.right() - margin);
386 _sym.insert(bb.top() + margin);
387 _sym.insert(bb.bottom() - margin);
388 }
389}
390
392{
393 {
394 set<double> sxmCpy = _sxm;
395 if (sxmCpy.empty()) return;
396 set<double>::iterator itx = sxmCpy.begin();
397 double xmin = *itx;
398 double xmax = xmin;
399 itx++;
400 for (; itx != sxmCpy.end(); ++itx)
401 {
402 xmax = *itx;
403 int nbpas = floor((xmax -xmin)/_pas);
404
405 if (nbpas >= 2)
406 {
407 double xpas = (xmax -xmin)/nbpas;
408 for (int i=1; i<nbpas; i++)
409 _sxm.insert(xmin +i*xpas);
410 }
411 xmin = xmax;
412 }
413 }
414 {
415 set<double> symCpy = _sym;
416 if (symCpy.empty()) return;
417 set<double>::iterator ity = symCpy.begin();
418 double ymin = *ity;
419 double ymax = ymin;
420 ity++;
421 for (; ity != symCpy.end(); ++ity)
422 {
423 ymax = *ity;
424 int nbpas = floor((ymax -ymin)/_pas);
425
426 if (nbpas >= 2)
427 {
428 double ypas = (ymax -ymin)/nbpas;
429 for (int i=1; i<nbpas; i++)
430 _sym.insert(ymin +i*ypas);
431 }
432 ymin = ymax;
433 }
434 }
435}
#define YASSERT(val)
YASSERT macro is always defined, used like assert, but throw a YACS::Exception instead of abort.
Definition: YacsTrace.hxx:59
#define DEBTRACE(msg)
Definition: YacsTrace.hxx:31
Node * getNode() const
Definition: Port.hxx:46
virtual QString getLabel()
Definition: SceneItem.cxx:135
std::map< std::pair< YACS::ENGINE::OutPort *, YACS::ENGINE::InPort * >, YACS::HMI::SubjectLink * > _mapOfSubjectLink
Definition: guiContext.hxx:72
std::map< YACS::ENGINE::DataPort *, YACS::HMI::SubjectDataPort * > _mapOfSubjectDataPort
Definition: guiContext.hxx:71
std::map< std::pair< YACS::ENGINE::Node *, YACS::ENGINE::Node * >, YACS::HMI::SubjectControlLink * > _mapOfSubjectControlLink
Definition: guiContext.hxx:73
std::map< YACS::ENGINE::Node *, YACS::HMI::SubjectNode * > _mapOfSubjectNode
Definition: guiContext.hxx:70
std::list< linkdef > getListOfCtrlLinkDef()
Definition: LinkMatrix.cxx:241
SceneComposedNodeItem * _bloc
Definition: LinkMatrix.hxx:103
std::list< linkdef > getListOfDataLinkDef()
Definition: LinkMatrix.cxx:262
std::vector< double > _ym
Definition: LinkMatrix.hxx:110
void getBoundingBox(SceneItem *obstacle, int margin, bool setObstacle=false)
Definition: LinkMatrix.cxx:364
std::pair< int, int > cellTo(YACS::ENGINE::InPort *inp)
Definition: LinkMatrix.cxx:178
LinkMatrix(SceneComposedNodeItem *bloc)
Definition: LinkMatrix.cxx:50
LinkPath getPath(LNodePath lnp)
Definition: LinkMatrix.cxx:283
QtGuiContext * _context
Definition: LinkMatrix.hxx:114
std::vector< int > _cost
Definition: LinkMatrix.hxx:113
std::vector< double > _xm
Definition: LinkMatrix.hxx:109
std::set< double > _sxm
Definition: LinkMatrix.hxx:107
std::map< double, int > _y2j
Definition: LinkMatrix.hxx:112
std::set< double > _sym
Definition: LinkMatrix.hxx:108
void incrementCost(LNodePath lnp)
Definition: LinkMatrix.cxx:319
std::map< double, int > _x2i
Definition: LinkMatrix.hxx:111
void explore(AbstractSceneItem *child, bool setObstacle=false)
Definition: LinkMatrix.cxx:340
std::pair< int, int > cellFrom(YACS::ENGINE::OutPort *outp)
Definition: LinkMatrix.cxx:115
int cost(int i, int j) const
Definition: LinkMatrix.hxx:98
static QtGuiContext * getQtCurrent()
std::map< YACS::HMI::Subject *, YACS::HMI::SceneItem * > _mapOfSceneItem
static int link_separation_weight
Definition: Resource.hxx:267
virtual std::list< AbstractSceneItem * > getChildren()
virtual SceneCtrlPortItem * getCtrlInPortItem()
virtual SceneCtrlPortItem * getCtrlOutPortItem()
virtual QRectF boundingRect() const
Definition: SceneItem.cxx:215
virtual SceneHeaderItem * getHeader()
static bool _addRowCols
Definition: Scene.hxx:40
std::list< LNode > LNodePath
Definition: LinkMatrix.hxx:62
std::list< linkPoint > LinkPath
Definition: LinkMatrix.hxx:77
def distance(node, new_node)
Definition: graph.py:275
YACS::HMI::SceneLinkItem * item
Definition: LinkMatrix.hxx:68
std::pair< int, int > from
Definition: LinkMatrix.hxx:66
std::pair< int, int > to
Definition: LinkMatrix.hxx:67