Code

PNG output for Cairo renderer
[inkscape.git] / src / libavoid / visibility.cpp
index e13656f5f8995b55bf0c66f8cbd1ffab6d25fc1b..f540baf219793db47bd5255ec48dbee303e305c8 100644 (file)
@@ -2,7 +2,7 @@
  * vim: ts=4 sw=4 et tw=0 wm=0
  *
  * libavoid - Fast, Incremental, Object-avoiding Line Router
- * Copyright (C) 2004-2005  Michael Wybrow <mjwybrow@users.sourceforge.net>
+ * Copyright (C) 2004-2006  Michael Wybrow <mjwybrow@users.sourceforge.net>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
 #include "libavoid/shape.h"
 #include "libavoid/debug.h"
 #include "libavoid/visibility.h"
+#include "libavoid/vertices.h"
 #include "libavoid/graph.h"
+#include "libavoid/geometry.h"
+#include "libavoid/router.h"
 
 #include <math.h>
 
 namespace Avoid {
 
 
-bool UseAStarSearch   = true;
-bool IgnoreRegions    = true;
-bool SelectiveReroute = true;
-bool IncludeEndpoints = true;
-bool UseLeesAlgorithm = false;
-bool InvisibilityGrph = true;
-bool PartialFeedback  = false;
-
-bool PartialTime = false;
-
-
-void computeCompleteVis(void)
-{
-    VertInf *beginVert = vertices.shapesBegin();
-    VertInf *endVert = vertices.end();
-    for (VertInf *i = beginVert; i != endVert; i = i->lstNext)
-    {
-        db_printf("-- CONSIDERING --\n");
-        i->id.db_print();
-
-        for (VertInf *j = i->lstPrev ; j != NULL; j = j->lstPrev)
-        {
-            bool knownNew = true;
-            EdgeInf::checkEdgeVisibility(i, j, knownNew);
-        }
-    }
-}
-
-
 void shapeVis(ShapeRef *shape)
 {
-    if (!InvisibilityGrph)
+    Router *router = shape->router();
+
+    if ( !(router->InvisibilityGrph) )
     {
         // Clear shape from graph.
         shape->removeFromGraph();
@@ -78,13 +54,13 @@ void shapeVis(ShapeRef *shape)
     VertInf *shapeEnd = shape->lastVert()->lstNext;
 
     VertInf *pointsBegin = NULL;
-    if (IncludeEndpoints)
+    if (router->IncludeEndpoints)
     {
-        pointsBegin = vertices.connsBegin();
+        pointsBegin = router->vertices.connsBegin();
     }
     else
     {
-        pointsBegin = vertices.shapesBegin();
+        pointsBegin = router->vertices.shapesBegin();
     }
 
     for (VertInf *curr = shapeBegin; curr != shapeEnd; curr = curr->lstNext)
@@ -101,7 +77,7 @@ void shapeVis(ShapeRef *shape)
         }
 
         db_printf("\tSecond Half:\n");
-        VertInf *pointsEnd = vertices.end();
+        VertInf *pointsEnd = router->vertices.end();
         for (VertInf *k = shapeEnd; k != pointsEnd; k = k->lstNext)
         {
             EdgeInf::checkEdgeVisibility(curr, k, knownNew);
@@ -112,7 +88,9 @@ void shapeVis(ShapeRef *shape)
 
 void shapeVisSweep(ShapeRef *shape)
 {
-    if (!InvisibilityGrph)
+    Router *router = shape->router();
+
+    if ( !(router->InvisibilityGrph) )
     {
         // Clear shape from graph.
         shape->removeFromGraph();
@@ -131,34 +109,35 @@ void shapeVisSweep(ShapeRef *shape)
 void vertexVisibility(VertInf *point, VertInf *partner, bool knownNew,
         const bool gen_contains)
 {
+    Router *router = point->_router;
     const VertID& pID = point->id;
 
     // Make sure we're only doing ptVis for endpoints.
     assert(!(pID.isShape));
 
-    if (!InvisibilityGrph)
+    if ( !(router->InvisibilityGrph) )
     {
         point->removeFromGraph();
     }
 
     if (gen_contains && !(pID.isShape))
     {
-        generateContains(point);
+        router->generateContains(point);
     }
 
-    if (UseLeesAlgorithm)
+    if (router->UseLeesAlgorithm)
     {
         vertexSweep(point);
     }
     else
     {
-        VertInf *shapesEnd = vertices.end();
-        for (VertInf *k = vertices.shapesBegin(); k != shapesEnd;
+        VertInf *shapesEnd = router->vertices.end();
+        for (VertInf *k = router->vertices.shapesBegin(); k != shapesEnd;
                 k = k->lstNext)
         {
             EdgeInf::checkEdgeVisibility(point, k, knownNew);
         }
-        if (IncludeEndpoints && partner)
+        if (router->IncludeEndpoints && partner)
         {
             EdgeInf::checkEdgeVisibility(point, partner, knownNew);
         }
@@ -175,10 +154,6 @@ static Point centerPoint;
 static VertID centerID;
 static double centerAngle;
 
-#ifdef LINEDEBUG
-    SDL_Surface *avoid_screen = NULL;
-#endif
-
 
 class PointPair
 {
@@ -341,14 +316,6 @@ static bool sweepVisible(EdgeSet& T, VertInf *currInf, VertInf *lastInf,
                 *blocker = (*closestIt).vInf1->id.objID;
                 return false;
             }
-            else
-            {
-                return true;
-            }
-        }
-        else
-        {
-            return true;
         }
     }
     else
@@ -375,14 +342,15 @@ static bool sweepVisible(EdgeSet& T, VertInf *currInf, VertInf *lastInf,
                     return false;
                 }
             }
-            return true;
         }
     }
+    return true;
 }
 
 
 void vertexSweep(VertInf *vert)
 {
+    Router *router = vert->_router;
     VertID& pID = vert->id;
     Point& pPoint = vert->point;
 
@@ -397,8 +365,8 @@ void vertexSweep(VertInf *vert)
     VertList v;
 
     // Initialise the vertex list
-    VertInf *beginVert = vertices.connsBegin();
-    VertInf *endVert = vertices.end();
+    VertInf *beginVert = router->vertices.connsBegin();
+    VertInf *endVert = router->vertices.end();
     for (VertInf *inf = beginVert; inf != endVert; inf = inf->lstNext)
     {
         if (inf->id == centerID)
@@ -414,7 +382,7 @@ void vertexSweep(VertInf *vert)
         }
         else
         {
-            if (IncludeEndpoints)
+            if (router->IncludeEndpoints)
             {
                 if (centerID.isShape)
                 {
@@ -439,16 +407,16 @@ void vertexSweep(VertInf *vert)
     v.sort(ppCompare);
 
     EdgeSet e;
-    ShapeSet& ss = contains[centerID];
+    ShapeSet& ss = router->contains[centerID];
 
     // And edge to T that intersect the initial ray.
-    VertInf *last = vertices.end();
-    for (VertInf *k = vertices.shapesBegin(); k != last; )
+    VertInf *last = router->vertices.end();
+    for (VertInf *k = router->vertices.shapesBegin(); k != last; )
     {
         VertID kID = k->id;
         if (!(centerID.isShape) && (ss.find(kID.objID) != ss.end()))
         {
-            uint shapeID = kID.objID;
+            unsigned int shapeID = kID.objID;
             db_printf("Center is inside shape %u so ignore shape edges.\n",
                     shapeID);
             // One of the endpoints is inside this shape so ignore it.
@@ -467,7 +435,7 @@ void vertexSweep(VertInf *vert)
             continue;
         }
 
-        Point xaxis = { DBL_MAX, centerInf->point.y };
+        Point xaxis(DBL_MAX, centerInf->point.y);
 
         if (segmentIntersect(centerInf->point, xaxis, kPrev->point, k->point))
         {
@@ -495,7 +463,7 @@ void vertexSweep(VertInf *vert)
     bool     lastVisible = false;
     int      lastBlocker = 0;
 
-    isBoundingShape isBounding(contains[centerID]);
+    isBoundingShape isBounding(router->contains[centerID]);
     VertList::iterator vfst = v.begin();
     VertList::iterator vfin = v.end();
     for (VertList::iterator t = vfst; t != vfin; ++t)
@@ -524,7 +492,7 @@ void vertexSweep(VertInf *vert)
         // Ignore vertices from bounding shapes, if sweeping round an endpoint.
         if (!(centerID.isShape) && isBounding(*t))
         {
-            if (InvisibilityGrph)
+            if (router->InvisibilityGrph)
             {
                 // if p and t can't see each other, add blank edge
                 db_printf("\tSkipping visibility edge... \n\t\t");
@@ -538,19 +506,21 @@ void vertexSweep(VertInf *vert)
         bool cone1 = true, cone2 = true;
         if (centerID.isShape)
         {
-            cone1 = inValidRegion(centerInf->shPrev->point, centerPoint,
+            cone1 = inValidRegion(router->IgnoreRegions,
+                    centerInf->shPrev->point, centerPoint,
                     centerInf->shNext->point, currInf->point);
         }
         if (currInf->id.isShape)
         {
-            cone2 = inValidRegion(currInf->shPrev->point, currInf->point,
+            cone2 = inValidRegion(router->IgnoreRegions,
+                    currInf->shPrev->point, currInf->point,
                     currInf->shNext->point, centerPoint);
         }
 
         if (!cone1 || !cone2)
         {
             lastInf = NULL;
-            if (InvisibilityGrph)
+            if (router->InvisibilityGrph)
             {
                 db_printf("\tSetting invisibility edge... \n\t\t");
                 edge->addBlocker(0);
@@ -576,7 +546,7 @@ void vertexSweep(VertInf *vert)
                 edge->setDist(currDist);
                 edge->db_print();
             }
-            else if (InvisibilityGrph)
+            else if (router->InvisibilityGrph)
             {
                 db_printf("\tSetting invisibility edge... \n\t\t");
                 edge->addBlocker(blocker);
@@ -602,7 +572,9 @@ void vertexSweep(VertInf *vert)
             EdgeSet::iterator ePtr;
             if (prevDir == BEHIND)
             {
-                ePtr = e.find(prevPair);
+                // XXX: Strangely e.find does not return the correct results.
+                // ePtr = e.find(prevPair);
+                ePtr = std::find(e.begin(), e.end(), prevPair);
                 if (ePtr != e.end())
                 {
                     e.erase(ePtr);
@@ -625,7 +597,9 @@ void vertexSweep(VertInf *vert)
 
             if (nextDir == BEHIND)
             {
-                ePtr = e.find(nextPair);
+                // XXX: Strangely e.find does not return the correct results.
+                // ePtr = e.find(nextPair);
+                ePtr = std::find(e.begin(), e.end(), nextPair);
                 if (ePtr != e.end())
                 {
                     e.erase(ePtr);