Lazy-allocate a few pad and padstack things
This commit is contained in:
+39
-17
@@ -114,7 +114,6 @@ PAD::PAD( FOOTPRINT* parent ) :
|
||||
for( PCB_LAYER_ID layer : LAYER_RANGE( F_Cu, B_Cu, BoardCopperLayerCount() ) )
|
||||
m_zoneLayerOverrides[layer] = ZLO_NONE;
|
||||
|
||||
m_lastGalZoomLevel = 0.0;
|
||||
}
|
||||
|
||||
|
||||
@@ -954,7 +953,9 @@ const std::shared_ptr<SHAPE_POLY_SET>& PAD::GetEffectivePolygon( PCB_LAYER_ID aL
|
||||
|
||||
aLayer = Padstack().EffectiveLayerFor( aLayer );
|
||||
|
||||
return m_effectivePolygons[ aLayer ][ aErrorLoc ];
|
||||
const PAD_DRAW_CACHE_DATA& drawCache = getDrawCache();
|
||||
|
||||
return drawCache.m_effectivePolygons.at( aLayer )[ aErrorLoc ];
|
||||
}
|
||||
|
||||
|
||||
@@ -1049,14 +1050,16 @@ std::shared_ptr<SHAPE> PAD::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING fla
|
||||
|
||||
aLayer = Padstack().EffectiveLayerFor( aLayer );
|
||||
|
||||
wxCHECK_MSG( m_effectiveShapes.contains( aLayer ), nullptr,
|
||||
const PAD_DRAW_CACHE_DATA& drawCache = getDrawCache();
|
||||
|
||||
wxCHECK_MSG( drawCache.m_effectiveShapes.contains( aLayer ), nullptr,
|
||||
wxString::Format( wxT( "Missing shape in PAD::GetEffectiveShape for layer %s." ),
|
||||
magic_enum::enum_name( aLayer ) ) );
|
||||
wxCHECK_MSG( m_effectiveShapes.at( aLayer ), nullptr,
|
||||
wxCHECK_MSG( drawCache.m_effectiveShapes.at( aLayer ), nullptr,
|
||||
wxString::Format( wxT( "Null shape in PAD::GetEffectiveShape for layer %s." ),
|
||||
magic_enum::enum_name( aLayer ) ) );
|
||||
|
||||
return m_effectiveShapes[aLayer];
|
||||
return drawCache.m_effectiveShapes.at( aLayer );
|
||||
}
|
||||
|
||||
|
||||
@@ -1065,7 +1068,7 @@ std::shared_ptr<SHAPE_SEGMENT> PAD::GetEffectiveHoleShape() const
|
||||
if( m_shapesDirty )
|
||||
BuildEffectiveShapes();
|
||||
|
||||
return m_effectiveHoleShape;
|
||||
return getDrawCache().m_effectiveHoleShape;
|
||||
}
|
||||
|
||||
|
||||
@@ -1078,6 +1081,15 @@ int PAD::GetBoundingRadius() const
|
||||
}
|
||||
|
||||
|
||||
PAD::PAD_DRAW_CACHE_DATA& PAD::getDrawCache() const
|
||||
{
|
||||
if( !m_drawCache )
|
||||
m_drawCache = std::make_unique<PAD_DRAW_CACHE_DATA>();
|
||||
|
||||
return *m_drawCache;
|
||||
}
|
||||
|
||||
|
||||
void PAD::BuildEffectiveShapes() const
|
||||
{
|
||||
std::lock_guard<std::mutex> RAII_lock( m_dataMutex );
|
||||
@@ -1087,17 +1099,20 @@ void PAD::BuildEffectiveShapes() const
|
||||
if( !m_shapesDirty )
|
||||
return;
|
||||
|
||||
m_effectiveBoundingBox = BOX2I();
|
||||
PAD_DRAW_CACHE_DATA& drawCache = getDrawCache();
|
||||
|
||||
drawCache.m_effectiveBoundingBox = BOX2I();
|
||||
drawCache.m_effectiveShapes.clear();
|
||||
|
||||
Padstack().ForEachUniqueLayer(
|
||||
[&]( PCB_LAYER_ID aLayer )
|
||||
{
|
||||
const SHAPE_COMPOUND& layerShape = buildEffectiveShape( aLayer );
|
||||
m_effectiveBoundingBox.Merge( layerShape.BBox() );
|
||||
drawCache.m_effectiveBoundingBox.Merge( layerShape.BBox() );
|
||||
} );
|
||||
|
||||
// Hole shape
|
||||
m_effectiveHoleShape = nullptr;
|
||||
drawCache.m_effectiveHoleShape = nullptr;
|
||||
|
||||
VECTOR2I half_size = m_padStack.Drill().size / 2;
|
||||
int half_width;
|
||||
@@ -1115,9 +1130,10 @@ void PAD::BuildEffectiveShapes() const
|
||||
|
||||
RotatePoint( half_len, GetOrientation() );
|
||||
|
||||
m_effectiveHoleShape = std::make_shared<SHAPE_SEGMENT>( m_pos - half_len, m_pos + half_len,
|
||||
drawCache.m_effectiveHoleShape = std::make_shared<SHAPE_SEGMENT>( m_pos - half_len,
|
||||
m_pos + half_len,
|
||||
half_width * 2 );
|
||||
m_effectiveBoundingBox.Merge( m_effectiveHoleShape->BBox() );
|
||||
drawCache.m_effectiveBoundingBox.Merge( drawCache.m_effectiveHoleShape->BBox() );
|
||||
|
||||
// All done
|
||||
m_shapesDirty = false;
|
||||
@@ -1126,11 +1142,13 @@ void PAD::BuildEffectiveShapes() const
|
||||
|
||||
const SHAPE_COMPOUND& PAD::buildEffectiveShape( PCB_LAYER_ID aLayer ) const
|
||||
{
|
||||
m_effectiveShapes[aLayer] = std::make_shared<SHAPE_COMPOUND>();
|
||||
PAD_DRAW_CACHE_DATA& drawCache = getDrawCache();
|
||||
|
||||
drawCache.m_effectiveShapes[aLayer] = std::make_shared<SHAPE_COMPOUND>();
|
||||
|
||||
auto add = [this, aLayer]( SHAPE* aShape )
|
||||
{
|
||||
m_effectiveShapes[aLayer]->AddShape( aShape );
|
||||
getDrawCache().m_effectiveShapes[aLayer]->AddShape( aShape );
|
||||
};
|
||||
|
||||
VECTOR2I shapePos = ShapePos( aLayer ); // Fetch only once; rotation involves trig
|
||||
@@ -1273,7 +1291,7 @@ const SHAPE_COMPOUND& PAD::buildEffectiveShape( PCB_LAYER_ID aLayer ) const
|
||||
}
|
||||
}
|
||||
|
||||
return *m_effectiveShapes[aLayer];
|
||||
return *drawCache.m_effectiveShapes[aLayer];
|
||||
}
|
||||
|
||||
|
||||
@@ -1289,11 +1307,14 @@ void PAD::BuildEffectivePolygon( ERROR_LOC aErrorLoc ) const
|
||||
if( !m_polyDirty[ aErrorLoc ] )
|
||||
return;
|
||||
|
||||
PAD_DRAW_CACHE_DATA& drawCache = getDrawCache();
|
||||
|
||||
Padstack().ForEachUniqueLayer(
|
||||
[&]( PCB_LAYER_ID aLayer )
|
||||
{
|
||||
// Polygon
|
||||
std::shared_ptr<SHAPE_POLY_SET>& effectivePolygon = m_effectivePolygons[ aLayer ][ aErrorLoc ];
|
||||
std::shared_ptr<SHAPE_POLY_SET>& effectivePolygon =
|
||||
drawCache.m_effectivePolygons[ aLayer ][ aErrorLoc ];
|
||||
|
||||
effectivePolygon = std::make_shared<SHAPE_POLY_SET>();
|
||||
TransformShapeToPolygon( *effectivePolygon, aLayer, 0, GetMaxError(), aErrorLoc );
|
||||
@@ -1306,7 +1327,8 @@ void PAD::BuildEffectivePolygon( ERROR_LOC aErrorLoc ) const
|
||||
Padstack().ForEachUniqueLayer(
|
||||
[&]( PCB_LAYER_ID aLayer )
|
||||
{
|
||||
std::shared_ptr<SHAPE_POLY_SET>& effectivePolygon = m_effectivePolygons[ aLayer ][ aErrorLoc ];
|
||||
std::shared_ptr<SHAPE_POLY_SET>& effectivePolygon =
|
||||
drawCache.m_effectivePolygons[ aLayer ][ aErrorLoc ];
|
||||
|
||||
for( int cnt = 0; cnt < effectivePolygon->OutlineCount(); ++cnt )
|
||||
{
|
||||
@@ -1334,7 +1356,7 @@ const BOX2I PAD::GetBoundingBox() const
|
||||
if( m_shapesDirty )
|
||||
BuildEffectiveShapes();
|
||||
|
||||
return m_effectiveBoundingBox;
|
||||
return getDrawCache().m_effectiveBoundingBox;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+16
-11
@@ -1070,6 +1070,21 @@ protected:
|
||||
private:
|
||||
const SHAPE_COMPOUND& buildEffectiveShape( PCB_LAYER_ID aLayer ) const;
|
||||
|
||||
struct PAD_DRAW_CACHE_DATA
|
||||
{
|
||||
// Must be set to true to force rebuild shapes to draw (after geometry change for instance)
|
||||
typedef std::map<PCB_LAYER_ID, std::shared_ptr<SHAPE_COMPOUND>> LAYER_SHAPE_MAP;
|
||||
typedef std::map<PCB_LAYER_ID, std::array<std::shared_ptr<SHAPE_POLY_SET>, 2>> LAYER_POLYGON_MAP;
|
||||
|
||||
BOX2I m_effectiveBoundingBox;
|
||||
LAYER_SHAPE_MAP m_effectiveShapes;
|
||||
std::shared_ptr<SHAPE_SEGMENT> m_effectiveHoleShape;
|
||||
LAYER_POLYGON_MAP m_effectivePolygons;
|
||||
double m_lastGalZoomLevel = 0.0;
|
||||
};
|
||||
|
||||
PAD_DRAW_CACHE_DATA& getDrawCache() const;
|
||||
|
||||
void doCheckPad( PCB_LAYER_ID aLayer, UNITS_PROVIDER* aUnitsProvider, bool aForPadProperties,
|
||||
const std::function<void( int aErrorCode, const wxString& aMsg )>& aErrorHandler ) const;
|
||||
|
||||
@@ -1085,17 +1100,7 @@ private:
|
||||
// Mutex for shape building, poly building and zone layer overrides
|
||||
mutable std::mutex m_dataMutex;
|
||||
|
||||
// Must be set to true to force rebuild shapes to draw (after geometry change for instance)
|
||||
typedef std::map<PCB_LAYER_ID, std::shared_ptr<SHAPE_COMPOUND>> LAYER_SHAPE_MAP;
|
||||
mutable BOX2I m_effectiveBoundingBox;
|
||||
mutable LAYER_SHAPE_MAP m_effectiveShapes;
|
||||
mutable std::shared_ptr<SHAPE_SEGMENT> m_effectiveHoleShape;
|
||||
|
||||
typedef std::map<PCB_LAYER_ID, std::array<std::shared_ptr<SHAPE_POLY_SET>, 2>> LAYER_POLYGON_MAP;
|
||||
mutable LAYER_POLYGON_MAP m_effectivePolygons;
|
||||
// Last zoom level used to draw the pad: the LAYER_PAD_HOLEWALLS layer shape
|
||||
// depend on the zoom level. So keep trace on the last used zoom level
|
||||
mutable double m_lastGalZoomLevel;
|
||||
mutable std::unique_ptr<PAD_DRAW_CACHE_DATA> m_drawCache;
|
||||
|
||||
mutable int m_effectiveBoundingRadius;
|
||||
|
||||
|
||||
+31
-5
@@ -88,7 +88,7 @@ PADSTACK& PADSTACK::operator=( const PADSTACK &aOther )
|
||||
|
||||
m_mode = aOther.m_mode;
|
||||
m_layerSet = aOther.m_layerSet;
|
||||
m_customName = aOther.m_customName;
|
||||
SetCustomName( aOther.CustomName() );
|
||||
m_orientation = aOther.m_orientation;
|
||||
m_copperProps = aOther.m_copperProps;
|
||||
m_frontMaskProps = aOther.m_frontMaskProps;
|
||||
@@ -136,7 +136,7 @@ bool PADSTACK::operator==( const PADSTACK& aOther ) const
|
||||
if( m_layerSet != aOther.m_layerSet )
|
||||
return false;
|
||||
|
||||
if( m_customName != aOther.m_customName )
|
||||
if( CustomName() != aOther.CustomName() )
|
||||
return false;
|
||||
|
||||
if( m_orientation != aOther.m_orientation )
|
||||
@@ -1378,7 +1378,7 @@ int PADSTACK::Compare( const PADSTACK* aLeft, const PADSTACK* aRight )
|
||||
if( aLeft->m_layerSet != aRight->m_layerSet )
|
||||
return aLeft->m_layerSet.Seq() < aRight->m_layerSet.Seq();
|
||||
|
||||
if( ( diff = aLeft->m_customName.Cmp( aRight->m_customName ) ) != 0 )
|
||||
if( ( diff = wxString( aLeft->CustomName() ).Cmp( aRight->CustomName() ) ) != 0 )
|
||||
return diff;
|
||||
|
||||
TEST( aLeft->m_orientation.AsTenthsOfADegree(), aRight->m_orientation.AsTenthsOfADegree() );
|
||||
@@ -1439,7 +1439,7 @@ double PADSTACK::Similarity( const PADSTACK& aOther ) const
|
||||
if( m_layerSet != aOther.m_layerSet )
|
||||
similarity *= 0.9;
|
||||
|
||||
if( m_customName != aOther.m_customName )
|
||||
if( CustomName() != aOther.CustomName() )
|
||||
similarity *= 0.9;
|
||||
|
||||
if( m_orientation != aOther.m_orientation )
|
||||
@@ -1531,7 +1531,33 @@ PCB_LAYER_ID PADSTACK::EndLayer() const
|
||||
|
||||
wxString PADSTACK::Name() const
|
||||
{
|
||||
return m_customName;
|
||||
return CustomName();
|
||||
}
|
||||
|
||||
|
||||
const wxChar* PADSTACK::CustomName() const
|
||||
{
|
||||
if( m_customName )
|
||||
return *m_customName;
|
||||
|
||||
return wxEmptyString;
|
||||
}
|
||||
|
||||
|
||||
void PADSTACK::SetCustomName( const wxString& aCustomName )
|
||||
{
|
||||
if( aCustomName.IsEmpty() )
|
||||
{
|
||||
m_customName.reset();
|
||||
}
|
||||
else if( m_customName )
|
||||
{
|
||||
*m_customName = aCustomName;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_customName = std::make_unique<wxString>( aCustomName );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+4
-1
@@ -338,6 +338,9 @@ public:
|
||||
///! Returns the name of this padstack in IPC-7351 format
|
||||
wxString Name() const;
|
||||
|
||||
const wxChar* CustomName() const;
|
||||
void SetCustomName( const wxString& aCustomName );
|
||||
|
||||
EDA_ANGLE GetOrientation() const { return m_orientation; }
|
||||
void SetOrientation( EDA_ANGLE aAngle )
|
||||
{
|
||||
@@ -531,7 +534,7 @@ private:
|
||||
LSET m_layerSet;
|
||||
|
||||
///! An override for the IPC-7351 padstack name
|
||||
wxString m_customName;
|
||||
std::unique_ptr<wxString> m_customName;
|
||||
|
||||
///! The rotation of the pad relative to an outer reference frame
|
||||
EDA_ANGLE m_orientation;
|
||||
|
||||
Reference in New Issue
Block a user