Reduce memory usage of EDA_SHAPE pt 2

This commit is contained in:
Jon Evans
2026-03-08 23:56:30 -04:00
parent 5353982a4a
commit 067533928b
6 changed files with 93 additions and 72 deletions
+76 -54
View File
@@ -107,8 +107,8 @@ EDA_SHAPE::EDA_SHAPE( const SHAPE& aShape ) :
{
auto line = static_cast<const SHAPE_LINE_CHAIN&>( aShape );
m_shape = SHAPE_T::POLY;
m_poly = SHAPE_POLY_SET();
m_poly.AddOutline( line );
GetPolyShape() = SHAPE_POLY_SET();
GetPolyShape().AddOutline( line );
SetWidth( line.Width() );
break;
}
@@ -135,7 +135,7 @@ EDA_SHAPE::EDA_SHAPE( const SHAPE& aShape ) :
{
auto poly = static_cast<const SHAPE_SIMPLE&>( aShape );
m_shape = SHAPE_T::POLY;
poly.TransformToPolygon( m_poly, 0, ERROR_INSIDE );
poly.TransformToPolygon( GetPolyShape(), 0, ERROR_INSIDE );
break;
}
@@ -168,10 +168,11 @@ EDA_SHAPE::EDA_SHAPE( const EDA_SHAPE& aOther ) :
m_bezierC1( aOther.m_bezierC1 ),
m_bezierC2( aOther.m_bezierC2 ),
m_bezierPoints( aOther.m_bezierPoints ),
m_poly( aOther.m_poly ),
m_editState( aOther.m_editState ),
m_proxyItem( aOther.m_proxyItem )
{
if( aOther.m_poly )
m_poly = std::make_unique<SHAPE_POLY_SET>( *aOther.m_poly );
}
@@ -197,7 +198,10 @@ EDA_SHAPE& EDA_SHAPE::operator=( const EDA_SHAPE& aOther )
m_bezierC1 = aOther.m_bezierC1;
m_bezierC2 = aOther.m_bezierC2;
m_bezierPoints = aOther.m_bezierPoints;
m_poly = aOther.m_poly;
if( aOther.m_poly )
m_poly = std::make_unique<SHAPE_POLY_SET>( *aOther.m_poly );
else
m_poly.reset();
m_editState = aOther.m_editState;
m_proxyItem = aOther.m_proxyItem;
@@ -429,7 +433,7 @@ VECTOR2I EDA_SHAPE::getPosition() const
if( m_shape == SHAPE_T::ARC )
return getCenter();
else if( m_shape == SHAPE_T::POLY )
return m_poly.CVertex( 0 );
return GetPolyShape().CVertex( 0 );
else
return m_start;
}
@@ -451,8 +455,8 @@ double EDA_SHAPE::GetLength() const
return GetStart().Distance( GetEnd() );
case SHAPE_T::POLY:
for( int ii = 0; ii < m_poly.COutline( 0 ).SegmentCount(); ii++ )
length += m_poly.COutline( 0 ).CSegment( ii ).Length();
for( int ii = 0; ii < GetPolyShape().COutline( 0 ).SegmentCount(); ii++ )
length += GetPolyShape().COutline( 0 ).CSegment( ii ).Length();
return length;
@@ -575,10 +579,10 @@ bool EDA_SHAPE::IsClosed() const
return false;
case SHAPE_T::POLY:
if( m_poly.IsEmpty() )
if( GetPolyShape().IsEmpty() )
return false;
else
return m_poly.Outline( 0 ).IsClosed();
return GetPolyShape().Outline( 0 ).IsClosed();
case SHAPE_T::BEZIER:
if( m_bezierPoints.size() < 3 )
@@ -710,7 +714,7 @@ void EDA_SHAPE::UpdateHatching() const
if( !IsClosed() )
return;
shapeBuffer = m_poly.CloneDropTriangulation();
shapeBuffer = GetPolyShape().CloneDropTriangulation();
break;
default:
@@ -834,7 +838,7 @@ void EDA_SHAPE::move( const VECTOR2I& aMoveVector )
break;
case SHAPE_T::POLY:
m_poly.Move( aMoveVector );
GetPolyShape().Move( aMoveVector );
break;
case SHAPE_T::BEZIER:
@@ -883,9 +887,9 @@ void EDA_SHAPE::scale( double aScale )
{
std::vector<VECTOR2I> pts;
for( int ii = 0; ii < m_poly.OutlineCount(); ++ ii )
for( int ii = 0; ii < GetPolyShape().OutlineCount(); ++ ii )
{
for( const VECTOR2I& pt : m_poly.Outline( ii ).CPoints() )
for( const VECTOR2I& pt : GetPolyShape().Outline( ii ).CPoints() )
{
pts.emplace_back( pt );
scalePt( pts.back() );
@@ -944,14 +948,14 @@ void EDA_SHAPE::rotate( const VECTOR2I& aRotCentre, const EDA_ANGLE& aAngle )
// Convert non-cardinally-rotated rect to a diamond
ROUNDRECT rr( SHAPE_RECT( GetStart(), GetRectangleWidth(), GetRectangleHeight() ), m_cornerRadius );
m_shape = SHAPE_T::POLY;
rr.TransformToPolygon( m_poly, getMaxError() );
m_poly.Rotate( aAngle, aRotCentre );
rr.TransformToPolygon( GetPolyShape(), getMaxError() );
GetPolyShape().Rotate( aAngle, aRotCentre );
}
break;
case SHAPE_T::POLY:
m_poly.Rotate( aAngle, aRotCentre );
GetPolyShape().Rotate( aAngle, aRotCentre );
break;
case SHAPE_T::BEZIER:
@@ -998,7 +1002,7 @@ void EDA_SHAPE::flip( const VECTOR2I& aCentre, FLIP_DIRECTION aFlipDirection )
break;
case SHAPE_T::POLY:
m_poly.Mirror( aCentre, aFlipDirection );
GetPolyShape().Mirror( aCentre, aFlipDirection );
break;
case SHAPE_T::BEZIER:
@@ -1347,10 +1351,10 @@ const BOX2I EDA_SHAPE::getBoundingBox() const
break;
case SHAPE_T::POLY:
if( m_poly.IsEmpty() )
if( GetPolyShape().IsEmpty() )
break;
for( auto iter = m_poly.CIterate(); iter; iter++ )
for( auto iter = GetPolyShape().CIterate(); iter; iter++ )
bbox.Merge( *iter );
break;
@@ -1504,26 +1508,26 @@ bool EDA_SHAPE::hitTest( const VECTOR2I& aPosition, int aAccuracy ) const
return false;
case SHAPE_T::POLY:
if( m_poly.OutlineCount() < 1 ) // empty poly
if( GetPolyShape().OutlineCount() < 1 ) // empty poly
return false;
if( IsFilledForHitTesting() )
{
if( !m_poly.COutline( 0 ).IsClosed() )
if( !GetPolyShape().COutline( 0 ).IsClosed() )
{
// Only one outline is expected
SHAPE_LINE_CHAIN copy( m_poly.COutline( 0 ) );
SHAPE_LINE_CHAIN copy( GetPolyShape().COutline( 0 ) );
copy.SetClosed( true );
return copy.Collide( aPosition, maxdist );
}
else
{
return m_poly.Collide( aPosition, maxdist );
return GetPolyShape().Collide( aPosition, maxdist );
}
}
else
{
if( m_poly.CollideEdge( aPosition, nullptr, maxdist ) )
if( GetPolyShape().CollideEdge( aPosition, nullptr, maxdist ) )
return true;
if( IsHatchedFill() && GetHatching().Collide( aPosition, maxdist ) )
@@ -1677,9 +1681,9 @@ bool EDA_SHAPE::hitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) co
// Account for the width of the line
arect.Inflate( GetWidth() / 2 );
for( int ii = 0; ii < m_poly.OutlineCount(); ++ii )
for( int ii = 0; ii < GetPolyShape().OutlineCount(); ++ii )
{
if( checkOutline( m_poly.Outline( ii ) ) )
if( checkOutline( GetPolyShape().Outline( ii ) ) )
return true;
}
@@ -1925,11 +1929,11 @@ void EDA_SHAPE::computeArcBBox( BOX2I& aBBox ) const
void EDA_SHAPE::SetPolyPoints( const std::vector<VECTOR2I>& aPoints )
{
m_poly.RemoveAllContours();
m_poly.NewOutline();
GetPolyShape().RemoveAllContours();
GetPolyShape().NewOutline();
for( const VECTOR2I& p : aPoints )
m_poly.Append( p.x, p.y );
GetPolyShape().Append( p.x, p.y );
}
@@ -2073,9 +2077,9 @@ std::vector<VECTOR2I> EDA_SHAPE::GetPolyPoints() const
{
std::vector<VECTOR2I> points;
for( int ii = 0; ii < m_poly.OutlineCount(); ++ii )
for( int ii = 0; ii < GetPolyShape().OutlineCount(); ++ii )
{
const SHAPE_LINE_CHAIN& outline = m_poly.COutline( ii );
const SHAPE_LINE_CHAIN& outline = GetPolyShape().COutline( ii );
int pointCount = outline.PointCount();
if( pointCount )
@@ -2091,6 +2095,23 @@ std::vector<VECTOR2I> EDA_SHAPE::GetPolyPoints() const
}
SHAPE_POLY_SET& EDA_SHAPE::GetPolyShape()
{
if( !m_poly )
m_poly = std::make_unique<SHAPE_POLY_SET>();
return *m_poly;
}
const SHAPE_POLY_SET& EDA_SHAPE::GetPolyShape() const
{
if( !m_poly )
m_poly = std::make_unique<SHAPE_POLY_SET>();
return *m_poly;
}
bool EDA_SHAPE::IsPolyShapeValid() const
{
// return true if the polygonal shape is valid (has more than 2 points)
@@ -2133,12 +2154,12 @@ void EDA_SHAPE::beginEdit( const VECTOR2I& aPosition )
break;
case SHAPE_T::POLY:
m_poly.NewOutline();
m_poly.Outline( 0 ).SetClosed( false );
GetPolyShape().NewOutline();
GetPolyShape().Outline( 0 ).SetClosed( false );
// Start and end of the first segment (co-located for now)
m_poly.Outline( 0 ).Append( aPosition );
m_poly.Outline( 0 ).Append( aPosition, true );
GetPolyShape().Outline( 0 ).Append( aPosition );
GetPolyShape().Outline( 0 ).Append( aPosition, true );
break;
default:
@@ -2166,7 +2187,7 @@ bool EDA_SHAPE::continueEdit( const VECTOR2I& aPosition )
case SHAPE_T::POLY:
{
SHAPE_LINE_CHAIN& poly = m_poly.Outline( 0 );
SHAPE_LINE_CHAIN& poly = GetPolyShape().Outline( 0 );
// do not add zero-length segments
if( poly.CPoint( (int) poly.GetPointCount() - 2 ) != poly.CLastPoint() )
@@ -2334,7 +2355,8 @@ void EDA_SHAPE::calcEdit( const VECTOR2I& aPosition )
}
case SHAPE_T::POLY:
m_poly.Outline( 0 ).SetPoint( m_poly.Outline( 0 ).GetPointCount() - 1, aPosition );
GetPolyShape().Outline( 0 ).SetPoint( GetPolyShape().Outline( 0 ).GetPointCount() - 1,
aPosition );
break;
default:
@@ -2356,7 +2378,7 @@ void EDA_SHAPE::endEdit( bool aClosed )
case SHAPE_T::POLY:
{
SHAPE_LINE_CHAIN& poly = m_poly.Outline( 0 );
SHAPE_LINE_CHAIN& poly = GetPolyShape().Outline( 0 );
// do not include last point twice
if( poly.GetPointCount() > 2 )
@@ -2435,14 +2457,14 @@ int EDA_SHAPE::Compare( const EDA_SHAPE* aOther ) const
}
else if( m_shape == SHAPE_T::POLY )
{
TEST( m_poly.TotalVertices(), aOther->m_poly.TotalVertices() );
TEST( GetPolyShape().TotalVertices(), aOther->GetPolyShape().TotalVertices() );
}
for( size_t ii = 0; ii < m_bezierPoints.size(); ++ii )
TEST_PT( m_bezierPoints[ii], aOther->m_bezierPoints[ii] );
for( int ii = 0; ii < m_poly.TotalVertices(); ++ii )
TEST_PT( m_poly.CVertex( ii ), aOther->m_poly.CVertex( ii ) );
for( int ii = 0; ii < GetPolyShape().TotalVertices(); ++ii )
TEST_PT( GetPolyShape().CVertex( ii ), aOther->GetPolyShape().CVertex( ii ) );
TEST_E( m_stroke.GetWidth(), aOther->m_stroke.GetWidth() );
TEST( (int) m_stroke.GetLineStyle(), (int) aOther->m_stroke.GetLineStyle() );
@@ -2543,9 +2565,9 @@ void EDA_SHAPE::TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, int aClearance
if( solidFill )
{
for( int ii = 0; ii < m_poly.OutlineCount(); ++ii )
for( int ii = 0; ii < GetPolyShape().OutlineCount(); ++ii )
{
const SHAPE_LINE_CHAIN& poly = m_poly.Outline( ii );
const SHAPE_LINE_CHAIN& poly = GetPolyShape().Outline( ii );
SHAPE_POLY_SET tmp;
tmp.NewOutline();
@@ -2567,9 +2589,9 @@ void EDA_SHAPE::TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, int aClearance
}
else
{
for( int ii = 0; ii < m_poly.OutlineCount(); ++ii )
for( int ii = 0; ii < GetPolyShape().OutlineCount(); ++ii )
{
const SHAPE_LINE_CHAIN& poly = m_poly.Outline( ii );
const SHAPE_LINE_CHAIN& poly = GetPolyShape().Outline( ii );
for( int jj = 0; jj < (int) poly.SegmentCount(); ++jj )
{
@@ -2665,9 +2687,9 @@ bool EDA_SHAPE::operator==( const EDA_SHAPE& aOther ) const
if( m_bezierPoints != aOther.m_bezierPoints )
return false;
for( int ii = 0; ii < m_poly.TotalVertices(); ++ii )
for( int ii = 0; ii < GetPolyShape().TotalVertices(); ++ii )
{
if( m_poly.CVertex( ii ) != aOther.m_poly.CVertex( ii ) )
if( GetPolyShape().CVertex( ii ) != aOther.GetPolyShape().CVertex( ii ) )
return false;
}
@@ -2719,8 +2741,8 @@ double EDA_SHAPE::Similarity( const EDA_SHAPE& aOther ) const
}
{
int m = m_poly.TotalVertices();
int n = aOther.m_poly.TotalVertices();
int m = GetPolyShape().TotalVertices();
int n = aOther.GetPolyShape().TotalVertices();
std::vector<VECTOR2I> poly;
std::vector<VECTOR2I> otherPoly;
VECTOR2I lastPt( 0, 0 );
@@ -2732,16 +2754,16 @@ double EDA_SHAPE::Similarity( const EDA_SHAPE& aOther ) const
// will not be a match but the rest of the sequence will.
for( int ii = 0; ii < m; ++ii )
{
poly.emplace_back( lastPt - m_poly.CVertex( ii ) );
lastPt = m_poly.CVertex( ii );
poly.emplace_back( lastPt - GetPolyShape().CVertex( ii ) );
lastPt = GetPolyShape().CVertex( ii );
}
lastPt = VECTOR2I( 0, 0 );
for( int ii = 0; ii < n; ++ii )
{
otherPoly.emplace_back( lastPt - aOther.m_poly.CVertex( ii ) );
lastPt = aOther.m_poly.CVertex( ii );
otherPoly.emplace_back( lastPt - aOther.GetPolyShape().CVertex( ii ) );
lastPt = aOther.GetPolyShape().CVertex( ii );
}
size_t longest = alg::longest_common_subset( poly, otherPoly );
+1 -1
View File
@@ -131,7 +131,7 @@ void SCH_RULE_AREA::Plot( PLOTTER* aPlotter, bool aBackground, const SCH_PLOT_OP
ptList.clear();
const std::vector<VECTOR2I>& polyPoints = m_poly.Outline( 0 ).CPoints();
const std::vector<VECTOR2I>& polyPoints = GetPolyShape().Outline( 0 ).CPoints();
for( const VECTOR2I& pt : polyPoints )
ptList.push_back( pt );
+6 -6
View File
@@ -214,7 +214,7 @@ void SCH_SHAPE::Plot( PLOTTER* aPlotter, bool aBackground, const SCH_PLOT_OPTS&
{
ptList.clear();
for( const VECTOR2I& pt : m_poly.Outline( 0 ).CPoints() )
for( const VECTOR2I& pt : GetPolyShape().Outline( 0 ).CPoints() )
ptList.push_back( renderSettings->TransformCoordinate( pt ) + aOffset );
}
else if( GetShape() == SHAPE_T::BEZIER )
@@ -399,7 +399,7 @@ wxString SCH_SHAPE::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFu
case SHAPE_T::POLY:
return wxString::Format( _( "Polyline, %d points" ),
int( m_poly.Outline( 0 ).GetPointCount() ) );
int( GetPolyShape().Outline( 0 ).GetPointCount() ) );
case SHAPE_T::BEZIER:
return wxString::Format( _( "Bezier Curve, %d points" ),
@@ -458,13 +458,13 @@ void SCH_SHAPE::AddPoint( const VECTOR2I& aPosition )
{
if( GetShape() == SHAPE_T::POLY )
{
if( m_poly.IsEmpty() )
if( GetPolyShape().IsEmpty() )
{
m_poly.NewOutline();
m_poly.Outline( 0 ).SetClosed( false );
GetPolyShape().NewOutline();
GetPolyShape().Outline( 0 ).SetClosed( false );
}
m_poly.Outline( 0 ).Append( aPosition, true );
GetPolyShape().Outline( 0 ).Append( aPosition, true );
}
else
{
+7 -8
View File
@@ -345,9 +345,8 @@ public:
*/
int GetPointCount() const;
// Accessors to the polygonal shape
SHAPE_POLY_SET& GetPolyShape() { return m_poly; }
const SHAPE_POLY_SET& GetPolyShape() const { return m_poly; }
SHAPE_POLY_SET& GetPolyShape();
const SHAPE_POLY_SET& GetPolyShape() const;
/**
* @return true if the polygonal shape is valid (has more than 2 points).
@@ -356,13 +355,13 @@ public:
void SetPolyShape( const SHAPE_POLY_SET& aShape )
{
m_poly = aShape;
GetPolyShape() = aShape;
for( int ii = 0; ii < m_poly.OutlineCount(); ++ii )
for( int ii = 0; ii < GetPolyShape().OutlineCount(); ++ii )
{
if( m_poly.HoleCount( ii ) )
if( GetPolyShape().HoleCount( ii ) )
{
m_poly.Fracture();
GetPolyShape().Fracture();
break;
}
}
@@ -534,7 +533,7 @@ protected:
VECTOR2I m_bezierC2; // Bezier Control Point 2
std::vector<VECTOR2I> m_bezierPoints;
SHAPE_POLY_SET m_poly; // Stores the S_POLYGON shape
mutable std::unique_ptr<SHAPE_POLY_SET> m_poly; // Stores the S_POLYGON shape
int m_editState;
bool m_proxyItem; // A shape storing proxy information (ie: a pad
+2 -2
View File
@@ -515,9 +515,9 @@ void PCB_SHAPE::Normalize()
};
// Convert a poly back to a rectangle if appropriate
if( m_poly.OutlineCount() == 1 && m_poly.Outline( 0 ).SegmentCount() == 4 )
if( GetPolyShape().OutlineCount() == 1 && GetPolyShape().Outline( 0 ).SegmentCount() == 4 )
{
SHAPE_LINE_CHAIN& outline = m_poly.Outline( 0 );
SHAPE_LINE_CHAIN& outline = GetPolyShape().Outline( 0 );
if( horizontal( outline.Segment( 0 ) )
&& vertical( outline.Segment( 1 ) )
+1 -1
View File
@@ -743,7 +743,7 @@ void PCB_TEXTBOX::TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID
{
aBuffer.NewOutline();
const SHAPE_LINE_CHAIN& poly = m_poly.Outline( 0 );
const SHAPE_LINE_CHAIN& poly = GetPolyShape().Outline( 0 );
for( int ii = 0; ii < poly.PointCount(); ++ii )
aBuffer.Append( poly.GetPoint( ii ) );