]> OCCT Git - occt-copy.git/commitdiff
Win8 memory issue fixed.
authorduv <duv@opencascade.com>
Wed, 20 Apr 2016 10:56:32 +0000 (13:56 +0300)
committerduv <duv@opencascade.com>
Wed, 20 Apr 2016 10:56:32 +0000 (13:56 +0300)
src/BRepMesh/BRepMesh_Block.hxx
src/BRepMesh/BRepMesh_MinStCut.cxx
src/BRepMesh/BRepMesh_MinStCut.hxx
src/BRepMesh/BRepMesh_RestoreOrientationTool.cxx

index 53c63caf20a7d9f77b83f21c2a5e5036fdf32b3f..60ab0f272412775a1e826fc5e008edd0763394a6 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#ifndef __BLOCK_H__
-#define __BLOCK_H__
+#ifndef _BRepMesh_Block_HeaderFile
+#define _BRepMesh_Block_HeaderFile
 
 #include <stdlib.h>
+#include <stdexcept>
 
-template <class Type> class Block
+template <class Type> class Storage
 {
 public:
-
-  Block (int theSize, void (*theErrFunction) (char*) = NULL)
+  Storage (int theSize)
   {
-    myFirst = myLast = NULL;
-    myBlockSize = theSize;
-    myErrorFun = theErrFunction;
+    m_first = m_last = NULL;
+    m_BlockSize = theSize;
   }
 
-  ~Block()
+  ~Storage()
   {
-    while (myFirst)
+    while (m_first)
     {
-      BlockStruct* aNext = myFirst->Next;
-      delete myFirst;
-      myFirst = aNext;
+      Block* next = m_first->Next;
+      delete[] ( (char*) m_first);
+      m_first = next;
     }
   }
 
-  Type* New (int theNum = 1)
+  Type* New (int aNum = 1)
   {
-    Type* aLast;
+    Type* aResult;
 
-    if (!myLast || myLast->Current + theNum > myLast->Last)
+    if (!m_last || m_last->Current + aNum > m_last->Last)
     {
-      if (myLast && myLast->Next) { myLast = myLast->Next; }
+      if (m_last && m_last->Next)
+      {
+        m_last = m_last->Next;
+      }
+
       else
       {
-        BlockStruct* aNext = (BlockStruct*) new char [sizeof (BlockStruct) + (myBlockSize-1) *sizeof (Type)];
+        Block* aNext = (Block*) new char [sizeof (Block) + (m_BlockSize - 1) *sizeof (Type)];
+
+        if (!aNext)
+        {
+          throw std::runtime_error ("Not enough memory!");
+        }
+
+        if (m_last)
+        {
+          m_last->Next = aNext;
+        }
+
+        else
+        {
+          m_first = aNext;
+        }
+
+        m_last = aNext;
+        m_last->Current = & (m_last->Data[0]);
+        m_last->Last = m_last->Current + m_BlockSize;
+        m_last->Next = NULL;
+      }
+    }
 
-        if (!aNext) { if (myErrorFun) { (*myErrorFun) ("Not enough memory!"); } exit (1); }
+    aResult = m_last->Current;
+    m_last->Current += aNum;
+    return aResult;
+  }
 
-        if (myLast) { myLast->Next = aNext; }
-        else { myFirst = aNext; }
+  Type* ScanFirst()
+  {
+    for (m_scanCurrentBlock = m_first; m_scanCurrentBlock; m_scanCurrentBlock = m_scanCurrentBlock->Next)
+    {
+      m_scanCurrentData = & (m_scanCurrentBlock->Data[0]);
 
-        myLast = aNext;
-        myLast->Current = & (myLast->Data[0]);
-        myLast->Last = myLast->Current + myBlockSize;
-        myLast->Next = NULL;
+      if (m_scanCurrentData < m_scanCurrentBlock->Current)
+      {
+        return m_scanCurrentData ++;
       }
     }
 
-    aLast = myLast->Current;
-    myLast->Current += theNum;
-    return aLast;
+    return NULL;
   }
 
-  Type* ScanFirst()
+  Type* ScanNext()
   {
-    myScanCurrentBlock = myFirst;
+    while (m_scanCurrentData >= m_scanCurrentBlock->Current)
+    {
+      m_scanCurrentBlock = m_scanCurrentBlock->Next;
+
+      if (!m_scanCurrentBlock)
+      {
+        return NULL;
+      }
 
-    if (!myScanCurrentBlock) { return NULL; }
+      m_scanCurrentData = & (m_scanCurrentBlock->Data[0]);
+    }
 
-    myScanCurrentData = & (myScanCurrentBlock->Data[0]);
-    return myScanCurrentData++;
+    return m_scanCurrentData++;
   }
 
-  Type* ScanNext()
+  struct BlockIterator;
+  Type* ScanFirst (BlockIterator& anIter)
+  {
+    for (anIter.ScanCurrentBlock = m_first; anIter.ScanCurrentBlock; anIter.ScanCurrentBlock = anIter.ScanCurrentBlock->Next)
+    {
+      anIter.ScanCurrentData = & (anIter.ScanCurrentBlock->Data[0]);
+
+      if (anIter.ScanCurrentData < anIter.ScanCurrentBlock->Current)
+      {
+        return anIter.ScanCurrentData ++;
+      }
+    }
+
+    return NULL;
+  }
+  Type* ScanNext (BlockIterator& anIter)
   {
-    if (myScanCurrentData >= myScanCurrentBlock->Current)
+    while (anIter.ScanCurrentData >= anIter.ScanCurrentBlock->Current)
     {
-      myScanCurrentBlock = myScanCurrentBlock->Next;
+      anIter.ScanCurrentBlock = anIter.ScanCurrentBlock->Next;
 
-      if (!myScanCurrentBlock) { return NULL; }
+      if (!anIter.ScanCurrentBlock)
+      {
+        return NULL;
+      }
 
-      myScanCurrentData = & (myScanCurrentBlock->Data[0]);
+      anIter.ScanCurrentData = & (anIter.ScanCurrentBlock->Data[0]);
     }
 
-    return myScanCurrentData++;
+    return anIter.ScanCurrentData ++;
   }
 
   void Reset()
   {
-    BlockStruct* aBlock;
+    Block* aBlock;
 
-    if (!myFirst) { return; }
+    if (!m_first)
+    {
+      return;
+    }
 
-    for (aBlock = myFirst; ; aBlock = aBlock->Next)
+    for (aBlock = m_first; ; aBlock = aBlock->Next)
     {
       aBlock->Current = & (aBlock->Data[0]);
 
-      if (aBlock == myLast) { break; }
+      if (aBlock == m_last)
+      {
+        break;
+      }
     }
 
-    myLast = myFirst;
+    m_last = m_first;
   }
 
 private:
 
-  typedef struct BlockSt
+  typedef struct BlockStruct
   {
-    Type* Current;
-    Type* Last;
-    struct BlockSt* Next;
+    Type* Current, *Last;
+    struct BlockStruct* Next;
     Type Data[1];
-  } BlockStruct;
+  } Block;
 
-  int   myBlockSize;
-  BlockStruct* myFirst;
-  BlockStruct* myLast;
+  int m_BlockSize;
+  Block* m_first;
+  Block* m_last;
+public:
 
-  BlockStruct* myScanCurrentBlock;
-  Type*  myScanCurrentData;
+  struct BlockIterator
+  {
+    Block* ScanCurrentBlock;
+    Type* ScanCurrentData;
+  };
 
-  void (*myErrorFun) (char*);
+private:
+  Block* m_scanCurrentBlock;
+  Type* m_scanCurrentData;
 };
 
-template <class Type> class DBlock
+template <class Type> class DataBlock
 {
 public:
+  DataBlock (int size)
+  {
+    m_first = NULL;
+    m_firstFree = NULL;
+    m_blockSize = size;
+  }
 
-  DBlock (int theSize, void (*theErrFunction) (char*) = NULL) { myFirst = NULL; myFirstFree = NULL; myBLockSize = theSize; myErrFun = theErrFunction; }
-
-  ~DBlock() { while (myFirst) { BlockStruct* aNext = myFirst->Next; delete myFirst; myFirst = aNext; } }
+  ~DataBlock()
+  {
+    while (m_first)
+    {
+      Block* next = m_first->Next;
+      delete[] ( (char*) m_first);
+      m_first = next;
+    }
+  }
 
   Type* New()
   {
     BlockItem* anItem;
 
-    if (!myFirstFree)
+    if (!m_firstFree)
     {
-      BlockStruct* next = myFirst;
-      myFirst = (BlockStruct*) new char [sizeof (BlockStruct) + (myBLockSize-1) *sizeof (BlockItem)];
+      Block* next = m_first;
+      m_first = (Block*) new char [sizeof (Block) + (m_blockSize - 1) *sizeof (BlockItem)];
 
-      if (!myFirst) { if (myErrFun) { (*myErrFun) ("Not enough memory!"); } exit (1); }
+      if (!m_first)
+      {
+        throw std::runtime_error ("Not enough memory!");
+      }
 
-      myFirstFree = & (myFirst->Data[0]);
+      m_firstFree = & (m_first->Data[0]);
 
-      for (anItem=myFirstFree; anItem<myFirstFree+myBLockSize-1; anItem++)
-      { anItem->NextFree = anItem + 1; }
+      for (anItem = m_firstFree; anItem < m_firstFree + m_blockSize - 1; anItem++)
+      {
+        anItem->NextFree = anItem + 1;
+      }
 
       anItem->NextFree = NULL;
-      myFirst->Next = next;
+      m_first->Next = next;
     }
 
-    anItem = myFirstFree;
-    myFirstFree = anItem->NextFree;
+    anItem = m_firstFree;
+    m_firstFree = anItem->NextFree;
     return (Type*) anItem;
   }
 
   void Delete (Type* t)
   {
-    ( (BlockItem*) t)->NextFree = myFirstFree;
-    myFirstFree = (BlockItem*) t;
+    ( (BlockItem*) t)->NextFree = m_firstFree;
+    m_firstFree = (BlockItem*) t;
   }
 
 private:
 
-  typedef union BlockItemSt
+  typedef union BlockItemStruct
   {
-    Type      Item;
-    BlockItemSt* NextFree;
+    Type Val;
+    BlockItemStruct* NextFree;
   } BlockItem;
 
-  typedef struct BlockSt
+  typedef struct BlockStruct
   {
-    struct BlockSt*      Next;
-    BlockItem       Data[1];
-  } BlockStruct;
-
-  int     myBLockSize;
-  BlockStruct*   myFirst;
-  BlockItem* myFirstFree;
+    struct BlockStruct* Next;
+    BlockItem Data[1];
+  } Block;
 
-  void (*myErrFun) (char*);
+  int m_blockSize;
+  Block* m_first;
+  BlockItem* m_firstFree;
 };
 
-#endif
+#endif // _BRepMesh_Block_HeaderFile
 
index 0435080179de478b9443c145ce52e7eb7923315f..ed6a33ddde9fdfe1bfda474382a8b257614b256e 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#pragma warning (disable: 4706)
-#pragma warning (disable: 4701)
-#pragma warning (disable: 4127)
-
 #include <stdio.h>
+#include <string.h>
 #include <stdexcept>
+
 #include <BRepMesh_MinStCut.hxx>
 
-Graph::Graph (void (*theErrFun) (char*))
+GraphEval::GraphEval (const int theNodeNumMax)
+  : m_nodeNum (0), m_nodeNumMax (theNodeNumMax)
 {
-  myErrorFun = theErrFun;
-  myNodeBlockFirst = NULL;
-  myArcForBlockFirst = NULL;
-  myArcREvBlockFirst = NULL;
-  myFlow = 0;
+  m_nodes = (Node*) malloc (m_nodeNumMax * sizeof (Node));
+  m_edgeBlock  = new Storage<Edge> (EDGE_BLOCK_SIZE);
+  m_flow = 0;
 }
 
-Graph::~Graph()
+GraphEval::~GraphEval()
 {
-  while (myNodeBlockFirst)
-  {
-    NodeBlock* aNext = myNodeBlockFirst->Next;
-    delete myNodeBlockFirst;
-    myNodeBlockFirst = aNext;
-  }
-
-  while (myArcForBlockFirst)
-  {
-    ArcForBlock* next = myArcForBlockFirst->Next;
-    delete myArcForBlockFirst->Start;
-    myArcForBlockFirst = next;
-  }
-
-  while (myArcREvBlockFirst)
-  {
-    ArcRevBlock* next = myArcREvBlockFirst->Next;
-    delete myArcREvBlockFirst->Start;
-    myArcREvBlockFirst = next;
-  }
+  free (m_nodes);
+  delete m_edgeBlock;
 }
 
-Graph::NodeId Graph::AddNode()
+GraphEval::NodeId GraphEval::AddNode (int theNum)
 {
-  Node* aNode;
+  NodeId i = m_nodeNum;
+  m_nodeNum += theNum;
 
-  if (!myNodeBlockFirst || myNodeBlockFirst->Current+1 > &myNodeBlockFirst->Nodes[NODE_BLOCK_SIZE-1])
+  if (m_nodeNum > m_nodeNumMax)
   {
-    NodeBlock* next = myNodeBlockFirst;
-    myNodeBlockFirst = (NodeBlock*) new NodeBlock;
-
-    if (!myNodeBlockFirst)
-    {
-      throw std::runtime_error ("Not enough memory!");
-    }
-
-    myNodeBlockFirst->Current = & (myNodeBlockFirst->Nodes[0]);
-    myNodeBlockFirst->Next = next;
+    throw std::runtime_error ("Error: the number of nodes is exceeded!");
   }
 
-  aNode = myNodeBlockFirst->Current ++;
-  aNode->FirstOut = (ArcForward*) 0;
-  aNode->FirstIn = (ArcReverse*) 0;
+  memset (m_nodes + i, 0, theNum * sizeof (NodeStruct));
 
-  aNode->TrCapacity = 0;
+  return i;
+}
 
-  return (NodeId) aNode;
+void GraphEval::AddEdge (NodeId theNodeFrom, NodeId theNodeTo, CapacityType theCap, CapacityType theRevCap)
+{
+  Edge* a, *a_rev;
+  Node* from = m_nodes + theNodeFrom;
+  Node* to = m_nodes + theNodeTo;
+
+  a = m_edgeBlock->New (2);
+  a_rev = a + 1;
+
+  a->Sister = a_rev;
+  a_rev->Sister = a;
+  a->Next = from->First;
+  from->First = a;
+  a_rev->Next = ( (Node*) to)->First;
+  to->First = a_rev;
+  a->Head = to;
+  a_rev->Head = from;
+  a->ReverseCap = theCap;
+  a_rev->ReverseCap = theRevCap;
 }
 
-void Graph::AddEdge (NodeId theFromNode, NodeId theToNode, CapacityType theCapacity, CapacityType theReverseCapacity)
+void GraphEval::AddTWeights (NodeId theNode, CapacityType theCapSource, CapacityType theCapSink)
 {
-  ArcForward* anArcFor;
-  ArcReverse* anArcRev;
+  register CapacityType delta = m_nodes[theNode].TrCap;
 
-  if (!myArcForBlockFirst || myArcForBlockFirst->Current+1 > &myArcForBlockFirst->ArcsFor[ARC_BLOCK_SIZE])
+  if (delta > 0)
   {
-    ArcForBlock* aNext = myArcForBlockFirst;
-    char* aPtr = new char[sizeof (ArcForBlock) +1];
-
-    if (!aPtr)
-    {
-      throw std::runtime_error ("Not enough memory!");
-    }
-
-    if ( (int) aPtr & 1) { myArcForBlockFirst = (ArcForBlock*) (aPtr + 1); }
-    else              { myArcForBlockFirst = (ArcForBlock*) aPtr; }
-
-    myArcForBlockFirst->Start = aPtr;
-    myArcForBlockFirst->Current = & (myArcForBlockFirst->ArcsFor[0]);
-    myArcForBlockFirst->Next = aNext;
+    theCapSource += delta;
   }
 
-  if (!myArcREvBlockFirst || myArcREvBlockFirst->Current+1 > &myArcREvBlockFirst->ArcsRev[ARC_BLOCK_SIZE])
+  else
   {
-    ArcRevBlock* aNext = myArcREvBlockFirst;
-    char* aPter = new char[sizeof (ArcRevBlock) +1];
-
-    if (!aPter)
-    {
-      throw std::runtime_error ("Not enough memory!");
-    }
-
-    if ( (int) aPter & 1) { myArcREvBlockFirst = (ArcRevBlock*) (aPter + 1); }
-    else              { myArcREvBlockFirst = (ArcRevBlock*) aPter; }
-
-    myArcREvBlockFirst->Start = aPter;
-    myArcREvBlockFirst->Current = & (myArcREvBlockFirst->ArcsRev[0]);
-    myArcREvBlockFirst->Next = aNext;
+    theCapSink   -= delta;
   }
 
-  anArcFor = myArcForBlockFirst->Current ++;
-  anArcRev = myArcREvBlockFirst->Current ++;
-
-  anArcRev->Sister = (ArcForward*) theFromNode;
-  anArcFor->Shift  = (int) theToNode;
-  anArcFor->ResidualCap = theCapacity;
-  anArcFor->ReverseResidualCap = theReverseCapacity;
-
-  ( (Node*) theFromNode)->FirstOut =
-    (ArcForward*) ( (int) ( ( (Node*) theFromNode)->FirstOut) + 1);
-  ( (Node*) theToNode)->FirstIn =
-    (ArcReverse*) ( (int) ( ( (Node*) theToNode)->FirstIn) + 1);
+  m_flow += (theCapSource < theCapSink) ? theCapSource : theCapSink;
+  m_nodes[theNode].TrCap = theCapSource - theCapSink;
 }
 
-void Graph::SetTWeights (NodeId theNode, CapacityType theCapacityToSource, CapacityType theCapacityToSink)
-{
-  myFlow += (theCapacityToSource < theCapacityToSink) ? theCapacityToSource : theCapacityToSink;
-  ( (Node*) theNode)->TrCapacity = theCapacityToSource - theCapacityToSink;
-}
+#define TERM ( (Edge *) 1 )
+#define ORPH ( (Edge *) 2 )
 
-void Graph::AddTWeights (NodeId theNode, CapacityType theCapacityToSource, CapacityType theCapacityToSink)
-{
-  register CapacityType delta = ( (Node*) theNode)->TrCapacity;
+#define INFINITE 1000000000
 
-  if (delta > 0) { theCapacityToSource += delta; }
-  else           { theCapacityToSink   -= delta; }
-
-  myFlow += (theCapacityToSource < theCapacityToSink) ? theCapacityToSource : theCapacityToSink;
-  ( (Node*) theNode)->TrCapacity = theCapacityToSource - theCapacityToSink;
-}
-
-void Graph::prepareGraph()
+inline void GraphEval::setActive (Node* theNode)
 {
-  Node* aNode;
-  ArcForBlock* anArcBlockFor, *anArcBlockForFirst;
-  ArcRevBlock* anArcBlockRev, *anArcBlockRevFirst, *anArcBlockREvScan;
-  ArcForward* anArcFor;
-  ArcReverse* anArcRev, *anArcRevSCan, anArcREvTmp;
-  NodeBlock* aNodeBlock;
-  bool aForwardFlag = false, aReverseFlag = false;
-  int aK;
-
-  if (!myArcREvBlockFirst)
+  if (!theNode->Next)
   {
-    NodeId aNodeFrom = AddNode(), aNodeTo = AddNode();
-    AddEdge (aNodeFrom, aNodeTo, 1, 0);
-  }
+    if (m_queueLast[1])
+    {
+      m_queueLast[1]->Next = theNode;
+    }
 
-  /* FIRST STAGE */
-  anArcREvTmp.Sister = NULL;
+    else
+    {
+      m_queueFirst[1] = theNode;
+    }
 
-  for (anArcRev=myArcREvBlockFirst->Current; anArcRev<&myArcREvBlockFirst->ArcsRev[ARC_BLOCK_SIZE]; anArcRev++)
-  {
-    anArcRev->Sister = NULL;
+    m_queueLast[1] = theNode;
+    theNode->Next = theNode;
   }
+}
 
-  anArcBlockFor = anArcBlockForFirst = myArcForBlockFirst;
-  anArcBlockRev = anArcBlockRevFirst = anArcBlockREvScan = myArcREvBlockFirst;
-  anArcFor = &anArcBlockFor->ArcsFor[0];
-  anArcRev = anArcRevSCan = &anArcBlockRev->ArcsRev[0];
+inline GraphEval::Node* GraphEval::nextActive()
+{
+  Node* aNode;
 
-  for (aNodeBlock=myNodeBlockFirst; aNodeBlock; aNodeBlock=aNodeBlock->Next)
+  while (1)
   {
-    for (aNode=&aNodeBlock->Nodes[0]; aNode<aNodeBlock->Current; aNode++)
+    if (! (aNode = m_queueFirst[0]))
     {
-      /* outgoing arcs */
-      aK = (int) aNode->FirstOut;
-
-      if (anArcFor + aK > &anArcBlockFor->ArcsFor[ARC_BLOCK_SIZE])
-      {
-        if (aK > ARC_BLOCK_SIZE)
-        {
-          throw std::runtime_error ("# of arcs per node exceeds block size!");
-        }
-
-        if (aForwardFlag) { anArcBlockFor = NULL; }
-        else          { anArcBlockFor = anArcBlockFor->Next; anArcBlockREvScan = anArcBlockREvScan->Next; }
-
-        if (anArcBlockFor == NULL)
-        {
-          ArcForBlock* next = myArcForBlockFirst;
-          char* ptr = new char[sizeof (ArcForBlock) +1];
-
-          if (!ptr)
-          {
-            throw std::runtime_error ("Not enough memory!");
-          }
-
-          if ( (int) ptr & 1) { myArcForBlockFirst = (ArcForBlock*) (ptr + 1); }
-          else              { myArcForBlockFirst = (ArcForBlock*) ptr; }
-
-          myArcForBlockFirst->Start = ptr;
-          myArcForBlockFirst->Current = & (myArcForBlockFirst->ArcsFor[0]);
-          myArcForBlockFirst->Next = next;
-          anArcBlockFor = myArcForBlockFirst;
-          aForwardFlag = true;
-        }
-        else { anArcRevSCan = &anArcBlockREvScan->ArcsRev[0]; }
-
-        anArcFor = &anArcBlockFor->ArcsFor[0];
-      }
-
-      if (anArcBlockREvScan)
-      {
-        anArcRevSCan += aK;
-        aNode->Parent = (ArcForward*) anArcRevSCan;
-      }
-      else { aNode->Parent = (ArcForward*) &anArcREvTmp; }
-
-      anArcFor += aK;
-      aNode->FirstOut = anArcFor;
-      anArcBlockFor->last_node = aNode;
+      m_queueFirst[0] = aNode = m_queueFirst[1];
+      m_queueLast[0]  = m_queueLast[1];
+      m_queueFirst[1] = NULL;
+      m_queueLast[1]  = NULL;
 
-      /* incoming arcs */
-      aK = (int) aNode->FirstIn;
-
-      if (anArcRev + aK > &anArcBlockRev->ArcsRev[ARC_BLOCK_SIZE])
+      if (!aNode)
       {
-        if (aK > ARC_BLOCK_SIZE)
-        {
-          throw std::runtime_error ("# of arcs per node exceeds block size!");
-        }
-
-        if (aReverseFlag) { anArcBlockRev = NULL; }
-        else          { anArcBlockRev = anArcBlockRev->Next; }
-
-        if (anArcBlockRev == NULL)
-        {
-          ArcRevBlock* next = myArcREvBlockFirst;
-          char* ptr = new char[sizeof (ArcRevBlock) +1];
-
-          if (!ptr)
-          {
-            throw std::runtime_error ("Not enough memory!");
-          }
-
-          if ( (int) ptr & 1) { myArcREvBlockFirst = (ArcRevBlock*) (ptr + 1); }
-          else              { myArcREvBlockFirst = (ArcRevBlock*) ptr; }
-
-          myArcREvBlockFirst->Start = ptr;
-          myArcREvBlockFirst->Current = & (myArcREvBlockFirst->ArcsRev[0]);
-          myArcREvBlockFirst->Next = next;
-          anArcBlockRev = myArcREvBlockFirst;
-          aReverseFlag = true;
-        }
-
-        anArcRev = &anArcBlockRev->ArcsRev[0];
+        return NULL;
       }
-
-      anArcRev += aK;
-      aNode->FirstIn = anArcRev;
-      anArcBlockRev->last_node = aNode;
     }
 
-    aNode->FirstOut = anArcFor;
-    aNode->FirstIn  = anArcRev;
-  }
-
-  for (anArcBlockFor=myArcForBlockFirst; anArcBlockFor; anArcBlockFor=anArcBlockFor->Next)
-  {
-    anArcBlockFor->Current = anArcBlockFor->last_node->FirstOut;
-  }
-
-  for (anArcBlockFor=anArcBlockForFirst, anArcBlockRev=anArcBlockRevFirst;
-       anArcBlockFor;
-       anArcBlockFor=anArcBlockFor->Next, anArcBlockRev=anArcBlockRev->Next)
-    for (anArcFor=&anArcBlockFor->ArcsFor[0], anArcRev=&anArcBlockRev->ArcsRev[0];
-         anArcFor<&anArcBlockFor->ArcsFor[ARC_BLOCK_SIZE];
-         anArcFor++, anArcRev++)
+    if (aNode->Next == aNode)
     {
-      ArcForward* anArcForward;
-      ArcReverse* anArcReverse;
-      Node* aNodeFrom;
-      int aShift = 0, aShiftNew;
-      CapacityType aRCap, aReverseRCap, aRCapNew, aReverseRCapNew;
-
-      if (! (aNodeFrom= (Node*) (anArcRev->Sister))) { continue; }
-
-      anArcForward = anArcFor;
-      anArcReverse = anArcRev;
-
-      do
-      {
-        anArcReverse->Sister = NULL;
-
-        aShiftNew = (int)(((char*) (anArcForward->Shift)) - (char*) aNodeFrom);
-        aRCapNew = anArcForward->ResidualCap;
-        aReverseRCapNew = anArcForward->ReverseResidualCap;
-
-        if (aShift)
-        {
-          anArcForward->Shift = aShift;
-          anArcForward->ResidualCap = aRCap;
-          anArcForward->ReverseResidualCap = aReverseRCap;
-        }
-
-        aShift = aShiftNew;
-        aRCap = aRCapNew;
-        aReverseRCap = aReverseRCapNew;
-
-        anArcForward = -- aNodeFrom->FirstOut;
-
-        if ( (ArcReverse*) (aNodeFrom->Parent) != &anArcREvTmp)
-        {
-          aNodeFrom->Parent = (ArcForward*) ( ( (ArcReverse*) (aNodeFrom->Parent)) - 1);
-          anArcReverse = (ArcReverse*) (aNodeFrom->Parent);
-        }
-      }
-      while (aNodeFrom= (Node*) (anArcReverse->Sister));
-
-      anArcForward->Shift = aShift;
-      anArcForward->ResidualCap = aRCap;
-      anArcForward->ReverseResidualCap = aReverseRCap;
+      m_queueFirst[0] = m_queueLast[0] = NULL;
     }
 
-  for (anArcBlockFor=myArcForBlockFirst; anArcBlockFor; anArcBlockFor=anArcBlockFor->Next)
-  {
-    aNode = anArcBlockFor->last_node;
-    anArcFor = aNode->FirstOut;
-    anArcBlockFor->Current->Shift     = anArcFor->Shift;
-    anArcBlockFor->Current->ResidualCap     = anArcFor->ResidualCap;
-    anArcBlockFor->Current->ReverseResidualCap = anArcFor->ReverseResidualCap;
-    anArcFor->Shift = (int) (anArcBlockFor->Current + 1);
-    aNode->FirstOut = (ArcForward*) ( ( (char*) anArcFor) - 1);
-  }
-
-  /* THIRD STAGE */
-  for (anArcBlockRev=myArcREvBlockFirst; anArcBlockRev; anArcBlockRev=anArcBlockRev->Next)
-  {
-    anArcBlockRev->Current = anArcBlockRev->last_node->FirstIn;
-  }
-
-  for (aNodeBlock = myNodeBlockFirst; aNodeBlock; aNodeBlock=aNodeBlock->Next)
-    for (aNode = &aNodeBlock->Nodes[0]; aNode<aNodeBlock->Current; aNode++)
+    else
     {
-      ArcForward* aForwardFirst, *aForwardLAst;
-
-      aForwardFirst = aNode->FirstOut;
-
-      if (IS_ODD (aForwardFirst))
-      {
-        aForwardFirst = (ArcForward*) ( ( (char*) aForwardFirst) + 1);
-        aForwardLAst = (ArcForward*) ( (aForwardFirst ++)->Shift);
-      }
-      else { aForwardLAst = (aNode + 1)->FirstOut; }
-
-      for (anArcFor=aForwardFirst; anArcFor<aForwardLAst; anArcFor++)
-      {
-        Node* to = NEIGHBOR_NODE (aNode, anArcFor->Shift);
-        anArcRev = -- to->FirstIn;
-        anArcRev->Sister = anArcFor;
-      }
+      m_queueFirst[0] = aNode->Next;
     }
 
-  for (anArcBlockRev=myArcREvBlockFirst; anArcBlockRev; anArcBlockRev=anArcBlockRev->Next)
-  {
-    aNode = anArcBlockRev->last_node;
-    anArcRev = aNode->FirstIn;
-    anArcBlockRev->Current->Sister = anArcRev->Sister;
-    anArcRev->Sister = (ArcForward*) (anArcBlockRev->Current + 1);
-    aNode->FirstIn = (ArcReverse*) ( ( (char*) anArcRev) - 1);
-  }
-}
+    aNode->Next = NULL;
 
-#define TERMINAL ( (ArcForward *) 1 )
-#define ORPHAN   ( (ArcForward *) 2 )
-
-#define INFINITE_D 1000000000
-
-inline void Graph::setActive (Node* theNode)
-{
-  if (!theNode->Next)
-  {
-    if (myQueueLast[1]) { myQueueLast[1] -> Next = theNode; }
-    else               { myQueueFirst[1]        = theNode; }
-
-    myQueueLast[1] = theNode;
-    theNode -> Next = theNode;
-  }
-}
-
-inline Graph::Node* Graph::nextActive()
-{
-  Node* aNode;
-
-  while (true)
-  {
-    if (! (aNode=myQueueFirst[0]))
+    if (aNode->Parent)
     {
-      myQueueFirst[0] = aNode = myQueueFirst[1];
-      myQueueLast[0]  = myQueueLast[1];
-      myQueueFirst[1] = NULL;
-      myQueueLast[1]  = NULL;
-
-      if (!aNode) { return NULL; }
+      return aNode;
     }
-
-    if (aNode->Next == aNode) { myQueueFirst[0] = myQueueLast[0] = NULL; }
-    else              { myQueueFirst[0] = aNode -> Next; }
-
-    aNode -> Next = NULL;
-
-    if (aNode->Parent) { return aNode; }
   }
 }
 
-void Graph::maxflowInit()
+void GraphEval::maxflowInit()
 {
   Node* aNode;
-  NodeBlock* aNodeBlock;
 
-  myQueueFirst[0] = myQueueLast[0] = NULL;
-  myQueueFirst[1] = myQueueLast[1] = NULL;
-  myOrphanFirst = NULL;
+  m_queueFirst[0] = m_queueLast[0] = NULL;
+  m_queueFirst[1] = m_queueLast[1] = NULL;
+  m_orphanFirst = NULL;
 
-  for (aNodeBlock=myNodeBlockFirst; aNodeBlock; aNodeBlock=aNodeBlock->Next)
+  for (aNode = m_nodes; aNode < m_nodes + m_nodeNum; aNode++)
   {
-    for (aNode=&aNodeBlock->Nodes[0]; aNode<aNodeBlock->Current; aNode++)
+    aNode->Next = NULL;
+    aNode->TS = 0;
+
+    if (aNode->TrCap > 0)
     {
-      aNode -> Next = NULL;
-      aNode -> TimeStamp = 0;
+      aNode->IsSink = 0;
+      aNode->Parent = TERM;
+      setActive (aNode);
+      aNode->TS = 0;
+      aNode->DIST = 1;
+    }
 
-      if (aNode->TrCapacity > 0)
-      {
-        aNode -> IsSink = 0;
-        aNode -> Parent = TERMINAL;
-        setActive (aNode);
-        aNode -> TimeStamp = 0;
-        aNode -> Distance = 1;
-      }
-      else if (aNode->TrCapacity < 0)
-      {
-        aNode -> IsSink = 1;
-        aNode -> Parent = TERMINAL;
-        setActive (aNode);
-        aNode -> TimeStamp = 0;
-        aNode -> Distance = 1;
-      }
-      else
-      {
-        aNode -> Parent = NULL;
-      }
+    else if (aNode->TrCap < 0)
+    {
+      aNode->IsSink = 1;
+      aNode->Parent = TERM;
+      setActive (aNode);
+      aNode->TS = 0;
+      aNode->DIST = 1;
+    }
+
+    else
+    {
+      aNode->Parent = NULL;
     }
   }
 
-  myTime = 0;
+  m_time = 0;
 }
 
-void Graph::augment (Node* theSStart, Node* theTStart, CapacityType* theCapMiddle, CapacityType* theRevCapMiddle)
+void GraphEval::augment (Edge* theMiddleEdge)
 {
   Node* aNode;
-  ArcForward* anArc;
-  CapacityType aBottleneck;
+  Edge* anEdge;
+  TCapacityType aBottleneck;
   NodePtr* aNodePtr;
 
-  aBottleneck = *theCapMiddle;
+  aBottleneck = theMiddleEdge->ReverseCap;
 
-  for (aNode=theSStart; ;)
+  for (aNode = theMiddleEdge->Sister->Head; ; aNode = anEdge->Head)
   {
-    anArc = aNode -> Parent;
-
-    if (anArc == TERMINAL) { break; }
+    anEdge = aNode->Parent;
 
-    if (IS_ODD (anArc))
+    if (anEdge == TERM)
     {
-      anArc = MAKE_EVEN (anArc);
-
-      if (aBottleneck > anArc->ResidualCap) { aBottleneck = anArc -> ResidualCap; }
-
-      aNode = NEIGHBOR_NODE_REV (aNode, anArc -> Shift);
+      break;
     }
-    else
-    {
-      if (aBottleneck > anArc->ReverseResidualCap) { aBottleneck = anArc -> ReverseResidualCap; }
 
-      aNode = NEIGHBOR_NODE (aNode, anArc -> Shift);
+    if (aBottleneck > anEdge->Sister->ReverseCap)
+    {
+      aBottleneck = anEdge->Sister->ReverseCap;
     }
   }
 
-  if (aBottleneck > aNode->TrCapacity) { aBottleneck = aNode -> TrCapacity; }
-
-  for (aNode=theTStart; ;)
+  if (aBottleneck > aNode->TrCap)
   {
-    anArc = aNode -> Parent;
+    aBottleneck = aNode->TrCap;
+  }
 
-    if (anArc == TERMINAL) { break; }
+  for (aNode = theMiddleEdge->Head; ; aNode = anEdge->Head)
+  {
+    anEdge = aNode->Parent;
 
-    if (IS_ODD (anArc))
+    if (anEdge == TERM)
     {
-      anArc = MAKE_EVEN (anArc);
-
-      if (aBottleneck > anArc->ReverseResidualCap) { aBottleneck = anArc -> ReverseResidualCap; }
-
-      aNode = NEIGHBOR_NODE_REV (aNode, anArc -> Shift);
+      break;
     }
-    else
-    {
-      if (aBottleneck > anArc->ResidualCap) { aBottleneck = anArc -> ResidualCap; }
 
-      aNode = NEIGHBOR_NODE (aNode, anArc -> Shift);
+    if (aBottleneck > anEdge->ReverseCap)
+    {
+      aBottleneck = anEdge->ReverseCap;
     }
   }
 
-  if (aBottleneck > - aNode->TrCapacity) { aBottleneck = - aNode -> TrCapacity; }
+  if (aBottleneck > - aNode->TrCap)
+  {
+    aBottleneck = - aNode->TrCap;
+  }
 
 
-  *theRevCapMiddle += aBottleneck;
-  *theCapMiddle -= aBottleneck;
+  theMiddleEdge->Sister->ReverseCap += aBottleneck;
+  theMiddleEdge->ReverseCap -= aBottleneck;
 
-  for (aNode=theSStart; ;)
+  for (aNode = theMiddleEdge->Sister->Head; ; aNode = anEdge->Head)
   {
-    anArc = aNode -> Parent;
-
-    if (anArc == TERMINAL) { break; }
+    anEdge = aNode->Parent;
 
-    if (IS_ODD (anArc))
+    if (anEdge == TERM)
     {
-      anArc = MAKE_EVEN (anArc);
-      anArc -> ReverseResidualCap += aBottleneck;
-      anArc -> ResidualCap -= aBottleneck;
-
-      if (!anArc->ResidualCap)
-      {
-        aNode -> Parent = ORPHAN;
-        aNodePtr = myNodePtrBLock -> New();
-        aNodePtr -> Ptr = aNode;
-        aNodePtr -> Next = myOrphanFirst;
-        myOrphanFirst = aNodePtr;
-      }
-
-      aNode = NEIGHBOR_NODE_REV (aNode, anArc -> Shift);
+      break;
     }
-    else
-    {
-      anArc -> ResidualCap += aBottleneck;
-      anArc -> ReverseResidualCap -= aBottleneck;
 
-      if (!anArc->ReverseResidualCap)
-      {
-        aNode -> Parent = ORPHAN;
-        aNodePtr = myNodePtrBLock -> New();
-        aNodePtr -> Ptr = aNode;
-        aNodePtr -> Next = myOrphanFirst;
-        myOrphanFirst = aNodePtr;
-      }
+    anEdge->ReverseCap += aBottleneck;
+    anEdge->Sister->ReverseCap -= aBottleneck;
 
-      aNode = NEIGHBOR_NODE (aNode, anArc -> Shift);
+    if (!anEdge->Sister->ReverseCap)
+    {
+      aNode->Parent = ORPH;
+      aNodePtr = m_nodePtrBlock->New();
+      aNodePtr->Ptr = aNode;
+      aNodePtr->Next = m_orphanFirst;
+      m_orphanFirst = aNodePtr;
     }
   }
 
-  aNode -> TrCapacity -= aBottleneck;
+  aNode->TrCap -= aBottleneck;
 
-  if (!aNode->TrCapacity)
+  if (!aNode->TrCap)
   {
-    aNode -> Parent = ORPHAN;
-    aNodePtr = myNodePtrBLock -> New();
-    aNodePtr -> Ptr = aNode;
-    aNodePtr -> Next = myOrphanFirst;
-    myOrphanFirst = aNodePtr;
+    aNode->Parent = ORPH;
+    aNodePtr = m_nodePtrBlock->New();
+    aNodePtr->Ptr = aNode;
+    aNodePtr->Next = m_orphanFirst;
+    m_orphanFirst = aNodePtr;
   }
 
-  for (aNode=theTStart; ;)
+  for (aNode = theMiddleEdge->Head; ; aNode = anEdge->Head)
   {
-    anArc = aNode -> Parent;
-
-    if (anArc == TERMINAL) { break; }
+    anEdge = aNode->Parent;
 
-    if (IS_ODD (anArc))
+    if (anEdge == TERM)
     {
-      anArc = MAKE_EVEN (anArc);
-      anArc -> ResidualCap += aBottleneck;
-      anArc -> ReverseResidualCap -= aBottleneck;
-
-      if (!anArc->ReverseResidualCap)
-      {
-        aNode -> Parent = ORPHAN;
-        aNodePtr = myNodePtrBLock -> New();
-        aNodePtr -> Ptr = aNode;
-        aNodePtr -> Next = myOrphanFirst;
-        myOrphanFirst = aNodePtr;
-      }
-
-      aNode = NEIGHBOR_NODE_REV (aNode, anArc -> Shift);
+      break;
     }
-    else
-    {
-      anArc -> ReverseResidualCap += aBottleneck;
-      anArc -> ResidualCap -= aBottleneck;
 
-      if (!anArc->ResidualCap)
-      {
-        aNode -> Parent = ORPHAN;
-        aNodePtr = myNodePtrBLock -> New();
-        aNodePtr -> Ptr = aNode;
-        aNodePtr -> Next = myOrphanFirst;
-        myOrphanFirst = aNodePtr;
-      }
+    anEdge->Sister->ReverseCap += aBottleneck;
+    anEdge->ReverseCap -= aBottleneck;
 
-      aNode = NEIGHBOR_NODE (aNode, anArc -> Shift);
+    if (!anEdge->ReverseCap)
+    {
+      aNode->Parent = ORPH;
+      aNodePtr = m_nodePtrBlock->New();
+      aNodePtr->Ptr = aNode;
+      aNodePtr->Next = m_orphanFirst;
+      m_orphanFirst = aNodePtr;
     }
   }
 
-  aNode -> TrCapacity += aBottleneck;
+  aNode->TrCap += aBottleneck;
 
-  if (!aNode->TrCapacity)
+  if (!aNode->TrCap)
   {
-    aNode -> Parent = ORPHAN;
-    aNodePtr = myNodePtrBLock -> New();
-    aNodePtr -> Ptr = aNode;
-    aNodePtr -> Next = myOrphanFirst;
-    myOrphanFirst = aNodePtr;
+    aNode->Parent = ORPH;
+    aNodePtr = m_nodePtrBlock->New();
+    aNodePtr->Ptr = aNode;
+    aNodePtr->Next = m_orphanFirst;
+    m_orphanFirst = aNodePtr;
   }
 
-  myFlow += aBottleneck;
+
+  m_flow += aBottleneck;
 }
 
-void Graph::processSourceOrphan (Node* theNode)
+void GraphEval::processSourceOrphan (Node* theNode)
 {
   Node* aNode;
-  ArcForward* anArc0For, *anArc0ForFirst, *anArc0ForLast;
-  ArcReverse* anArc0Rev, *anArc0RevFirst, *anArc0RevLast;
-  ArcForward* anArc0Min = NULL, *anArc;
+  Edge* anEdge0, *anEdge0Min = NULL, *anEdge;
   NodePtr* aNodePtr;
-  int aDist, aDistMin = INFINITE_D;
-
-  anArc0ForFirst = theNode -> FirstOut;
+  int d, d_min = INFINITE;
 
-  if (IS_ODD (anArc0ForFirst))
-  {
-    anArc0ForFirst = (ArcForward*) ( ( (char*) anArc0ForFirst) + 1);
-    anArc0ForLast = (ArcForward*) ( (anArc0ForFirst ++) -> Shift);
-  }
-  else { anArc0ForLast = (theNode + 1) -> FirstOut; }
-
-  anArc0RevFirst = theNode -> FirstIn;
-
-  if (IS_ODD (anArc0RevFirst))
-  {
-    anArc0RevFirst = (ArcReverse*) ( ( (char*) anArc0RevFirst) + 1);
-    anArc0RevLast  = (ArcReverse*) ( (anArc0RevFirst ++) -> Sister);
-  }
-  else { anArc0RevLast = (theNode + 1) -> FirstIn; }
-
-
-  for (anArc0For=anArc0ForFirst; anArc0For<anArc0ForLast; anArc0For++)
-    if (anArc0For->ReverseResidualCap)
+  for (anEdge0 = theNode->First; anEdge0; anEdge0 = anEdge0->Next)
+    if (anEdge0->Sister->ReverseCap)
     {
-      aNode = NEIGHBOR_NODE (theNode, anArc0For -> Shift);
+      aNode = anEdge0->Head;
 
-      if (!aNode->IsSink && (anArc=aNode->Parent))
+      if (!aNode->IsSink && (anEdge = aNode->Parent))
       {
-        /* checking the origin of j */
-        aDist = 0;
+        d = 0;
 
-        while (true)
+        while (1)
         {
-          if (aNode->TimeStamp == myTime)
+          if (aNode->TS == m_time)
           {
-            aDist += aNode -> Distance;
+            d += aNode->DIST;
             break;
           }
 
-          anArc = aNode -> Parent;
-          aDist ++;
+          anEdge = aNode->Parent;
+          d ++;
 
-          if (anArc==TERMINAL)
+          if (anEdge == TERM)
           {
-            aNode -> TimeStamp = myTime;
-            aNode -> Distance = 1;
+            aNode->TS = m_time;
+            aNode->DIST = 1;
             break;
           }
 
-          if (anArc==ORPHAN) { aDist = INFINITE_D; break; }
-
-          if (IS_ODD (anArc))
-          { aNode = NEIGHBOR_NODE_REV (aNode, MAKE_EVEN (anArc) -> Shift); }
-          else
-          { aNode = NEIGHBOR_NODE (aNode, anArc -> Shift); }
-        }
-
-        if (aDist<INFINITE_D)
-        {
-          if (aDist<aDistMin)
+          if (anEdge == ORPH)
           {
-            anArc0Min = anArc0For;
-            aDistMin = aDist;
-          }
-
-          for (aNode=NEIGHBOR_NODE (theNode, anArc0For->Shift); aNode->TimeStamp!=myTime;)
-          {
-            aNode -> TimeStamp = myTime;
-            aNode -> Distance = aDist --;
-            anArc = aNode->Parent;
-
-            if (IS_ODD (anArc))
-            { aNode = NEIGHBOR_NODE_REV (aNode, MAKE_EVEN (anArc) -> Shift); }
-            else
-            { aNode = NEIGHBOR_NODE (aNode, anArc -> Shift); }
-          }
-        }
-      }
-    }
-
-  for (anArc0Rev=anArc0RevFirst; anArc0Rev<anArc0RevLast; anArc0Rev++)
-  {
-    anArc0For = anArc0Rev -> Sister;
-
-    if (anArc0For->ResidualCap)
-    {
-      aNode = NEIGHBOR_NODE_REV (theNode, anArc0For -> Shift);
-
-      if (!aNode->IsSink && (anArc=aNode->Parent))
-      {
-        aDist = 0;
-
-        while (true)
-        {
-          if (aNode->TimeStamp == myTime)
-          {
-            aDist += aNode -> Distance;
+            d = INFINITE;
             break;
           }
 
-          anArc = aNode -> Parent;
-          aDist ++;
-
-          if (anArc==TERMINAL)
-          {
-            aNode -> TimeStamp = myTime;
-            aNode -> Distance = 1;
-            break;
-          }
-
-          if (anArc==ORPHAN) { aDist = INFINITE_D; break; }
-
-          if (IS_ODD (anArc))
-          { aNode = NEIGHBOR_NODE_REV (aNode, MAKE_EVEN (anArc) -> Shift); }
-          else
-          { aNode = NEIGHBOR_NODE (aNode, anArc -> Shift); }
+          aNode = anEdge->Head;
         }
 
-        if (aDist<INFINITE_D)
+        if (d < INFINITE)
         {
-          if (aDist<aDistMin)
+          if (d < d_min)
           {
-            anArc0Min = MAKE_ODD (anArc0For);
-            aDistMin = aDist;
+            anEdge0Min = anEdge0;
+            d_min = d;
           }
 
-          for (aNode=NEIGHBOR_NODE_REV (theNode,anArc0For->Shift); aNode->TimeStamp!=myTime;)
+          for (aNode = anEdge0->Head; aNode->TS != m_time; aNode = aNode->Parent->Head)
           {
-            aNode -> TimeStamp = myTime;
-            aNode -> Distance = aDist --;
-            anArc = aNode->Parent;
-
-            if (IS_ODD (anArc))
-            { aNode = NEIGHBOR_NODE_REV (aNode, MAKE_EVEN (anArc) -> Shift); }
-            else
-            { aNode = NEIGHBOR_NODE (aNode, anArc -> Shift); }
+            aNode->TS = m_time;
+            aNode->DIST = d --;
           }
         }
       }
     }
-  }
 
-  if (theNode->Parent = anArc0Min)
+  if (theNode->Parent = anEdge0Min)
   {
-    theNode -> TimeStamp = myTime;
-    theNode -> Distance = aDistMin + 1;
+    theNode->TS = m_time;
+    theNode->DIST = d_min + 1;
   }
+
   else
   {
-    theNode -> TimeStamp = 0;
+    theNode->TS = 0;
 
-    for (anArc0For=anArc0ForFirst; anArc0For<anArc0ForLast; anArc0For++)
+    for (anEdge0 = theNode->First; anEdge0; anEdge0 = anEdge0->Next)
     {
-      aNode = NEIGHBOR_NODE (theNode, anArc0For -> Shift);
+      aNode = anEdge0->Head;
 
-      if (!aNode->IsSink && (anArc=aNode->Parent))
+      if (!aNode->IsSink && (anEdge = aNode->Parent))
       {
-        if (anArc0For->ReverseResidualCap) { setActive (aNode); }
-
-        if (anArc!=TERMINAL && anArc!=ORPHAN && IS_ODD (anArc) && NEIGHBOR_NODE_REV (aNode, MAKE_EVEN (anArc)->Shift) ==theNode)
+        if (anEdge0->Sister->ReverseCap)
         {
-          aNode -> Parent = ORPHAN;
-          aNodePtr = myNodePtrBLock -> New();
-          aNodePtr -> Ptr = aNode;
-
-          if (myOrphanLast) { myOrphanLast -> Next = aNodePtr; }
-          else             { myOrphanFirst        = aNodePtr; }
-
-          myOrphanLast = aNodePtr;
-          aNodePtr -> Next = NULL;
+          setActive (aNode);
         }
-      }
-    }
 
-    for (anArc0Rev=anArc0RevFirst; anArc0Rev<anArc0RevLast; anArc0Rev++)
-    {
-      anArc0For = anArc0Rev -> Sister;
-      aNode = NEIGHBOR_NODE_REV (theNode, anArc0For -> Shift);
-
-      if (!aNode->IsSink && (anArc=aNode->Parent))
-      {
-        if (anArc0For->ResidualCap) { setActive (aNode); }
-
-        if (anArc!=TERMINAL && anArc!=ORPHAN && !IS_ODD (anArc) && NEIGHBOR_NODE (aNode, anArc->Shift) ==theNode)
+        if (anEdge != TERM && anEdge != ORPH && anEdge->Head == theNode)
         {
-          aNode -> Parent = ORPHAN;
-          aNodePtr = myNodePtrBLock -> New();
-          aNodePtr -> Ptr = aNode;
+          aNode->Parent = ORPH;
+          aNodePtr = m_nodePtrBlock->New();
+          aNodePtr->Ptr = aNode;
+
+          if (m_orphanLast)
+          {
+            m_orphanLast->Next = aNodePtr;
+          }
 
-          if (myOrphanLast) { myOrphanLast -> Next = aNodePtr; }
-          else             { myOrphanFirst        = aNodePtr; }
+          else
+          {
+            m_orphanFirst        = aNodePtr;
+          }
 
-          myOrphanLast = aNodePtr;
-          aNodePtr -> Next = NULL;
+          m_orphanLast = aNodePtr;
+          aNodePtr->Next = NULL;
         }
       }
     }
   }
 }
 
-void Graph::processSinkOrphan (Node* theNode)
+void GraphEval::processSinkOrphan (Node* theNode)
 {
   Node* aNode;
-  ArcForward* anArc0For, *anArc0ForFirst, *anArc0ForLast;
-  ArcReverse* anArc0Rev, *anArc0RevFirst, *anArc0RevLast;
-  ArcForward* anArc0Min = NULL, *anArc;
+  Edge* anEdge0, *anEdge0Min = NULL, *anEdge;
   NodePtr* aNodePtr;
-  int aDist, aDistMin = INFINITE_D;
-
-  anArc0ForFirst = theNode -> FirstOut;
+  int d, d_min = INFINITE;
 
-  if (IS_ODD (anArc0ForFirst))
-  {
-    anArc0ForFirst = (ArcForward*) ( ( (char*) anArc0ForFirst) + 1);
-    anArc0ForLast = (ArcForward*) ( (anArc0ForFirst ++) -> Shift);
-  }
-  else { anArc0ForLast = (theNode + 1) -> FirstOut; }
-
-  anArc0RevFirst = theNode -> FirstIn;
-
-  if (IS_ODD (anArc0RevFirst))
-  {
-    anArc0RevFirst = (ArcReverse*) ( ( (char*) anArc0RevFirst) + 1);
-    anArc0RevLast  = (ArcReverse*) ( (anArc0RevFirst ++) -> Sister);
-  }
-  else { anArc0RevLast = (theNode + 1) -> FirstIn; }
-
-
-  for (anArc0For=anArc0ForFirst; anArc0For<anArc0ForLast; anArc0For++)
-    if (anArc0For->ResidualCap)
+  for (anEdge0 = theNode->First; anEdge0; anEdge0 = anEdge0->Next)
+    if (anEdge0->ReverseCap)
     {
-      aNode = NEIGHBOR_NODE (theNode, anArc0For -> Shift);
+      aNode = anEdge0->Head;
 
-      if (aNode->IsSink && (anArc=aNode->Parent))
+      if (aNode->IsSink && (anEdge = aNode->Parent))
       {
-        aDist = 0;
+        d = 0;
 
-        while (true)
+        while (1)
         {
-          if (aNode->TimeStamp == myTime)
+          if (aNode->TS == m_time)
           {
-            aDist += aNode -> Distance;
+            d += aNode->DIST;
             break;
           }
 
-          anArc = aNode -> Parent;
-          aDist ++;
+          anEdge = aNode->Parent;
+          d ++;
 
-          if (anArc==TERMINAL)
+          if (anEdge == TERM)
           {
-            aNode -> TimeStamp = myTime;
-            aNode -> Distance = 1;
+            aNode->TS = m_time;
+            aNode->DIST = 1;
             break;
           }
 
-          if (anArc==ORPHAN) { aDist = INFINITE_D; break; }
-
-          if (IS_ODD (anArc))
-          { aNode = NEIGHBOR_NODE_REV (aNode, MAKE_EVEN (anArc) -> Shift); }
-          else
-          { aNode = NEIGHBOR_NODE (aNode, anArc -> Shift); }
-        }
-
-        if (aDist<INFINITE_D)
-        {
-          if (aDist<aDistMin)
+          if (anEdge == ORPH)
           {
-            anArc0Min = anArc0For;
-            aDistMin = aDist;
-          }
-
-          for (aNode=NEIGHBOR_NODE (theNode, anArc0For->Shift); aNode->TimeStamp!=myTime;)
-          {
-            aNode -> TimeStamp = myTime;
-            aNode -> Distance = aDist --;
-            anArc = aNode->Parent;
-
-            if (IS_ODD (anArc))
-            { aNode = NEIGHBOR_NODE_REV (aNode, MAKE_EVEN (anArc) -> Shift); }
-            else
-            { aNode = NEIGHBOR_NODE (aNode, anArc -> Shift); }
-          }
-        }
-      }
-    }
-
-  for (anArc0Rev=anArc0RevFirst; anArc0Rev<anArc0RevLast; anArc0Rev++)
-  {
-    anArc0For = anArc0Rev -> Sister;
-
-    if (anArc0For->ReverseResidualCap)
-    {
-      aNode = NEIGHBOR_NODE_REV (theNode, anArc0For -> Shift);
-
-      if (aNode->IsSink && (anArc=aNode->Parent))
-      {
-        aDist = 0;
-
-        while (true)
-        {
-          if (aNode->TimeStamp == myTime)
-          {
-            aDist += aNode -> Distance;
-            break;
-          }
-
-          anArc = aNode -> Parent;
-          aDist ++;
-
-          if (anArc==TERMINAL)
-          {
-            aNode -> TimeStamp = myTime;
-            aNode -> Distance = 1;
+            d = INFINITE;
             break;
           }
 
-          if (anArc==ORPHAN) { aDist = INFINITE_D; break; }
-
-          if (IS_ODD (anArc))
-          { aNode = NEIGHBOR_NODE_REV (aNode, MAKE_EVEN (anArc) -> Shift); }
-          else
-          { aNode = NEIGHBOR_NODE (aNode, anArc -> Shift); }
+          aNode = anEdge->Head;
         }
 
-        if (aDist<INFINITE_D)
+        if (d < INFINITE)
         {
-          if (aDist<aDistMin)
+          if (d < d_min)
           {
-            anArc0Min = MAKE_ODD (anArc0For);
-            aDistMin = aDist;
+            anEdge0Min = anEdge0;
+            d_min = d;
           }
 
-          for (aNode=NEIGHBOR_NODE_REV (theNode,anArc0For->Shift); aNode->TimeStamp!=myTime;)
+          for (aNode = anEdge0->Head; aNode->TS != m_time; aNode = aNode->Parent->Head)
           {
-            aNode -> TimeStamp = myTime;
-            aNode -> Distance = aDist --;
-            anArc = aNode->Parent;
-
-            if (IS_ODD (anArc))
-            { aNode = NEIGHBOR_NODE_REV (aNode, MAKE_EVEN (anArc) -> Shift); }
-            else
-            { aNode = NEIGHBOR_NODE (aNode, anArc -> Shift); }
+            aNode->TS = m_time;
+            aNode->DIST = d --;
           }
         }
       }
     }
-  }
 
-  if (theNode->Parent = anArc0Min)
+  if (theNode->Parent = anEdge0Min)
   {
-    theNode -> TimeStamp = myTime;
-    theNode -> Distance = aDistMin + 1;
+    theNode->TS = m_time;
+    theNode->DIST = d_min + 1;
   }
+
   else
   {
-    theNode -> TimeStamp = 0;
+    theNode->TS = 0;
 
-    for (anArc0For=anArc0ForFirst; anArc0For<anArc0ForLast; anArc0For++)
+    for (anEdge0 = theNode->First; anEdge0; anEdge0 = anEdge0->Next)
     {
-      aNode = NEIGHBOR_NODE (theNode, anArc0For -> Shift);
+      aNode = anEdge0->Head;
 
-      if (aNode->IsSink && (anArc=aNode->Parent))
+      if (aNode->IsSink && (anEdge = aNode->Parent))
       {
-        if (anArc0For->ResidualCap) { setActive (aNode); }
-
-        if (anArc!=TERMINAL && anArc!=ORPHAN && IS_ODD (anArc) && NEIGHBOR_NODE_REV (aNode, MAKE_EVEN (anArc)->Shift) ==theNode)
+        if (anEdge0->ReverseCap)
         {
-          aNode -> Parent = ORPHAN;
-          aNodePtr = myNodePtrBLock -> New();
-          aNodePtr -> Ptr = aNode;
-
-          if (myOrphanLast) { myOrphanLast -> Next = aNodePtr; }
-          else             { myOrphanFirst        = aNodePtr; }
-
-          myOrphanLast = aNodePtr;
-          aNodePtr -> Next = NULL;
+          setActive (aNode);
         }
-      }
-    }
-
-    for (anArc0Rev=anArc0RevFirst; anArc0Rev<anArc0RevLast; anArc0Rev++)
-    {
-      anArc0For = anArc0Rev -> Sister;
-      aNode = NEIGHBOR_NODE_REV (theNode, anArc0For -> Shift);
-
-      if (aNode->IsSink && (anArc=aNode->Parent))
-      {
-        if (anArc0For->ReverseResidualCap) { setActive (aNode); }
 
-        if (anArc!=TERMINAL && anArc!=ORPHAN && !IS_ODD (anArc) && NEIGHBOR_NODE (aNode, anArc->Shift) ==theNode)
+        if (anEdge != TERM && anEdge != ORPH && anEdge->Head == theNode)
         {
-          aNode -> Parent = ORPHAN;
-          aNodePtr = myNodePtrBLock -> New();
-          aNodePtr -> Ptr = aNode;
+          aNode->Parent = ORPH;
+          aNodePtr = m_nodePtrBlock->New();
+          aNodePtr->Ptr = aNode;
 
-          if (myOrphanLast) { myOrphanLast -> Next = aNodePtr; }
-          else             { myOrphanFirst        = aNodePtr; }
+          if (m_orphanLast)
+          {
+            m_orphanLast->Next = aNodePtr;
+          }
+
+          else
+          {
+            m_orphanFirst        = aNodePtr;
+          }
 
-          myOrphanLast = aNodePtr;
-          aNodePtr -> Next = NULL;
+          m_orphanLast = aNodePtr;
+          aNodePtr->Next = NULL;
         }
       }
     }
   }
 }
 
-Graph::FlowType Graph::MaximumFlow()
+GraphEval::FlowType GraphEval::MaximumFlow()
 {
-  Node* aNode0, *aNode1, *aCurrentNode = NULL, *aSStart, *aTStart;
-  CapacityType* aCapacityMiddle, *aRevCapacityMiddle;
-  ArcForward* anArcFor, *anArcForFirst, *anArcForLast;
-  ArcReverse* anArcRev, *anArcRevFirst, *anArcRevLAst;
-  NodePtr* aNodePtr, *aNodePtrNext;
+  Node* i, *j, *current_node = NULL;
+  Edge* a;
+  NodePtr* np, *np_next;
 
-  prepareGraph();
   maxflowInit();
-  myNodePtrBLock = new DBlock<NodePtr> (NODEPTR_BLOCK_SIZE, myErrorFun);
+  m_nodePtrBlock = new DataBlock<NodePtr> (NODEPTR_BLOCK_SIZE);
 
-  while (true)
+  while (1)
   {
-    if (aNode0=aCurrentNode)
-    {
-      aNode0 -> Next = NULL;
-
-      if (!aNode0->Parent) { aNode0 = NULL; }
-    }
-
-    if (!aNode0)
+    if (i = current_node)
     {
-      if (! (aNode0 = nextActive())) { break; }
-    }
-
-    aSStart = NULL;
-
-    anArcForFirst = aNode0 -> FirstOut;
+      i->Next = NULL;
 
-    if (IS_ODD (anArcForFirst))
-    {
-      anArcForFirst = (ArcForward*) ( ( (char*) anArcForFirst) + 1);
-      anArcForLast = (ArcForward*) ( (anArcForFirst ++) -> Shift);
+      if (!i->Parent)
+      {
+        i = NULL;
+      }
     }
-    else { anArcForLast = (aNode0 + 1) -> FirstOut; }
 
-    anArcRevFirst = aNode0 -> FirstIn;
-
-    if (IS_ODD (anArcRevFirst))
+    if (!i)
     {
-      anArcRevFirst = (ArcReverse*) ( ( (char*) anArcRevFirst) + 1);
-      anArcRevLAst = (ArcReverse*) ( (anArcRevFirst ++) -> Sister);
+      if (! (i = nextActive()))
+      {
+        break;
+      }
     }
-    else { anArcRevLAst = (aNode0 + 1) -> FirstIn; }
 
-    if (!aNode0->IsSink)
+    if (!i->IsSink)
     {
-      for (anArcFor=anArcForFirst; anArcFor<anArcForLast; anArcFor++)
-        if (anArcFor->ResidualCap)
+      for (a = i->First; a; a = a->Next)
+        if (a->ReverseCap)
         {
-          aNode1 = NEIGHBOR_NODE (aNode0, anArcFor -> Shift);
+          j = a->Head;
 
-          if (!aNode1->Parent)
+          if (!j->Parent)
           {
-            aNode1 -> IsSink = 0;
-            aNode1 -> Parent = MAKE_ODD (anArcFor);
-            aNode1 -> TimeStamp = aNode0 -> TimeStamp;
-            aNode1 -> Distance = aNode0 -> Distance + 1;
-            setActive (aNode1);
+            j->IsSink = 0;
+            j->Parent = a->Sister;
+            j->TS = i->TS;
+            j->DIST = i->DIST + 1;
+            setActive (j);
           }
-          else if (aNode1->IsSink)
+
+          else if (j->IsSink)
           {
-            aSStart = aNode0;
-            aTStart = aNode1;
-            aCapacityMiddle     = & (anArcFor -> ResidualCap);
-            aRevCapacityMiddle = & (anArcFor -> ReverseResidualCap);
             break;
           }
-          else if (aNode1->TimeStamp <= aNode0->TimeStamp &&
-                   aNode1->Distance > aNode0->Distance)
-          {
-            aNode1 -> Parent = MAKE_ODD (anArcFor);
-            aNode1 -> TimeStamp = aNode0 -> TimeStamp;
-            aNode1 -> Distance = aNode0 -> Distance + 1;
-          }
-        }
 
-      if (!aSStart)
-        for (anArcRev=anArcRevFirst; anArcRev<anArcRevLAst; anArcRev++)
-        {
-          anArcFor = anArcRev -> Sister;
-
-          if (anArcFor->ReverseResidualCap)
+          else if (j->TS <= i->TS &&
+                   j->DIST > i->DIST)
           {
-            aNode1 = NEIGHBOR_NODE_REV (aNode0, anArcFor -> Shift);
-
-            if (!aNode1->Parent)
-            {
-              aNode1 -> IsSink = 0;
-              aNode1 -> Parent = anArcFor;
-              aNode1 -> TimeStamp = aNode0 -> TimeStamp;
-              aNode1 -> Distance = aNode0 -> Distance + 1;
-              setActive (aNode1);
-            }
-            else if (aNode1->IsSink)
-            {
-              aSStart = aNode0;
-              aTStart = aNode1;
-              aCapacityMiddle     = & (anArcFor -> ReverseResidualCap);
-              aRevCapacityMiddle = & (anArcFor -> ResidualCap);
-              break;
-            }
-            else if (aNode1->TimeStamp <= aNode0->TimeStamp &&
-                     aNode1->Distance > aNode0->Distance)
-            {
-              aNode1 -> Parent = anArcFor;
-              aNode1 -> TimeStamp = aNode0 -> TimeStamp;
-              aNode1 -> Distance = aNode0 -> Distance + 1;
-            }
+            j->Parent = a->Sister;
+            j->TS = i->TS;
+            j->DIST = i->DIST + 1;
           }
         }
     }
+
     else
     {
-      for (anArcFor=anArcForFirst; anArcFor<anArcForLast; anArcFor++)
-        if (anArcFor->ReverseResidualCap)
+      for (a = i->First; a; a = a->Next)
+        if (a->Sister->ReverseCap)
         {
-          aNode1 = NEIGHBOR_NODE (aNode0, anArcFor -> Shift);
+          j = a->Head;
 
-          if (!aNode1->Parent)
+          if (!j->Parent)
           {
-            aNode1 -> IsSink = 1;
-            aNode1 -> Parent = MAKE_ODD (anArcFor);
-            aNode1 -> TimeStamp = aNode0 -> TimeStamp;
-            aNode1 -> Distance = aNode0 -> Distance + 1;
-            setActive (aNode1);
+            j->IsSink = 1;
+            j->Parent = a->Sister;
+            j->TS = i->TS;
+            j->DIST = i->DIST + 1;
+            setActive (j);
           }
-          else if (!aNode1->IsSink)
+
+          else if (!j->IsSink)
           {
-            aSStart = aNode1;
-            aTStart = aNode0;
-            aCapacityMiddle     = & (anArcFor -> ReverseResidualCap);
-            aRevCapacityMiddle = & (anArcFor -> ResidualCap);
+            a = a->Sister;
             break;
           }
-          else if (aNode1->TimeStamp <= aNode0->TimeStamp &&
-                   aNode1->Distance > aNode0->Distance)
+
+          else if (j->TS <= i->TS &&
+                   j->DIST > i->DIST)
           {
-            aNode1 -> Parent = MAKE_ODD (anArcFor);
-            aNode1 -> TimeStamp = aNode0 -> TimeStamp;
-            aNode1 -> Distance = aNode0 -> Distance + 1;
+            j->Parent = a->Sister;
+            j->TS = i->TS;
+            j->DIST = i->DIST + 1;
           }
         }
+    }
+
+    m_time ++;
+
+    if (a)
+    {
+      i->Next = i;
+      current_node = i;
+
+      augment (a);
 
-      for (anArcRev=anArcRevFirst; anArcRev<anArcRevLAst; anArcRev++)
+      while (np = m_orphanFirst)
       {
-        anArcFor = anArcRev -> Sister;
+        np_next = np->Next;
+        np->Next = NULL;
 
-        if (anArcFor->ResidualCap)
+        while (np = m_orphanFirst)
         {
-          aNode1 = NEIGHBOR_NODE_REV (aNode0, anArcFor -> Shift);
+          m_orphanFirst = np->Next;
+          i = np->Ptr;
+          m_nodePtrBlock->Delete (np);
 
-          if (!aNode1->Parent)
+          if (!m_orphanFirst)
           {
-            aNode1 -> IsSink = 1;
-            aNode1 -> Parent = anArcFor;
-            aNode1 -> TimeStamp = aNode0 -> TimeStamp;
-            aNode1 -> Distance = aNode0 -> Distance + 1;
-            setActive (aNode1);
+            m_orphanLast = NULL;
           }
-          else if (!aNode1->IsSink)
+
+          if (i->IsSink)
           {
-            aSStart = aNode1;
-            aTStart = aNode0;
-            aCapacityMiddle     = & (anArcFor -> ResidualCap);
-            aRevCapacityMiddle = & (anArcFor -> ReverseResidualCap);
-            break;
+            processSinkOrphan (i);
           }
-          else if (aNode1->TimeStamp <= aNode0->TimeStamp &&
-                   aNode1->Distance > aNode0->Distance)
+
+          else
           {
-            aNode1 -> Parent = anArcFor;
-            aNode1 -> TimeStamp = aNode0 -> TimeStamp;
-            aNode1 -> Distance = aNode0 -> Distance + 1;
+            processSourceOrphan (i);
           }
         }
+
+        m_orphanFirst = np_next;
       }
     }
 
-    myTime ++;
-
-    if (aSStart)
+    else
     {
-      aNode0 -> Next = aNode0;
-      aCurrentNode = aNode0;
-
-      augment (aSStart, aTStart, aCapacityMiddle, aRevCapacityMiddle);
-
-      while (aNodePtr=myOrphanFirst)
-      {
-        aNodePtrNext = aNodePtr -> Next;
-        aNodePtr -> Next = NULL;
-
-        while (aNodePtr=myOrphanFirst)
-        {
-          myOrphanFirst = aNodePtr -> Next;
-          aNode0 = aNodePtr -> Ptr;
-          myNodePtrBLock -> Delete (aNodePtr);
-
-          if (!myOrphanFirst) { myOrphanLast = NULL; }
-
-          if (aNode0->IsSink) { processSinkOrphan (aNode0); }
-          else            { processSourceOrphan (aNode0); }
-        }
-
-        myOrphanFirst = aNodePtrNext;
-      }
+      current_node = NULL;
     }
-    else { aCurrentNode = NULL; }
   }
 
-  delete myNodePtrBLock;
+  delete m_nodePtrBlock;
 
-  return myFlow;
+  return m_flow;
 }
 
-Graph::TerminalType Graph::Label (NodeId i)
+GraphEval::TerminalType GraphEval::Label (NodeId theNode)
 {
-  if ( ( (Node*) i)->Parent && ! ( (Node*) i)->IsSink) { return SOURCE; }
+  if (m_nodes[theNode].Parent && ! (m_nodes[theNode].IsSink))
+  {
+    return SOURCE;
+  }
 
   return SINK;
 }
index 3657a8ffade104fef0948540bddbed330e9594f0..bb6dcf8cdd8874686202f9a32e6cd43fefe04a99 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#ifndef __GRAPH_H__
-#define __GRAPH_H__
+#ifndef _BRepMesh_MinStCut_HeaderFile
+#define _BRepMesh_MinStCut_HeaderFile
+
+#include <cassert>
 
-#include <assert.h>
 #include <BRepMesh_Block.hxx>
 
-#define NODE_BLOCK_SIZE 512
-#define ARC_BLOCK_SIZE 1024
+#define EDGE_BLOCK_SIZE 1024
 #define NODEPTR_BLOCK_SIZE 128
 
-class Graph
+class GraphEval
 {
 public:
   typedef enum
   {
-    SOURCE  = 0,
-    SINK  = 1
+    SOURCE = 0,
+    SINK = 1
   } TerminalType;
 
+  typedef int NodeId;
   typedef double CapacityType;
   typedef double FlowType;
-  typedef void* NodeId;
-
-  Graph (void (*theErrFun) (char*) = NULL);
-
-  ~Graph();
-
-  NodeId AddNode();
-
-  void AddEdge (NodeId theFromNode, NodeId theToNode, CapacityType theCapNode, CapacityType theRevCapacity);
-
-  void SetTWeights (NodeId theNode, CapacityType theCapacityToSource, CapacityType theCapacityToSink);
+  typedef double TCapacityType;
 
-  void AddTWeights (NodeId theNode, CapacityType theCapacityToSource, CapacityType theCapacityToSink);
+  GraphEval (const int theNodeNumMax);
 
-  TerminalType Label (NodeId i);
+  ~GraphEval();
 
+  NodeId AddNode (int theNum = 1);
+  void AddEdge (NodeId theNodeFrom, NodeId theNodeTo, CapacityType theCap, CapacityType theRevCap);
+  void AddTWeights (NodeId theNode, CapacityType theCapSource, CapacityType theCapSink);
+  TerminalType Label (NodeId theNode);
   FlowType MaximumFlow();
 
 private:
+  struct EdgeStruct;
 
-  struct ArcForwardSt;
-  struct ArcReverseSt;
-
-#define IS_ODD(a) ((int)(a) & 1)
-#define MAKE_ODD(a)  ((ArcForward *) ((int)(a) | 1))
-#define MAKE_EVEN(a) ((ArcForward *) ((int)(a) & (~1)))
-#define MAKE_ODD_REV(a)  ((ArcReverse *) ((int)(a) | 1))
-#define MAKE_EVEN_REV(a) ((ArcReverse *) ((int)(a) & (~1)))
-
-  typedef struct NodeSt
+  typedef struct NodeStruct
   {
-    ArcForwardSt*  FirstOut;
-    ArcReverseSt*  FirstIn;
-
-    ArcForwardSt*  Parent;
+    EdgeStruct* First;
 
-    NodeSt*      Next;
+    EdgeStruct* Parent;
+    NodeStruct* Next;
+    int TS;
+    int DIST;
+    short IsSink;
 
-    int       TimeStamp;
-    int       Distance;
-    short     IsSink;
-
-    CapacityType      TrCapacity;
+    CapacityType TrCap;
   } Node;
 
-#define NEIGHBOR_NODE(i, shift) ((Node *) ((char *)(i) + (shift)))
-#define NEIGHBOR_NODE_REV(i, shift) ((Node *) ((char *)(i) - (shift)))
-  typedef struct ArcForwardSt
+  typedef struct EdgeStruct
   {
-    int Shift;
-    CapacityType ResidualCap;
-    CapacityType ReverseResidualCap;
-  } ArcForward;
+    NodeStruct* Head;
+    EdgeStruct* Next;
+    EdgeStruct* Sister;
 
-  typedef struct ArcReverseSt
-  {
-    ArcForward*    Sister;
-  } ArcReverse;
+    CapacityType ReverseCap;
+  } Edge;
 
-  typedef struct NodePtrSt
+  typedef struct NodePtrStruct
   {
-    NodeSt*      Ptr;
-    NodePtrSt*   Next;
+    NodeStruct* Ptr;
+    NodePtrStruct* Next;
   } NodePtr;
 
-  typedef struct NodeBLockSt
-  {
-    Node*          Current;
-    struct NodeBLockSt*  Next;
-    Node          Nodes[NODE_BLOCK_SIZE];
-  } NodeBlock;
+  NodeStruct* m_nodes;
+  int m_nodeNum, m_nodeNumMax;
+  Storage<Edge>* m_edgeBlock;
+  DataBlock<NodePtr>* m_nodePtrBlock;
 
-#define last_node LAST_NODE.LAST_NODE
+  FlowType m_flow;
 
-  typedef struct ArcForBlockSt
-  {
-    char*          Start;
-    ArcForward*        Current;
-    struct ArcForBlockSt*  Next;
-    ArcForward        ArcsFor[ARC_BLOCK_SIZE];
-    union
-    {
-      ArcForward      Dummy;
-      Node*        LAST_NODE;
-    }           LAST_NODE;
-  } ArcForBlock;
-
-  typedef struct ArcRevBlockSt
-  {
-    char*          Start;
-    ArcReverse*        Current;
-    struct ArcRevBlockSt*  Next;
-    ArcReverse        ArcsRev[ARC_BLOCK_SIZE];
-    union
-    {
-      ArcReverse      Dummy;
-      Node*        LAST_NODE;
-    }           LAST_NODE;
-  } ArcRevBlock;
-
-  NodeBlock*     myNodeBlockFirst;
-  ArcForBlock*   myArcForBlockFirst;
-  ArcRevBlock*   myArcREvBlockFirst;
-  DBlock<NodePtr>*   myNodePtrBLock;
-
-  void (*myErrorFun) (char*);
-
-  FlowType      myFlow;
-
-  Node*        myQueueFirst[2], *myQueueLast[2];
-  NodePtr*       myOrphanFirst, *myOrphanLast;
-  int         myTime;
+  Node* m_queueFirst[2], *m_queueLast[2];
+  NodePtr* m_orphanFirst, *m_orphanLast;
+  int m_time;
 
   void setActive (Node* theNode);
   Node* nextActive();
 
-  void prepareGraph();
   void maxflowInit();
-  void augment (Node* theSStart, Node* theTStart, CapacityType* theCapMiddle, CapacityType* theRevCapMiddle);
+  void augment (Edge* theMiddleEdge);
   void processSourceOrphan (Node* theNode);
   void processSinkOrphan (Node* theNode);
 };
 
-class Energy : Graph
+class Energy : GraphEval
 {
 public:
   typedef NodeId Var;
@@ -165,7 +106,7 @@ public:
   typedef CapacityType Value;
   typedef FlowType TotalValue;
 
-  Energy (void (*theErrFun) (char*) = NULL);
+  Energy (const int theMaxNodes);
 
   ~Energy();
 
@@ -184,23 +125,19 @@ public:
 
   int Label (Var x);
 
-private:
-
-  TotalValue  myEConst;
-  void (*myErrorFun) (char*);
 };
 
-inline Energy::Energy (void (*err_function) (char*)) : Graph (err_function)
+inline Energy::Energy (const int theMaxNodes)
+  : GraphEval (theMaxNodes)
 {
-  myEConst = 0;
-  myErrorFun = err_function;
 }
 
 inline Energy::~Energy() {}
 
-inline Energy::Var Energy::AddVariable() {  return AddNode(); }
-
-inline void Energy::AddConstant (Value A) { myEConst += A; }
+inline Energy::Var Energy::AddVariable()
+{
+  return AddNode();
+}
 
 inline void Energy::AddTerm (Var x,
                              Value A, Value B)
@@ -222,22 +159,24 @@ inline void Energy::AddPairwise (Var x, Var y,
   {
     AddTWeights (x, 0, B);
     AddTWeights (y, 0, -B);
-    AddEdge (x, y, 0, B+C);
+    AddEdge (x, y, 0, B + C);
   }
+
   else if (C < 0)
   {
     AddTWeights (x, 0, -C);
     AddTWeights (y, 0, C);
-    AddEdge (x, y, B+C, 0);
+    AddEdge (x, y, B + C, 0);
   }
+
   else
   {
     AddEdge (x, y, B, C);
   }
 }
 
-inline Energy::TotalValue Energy::Minimize() { return myEConst + MaximumFlow(); }
+inline Energy::TotalValue Energy::Minimize() { return MaximumFlow(); }
 
-inline int Energy::Label (Var x) { return (int) Graph::Label (x); }
+inline int Energy::Label (Var x) { return (int) GraphEval::Label (x); }
 
-#endif
+#endif // _BRepMesh_MinStCut_HeaderFile
index 996da0bc3a2709d64cf94c6bae57ae8d5d0ec405..44cdc8a48dfca32b82631d317ba3d9ff15f5424c 100644 (file)
@@ -789,7 +789,7 @@ void BRepMesh_RestoreOrientationTool::Perform()
 #endif
 
   // Optimization
-  Energy* aGraph = new Energy();
+  Energy* aGraph = new Energy (myPatches.size());
 
   std::vector<Energy::Var> aVariables (myPatches.size());
 
@@ -857,19 +857,6 @@ void BRepMesh_RestoreOrientationTool::Perform()
   std::cout << "Optimization time:  " << aTimer.ElapsedTime() << std::endl;
 #endif
 
-  Handle (BRepMesh_TriangulatedPatch) aMergedPatch = new BRepMesh_TriangulatedPatch(myFaceList[0]);
-  for (Standard_Size i = 0; i < myPatches.size(); ++i)
-  {
-    Handle (BRepMesh_TriangulatedPatch)& aTriPatch = myPatches[i];
-
-    if (aFlipped[i])
-    {
-      aTriPatch->Flip();
-    }
-
-    aMergedPatch->Append (aTriPatch);
-  }
-
   BRep_Builder aBuilder;
   TopoDS_Compound aCompound;
   aBuilder.MakeCompound (aCompound);