From: duv Date: Wed, 20 Apr 2016 10:56:32 +0000 (+0300) Subject: Win8 memory issue fixed. X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=ec88ba6508253e312af0f01bb6f902884d46d43f;p=occt-copy.git Win8 memory issue fixed. --- diff --git a/src/BRepMesh/BRepMesh_Block.hxx b/src/BRepMesh/BRepMesh_Block.hxx index 53c63caf20..60ab0f2724 100644 --- a/src/BRepMesh/BRepMesh_Block.hxx +++ b/src/BRepMesh/BRepMesh_Block.hxx @@ -13,179 +13,258 @@ // 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 +#include -template class Block +template 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 DBlock +template 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; anItemNextFree = 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 diff --git a/src/BRepMesh/BRepMesh_MinStCut.cxx b/src/BRepMesh/BRepMesh_MinStCut.cxx index 0435080179..ed6a33ddde 100644 --- a/src/BRepMesh/BRepMesh_MinStCut.cxx +++ b/src/BRepMesh/BRepMesh_MinStCut.cxx @@ -13,1264 +13,664 @@ // 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 +#include #include + #include -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_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]; aNodeCurrent; 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]; aNodeCurrent; 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; anArcForShift); - 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]; aNodeCurrent; 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; anArc0ForReverseResidualCap) + 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 (aDistShift); 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 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 (aDistShift); 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; anArc0ForFirst; 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 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; anArc0ForResidualCap) + 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 (aDistShift); 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 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 (aDistShift); 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; anArc0ForFirst; 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 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_BLOCK_SIZE, myErrorFun); + m_nodePtrBlock = new DataBlock (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; anArcForResidualCap) + 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 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; anArcForReverseResidualCap) + 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 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; } diff --git a/src/BRepMesh/BRepMesh_MinStCut.hxx b/src/BRepMesh/BRepMesh_MinStCut.hxx index 3657a8ffad..bb6dcf8cdd 100644 --- a/src/BRepMesh/BRepMesh_MinStCut.hxx +++ b/src/BRepMesh/BRepMesh_MinStCut.hxx @@ -13,151 +13,92 @@ // 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 -#include #include -#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* m_edgeBlock; + DataBlock* 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* 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 diff --git a/src/BRepMesh/BRepMesh_RestoreOrientationTool.cxx b/src/BRepMesh/BRepMesh_RestoreOrientationTool.cxx index 996da0bc3a..44cdc8a48d 100644 --- a/src/BRepMesh/BRepMesh_RestoreOrientationTool.cxx +++ b/src/BRepMesh/BRepMesh_RestoreOrientationTool.cxx @@ -789,7 +789,7 @@ void BRepMesh_RestoreOrientationTool::Perform() #endif // Optimization - Energy* aGraph = new Energy(); + Energy* aGraph = new Energy (myPatches.size()); std::vector 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);