2
* vim: ts=4 sw=4 et tw=0 wm=0
4
* libavoid - Fast, Incremental, Object-avoiding Line Router
5
* Copyright (C) 2004-2006 Michael Wybrow <mjwybrow@users.sourceforge.net>
7
* This library is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Lesser General Public
9
* License as published by the Free Software Foundation; either
10
* version 2.1 of the License, or (at your option) any later version.
12
* This library is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with this library; if not, write to the Free Software
19
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23
#include "libavoid/vertices.h"
24
#include "libavoid/geometry.h"
25
#include "libavoid/graph.h" // For alertConns
26
#include "libavoid/debug.h"
27
#include "libavoid/router.h"
44
VertID::VertID(unsigned int id, bool s, int n)
52
VertID::VertID(const VertID& other)
54
, isShape(other.isShape)
60
VertID& VertID::operator= (const VertID& rhs)
62
// Gracefully handle self assignment
63
//if (this == &rhs) return *this;
66
isShape = rhs.isShape;
73
bool VertID::operator==(const VertID& rhs) const
75
if ((objID != rhs.objID) || (vn != rhs.vn))
79
assert(isShape == rhs.isShape);
84
bool VertID::operator!=(const VertID& rhs) const
86
if ((objID != rhs.objID) || (vn != rhs.vn))
90
assert(isShape == rhs.isShape);
95
bool VertID::operator<(const VertID& rhs) const
97
if ((objID < rhs.objID) ||
98
((objID == rhs.objID) && (vn < rhs.vn)))
106
VertID VertID::operator+(const int& rhs) const
108
return VertID(objID, isShape, vn + rhs);
112
VertID VertID::operator-(const int& rhs) const
114
return VertID(objID, isShape, vn - rhs);
118
VertID& VertID::operator++(int)
125
void VertID::print(FILE *file) const
127
fprintf(file, "[%u,%d]", objID, vn);
130
void VertID::db_print(void) const
132
db_printf("[%u,%d]", objID, vn);
136
const int VertID::src = 1;
137
const int VertID::tar = 2;
140
ostream& operator<<(ostream& os, const VertID& vID)
142
return os << '[' << vID.objID << ',' << vID.vn << ']';
147
VertInf::VertInf(Router *router, const VertID& vid, const Point& vpoint)
163
void VertInf::Reset(const Point& vpoint)
169
void VertInf::removeFromGraph(const bool isConnVert)
173
assert(!(id.isShape));
179
EdgeInfList& visList = tmp->visList;
180
EdgeInfList::iterator finish = visList.end();
181
EdgeInfList::iterator edge;
182
while ((edge = visList.begin()) != finish)
184
// Remove each visibility edge
185
(*edge)->alertConns();
189
EdgeInfList& invisList = tmp->invisList;
190
finish = invisList.end();
191
while ((edge = invisList.begin()) != finish)
193
// Remove each invisibility edge
199
bool directVis(VertInf *src, VertInf *dst)
201
ShapeSet ss = ShapeSet();
203
Point& p = src->point;
204
Point& q = dst->point;
206
VertID& pID = src->id;
207
VertID& qID = dst->id;
209
// We better be part of the same instance of libavoid.
210
Router *router = src->_router;
211
assert(router == dst->_router);
213
ContainsMap& contains = router->contains;
216
ss.insert(contains[pID].begin(), contains[pID].end());
220
ss.insert(contains[qID].begin(), contains[qID].end());
223
// The "beginning" should be the first shape vertex, rather
224
// than an endpoint, which are also stored in "vertices".
225
VertInf *endVert = router->vertices.end();
226
for (VertInf *k = router->vertices.shapesBegin(); k != endVert;
229
if ((ss.find(k->id.objID) == ss.end()))
231
if (segmentIntersect(p, q, k->point, k->shNext->point))
241
VertInfList::VertInfList()
242
: _firstShapeVert(NULL)
243
, _firstConnVert(NULL)
244
, _lastShapeVert(NULL)
245
, _lastConnVert(NULL)
252
#define checkVertInfListConditions() \
254
assert((!_firstConnVert && (_connVertices == 0)) || \
255
((_firstConnVert->lstPrev == NULL) && (_connVertices > 0))); \
256
assert((!_firstShapeVert && (_shapeVertices == 0)) || \
257
((_firstShapeVert->lstPrev == NULL) && (_shapeVertices > 0))); \
258
assert(!_lastShapeVert || (_lastShapeVert->lstNext == NULL)); \
259
assert(!_lastConnVert || (_lastConnVert->lstNext == _firstShapeVert)); \
260
assert((!_firstConnVert && !_lastConnVert) || \
261
(_firstConnVert && _lastConnVert) ); \
262
assert((!_firstShapeVert && !_lastShapeVert) || \
263
(_firstShapeVert && _lastShapeVert) ); \
264
assert(!_firstShapeVert || _firstShapeVert->id.isShape); \
265
assert(!_lastShapeVert || _lastShapeVert->id.isShape); \
266
assert(!_firstConnVert || !(_firstConnVert->id.isShape)); \
267
assert(!_lastConnVert || !(_lastConnVert->id.isShape)); \
271
void VertInfList::addVertex(VertInf *vert)
273
checkVertInfListConditions();
274
assert(vert->lstPrev == NULL);
275
assert(vert->lstNext == NULL);
277
if (!(vert->id.isShape))
279
// A Connector vertex
282
// Join with previous front
283
vert->lstNext = _firstConnVert;
284
_firstConnVert->lstPrev = vert;
287
_firstConnVert = vert;
291
// Make front and back
292
_firstConnVert = vert;
293
_lastConnVert = vert;
295
// Link to front of shapes list
296
vert->lstNext = _firstShapeVert;
300
else // if (vert->id.shape > 0)
305
// Join with previous back
306
vert->lstPrev = _lastShapeVert;
307
_lastShapeVert->lstNext = vert;
310
_lastShapeVert = vert;
314
// Make first and last
315
_firstShapeVert = vert;
316
_lastShapeVert = vert;
318
// Join with conns list
321
assert (_lastConnVert->lstNext == NULL);
323
_lastConnVert->lstNext = vert;
328
checkVertInfListConditions();
332
void VertInfList::removeVertex(VertInf *vert)
334
// Conditions for correct data structure
335
checkVertInfListConditions();
337
if (!(vert->id.isShape))
339
// A Connector vertex
340
if (vert == _firstConnVert)
343
if (vert == _lastConnVert)
345
_firstConnVert = NULL;
346
_lastConnVert = NULL;
351
_firstConnVert = _firstConnVert->lstNext;
356
_firstConnVert->lstPrev = NULL;
360
else if (vert == _lastConnVert)
363
_lastConnVert = _lastConnVert->lstPrev;
365
// Make last point to shapes list
366
_lastConnVert->lstNext = _firstShapeVert;
370
vert->lstNext->lstPrev = vert->lstPrev;
371
vert->lstPrev->lstNext = vert->lstNext;
375
else // if (vert->id.shape > 0)
378
if (vert == _lastShapeVert)
381
_lastShapeVert = _lastShapeVert->lstPrev;
383
if (vert == _firstShapeVert)
385
_firstShapeVert = NULL;
388
_lastConnVert->lstNext = NULL;
394
_lastShapeVert->lstNext = NULL;
397
else if (vert == _firstShapeVert)
400
_firstShapeVert = _firstShapeVert->lstNext;
402
// Correct the last conn vertex
405
_lastConnVert->lstNext = _firstShapeVert;
410
_firstShapeVert->lstPrev = NULL;
415
vert->lstNext->lstPrev = vert->lstPrev;
416
vert->lstPrev->lstNext = vert->lstNext;
420
vert->lstPrev = NULL;
421
vert->lstNext = NULL;
423
checkVertInfListConditions();
427
VertInf *VertInfList::shapesBegin(void)
429
return _firstShapeVert;
433
VertInf *VertInfList::connsBegin(void)
437
return _firstConnVert;
439
// No connector vertices
440
return _firstShapeVert;
444
VertInf *VertInfList::end(void)