1 // Copyright (C) 2006-2008 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #include "LinkMatrix.hxx"
20 #include "SceneComposedNodeItem.hxx"
21 #include "SceneElementaryNodeItem.hxx"
22 #include "SceneHeaderItem.hxx"
23 #include "SceneLinkItem.hxx"
24 #include "QtGuiContext.hxx"
26 #include "OutPort.hxx"
31 #include "YacsTrace.hxx"
34 using namespace YACS::ENGINE;
35 using namespace YACS::HMI;
37 double LNode::distance(const LNode& o) const
41 return sqrt(double(dx*dx +dy*dy));
45 LinkMatrix::LinkMatrix(SceneComposedNodeItem *bloc): _bloc(bloc)
56 _context = QtGuiContext::getQtCurrent();
59 LinkMatrix::~LinkMatrix()
63 void LinkMatrix::compute()
65 getBoundingBox(_bloc,0);
66 explore(_bloc); // --- define the boundaries _xm[i] and _ym[j]
69 DEBTRACE("_sxm.size()=" << _im);
71 for(std::set<double>::iterator it = _sxm.begin(); it != _sxm.end(); ++it)
75 DEBTRACE("_xm[" << i << "] = " << _xm[i]);
80 DEBTRACE("_sym.size()=" << _jm);
82 for(std::set<double>::iterator it = _sym.begin(); it != _sym.end(); ++it)
86 DEBTRACE("_ym[" << i << "] = " << _ym[i]);
89 _cost.reserve(_im*_jm);
90 for (int ij=0; ij < _im*_jm; ij++)
91 _cost[ij] = 1; // --- set the _cost matrix open everywhere (no obstacles)
92 explore(_bloc, true); // --- fill the cells cost(i,j) with obstacles
94 for (int j=0; j<_jm; j++)
97 for (int i=0; i<_im; i++)
107 std::pair<int,int> LinkMatrix::cellFrom(YACS::ENGINE::OutPort* outp)
109 SubjectDataPort* subDP = _context->_mapOfSubjectDataPort[outp];
110 SceneItem* item = _context->_mapOfSceneItem[subDP];
111 QRectF bb = (item->mapToScene(item->boundingRect())).boundingRect();
112 qreal xp = bb.right();
113 qreal yp = (bb.top() + bb.bottom())*0.5;
115 for (int i=0; i<_im-1; i++)
122 for (int j=0; j<_jm-1; j++)
128 while (!cost(ifrom,jfrom)) ifrom++; // --- from point is inside an obstacle
130 return pair<int,int>(ifrom,jfrom);
133 std::pair<int,int> LinkMatrix::cellFrom(YACS::ENGINE::OutGate* outp)
135 SubjectNode* subNode = _context->_mapOfSubjectNode[outp->getNode()];
136 SceneItem* item = _context->_mapOfSceneItem[subNode];
137 QRectF bb = (item->mapToScene(item->boundingRect())).boundingRect();
138 qreal xp = bb.right();
139 qreal yp = (bb.top() + bb.bottom())*0.5;
141 for (int i=0; i<_im-1; i++)
148 for (int j=0; j<_jm-1; j++)
154 while (!cost(ifrom,jfrom)) ifrom++; // --- from point is inside an obstacle
156 return pair<int,int>(ifrom,jfrom);
159 std::pair<int,int> LinkMatrix::cellTo(YACS::ENGINE::InPort* inp)
161 SubjectDataPort* subDP = _context->_mapOfSubjectDataPort[inp];
162 SceneItem* item = _context->_mapOfSceneItem[subDP];
163 QRectF bb = (item->mapToScene(item->boundingRect())).boundingRect();
164 qreal xp = bb.left();
165 qreal yp = (bb.top() + bb.bottom())*0.5;
167 for (int i=0; i<_im-1; i++)
174 for (int j=0; j<_jm-1; j++)
180 while (!cost(ito,jto)) ito--; // --- from point is inside an obstacle
182 return pair<int,int>(ito,jto);
185 std::pair<int,int> LinkMatrix::cellTo(YACS::ENGINE::InGate* inp)
187 SubjectNode* subNode = _context->_mapOfSubjectNode[inp->getNode()];
188 SceneItem* item = _context->_mapOfSceneItem[subNode];
189 QRectF bb = (item->mapToScene(item->boundingRect())).boundingRect();
190 qreal xp = bb.left();
191 qreal yp = (bb.top() + bb.bottom())*0.5;
193 for (int i=0; i<_im-1; i++)
200 for (int j=0; j<_jm-1; j++)
206 while (!cost(ito,jto)) ito--; // --- from point is inside an obstacle
208 return pair<int,int>(ito,jto);
211 std::list<linkdef> LinkMatrix::getListOfCtrlLinkDef()
214 map<pair<Node*, Node*>, SubjectControlLink*>::const_iterator it;
215 for (it = _context->_mapOfSubjectControlLink.begin();
216 it != _context->_mapOfSubjectControlLink.end(); ++it)
219 pair<Node*, Node*> outin = it->first;
220 SubjectControlLink* sub = it->second;
221 ali.from = cellFrom(outin.first->getOutGate());
222 ali.to = cellTo(outin.second->getInGate());
223 ali.item = dynamic_cast<SceneLinkItem*>(_context->_mapOfSceneItem[sub]);
224 alist.push_back(ali);
225 DEBTRACE("from("<<ali.from.first<<","<<ali.from.second
226 <<") to ("<<ali.to.first<<","<<ali.to.second
227 <<") " << ali.item->getLabel().toStdString());
232 std::list<linkdef> LinkMatrix::getListOfDataLinkDef()
235 map<pair<OutPort*, InPort*>, SubjectLink*>::const_iterator it;
236 for (it = _context->_mapOfSubjectLink.begin();
237 it != _context->_mapOfSubjectLink.end(); ++it)
240 pair<OutPort*, InPort*> outin = it->first;
241 SubjectLink* sub = it->second;
242 ali.from = cellFrom(outin.first);
243 ali.to = cellTo(outin.second);
244 ali.item = dynamic_cast<SceneLinkItem*>(_context->_mapOfSceneItem[sub]);
245 alist.push_back(ali);
246 DEBTRACE("from("<<ali.from.first<<","<<ali.from.second
247 <<") to ("<<ali.to.first<<","<<ali.to.second
248 <<") " << ali.item->getLabel().toStdString());
253 LinkPath LinkMatrix::getPath(LNodePath lnp)
255 DEBTRACE("LinkMatrix::getPath " << lnp.size());
258 int dim = lnp.size();
259 LNodePath::const_iterator it = lnp.begin();
260 for (int k=0; k<dim; k++)
265 a.x = 0.5*(_xm[i] + _xm[i+1]);
266 a.y = 0.5*(_ym[j] + _ym[j+1]);
268 DEBTRACE(a.x << " " << a.y);
274 int LinkMatrix::cost(int i, int j) const
282 * find recursively elementary nodes and node headers and call getBoundingBox on each item.
283 * first pass with setObstacle = false stores the x and y coordinates of the mesh boundaries.
284 * second pass with setObstacle = true fills the mesh with obstacles i.e. elementary nodes or
287 void LinkMatrix::explore(AbstractSceneItem *child, bool setObstacle)
289 SceneComposedNodeItem *cnItem = dynamic_cast<SceneComposedNodeItem*>(child);
292 SceneHeaderItem *obstacle = cnItem->getHeader();
293 if (obstacle) getBoundingBox(obstacle, 0, setObstacle);
294 list<AbstractSceneItem*> children = cnItem->getChildren();
295 for (list<AbstractSceneItem*>::const_iterator it = children.begin(); it != children.end(); ++it)
296 explore(*it, setObstacle);
298 SceneElementaryNodeItem *ceItem = dynamic_cast<SceneElementaryNodeItem*>(child);
301 getBoundingBox(ceItem, 1, setObstacle);
306 * first pass with setObstacle = false stores the x and y coordinates of the mesh boundaries.
307 * second pass with setObstacle = true fills the mesh with obstacles i.e. elementary nodes or
308 * nodeHeaders. For elementary nodes, the bounding box is smaller to let a path between nodes
309 * that are stick together.
311 void LinkMatrix::getBoundingBox(SceneItem *obstacle, int margin, bool setObstacle)
313 QRectF bb = (obstacle->mapToScene(obstacle->boundingRect())).boundingRect();
316 int imin = _x2i[bb.left() + margin];
317 int imax = _x2i[bb.right() - margin];
318 int jmin = _y2j[bb.top() + margin];
319 int jmax = _y2j[bb.bottom() - margin];
320 DEBTRACE(bb.left() << " " << bb.right() << " " << bb.top() << " " << bb.bottom() );
321 DEBTRACE(imin << " " << imax << " " << jmin << " " << jmax);
322 for (int j=jmin; j<jmax; j++)
323 for (int i=imin; i<imax; i++)
326 _cost[ij] = 0; // --- obstacle
331 _sxm.insert(bb.left() + margin);
332 _sxm.insert(bb.right() - margin);
333 _sym.insert(bb.top() + margin);
334 _sym.insert(bb.bottom() - margin);