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()
{
delete m_segmentRefs;
}
@ -88,21 +87,16 @@ void LINE::Mark( int 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()
{
if( m_segmentRefs )
{
for( SEGMENT* s : *m_segmentRefs )
s->Unmark();
}
for( SEGMENT* s : m_segmentRefs )
s->Unmark();
m_marker = 0;
}
@ -112,12 +106,9 @@ int LINE::Marker() const
{
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;
@ -126,14 +117,7 @@ int LINE::Marker() const
void LINE::copyLinks( const LINE* aParent )
{
if( aParent->m_segmentRefs == NULL )
{
m_segmentRefs = NULL;
return;
}
m_segmentRefs = new SEGMENT_REFS();
*m_segmentRefs = *aParent->m_segmentRefs;
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;
@ -269,9 +253,7 @@ bool LINE::Walkaround( SHAPE_LINE_CHAIN aObstacle, SHAPE_LINE_CHAIN& aPre,
}
void LINE::Walkaround( const SHAPE_LINE_CHAIN& aObstacle,
SHAPE_LINE_CHAIN& aPath,
bool aCw ) const
void LINE::Walkaround( const SHAPE_LINE_CHAIN& aObstacle, SHAPE_LINE_CHAIN& aPath, bool aCw ) const
{
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++ )
{
@ -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 );
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++ )
wxLogTrace( "PNS", "seg %d: %p", i, (*m_segmentRefs)[i] );
for( int i = 0; i < (int) m_segmentRefs.size(); i++ )
wxLogTrace( "PNS", "seg %d: %p\n", i, m_segmentRefs[i] );
}
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 );
SHAPE_LINE_CHAIN paths[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++ )
{
@ -588,7 +570,10 @@ void LINE::DragSegment( const VECTOR2I& aP, int aIndex, int aSnappingThreshold )
if( aIndex == 0 )
{
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
{
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( !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
{
guideB[0] = SEG( dragged.B, dragged.B + drag_dir.Right().ToVector() );
@ -712,8 +700,7 @@ void 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;
if( m_segmentRefs )
{
for( SEGMENT* s : *m_segmentRefs )
s->SetRank( aRank );
}
for( SEGMENT* s : m_segmentRefs )
s->SetRank( aRank );
}
int LINE::Rank() const
{
int min_rank = INT_MAX;
int rank;
if( m_segmentRefs )
{
for( SEGMENT *s : *m_segmentRefs )
if( IsLinked() ) {
for( SEGMENT *s : m_segmentRefs )
{
min_rank = std::min( min_rank, s->Rank() );
rank = ( min_rank == INT_MAX ) ? -1 : min_rank;
}
else
{
rank = m_rank;
}
} else {
min_rank = m_rank;
}
int rank = ( min_rank == INT_MAX ) ? -1 : min_rank;
return rank;
}
@ -766,13 +750,17 @@ void LINE::ClipVertexRange( int aStart, int aEnd )
{
m_line = m_line.Slice( aStart, aEnd );
if( m_segmentRefs )
{
SEGMENT_REFS* snew = new SEGMENT_REFS( m_segmentRefs->begin() + aStart,
m_segmentRefs->begin() + aEnd );
if( IsLinked() ) {
assert( m_segmentRefs.size() >= (aEnd - aStart) );
delete m_segmentRefs;
m_segmentRefs = snew;
// Note: The range includes aEnd, but we have n-1 segments.
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()
{
if( m_segmentRefs )
delete m_segmentRefs;
m_segmentRefs = NULL;
m_segmentRefs.clear();
}
@ -896,7 +881,7 @@ OPT_BOX2I LINE::ChangedArea( const LINE* aOther ) const
bool LINE::HasLockedSegments() const
{
for( const SEGMENT* seg : *m_segmentRefs )
for( const SEGMENT* seg : m_segmentRefs )
{
if( seg->Marker() & MK_LOCKED )
return true;

View File

@ -68,7 +68,6 @@ public:
*/
LINE() : ITEM( LINE_T )
{
m_segmentRefs = NULL;
m_hasVia = false;
m_width = 1; // Dummy value
}
@ -87,7 +86,6 @@ public:
{
m_net = aBase.m_net;
m_layers = aBase.m_layers;
m_segmentRefs = NULL;
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.
void LinkSegment( SEGMENT* aSeg )
{
if( !m_segmentRefs )
m_segmentRefs = new SEGMENT_REFS();
m_segmentRefs->push_back( aSeg );
m_segmentRefs.push_back( aSeg );
}
///> Returns the list of segments from the owning node that constitute this
///> line (or NULL if the line is not linked)
SEGMENT_REFS* LinkedSegments()
SEGMENT_REFS& LinkedSegments()
{
return m_segmentRefs;
}
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.
bool ContainsSegment( SEGMENT* aSeg ) const
{
if( !m_segmentRefs )
return false;
return std::find( m_segmentRefs->begin(), m_segmentRefs->end(),
aSeg ) != m_segmentRefs->end();
return std::find( m_segmentRefs.begin(), m_segmentRefs.end(),
aSeg ) != m_segmentRefs.end();
}
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.
@ -214,10 +211,7 @@ public:
///> Returns the number of segments that were assembled together to form this line.
int LinkCount() const
{
if( !m_segmentRefs )
return -1;
return m_segmentRefs->size();
return m_segmentRefs.size();
}
///> 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 );
///> 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
///> of an obstacle object (aObstacle).
@ -246,10 +240,10 @@ public:
SHAPE_LINE_CHAIN& aPath,
bool aCw ) const;
bool Is45Degree();
bool Is45Degree() const;
///> Prints out all linked segments
void ShowLinks();
void ShowLinks() const;
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
///> if the line is not a part of any node.
SEGMENT_REFS* m_segmentRefs;
SEGMENT_REFS m_segmentRefs;
///> The actual shape of the 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++ )
{
SEGMENT* seg = ( *aLatest.LinkedSegments() )[s];
SEGMENT* seg = aLatest.GetLink(s);
LINE ourLine = aNode->AssembleLine( seg );
JOINT a, b;
std::vector<LINE> lines;
@ -970,7 +970,7 @@ void LINE_PLACER::removeLoops( NODE* aNode, LINE& aLatest )
if( !( line.ContainsSegment( seg ) ) && line.SegmentCount() )
{
for( SEGMENT *ss : *line.LinkedSegments() )
for( SEGMENT *ss : line.LinkedSegments() )
toErase.insert( ss );
removedCount++;

View File

@ -661,11 +661,9 @@ void NODE::removeSegment( SEGMENT* aSeg )
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 );
}

View File

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

View File

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

View File

@ -36,10 +36,10 @@ namespace PNS {
bool TOPOLOGY::SimplifyLine( LINE* aLine )
{
if( !aLine->LinkedSegments() || !aLine->SegmentCount() )
if( !aLine->IsLinked() || !aLine->SegmentCount() )
return false;
SEGMENT* root = ( *aLine->LinkedSegments() )[0];
SEGMENT* root = aLine->GetLink(0);
LINE l = m_world->AssembleLine( root );
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 )
{
VECTOR2I anchor = aLeft ? aLine->CPoint( 0 ) : aLine->CPoint( -1 );
SEGMENT* last = aLeft ? aLine->LinkedSegments()->front() : aLine->LinkedSegments()->back();
assert( aLine->IsLinked() );
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 );
assert( jt != NULL );