Make the segment-ref container a true member of PNS::LINE

improve const correctness
return segment container by ref
change client code accordingly
This commit is contained in:
decimad 2016-08-29 20:36:05 +02:00 committed by Maciej Suminski
parent 2faca77adf
commit 4770be0920
7 changed files with 82 additions and 112 deletions

View File

@ -54,7 +54,6 @@ LINE::LINE( const LINE& aOther ) :
LINE::~LINE() LINE::~LINE()
{ {
delete m_segmentRefs;
} }
@ -88,21 +87,16 @@ void LINE::Mark( int aMarker )
{ {
m_marker = aMarker; m_marker = aMarker;
if( m_segmentRefs ) for( SEGMENT* s : m_segmentRefs )
{ s->Mark( aMarker );
for( SEGMENT* s : *m_segmentRefs )
s->Mark( aMarker );
}
} }
void LINE::Unmark() void LINE::Unmark()
{ {
if( m_segmentRefs ) for( SEGMENT* s : m_segmentRefs )
{ s->Unmark();
for( SEGMENT* s : *m_segmentRefs )
s->Unmark();
}
m_marker = 0; m_marker = 0;
} }
@ -112,12 +106,9 @@ int LINE::Marker() const
{ {
int marker = m_marker; int marker = m_marker;
if( m_segmentRefs ) for( SEGMENT* s : m_segmentRefs )
{ {
for( SEGMENT* s : *m_segmentRefs ) marker |= s->Marker();
{
marker |= s->Marker();
}
} }
return marker; return marker;
@ -126,14 +117,7 @@ int LINE::Marker() const
void LINE::copyLinks( const LINE* aParent ) void LINE::copyLinks( const LINE* aParent )
{ {
if( aParent->m_segmentRefs == NULL ) m_segmentRefs = aParent->m_segmentRefs;
{
m_segmentRefs = NULL;
return;
}
m_segmentRefs = new SEGMENT_REFS();
*m_segmentRefs = *aParent->m_segmentRefs;
} }
@ -151,7 +135,7 @@ SEGMENT* SEGMENT::Clone() const
} }
int LINE::CountCorners( int aAngles ) int LINE::CountCorners( int aAngles ) const
{ {
int count = 0; int count = 0;
@ -269,9 +253,7 @@ bool LINE::Walkaround( SHAPE_LINE_CHAIN aObstacle, SHAPE_LINE_CHAIN& aPre,
} }
void LINE::Walkaround( const SHAPE_LINE_CHAIN& aObstacle, void LINE::Walkaround( const SHAPE_LINE_CHAIN& aObstacle, SHAPE_LINE_CHAIN& aPath, bool aCw ) const
SHAPE_LINE_CHAIN& aPath,
bool aCw ) const
{ {
SHAPE_LINE_CHAIN walk, post; SHAPE_LINE_CHAIN walk, post;
@ -288,7 +270,7 @@ const SHAPE_LINE_CHAIN SEGMENT::Hull( int aClearance, int aWalkaroundThickness )
} }
bool LINE::Is45Degree() bool LINE::Is45Degree() const
{ {
for( int i = 0; i < m_line.SegmentCount(); i++ ) for( int i = 0; i < m_line.SegmentCount(); i++ )
{ {
@ -340,18 +322,18 @@ const LINE LINE::ClipToNearestObstacle( NODE* aNode ) const
} }
void LINE::ShowLinks() void LINE::ShowLinks() const
{ {
if( !m_segmentRefs ) if( !IsLinked() )
{ {
wxLogTrace( "PNS", "line %p: no links", this ); wxLogTrace( "PNS", "line %p: no links", this );
return; return;
} }
wxLogTrace( "PNS", "line %p: %d linked segs", this, (int) m_segmentRefs->size() ); wxLogTrace( "PNS", "line %p: %d linked segs", this, (int) m_segmentRefs.size() );
for( int i = 0; i < (int) m_segmentRefs->size(); i++ ) for( int i = 0; i < (int) m_segmentRefs.size(); i++ )
wxLogTrace( "PNS", "seg %d: %p", i, (*m_segmentRefs)[i] ); wxLogTrace( "PNS", "seg %d: %p\n", i, m_segmentRefs[i] );
} }
SHAPE_LINE_CHAIN dragCornerInternal( const SHAPE_LINE_CHAIN& aOrigin, const VECTOR2I& aP ) SHAPE_LINE_CHAIN dragCornerInternal( const SHAPE_LINE_CHAIN& aOrigin, const VECTOR2I& aP )
@ -376,7 +358,7 @@ SHAPE_LINE_CHAIN dragCornerInternal( const SHAPE_LINE_CHAIN& aOrigin, const VECT
VECTOR2I p_start = aOrigin.CPoint( i ); VECTOR2I p_start = aOrigin.CPoint( i );
SHAPE_LINE_CHAIN paths[2]; SHAPE_LINE_CHAIN paths[2];
DIRECTION_45 dirs[2]; DIRECTION_45 dirs[2];
DIRECTION_45 d_prev = ( i > 0 ? DIRECTION_45( aOrigin.CSegment( i - 1 ) ) : DIRECTION_45() ); DIRECTION_45 d_prev = ( i > 0 ? DIRECTION_45( aOrigin.CSegment( i-1 ) ) : DIRECTION_45() );
for( int j = 0; j < 2; j++ ) for( int j = 0; j < 2; j++ )
{ {
@ -588,7 +570,10 @@ void LINE::DragSegment( const VECTOR2I& aP, int aIndex, int aSnappingThreshold )
if( aIndex == 0 ) if( aIndex == 0 )
{ {
if( !lockEndpointA ) if( !lockEndpointA )
guideA[0] = guideA[1] = SEG( dragged.A, dragged.A + drag_dir.Right().Right().ToVector() ); {
guideA[0] = guideA[1] = SEG( dragged.A,
dragged.A + drag_dir.Right().Right().ToVector() );
}
else else
{ {
guideA[0] = SEG( dragged.A, dragged.A + drag_dir.Right().ToVector() ); guideA[0] = SEG( dragged.A, dragged.A + drag_dir.Right().ToVector() );
@ -609,7 +594,10 @@ void LINE::DragSegment( const VECTOR2I& aP, int aIndex, int aSnappingThreshold )
if( aIndex == m_line.SegmentCount() - 1 ) if( aIndex == m_line.SegmentCount() - 1 )
{ {
if( !lockEndpointB ) if( !lockEndpointB )
guideB[0] = guideB[1] = SEG( dragged.B, dragged.B + drag_dir.Right().Right().ToVector() ); {
guideB[0] = guideB[1] = SEG( dragged.B,
dragged.B + drag_dir.Right().Right().ToVector() );
}
else else
{ {
guideB[0] = SEG( dragged.B, dragged.B + drag_dir.Right().ToVector() ); guideB[0] = SEG( dragged.B, dragged.B + drag_dir.Right().ToVector() );
@ -712,8 +700,7 @@ void LINE::Reverse()
{ {
m_line = m_line.Reverse(); m_line = m_line.Reverse();
if( m_segmentRefs ) std::reverse( m_segmentRefs.begin(), m_segmentRefs.end() );
std::reverse( m_segmentRefs->begin(), m_segmentRefs->end() );
} }
@ -734,30 +721,27 @@ void LINE::SetRank( int aRank )
{ {
m_rank = aRank; m_rank = aRank;
if( m_segmentRefs ) for( SEGMENT* s : m_segmentRefs )
{ s->SetRank( aRank );
for( SEGMENT* s : *m_segmentRefs )
s->SetRank( aRank );
}
} }
int LINE::Rank() const int LINE::Rank() const
{ {
int min_rank = INT_MAX; int min_rank = INT_MAX;
int rank;
if( m_segmentRefs ) if( IsLinked() ) {
{ for( SEGMENT *s : m_segmentRefs )
for( SEGMENT *s : *m_segmentRefs ) {
min_rank = std::min( min_rank, s->Rank() ); min_rank = std::min( min_rank, s->Rank() );
rank = ( min_rank == INT_MAX ) ? -1 : min_rank; }
} } else {
else min_rank = m_rank;
{
rank = m_rank;
} }
int rank = ( min_rank == INT_MAX ) ? -1 : min_rank;
return rank; return rank;
} }
@ -766,13 +750,17 @@ void LINE::ClipVertexRange( int aStart, int aEnd )
{ {
m_line = m_line.Slice( aStart, aEnd ); m_line = m_line.Slice( aStart, aEnd );
if( m_segmentRefs ) if( IsLinked() ) {
{ assert( m_segmentRefs.size() >= (aEnd - aStart) );
SEGMENT_REFS* snew = new SEGMENT_REFS( m_segmentRefs->begin() + aStart,
m_segmentRefs->begin() + aEnd );
delete m_segmentRefs; // Note: The range includes aEnd, but we have n-1 segments.
m_segmentRefs = snew; std::rotate(
m_segmentRefs.begin(),
m_segmentRefs.begin() + aStart,
m_segmentRefs.begin() + aEnd
);
m_segmentRefs.resize( aEnd - aStart );
} }
} }
@ -794,10 +782,7 @@ bool LINE::HasLoops() const
void LINE::ClearSegmentLinks() void LINE::ClearSegmentLinks()
{ {
if( m_segmentRefs ) m_segmentRefs.clear();
delete m_segmentRefs;
m_segmentRefs = NULL;
} }
@ -896,7 +881,7 @@ OPT_BOX2I LINE::ChangedArea( const LINE* aOther ) const
bool LINE::HasLockedSegments() const bool LINE::HasLockedSegments() const
{ {
for( const SEGMENT* seg : *m_segmentRefs ) for( const SEGMENT* seg : m_segmentRefs )
{ {
if( seg->Marker() & MK_LOCKED ) if( seg->Marker() & MK_LOCKED )
return true; return true;

View File

@ -68,7 +68,6 @@ public:
*/ */
LINE() : ITEM( LINE_T ) LINE() : ITEM( LINE_T )
{ {
m_segmentRefs = NULL;
m_hasVia = false; m_hasVia = false;
m_width = 1; // Dummy value m_width = 1; // Dummy value
} }
@ -87,7 +86,6 @@ public:
{ {
m_net = aBase.m_net; m_net = aBase.m_net;
m_layers = aBase.m_layers; m_layers = aBase.m_layers;
m_segmentRefs = NULL;
m_hasVia = false; m_hasVia = false;
} }
@ -175,37 +173,36 @@ public:
///> Adds a reference to a segment registered in a NODE that is a part of this line. ///> Adds a reference to a segment registered in a NODE that is a part of this line.
void LinkSegment( SEGMENT* aSeg ) void LinkSegment( SEGMENT* aSeg )
{ {
if( !m_segmentRefs ) m_segmentRefs.push_back( aSeg );
m_segmentRefs = new SEGMENT_REFS();
m_segmentRefs->push_back( aSeg );
} }
///> Returns the list of segments from the owning node that constitute this ///> Returns the list of segments from the owning node that constitute this
///> line (or NULL if the line is not linked) ///> line (or NULL if the line is not linked)
SEGMENT_REFS* LinkedSegments() SEGMENT_REFS& LinkedSegments()
{ {
return m_segmentRefs; return m_segmentRefs;
} }
bool IsLinked() const bool IsLinked() const
{ {
return m_segmentRefs != NULL; return m_segmentRefs.size() != 0;
}
bool IsLinkedChecked() const
{
return IsLinked() && LinkCount() == SegmentCount();
} }
///> Checks if the segment aSeg is a part of the line. ///> Checks if the segment aSeg is a part of the line.
bool ContainsSegment( SEGMENT* aSeg ) const bool ContainsSegment( SEGMENT* aSeg ) const
{ {
if( !m_segmentRefs ) return std::find( m_segmentRefs.begin(), m_segmentRefs.end(),
return false; aSeg ) != m_segmentRefs.end();
return std::find( m_segmentRefs->begin(), m_segmentRefs->end(),
aSeg ) != m_segmentRefs->end();
} }
SEGMENT* GetLink( int aIndex ) const SEGMENT* GetLink( int aIndex ) const
{ {
return (*m_segmentRefs)[aIndex]; return m_segmentRefs[aIndex];
} }
///> Erases the linking information. Used to detach the line from the owning node. ///> Erases the linking information. Used to detach the line from the owning node.
@ -214,10 +211,7 @@ public:
///> Returns the number of segments that were assembled together to form this line. ///> Returns the number of segments that were assembled together to form this line.
int LinkCount() const int LinkCount() const
{ {
if( !m_segmentRefs ) return m_segmentRefs.size();
return -1;
return m_segmentRefs->size();
} }
///> Clips the line to the nearest obstacle, traversing from the line's start vertex (0). ///> Clips the line to the nearest obstacle, traversing from the line's start vertex (0).
@ -228,7 +222,7 @@ public:
void ClipVertexRange ( int aStart, int aEnd ); void ClipVertexRange ( int aStart, int aEnd );
///> Returns the number of corners of angles specified by mask aAngles. ///> Returns the number of corners of angles specified by mask aAngles.
int CountCorners( int aAngles ); int CountCorners( int aAngles ) const;
///> Calculates a line thightly wrapping a convex hull ///> Calculates a line thightly wrapping a convex hull
///> of an obstacle object (aObstacle). ///> of an obstacle object (aObstacle).
@ -246,10 +240,10 @@ public:
SHAPE_LINE_CHAIN& aPath, SHAPE_LINE_CHAIN& aPath,
bool aCw ) const; bool aCw ) const;
bool Is45Degree(); bool Is45Degree() const;
///> Prints out all linked segments ///> Prints out all linked segments
void ShowLinks(); void ShowLinks() const;
bool EndsWithVia() const { return m_hasVia; } bool EndsWithVia() const { return m_hasVia; }
@ -285,7 +279,7 @@ private:
///> List of segments in the owning NODE (ITEM::m_owner) that constitute this line, or NULL ///> List of segments in the owning NODE (ITEM::m_owner) that constitute this line, or NULL
///> if the line is not a part of any node. ///> if the line is not a part of any node.
SEGMENT_REFS* m_segmentRefs; SEGMENT_REFS m_segmentRefs;
///> The actual shape of the line ///> The actual shape of the line
SHAPE_LINE_CHAIN m_line; SHAPE_LINE_CHAIN m_line;

View File

@ -947,7 +947,7 @@ void LINE_PLACER::removeLoops( NODE* aNode, LINE& aLatest )
for( int s = 0; s < aLatest.LinkCount(); s++ ) for( int s = 0; s < aLatest.LinkCount(); s++ )
{ {
SEGMENT* seg = ( *aLatest.LinkedSegments() )[s]; SEGMENT* seg = aLatest.GetLink(s);
LINE ourLine = aNode->AssembleLine( seg ); LINE ourLine = aNode->AssembleLine( seg );
JOINT a, b; JOINT a, b;
std::vector<LINE> lines; std::vector<LINE> lines;
@ -970,7 +970,7 @@ void LINE_PLACER::removeLoops( NODE* aNode, LINE& aLatest )
if( !( line.ContainsSegment( seg ) ) && line.SegmentCount() ) if( !( line.ContainsSegment( seg ) ) && line.SegmentCount() )
{ {
for( SEGMENT *ss : *line.LinkedSegments() ) for( SEGMENT *ss : line.LinkedSegments() )
toErase.insert( ss ); toErase.insert( ss );
removedCount++; removedCount++;

View File

@ -661,11 +661,9 @@ void NODE::removeSegment( SEGMENT* aSeg )
void NODE::removeLine( LINE* aLine ) void NODE::removeLine( LINE* aLine )
{ {
std::vector<SEGMENT*>* segRefs = aLine->LinkedSegments(); std::vector<SEGMENT*>& segRefs = aLine->LinkedSegments();
assert( segRefs != NULL ); for( SEGMENT* seg : segRefs )
for( SEGMENT* seg : *segRefs )
{ {
removeSegment( seg ); removeSegment( seg );
} }

View File

@ -181,17 +181,16 @@ void OPTIMIZER::cacheAdd( ITEM* aItem, bool aIsStatic = false )
void OPTIMIZER::removeCachedSegments( LINE* aLine, int aStartVertex, int aEndVertex ) void OPTIMIZER::removeCachedSegments( LINE* aLine, int aStartVertex, int aEndVertex )
{ {
LINE::SEGMENT_REFS* segs = aLine->LinkedSegments(); if( !aLine->IsLinked() ) return;
if( !segs ) LINE::SEGMENT_REFS& segs = aLine->LinkedSegments();
return;
if( aEndVertex < 0 ) if( aEndVertex < 0 )
aEndVertex += aLine->PointCount(); aEndVertex += aLine->PointCount();
for( int i = aStartVertex; i < aEndVertex - 1; i++ ) for( int i = aStartVertex; i < aEndVertex - 1; i++ )
{ {
SEGMENT* s = (*segs)[i]; SEGMENT* s = segs[i];
m_cacheTags.erase( s ); m_cacheTags.erase( s );
m_cache.Remove( s ); m_cache.Remove( s );
} }

View File

@ -252,10 +252,8 @@ SHOVE::SHOVE_STATUS SHOVE::ProcessSingleLine( LINE& aCurrent, LINE& aObstacle,
bool obstacleIsHead = false; bool obstacleIsHead = false;
if( aObstacle.LinkedSegments() ) for( SEGMENT* s : aObstacle.LinkedSegments() )
{ {
for( SEGMENT* s : *aObstacle.LinkedSegments() )
if( s->Marker() & MK_HEAD ) if( s->Marker() & MK_HEAD )
{ {
obstacleIsHead = true; obstacleIsHead = true;
@ -861,10 +859,7 @@ void SHOVE::unwindStack( ITEM* aItem )
{ {
LINE* l = static_cast<LINE*>( aItem ); LINE* l = static_cast<LINE*>( aItem );
if( !l->LinkedSegments() ) for( SEGMENT* seg : l->LinkedSegments() )
return;
for( SEGMENT* seg : *l->LinkedSegments() )
unwindStack( seg ); unwindStack( seg );
} }
} }
@ -872,7 +867,7 @@ void SHOVE::unwindStack( ITEM* aItem )
bool SHOVE::pushLine( const LINE& aL, bool aKeepCurrentOnTop ) bool SHOVE::pushLine( const LINE& aL, bool aKeepCurrentOnTop )
{ {
if( aL.LinkCount() >= 0 && ( aL.LinkCount() != aL.SegmentCount() ) ) if( !aL.IsLinkedChecked() )
return false; return false;
if( aKeepCurrentOnTop && m_lineStack.size() > 0) if( aKeepCurrentOnTop && m_lineStack.size() > 0)
@ -897,10 +892,7 @@ void SHOVE::popLine( )
{ {
bool found = false; bool found = false;
if( !l.LinkedSegments() ) for( SEGMENT *s : l.LinkedSegments() )
continue;
for( SEGMENT *s : *l.LinkedSegments() )
{ {
if( i->ContainsSegment( s ) ) if( i->ContainsSegment( s ) )
{ {

View File

@ -36,10 +36,10 @@ namespace PNS {
bool TOPOLOGY::SimplifyLine( LINE* aLine ) bool TOPOLOGY::SimplifyLine( LINE* aLine )
{ {
if( !aLine->LinkedSegments() || !aLine->SegmentCount() ) if( !aLine->IsLinked() || !aLine->SegmentCount() )
return false; return false;
SEGMENT* root = ( *aLine->LinkedSegments() )[0]; SEGMENT* root = aLine->GetLink(0);
LINE l = m_world->AssembleLine( root ); LINE l = m_world->AssembleLine( root );
SHAPE_LINE_CHAIN simplified( l.CLine() ); SHAPE_LINE_CHAIN simplified( l.CLine() );
@ -178,8 +178,10 @@ ITEM* TOPOLOGY::NearestUnconnectedItem( JOINT* aStart, int* aAnchor, int aKindMa
bool TOPOLOGY::followTrivialPath( LINE* aLine, bool aLeft, ITEM_SET& aSet, std::set<ITEM*>& aVisited ) bool TOPOLOGY::followTrivialPath( LINE* aLine, bool aLeft, ITEM_SET& aSet, std::set<ITEM*>& aVisited )
{ {
VECTOR2I anchor = aLeft ? aLine->CPoint( 0 ) : aLine->CPoint( -1 ); assert( aLine->IsLinked() );
SEGMENT* last = aLeft ? aLine->LinkedSegments()->front() : aLine->LinkedSegments()->back();
VECTOR2I anchor = aLeft ? aLine->CPoint( 0 ) : aLine->CPoint( -1 );
SEGMENT* last = aLeft ? aLine->LinkedSegments().front() : aLine->LinkedSegments().back();
JOINT* jt = m_world->FindJoint( anchor, aLine ); JOINT* jt = m_world->FindJoint( anchor, aLine );
assert( jt != NULL ); assert( jt != NULL );