Fix a threading segfault when filling zones
The shape cache gets reset by the zone fill algorithm. This needs to be cleaned before multiple threads are created and cannot be modified when threading. Fixes https://gitlab.com/kicad/code/kicad/issues/4723
This commit is contained in:
parent
f5842156a5
commit
224b41e8b1
|
@ -193,7 +193,7 @@ void D_PAD::SetChamferRectRatio( double aChamferScale )
|
|||
const std::vector<std::shared_ptr<SHAPE>>& D_PAD::GetEffectiveShapes() const
|
||||
{
|
||||
if( m_shapesDirty )
|
||||
buildEffectiveShapes();
|
||||
BuildEffectiveShapes();
|
||||
|
||||
return m_effectiveShapes;
|
||||
}
|
||||
|
@ -202,7 +202,7 @@ const std::vector<std::shared_ptr<SHAPE>>& D_PAD::GetEffectiveShapes() const
|
|||
const std::shared_ptr<SHAPE_SEGMENT>& D_PAD::GetEffectiveHoleShape() const
|
||||
{
|
||||
if( m_shapesDirty )
|
||||
buildEffectiveShapes();
|
||||
BuildEffectiveShapes();
|
||||
|
||||
return m_effectiveHoleShape;
|
||||
}
|
||||
|
@ -211,13 +211,13 @@ const std::shared_ptr<SHAPE_SEGMENT>& D_PAD::GetEffectiveHoleShape() const
|
|||
int D_PAD::GetBoundingRadius() const
|
||||
{
|
||||
if( m_shapesDirty )
|
||||
buildEffectiveShapes();
|
||||
BuildEffectiveShapes();
|
||||
|
||||
return m_effectiveBoundingRadius;
|
||||
}
|
||||
|
||||
|
||||
void D_PAD::buildEffectiveShapes() const
|
||||
void D_PAD::BuildEffectiveShapes() const
|
||||
{
|
||||
m_effectiveShapes.clear();
|
||||
m_effectiveHoleShape = nullptr;
|
||||
|
|
|
@ -317,6 +317,8 @@ public:
|
|||
void SetDrillShape( PAD_DRILL_SHAPE_T aShape ) { m_drillShape = aShape; m_shapesDirty = true; }
|
||||
PAD_DRILL_SHAPE_T GetDrillShape() const { return m_drillShape; }
|
||||
|
||||
bool IsDirty() const { return m_shapesDirty; }
|
||||
|
||||
/**
|
||||
* JEY TODO: temporary until Tom is done with DRC stuff....
|
||||
*/
|
||||
|
@ -575,6 +577,11 @@ public:
|
|||
*/
|
||||
bool PadShouldBeNPTH() const;
|
||||
|
||||
/**
|
||||
* Rebuilds the shape cache for the pad and clears the dirty bit
|
||||
*/
|
||||
void BuildEffectiveShapes() const;
|
||||
|
||||
virtual void ViewGetLayers( int aLayers[], int& aCount ) const override;
|
||||
|
||||
virtual unsigned int ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const override;
|
||||
|
@ -597,8 +604,6 @@ private:
|
|||
|
||||
void addPadPrimitivesToPolygon( SHAPE_POLY_SET* aMergedPolygon, int aError ) const;
|
||||
|
||||
void buildEffectiveShapes() const;
|
||||
|
||||
private:
|
||||
wxString m_name; ///< pad name (pin number in schematic)
|
||||
wxString m_pinFunction; ///< pin function in schematic
|
||||
|
|
|
@ -119,6 +119,16 @@ bool ZONE_FILLER::Fill( const std::vector<ZONE_CONTAINER*>& aZones, bool aCheck
|
|||
m_boardOutline.RemoveAllContours();
|
||||
m_brdOutlinesValid = m_board->GetBoardPolygonOutlines( m_boardOutline );
|
||||
|
||||
// Update the bounding box shape caches in the pads to prevent multi-threaded rebuilds
|
||||
for( auto module : m_board->Modules() )
|
||||
{
|
||||
for( auto pad : module->Pads() )
|
||||
{
|
||||
if( pad->IsDirty() )
|
||||
pad->BuildEffectiveShapes();
|
||||
}
|
||||
}
|
||||
|
||||
for( auto zone : aZones )
|
||||
{
|
||||
// Keepout zones are not filled
|
||||
|
@ -949,16 +959,14 @@ void ZONE_FILLER::buildThermalSpokes( const ZONE_CONTAINER* aZone, PCB_LAYER_ID
|
|||
//
|
||||
// We use the bounding-box to lay out the spokes, but for this to work the
|
||||
// bounding box has to be built at the same rotation as the spokes.
|
||||
|
||||
// We have to use a dummy pad to avoid dirtying the cached shapes
|
||||
wxPoint shapePos = pad->ShapePos();
|
||||
wxPoint padPos = pad->GetPosition();
|
||||
double padAngle = pad->GetOrientation();
|
||||
pad->SetOrientation( 0.0 );
|
||||
pad->SetPosition( { 0, 0 } );
|
||||
BOX2I reliefBB = pad->GetBoundingBox();
|
||||
pad->SetPosition( padPos );
|
||||
pad->SetOrientation( padAngle );
|
||||
double padAngle = pad->GetOrientation();
|
||||
D_PAD dummy_pad( *pad );
|
||||
dummy_pad.SetOrientation( 0.0 );
|
||||
dummy_pad.SetPosition( { 0, 0 } );
|
||||
|
||||
BOX2I reliefBB = dummy_pad.GetBoundingBox();
|
||||
reliefBB.Inflate( thermalReliefGap + epsilon );
|
||||
|
||||
// For circle pads, the thermal spoke orientation is 45 deg
|
||||
|
|
Loading…
Reference in New Issue