2
* vim: ts=4 sw=4 et tw=0 wm=0
4
* libavoid - Fast, Incremental, Object-avoiding Line Router
5
* Copyright (C) 2004-2005 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/geometry.h"
24
#include "libavoid/graph.h" // For alertConns
25
#include "libavoid/debug.h"
40
VertID::VertID(unsigned int id, bool s, int n)
48
VertID::VertID(const VertID& other)
50
, isShape(other.isShape)
56
VertID& VertID::operator= (const VertID& rhs)
58
// Gracefully handle self assignment
59
//if (this == &rhs) return *this;
62
isShape = rhs.isShape;
69
bool VertID::operator==(const VertID& rhs) const
71
if ((objID != rhs.objID) || (vn != rhs.vn))
75
assert(isShape == rhs.isShape);
80
bool VertID::operator!=(const VertID& rhs) const
82
if ((objID != rhs.objID) || (vn != rhs.vn))
86
assert(isShape == rhs.isShape);
91
bool VertID::operator<(const VertID& rhs) const
93
if ((objID < rhs.objID) ||
94
((objID == rhs.objID) && (vn < rhs.vn)))
102
VertID VertID::operator+(const int& rhs) const
104
return VertID(objID, isShape, vn + rhs);
108
VertID VertID::operator-(const int& rhs) const
110
return VertID(objID, isShape, vn - rhs);
114
VertID& VertID::operator++(int)
121
void VertID::print(FILE *file) const
123
fprintf(file, "[%u,%d]", objID, vn);
127
void VertID::db_print(void) const
129
db_printf("[%u,%d]", objID, vn);
133
const int VertID::src = 1;
134
const int VertID::tar = 2;
137
VertInf::VertInf(const VertID& vid, const Point& vpoint)
152
void VertInf::Reset(const Point& vpoint)
158
void VertInf::removeFromGraph(const bool isConnVert)
162
assert(!(id.isShape));
168
EdgeInfList& visList = tmp->visList;
169
EdgeInfList::iterator finish = visList.end();
170
EdgeInfList::iterator edge;
171
while ((edge = visList.begin()) != finish)
173
// Remove each visibility edge
174
(*edge)->alertConns();
178
EdgeInfList& invisList = tmp->invisList;
179
finish = invisList.end();
180
while ((edge = invisList.begin()) != finish)
182
// Remove each invisibility edge
188
bool directVis(VertInf *src, VertInf *dst)
190
ShapeSet ss = ShapeSet();
192
Point& p = src->point;
193
Point& q = dst->point;
195
VertID& pID = src->id;
196
VertID& qID = dst->id;
200
ss.insert(contains[pID].begin(), contains[pID].end());
204
ss.insert(contains[qID].begin(), contains[qID].end());
207
// The "beginning" should be the first shape vertex, rather
208
// than an endpoint, which are also stored in "vertices".
209
VertInf *endVert = vertices.end();
210
for (VertInf *k = vertices.shapesBegin(); k != endVert; k = k->lstNext)
212
if ((ss.find(k->id.objID) == ss.end()))
214
if (segmentIntersect(p, q, k->point, k->shNext->point))
224
VertInfList::VertInfList()
225
: _firstShapeVert(NULL)
226
, _firstConnVert(NULL)
227
, _lastShapeVert(NULL)
228
, _lastConnVert(NULL)
235
#define checkVertInfListConditions() \
237
assert((!_firstConnVert && (_connVertices == 0)) || \
238
((_firstConnVert->lstPrev == NULL) && (_connVertices > 0))); \
239
assert((!_firstShapeVert && (_shapeVertices == 0)) || \
240
((_firstShapeVert->lstPrev == NULL) && (_shapeVertices > 0))); \
241
assert(!_lastShapeVert || (_lastShapeVert->lstNext == NULL)); \
242
assert(!_lastConnVert || (_lastConnVert->lstNext == _firstShapeVert)); \
243
assert((!_firstConnVert && !_lastConnVert) || \
244
(_firstConnVert && _lastConnVert) ); \
245
assert((!_firstShapeVert && !_lastShapeVert) || \
246
(_firstShapeVert && _lastShapeVert) ); \
247
assert(!_firstShapeVert || _firstShapeVert->id.isShape); \
248
assert(!_lastShapeVert || _lastShapeVert->id.isShape); \
249
assert(!_firstConnVert || !(_firstConnVert->id.isShape)); \
250
assert(!_lastConnVert || !(_lastConnVert->id.isShape)); \
254
void VertInfList::addVertex(VertInf *vert)
256
checkVertInfListConditions();
257
assert(vert->lstPrev == NULL);
258
assert(vert->lstNext == NULL);
260
if (!(vert->id.isShape))
262
// A Connector vertex
265
// Join with previous front
266
vert->lstNext = _firstConnVert;
267
_firstConnVert->lstPrev = vert;
270
_firstConnVert = vert;
274
// Make front and back
275
_firstConnVert = vert;
276
_lastConnVert = vert;
278
// Link to front of shapes list
279
vert->lstNext = _firstShapeVert;
283
else // if (vert->id.shape > 0)
288
// Join with previous back
289
vert->lstPrev = _lastShapeVert;
290
_lastShapeVert->lstNext = vert;
293
_lastShapeVert = vert;
297
// Make first and last
298
_firstShapeVert = vert;
299
_lastShapeVert = vert;
301
// Join with conns list
304
assert (_lastConnVert->lstNext == NULL);
306
_lastConnVert->lstNext = vert;
311
checkVertInfListConditions();
315
void VertInfList::removeVertex(VertInf *vert)
317
// Conditions for correct data structure
318
checkVertInfListConditions();
320
if (!(vert->id.isShape))
322
// A Connector vertex
323
if (vert == _firstConnVert)
326
if (vert == _lastConnVert)
328
_firstConnVert = NULL;
329
_lastConnVert = NULL;
334
_firstConnVert = _firstConnVert->lstNext;
339
_firstConnVert->lstPrev = NULL;
343
else if (vert == _lastConnVert)
346
_lastConnVert = _lastConnVert->lstPrev;
348
// Make last point to shapes list
349
_lastConnVert->lstNext = _firstShapeVert;
353
vert->lstNext->lstPrev = vert->lstPrev;
354
vert->lstPrev->lstNext = vert->lstNext;
358
else // if (vert->id.shape > 0)
361
if (vert == _lastShapeVert)
364
_lastShapeVert = _lastShapeVert->lstPrev;
366
if (vert == _firstShapeVert)
368
_firstShapeVert = NULL;
371
_lastConnVert->lstNext = NULL;
377
_lastShapeVert->lstNext = NULL;
380
else if (vert == _firstShapeVert)
383
_firstShapeVert = _firstShapeVert->lstNext;
385
// Correct the last conn vertex
388
_lastConnVert->lstNext = _firstShapeVert;
393
_firstShapeVert->lstPrev = NULL;
398
vert->lstNext->lstPrev = vert->lstPrev;
399
vert->lstPrev->lstNext = vert->lstNext;
403
vert->lstPrev = NULL;
404
vert->lstNext = NULL;
406
checkVertInfListConditions();
410
VertInf *VertInfList::shapesBegin(void)
412
return _firstShapeVert;
416
VertInf *VertInfList::connsBegin(void)
420
return _firstConnVert;
422
// No connector vertices
423
return _firstShapeVert;
427
VertInf *VertInfList::end(void)
433
VertInfList vertices;