Compare commits

..

9 Commits

Author SHA1 Message Date
Jon Evans eec5b07179 Add 10.99 qa config dir 2026-03-19 22:05:21 -04:00
Jon Evans ac8f0096ce Lazy-allocate a few pad and padstack things 2026-03-19 21:32:07 -04:00
Jon Evans 755280dec1 Defer initialization of PIN_LAYOUT_CACHE until it is needed 2026-03-19 21:32:07 -04:00
Jon Evans 067533928b Reduce memory usage of EDA_SHAPE pt 2 2026-03-19 21:32:06 -04:00
Jon Evans 5353982a4a Reduce memory usage of EDA_SHAPE 2026-03-19 21:32:02 -04:00
Jon Evans 683bb74b7f Reduce memory usage of FOOTPRINT caches
These aren't needed until a footprint is materialized
2026-03-19 21:25:34 -04:00
Jon Evans 082ec945fc Reduce memory usage of text/fields
Lazy construction of caches that are only needed
for some of these reduces their footprint significantly.
2026-03-19 21:25:34 -04:00
Seth Hillbrand 8f6d321fb5 Zone fill: DAG scheduling and batching
Replace the polling loop in ZONE_FILLER::Fill with a DAG-based wave
scheduler. Each zone-layer pair's fill dependencies are computed
upfront as a directed acyclic graph, and zones are processed in waves
instead of resubmitting each time.

Batch multiple BooleanSubtract calls into single operations in
subtractHigherPriorityZones, fillNonCopperZone, and
refillZoneFromCache by collecting all knockouts into one SHAPE_POLY_SET
before subtracting.
2026-03-19 16:55:53 -07:00
Wayne Stambaugh 10554d4812 Begin version 11 development. 2026-03-19 17:32:42 -04:00
36 changed files with 4060 additions and 739 deletions
+1 -1
View File
@@ -37,7 +37,7 @@
# KiCad.
#
# Note: This version string should follow the semantic versioning system
set( KICAD_SEMANTIC_VERSION "10.0.0-unknown" )
set( KICAD_SEMANTIC_VERSION "10.99.0-unknown" )
# Default the version to the semantic version.
# This is overridden by the git repository tag though (if using git)
+180 -66
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;
}
@@ -151,6 +151,64 @@ EDA_SHAPE::EDA_SHAPE( const SHAPE& aShape ) :
}
EDA_SHAPE::EDA_SHAPE( const EDA_SHAPE& aOther ) :
m_endsSwapped( aOther.m_endsSwapped ),
m_shape( aOther.m_shape ),
m_stroke( aOther.m_stroke ),
m_fill( aOther.m_fill ),
m_fillColor( aOther.m_fillColor ),
m_hatchingDirty( true ),
m_rectangleHeight( aOther.m_rectangleHeight ),
m_rectangleWidth( aOther.m_rectangleWidth ),
m_cornerRadius( aOther.m_cornerRadius ),
m_start( aOther.m_start ),
m_end( aOther.m_end ),
m_arcCenter( aOther.m_arcCenter ),
m_arcMidData( aOther.m_arcMidData ),
m_bezierC1( aOther.m_bezierC1 ),
m_bezierC2( aOther.m_bezierC2 ),
m_bezierPoints( aOther.m_bezierPoints ),
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 );
}
EDA_SHAPE& EDA_SHAPE::operator=( const EDA_SHAPE& aOther )
{
if( this == &aOther )
return *this;
m_endsSwapped = aOther.m_endsSwapped;
m_shape = aOther.m_shape;
m_stroke = aOther.m_stroke;
m_fill = aOther.m_fill;
m_fillColor = aOther.m_fillColor;
m_hatchingCache.reset();
m_hatchingDirty = true;
m_rectangleHeight = aOther.m_rectangleHeight;
m_rectangleWidth = aOther.m_rectangleWidth;
m_cornerRadius = aOther.m_cornerRadius;
m_start = aOther.m_start;
m_end = aOther.m_end;
m_arcCenter = aOther.m_arcCenter;
m_arcMidData = aOther.m_arcMidData;
m_bezierC1 = aOther.m_bezierC1;
m_bezierC2 = aOther.m_bezierC2;
m_bezierPoints = aOther.m_bezierPoints;
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;
return *this;
}
void EDA_SHAPE::Serialize( google::protobuf::Any &aContainer ) const
{
using namespace kiapi::common;
@@ -375,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;
}
@@ -397,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;
@@ -521,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 )
@@ -572,6 +630,42 @@ UI_FILL_MODE EDA_SHAPE::GetFillModeProp() const
}
const SHAPE_POLY_SET& EDA_SHAPE::GetHatching() const
{
if( !m_hatchingCache )
m_hatchingCache = std::make_unique<EDA_SHAPE_HATCH_CACHE_DATA>();
return m_hatchingCache->hatching;
}
const std::vector<SEG>& EDA_SHAPE::GetHatchLines() const
{
if( !m_hatchingCache )
m_hatchingCache = std::make_unique<EDA_SHAPE_HATCH_CACHE_DATA>();
return m_hatchingCache->hatchLines;
}
SHAPE_POLY_SET& EDA_SHAPE::hatching() const
{
if( !m_hatchingCache )
m_hatchingCache = std::make_unique<EDA_SHAPE_HATCH_CACHE_DATA>();
return m_hatchingCache->hatching;
}
std::vector<SEG>& EDA_SHAPE::hatchLines() const
{
if( !m_hatchingCache )
m_hatchingCache = std::make_unique<EDA_SHAPE_HATCH_CACHE_DATA>();
return m_hatchingCache->hatchLines;
}
void EDA_SHAPE::UpdateHatching() const
{
if( !m_hatchingDirty )
@@ -620,7 +714,7 @@ void EDA_SHAPE::UpdateHatching() const
if( !IsClosed() )
return;
shapeBuffer = m_poly.CloneDropTriangulation();
shapeBuffer = GetPolyShape().CloneDropTriangulation();
break;
default:
@@ -630,8 +724,8 @@ void EDA_SHAPE::UpdateHatching() const
// Clear cached hatching only after all validation passes.
// This prevents flickering when early returns would otherwise leave empty hatching.
m_hatching.RemoveAllContours();
m_hatchLines.clear();
hatching().RemoveAllContours();
hatchLines().clear();
BOX2I extents = shapeBuffer.BBox();
int majorAxis = std::max( extents.GetWidth(), extents.GetHeight() );
@@ -649,7 +743,7 @@ void EDA_SHAPE::UpdateHatching() const
// Generate hatch lines for stroke-based rendering. All hatch types use line segments.
std::vector<SEG> hatchSegs = shapeBuffer.GenerateHatchLines( slopes, spacing, -1 );
m_hatchLines = hatchSegs;
hatchLines() = hatchSegs;
// Also generate polygon representation for exports, 3D viewer, and hit testing
if( GetFillMode() == FILL_T::HATCH || GetFillMode() == FILL_T::REVERSE_HATCH )
@@ -659,10 +753,11 @@ void EDA_SHAPE::UpdateHatching() const
// We don't really need the rounded ends at all, so don't spend any extra time on them
int maxError = lineWidth;
TransformOvalToPolygon( m_hatching, seg.A, seg.B, lineWidth, maxError, ERROR_INSIDE );
TransformOvalToPolygon( hatching(), seg.A, seg.B, lineWidth, maxError,
ERROR_INSIDE );
}
m_hatching.Fracture();
hatching().Fracture();
m_hatchingDirty = false;
}
else
@@ -673,8 +768,8 @@ void EDA_SHAPE::UpdateHatching() const
int gridsize = spacing;
int hole_size = gridsize - GetHatchLineWidth();
m_hatching = shapeBuffer.CloneDropTriangulation();
m_hatching.Rotate( -ANGLE_45 );
hatching() = shapeBuffer.CloneDropTriangulation();
hatching().Rotate( -ANGLE_45 );
// Build hole shape
SHAPE_LINE_CHAIN hole_base;
@@ -689,7 +784,7 @@ void EDA_SHAPE::UpdateHatching() const
hole_base.SetClosed( true );
// Build holes
BOX2I bbox = m_hatching.BBox( 0 );
BOX2I bbox = GetHatching().BBox( 0 );
SHAPE_POLY_SET holes;
int x_offset = bbox.GetX() - ( bbox.GetX() ) % gridsize - gridsize;
@@ -705,16 +800,17 @@ void EDA_SHAPE::UpdateHatching() const
}
}
m_hatching.BooleanSubtract( holes );
m_hatching.Fracture();
hatching().BooleanSubtract( holes );
hatching().Fracture();
// Must re-rotate after Fracture(). Clipper struggles mightily with fracturing 45-degree holes.
m_hatching.Rotate( ANGLE_45 );
// Must re-rotate after Fracture(). Clipper struggles mightily with fracturing
// 45-degree holes.
hatching().Rotate( ANGLE_45 );
if( !knockouts.IsEmpty() )
{
m_hatching.BooleanSubtract( knockouts );
m_hatching.Fracture();
hatching().BooleanSubtract( knockouts );
hatching().Fracture();
}
m_hatchingDirty = false;
@@ -742,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:
@@ -791,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() );
@@ -852,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:
@@ -906,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:
@@ -1255,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;
@@ -1412,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 ) )
@@ -1585,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;
}
@@ -1833,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 );
}
@@ -1981,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 )
@@ -1999,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)
@@ -2041,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:
@@ -2074,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() )
@@ -2242,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:
@@ -2264,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 )
@@ -2343,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() );
@@ -2451,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();
@@ -2475,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 )
{
@@ -2573,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;
}
@@ -2627,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 );
@@ -2640,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 );
+43 -59
View File
@@ -100,8 +100,6 @@ GR_TEXT_V_ALIGN_T EDA_TEXT::MapVertJustify( int aVertJustify )
EDA_TEXT::EDA_TEXT( const EDA_IU_SCALE& aIuScale, const wxString& aText ) :
m_text( aText ),
m_IuScale( aIuScale ),
m_render_cache_font( nullptr ),
m_render_cache_mirrored( false ),
m_visible( true )
{
SetTextSize( VECTOR2I( EDA_UNIT_UTILS::Mils2IU( m_IuScale, DEFAULT_SIZE_TEXT ),
@@ -131,21 +129,7 @@ EDA_TEXT::EDA_TEXT( const EDA_TEXT& aText ) :
m_pos = aText.m_pos;
m_visible = aText.m_visible;
m_render_cache_font = aText.m_render_cache_font;
m_render_cache_text = aText.m_render_cache_text;
m_render_cache_angle = aText.m_render_cache_angle;
m_render_cache_offset = aText.m_render_cache_offset;
m_render_cache_mirrored = aText.m_render_cache_mirrored;
m_render_cache.clear();
for( const std::unique_ptr<KIFONT::GLYPH>& glyph : aText.m_render_cache )
{
if( KIFONT::OUTLINE_GLYPH* outline = dynamic_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() ) )
m_render_cache.emplace_back( std::make_unique<KIFONT::OUTLINE_GLYPH>( *outline ) );
else if( KIFONT::STROKE_GLYPH* stroke = dynamic_cast<KIFONT::STROKE_GLYPH*>( glyph.get() ) )
m_render_cache.emplace_back( std::make_unique<KIFONT::STROKE_GLYPH>( *stroke ) );
}
m_render_cache.reset();
{
std::lock_guard<std::mutex> bboxLock( aText.m_bbox_cacheMutex );
@@ -174,21 +158,7 @@ EDA_TEXT& EDA_TEXT::operator=( const EDA_TEXT& aText )
m_pos = aText.m_pos;
m_visible = aText.m_visible;
m_render_cache_font = aText.m_render_cache_font;
m_render_cache_text = aText.m_render_cache_text;
m_render_cache_angle = aText.m_render_cache_angle;
m_render_cache_offset = aText.m_render_cache_offset;
m_render_cache_mirrored = aText.m_render_cache_mirrored;
m_render_cache.clear();
for( const std::unique_ptr<KIFONT::GLYPH>& glyph : aText.m_render_cache )
{
if( KIFONT::OUTLINE_GLYPH* outline = dynamic_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() ) )
m_render_cache.emplace_back( std::make_unique<KIFONT::OUTLINE_GLYPH>( *outline ) );
else if( KIFONT::STROKE_GLYPH* stroke = dynamic_cast<KIFONT::STROKE_GLYPH*>( glyph.get() ) )
m_render_cache.emplace_back( std::make_unique<KIFONT::STROKE_GLYPH>( *stroke ) );
}
m_render_cache.reset();
{
std::scoped_lock<std::mutex, std::mutex> bboxLock( m_bbox_cacheMutex, aText.m_bbox_cacheMutex );
@@ -524,8 +494,8 @@ bool EDA_TEXT::ResolveFont( const std::vector<wxString>* aEmbeddedFonts )
{
m_attributes.m_Font = KIFONT::FONT::GetFont( m_unresolvedFontName, IsBold(), IsItalic(), aEmbeddedFonts );
if( !m_render_cache.empty() )
m_render_cache_font = m_attributes.m_Font;
if( m_render_cache && !m_render_cache->glyphs.empty() )
m_render_cache->font = m_attributes.m_Font;
m_unresolvedFontName = wxEmptyString;
return true;
@@ -612,12 +582,15 @@ void EDA_TEXT::Offset( const VECTOR2I& aOffset )
m_pos += aOffset;
for( std::unique_ptr<KIFONT::GLYPH>& glyph : m_render_cache )
if( m_render_cache )
{
if( KIFONT::OUTLINE_GLYPH* outline = dynamic_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() ) )
outline->Move( aOffset );
else if( KIFONT::STROKE_GLYPH* stroke = dynamic_cast<KIFONT::STROKE_GLYPH*>( glyph.get() ) )
glyph = stroke->Transform( { 1.0, 1.0 }, aOffset, 0, ANGLE_0, false, { 0, 0 } );
for( std::unique_ptr<KIFONT::GLYPH>& glyph : m_render_cache->glyphs )
{
if( KIFONT::OUTLINE_GLYPH* outline = dynamic_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() ) )
outline->Move( aOffset );
else if( KIFONT::STROKE_GLYPH* stroke = dynamic_cast<KIFONT::STROKE_GLYPH*>( glyph.get() ) )
glyph = stroke->Transform( { 1.0, 1.0 }, aOffset, 0, ANGLE_0, false, { 0, 0 } );
}
}
ClearBoundingBoxCache();
@@ -682,7 +655,7 @@ const KIFONT::METRICS& EDA_TEXT::getFontMetrics() const
void EDA_TEXT::ClearRenderCache()
{
m_render_cache.clear();
m_render_cache.reset();
}
@@ -701,26 +674,31 @@ EDA_TEXT::GetRenderCache( const KIFONT::FONT* aFont, const wxString& forResolved
EDA_ANGLE resolvedAngle = GetDrawRotation();
bool mirrored = IsMirrored();
if( m_render_cache.empty() || m_render_cache_font != aFont || m_render_cache_text != forResolvedText
|| m_render_cache_angle != resolvedAngle || m_render_cache_offset != aOffset
|| m_render_cache_mirrored != mirrored )
if( !m_render_cache )
m_render_cache = std::make_unique<EDA_TEXT_RENDER_CACHE_DATA>();
if( m_render_cache->glyphs.empty() || m_render_cache->font != aFont
|| m_render_cache->text != forResolvedText
|| m_render_cache->angle != resolvedAngle || m_render_cache->offset != aOffset
|| m_render_cache->mirrored != mirrored )
{
m_render_cache.clear();
m_render_cache->glyphs.clear();
const KIFONT::OUTLINE_FONT* font = static_cast<const KIFONT::OUTLINE_FONT*>( aFont );
TEXT_ATTRIBUTES attrs = GetAttributes();
attrs.m_Angle = resolvedAngle;
font->GetLinesAsGlyphs( &m_render_cache, forResolvedText, GetDrawPos() + aOffset, attrs, getFontMetrics() );
m_render_cache_font = aFont;
m_render_cache_angle = resolvedAngle;
m_render_cache_text = forResolvedText;
m_render_cache_offset = aOffset;
m_render_cache_mirrored = mirrored;
font->GetLinesAsGlyphs( &m_render_cache->glyphs, forResolvedText, GetDrawPos() + aOffset, attrs,
getFontMetrics() );
m_render_cache->font = aFont;
m_render_cache->angle = resolvedAngle;
m_render_cache->text = forResolvedText;
m_render_cache->offset = aOffset;
m_render_cache->mirrored = mirrored;
}
return &m_render_cache;
return &m_render_cache->glyphs;
}
return nullptr;
@@ -730,19 +708,25 @@ EDA_TEXT::GetRenderCache( const KIFONT::FONT* aFont, const wxString& forResolved
void EDA_TEXT::SetupRenderCache( const wxString& aResolvedText, const KIFONT::FONT* aFont, const EDA_ANGLE& aAngle,
const VECTOR2I& aOffset )
{
m_render_cache_text = aResolvedText;
m_render_cache_font = aFont;
m_render_cache_angle = aAngle;
m_render_cache_offset = aOffset;
m_render_cache_mirrored = IsMirrored();
m_render_cache.clear();
if( !m_render_cache )
m_render_cache = std::make_unique<EDA_TEXT_RENDER_CACHE_DATA>();
m_render_cache->text = aResolvedText;
m_render_cache->font = aFont;
m_render_cache->angle = aAngle;
m_render_cache->offset = aOffset;
m_render_cache->mirrored = IsMirrored();
m_render_cache->glyphs.clear();
}
void EDA_TEXT::AddRenderCacheGlyph( const SHAPE_POLY_SET& aPoly )
{
m_render_cache.emplace_back( std::make_unique<KIFONT::OUTLINE_GLYPH>( aPoly ) );
static_cast<KIFONT::OUTLINE_GLYPH*>( m_render_cache.back().get() )->CacheTriangulation();
if( !m_render_cache )
m_render_cache = std::make_unique<EDA_TEXT_RENDER_CACHE_DATA>();
m_render_cache->glyphs.emplace_back( std::make_unique<KIFONT::OUTLINE_GLYPH>( aPoly ) );
static_cast<KIFONT::OUTLINE_GLYPH*>( m_render_cache->glyphs.back().get() )->CacheTriangulation();
}
+1
View File
@@ -75,6 +75,7 @@ principle should be easily implemented by adapting the current STL containers.
%ignore InitKiCadAbout;
%ignore GetCommandOptions;
%ignore EDA_TEXT_RENDER_CACHE_DATA;
%rename(getWxRect) operator wxRect;
%rename(getBOX2I) operator BOX2I;
+18 -40
View File
@@ -56,7 +56,6 @@ SCH_FIELD::SCH_FIELD() :
m_isGeneratedField( false ),
m_autoAdded( false ),
m_showInChooser( true ),
m_renderCacheValid( false ),
m_lastResolvedColor( COLOR4D::UNSPECIFIED )
{
}
@@ -116,21 +115,9 @@ SCH_FIELD::SCH_FIELD( const SCH_FIELD& aField ) :
m_isGeneratedField = aField.m_isGeneratedField;
m_autoAdded = aField.m_autoAdded;
m_showInChooser = aField.m_showInChooser;
m_renderCache.clear();
for( const std::unique_ptr<KIFONT::GLYPH>& glyph : aField.m_renderCache )
{
if( KIFONT::OUTLINE_GLYPH* outline = dynamic_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() ) )
m_renderCache.emplace_back( std::make_unique<KIFONT::OUTLINE_GLYPH>( *outline ) );
else if( KIFONT::STROKE_GLYPH* stroke = dynamic_cast<KIFONT::STROKE_GLYPH*>( glyph.get() ) )
m_renderCache.emplace_back( std::make_unique<KIFONT::STROKE_GLYPH>( *stroke ) );
}
m_renderCacheValid = aField.m_renderCacheValid;
m_renderCachePos = aField.m_renderCachePos;
m_lastResolvedColor = aField.m_lastResolvedColor;
m_renderCache.reset();
}
@@ -145,22 +132,10 @@ SCH_FIELD& SCH_FIELD::operator=( const SCH_FIELD& aField )
m_showName = aField.m_showName;
m_allowAutoPlace = aField.m_allowAutoPlace;
m_isGeneratedField = aField.m_isGeneratedField;
m_renderCache.clear();
for( const std::unique_ptr<KIFONT::GLYPH>& glyph : aField.m_renderCache )
{
if( KIFONT::OUTLINE_GLYPH* outline = dynamic_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() ) )
m_renderCache.emplace_back( std::make_unique<KIFONT::OUTLINE_GLYPH>( *outline ) );
else if( KIFONT::STROKE_GLYPH* stroke = dynamic_cast<KIFONT::STROKE_GLYPH*>( glyph.get() ) )
m_renderCache.emplace_back( std::make_unique<KIFONT::STROKE_GLYPH>( *stroke ) );
}
m_renderCacheValid = aField.m_renderCacheValid;
m_renderCachePos = aField.m_renderCachePos;
m_lastResolvedColor = aField.m_lastResolvedColor;
m_renderCache.reset();
return *this;
}
@@ -274,7 +249,7 @@ void SCH_FIELD::ClearCaches()
void SCH_FIELD::ClearRenderCache()
{
EDA_TEXT::ClearRenderCache();
m_renderCacheValid = false;
m_renderCache.reset();
}
@@ -287,21 +262,24 @@ SCH_FIELD::GetRenderCache( const wxString& forResolvedText, const VECTOR2I& forP
{
KIFONT::OUTLINE_FONT* outlineFont = static_cast<KIFONT::OUTLINE_FONT*>( font );
if( m_renderCache.empty() || !m_renderCacheValid )
if( !m_renderCache )
m_renderCache = std::make_unique<SCH_FIELD_RENDER_CACHE_DATA>();
if( m_renderCache->glyphs.empty() )
{
m_renderCache.clear();
m_renderCache->glyphs.clear();
outlineFont->GetLinesAsGlyphs( &m_renderCache, forResolvedText, forPosition, aAttrs, GetFontMetrics() );
outlineFont->GetLinesAsGlyphs( &m_renderCache->glyphs, forResolvedText, forPosition, aAttrs,
GetFontMetrics() );
m_renderCachePos = forPosition;
m_renderCacheValid = true;
m_renderCache->pos = forPosition;
}
if( m_renderCachePos != forPosition )
if( m_renderCache->pos != forPosition )
{
VECTOR2I delta = forPosition - m_renderCachePos;
VECTOR2I delta = forPosition - m_renderCache->pos;
for( std::unique_ptr<KIFONT::GLYPH>& glyph : m_renderCache )
for( std::unique_ptr<KIFONT::GLYPH>& glyph : m_renderCache->glyphs )
{
if( glyph->IsOutline() )
static_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() )->Move( delta );
@@ -309,10 +287,10 @@ SCH_FIELD::GetRenderCache( const wxString& forResolvedText, const VECTOR2I& forP
static_cast<KIFONT::STROKE_GLYPH*>( glyph.get() )->Move( delta );
}
m_renderCachePos = forPosition;
m_renderCache->pos = forPosition;
}
return &m_renderCache;
return &m_renderCache->glyphs;
}
return nullptr;
+8 -3
View File
@@ -38,6 +38,13 @@ class SCH_EDIT_FRAME;
class SCH_TEXT;
struct SCH_FIELD_RENDER_CACHE_DATA
{
VECTOR2I pos;
std::vector<std::unique_ptr<KIFONT::GLYPH>> glyphs;
};
class SCH_FIELD : public SCH_ITEM, public EDA_TEXT
{
public:
@@ -343,9 +350,7 @@ private:
bool m_autoAdded; ///< Was this field automatically added to a LIB_SYMBOL?
bool m_showInChooser; ///< This field is available as a data column for the chooser
mutable bool m_renderCacheValid;
mutable VECTOR2I m_renderCachePos;
mutable std::vector<std::unique_ptr<KIFONT::GLYPH>> m_renderCache;
mutable std::unique_ptr<SCH_FIELD_RENDER_CACHE_DATA> m_renderCache;
mutable COLOR4D m_lastResolvedColor;
};
+31 -17
View File
@@ -128,8 +128,7 @@ SCH_PIN::SCH_PIN( LIB_SYMBOL* aParentSymbol ) :
m_hidden( false ),
m_numTextSize( schIUScale.MilsToIU( DEFAULT_PINNUM_SIZE ) ),
m_nameTextSize( schIUScale.MilsToIU( DEFAULT_PINNAME_SIZE ) ),
m_isDangling( true ),
m_layoutCache( std::make_unique<PIN_LAYOUT_CACHE>( *this ) )
m_isDangling( true )
{
if( SYMBOL_EDITOR_SETTINGS* cfg = GetAppSettings<SYMBOL_EDITOR_SETTINGS>( "symbol_editor" ) )
{
@@ -156,8 +155,7 @@ SCH_PIN::SCH_PIN( LIB_SYMBOL* aParentSymbol, const wxString& aName, const wxStri
m_hidden( false ),
m_numTextSize( aNumTextSize ),
m_nameTextSize( aNameTextSize ),
m_isDangling( true ),
m_layoutCache( std::make_unique<PIN_LAYOUT_CACHE>( *this ) )
m_isDangling( true )
{
SetName( aName );
SetNumber( aNumber );
@@ -172,8 +170,7 @@ SCH_PIN::SCH_PIN( SCH_SYMBOL* aParentSymbol, SCH_PIN* aLibPin ) :
m_orientation( PIN_ORIENTATION::INHERIT ),
m_shape( GRAPHIC_PINSHAPE::INHERIT ),
m_type( ELECTRICAL_PINTYPE::PT_INHERIT ),
m_isDangling( true ),
m_layoutCache( std::make_unique<PIN_LAYOUT_CACHE>( *this ) )
m_isDangling( true )
{
wxASSERT( aParentSymbol );
@@ -194,8 +191,7 @@ SCH_PIN::SCH_PIN( SCH_SYMBOL* aParentSymbol, const wxString& aNumber, const wxSt
m_type( ELECTRICAL_PINTYPE::PT_INHERIT ),
m_number( aNumber ),
m_alt( aAlt ),
m_isDangling( true ),
m_layoutCache( std::make_unique<PIN_LAYOUT_CACHE>( *this ) )
m_isDangling( true )
{
wxASSERT( aParentSymbol );
@@ -217,8 +213,7 @@ SCH_PIN::SCH_PIN( const SCH_PIN& aPin ) :
m_numTextSize( aPin.m_numTextSize ),
m_nameTextSize( aPin.m_nameTextSize ),
m_alt( aPin.m_alt ),
m_isDangling( aPin.m_isDangling ),
m_layoutCache( std::make_unique<PIN_LAYOUT_CACHE>( *this ) )
m_isDangling( aPin.m_isDangling )
{
SetName( aPin.m_name );
SetNumber( aPin.m_number );
@@ -250,6 +245,7 @@ SCH_PIN& SCH_PIN::operator=( const SCH_PIN& aPin )
m_numTextSize = aPin.m_numTextSize;
m_nameTextSize = aPin.m_nameTextSize;
m_isDangling = aPin.m_isDangling;
m_layoutCache.reset();
return *this;
}
@@ -338,7 +334,9 @@ void SCH_PIN::SetType( ELECTRICAL_PINTYPE aType )
return;
m_type = aType;
m_layoutCache->MarkDirty( PIN_LAYOUT_CACHE::DIRTY_FLAGS::ELEC_TYPE );
if( m_layoutCache )
m_layoutCache->MarkDirty( PIN_LAYOUT_CACHE::DIRTY_FLAGS::ELEC_TYPE );
}
@@ -430,7 +428,8 @@ void SCH_PIN::SetName( const wxString& aName )
// pin name string does not support spaces
m_name.Replace( wxT( " " ), wxT( "_" ) );
m_layoutCache->MarkDirty( PIN_LAYOUT_CACHE::DIRTY_FLAGS::NAME );
if( m_layoutCache )
m_layoutCache->MarkDirty( PIN_LAYOUT_CACHE::DIRTY_FLAGS::NAME );
}
@@ -650,7 +649,8 @@ void SCH_PIN::SetNumber( const wxString& aNumber )
// pin number string does not support spaces
m_number.Replace( wxT( " " ), wxT( "_" ) );
m_layoutCache->MarkDirty( PIN_LAYOUT_CACHE::DIRTY_FLAGS::NUMBER );
if( m_layoutCache )
m_layoutCache->MarkDirty( PIN_LAYOUT_CACHE::DIRTY_FLAGS::NUMBER );
}
@@ -674,7 +674,9 @@ void SCH_PIN::SetNameTextSize( int aSize )
return;
m_nameTextSize = aSize;
m_layoutCache->MarkDirty( PIN_LAYOUT_CACHE::DIRTY_FLAGS::NAME );
if( m_layoutCache )
m_layoutCache->MarkDirty( PIN_LAYOUT_CACHE::DIRTY_FLAGS::NAME );
}
@@ -698,7 +700,9 @@ void SCH_PIN::SetNumberTextSize( int aSize )
return;
m_numTextSize = aSize;
m_layoutCache->MarkDirty( PIN_LAYOUT_CACHE::DIRTY_FLAGS::NUMBER );
if( m_layoutCache )
m_layoutCache->MarkDirty( PIN_LAYOUT_CACHE::DIRTY_FLAGS::NUMBER );
}
@@ -1576,8 +1580,18 @@ BOX2I SCH_PIN::GetBoundingBox( bool aIncludeLabelsOnInvisiblePins, bool aInclude
bool aIncludeElectricalType ) const
{
// Just defer to the cache
return m_layoutCache->GetPinBoundingBox( aIncludeLabelsOnInvisiblePins, aIncludeNameAndNumber,
aIncludeElectricalType );
return GetLayoutCache().GetPinBoundingBox( aIncludeLabelsOnInvisiblePins,
aIncludeNameAndNumber,
aIncludeElectricalType );
}
PIN_LAYOUT_CACHE& SCH_PIN::GetLayoutCache() const
{
if( !m_layoutCache )
m_layoutCache = std::make_unique<PIN_LAYOUT_CACHE>( *this );
return *m_layoutCache;
}
+1 -1
View File
@@ -348,7 +348,7 @@ public:
* laid out than just the bounding box, you can use this. The SCH_PAINTER,
* for example, can use this to avoid having to duplicate text extent calcs.
*/
PIN_LAYOUT_CACHE& GetLayoutCache() const { return *m_layoutCache; }
PIN_LAYOUT_CACHE& GetLayoutCache() const;
protected:
wxString getItemDescription( ALT* aAlt ) const;
+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
{
+28 -14
View File
@@ -24,6 +24,8 @@
#pragma once
#include <memory>
#include <core/mirror.h>
#include <geometry/shape_poly_set.h>
#include <geometry/approximation.h>
@@ -84,6 +86,13 @@ struct ARC_MID
};
struct EDA_SHAPE_HATCH_CACHE_DATA
{
SHAPE_POLY_SET hatching;
std::vector<SEG> hatchLines;
};
class EDA_SHAPE : public SERIALIZABLE
{
public:
@@ -92,8 +101,11 @@ public:
/// Construct an EDA_SHAPE from an abstract SHAPE geometry.
EDA_SHAPE( const SHAPE& aShape );
// Do not create a copy constructor & operator=.
// The ones generated by the compiler are adequate.
EDA_SHAPE( const EDA_SHAPE& aOther );
EDA_SHAPE& operator=( const EDA_SHAPE& aOther );
EDA_SHAPE( EDA_SHAPE&& ) noexcept = default;
EDA_SHAPE& operator=( EDA_SHAPE&& ) noexcept = default;
virtual ~EDA_SHAPE();
@@ -145,8 +157,8 @@ public:
UI_FILL_MODE GetFillModeProp() const;
void SetHatchingDirty() { m_hatchingDirty = true; }
const SHAPE_POLY_SET& GetHatching() const { return m_hatching; }
const std::vector<SEG>& GetHatchLines() const { return m_hatchLines; }
const SHAPE_POLY_SET& GetHatching() const;
const std::vector<SEG>& GetHatchLines() const;
bool IsClosed() const;
@@ -333,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).
@@ -344,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;
}
}
@@ -494,6 +505,10 @@ protected:
virtual int getMaxError() const { return 100; }
// non-const for PCB_SHAPE
SHAPE_POLY_SET& hatching() const;
std::vector<SEG>& hatchLines() const;
protected:
bool m_endsSwapped; // true if start/end were swapped e.g. SetArcAngleAndEnd
SHAPE_T m_shape; // Shape: line, Circle, Arc
@@ -501,8 +516,7 @@ protected:
FILL_T m_fill;
COLOR4D m_fillColor;
mutable SHAPE_POLY_SET m_hatching;
mutable std::vector<SEG> m_hatchLines;
mutable std::unique_ptr<EDA_SHAPE_HATCH_CACHE_DATA> m_hatchingCache;
mutable bool m_hatchingDirty;
long long int m_rectangleHeight;
@@ -519,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
+12 -6
View File
@@ -40,6 +40,17 @@ class SHAPE_COMPOUND;
class SHAPE_POLY_SET;
struct EDA_TEXT_RENDER_CACHE_DATA
{
wxString text;
const KIFONT::FONT* font = nullptr;
EDA_ANGLE angle;
VECTOR2I offset;
bool mirrored = false;
std::vector<std::unique_ptr<KIFONT::GLYPH>> glyphs;
};
// These are only here for algorithmic safety, not to tell the user what to do.
// PL_EDITOR has the least resolution (its internal units are microns), so the min size is chosen
// to yield 1 in PL_EDITOR.
@@ -463,12 +474,7 @@ private:
std::reference_wrapper<const EDA_IU_SCALE> m_IuScale;
mutable wxString m_render_cache_text;
mutable const KIFONT::FONT* m_render_cache_font;
mutable EDA_ANGLE m_render_cache_angle;
mutable VECTOR2I m_render_cache_offset;
mutable bool m_render_cache_mirrored;
mutable std::vector<std::unique_ptr<KIFONT::GLYPH>> m_render_cache;
mutable std::unique_ptr<EDA_TEXT_RENDER_CACHE_DATA> m_render_cache;
struct BBOX_CACHE_ENTRY
{
+113 -90
View File
@@ -87,9 +87,6 @@ FOOTPRINT::FOOTPRINT( BOARD* parent ) :
m_attributes( 0 ),
m_fpStatus( FP_PADS_are_LOCKED ),
m_fileFormatVersionAtLoad( 0 ),
m_boundingBoxCacheTimeStamp( 0 ),
m_textExcludedBBoxCacheTimeStamp( 0 ),
m_hullCacheTimeStamp( 0 ),
m_duplicatePadNumbersAreJumpers( false ),
m_allowMissingCourtyard( false ),
m_allowSolderMaskBridges( false ),
@@ -135,12 +132,7 @@ FOOTPRINT::FOOTPRINT( const FOOTPRINT& aFootprint ) :
m_fpStatus = aFootprint.m_fpStatus;
m_fileFormatVersionAtLoad = aFootprint.m_fileFormatVersionAtLoad;
m_cachedBoundingBox = aFootprint.m_cachedBoundingBox;
m_boundingBoxCacheTimeStamp = aFootprint.m_boundingBoxCacheTimeStamp;
m_cachedTextExcludedBBox = aFootprint.m_cachedTextExcludedBBox;
m_textExcludedBBoxCacheTimeStamp = aFootprint.m_textExcludedBBoxCacheTimeStamp;
m_cachedHull = aFootprint.m_cachedHull;
m_hullCacheTimeStamp = aFootprint.m_hullCacheTimeStamp;
m_geometry_cache.reset();
m_netTiePadGroups = aFootprint.m_netTiePadGroups;
m_jumperPadGroups = aFootprint.m_jumperPadGroups;
@@ -824,6 +816,9 @@ FOOTPRINT& FOOTPRINT::operator=( FOOTPRINT&& aOther )
{
BOARD_ITEM::operator=( aOther );
m_courtyard_cache.reset();
m_geometry_cache.reset();
m_pos = aOther.m_pos;
m_fpid = aOther.m_fpid;
m_attributes = aOther.m_attributes;
@@ -834,13 +829,6 @@ FOOTPRINT& FOOTPRINT::operator=( FOOTPRINT&& aOther )
m_path = aOther.m_path;
m_variants = std::move( aOther.m_variants );
m_cachedBoundingBox = aOther.m_cachedBoundingBox;
m_boundingBoxCacheTimeStamp = aOther.m_boundingBoxCacheTimeStamp;
m_cachedTextExcludedBBox = aOther.m_cachedTextExcludedBBox;
m_textExcludedBBoxCacheTimeStamp = aOther.m_textExcludedBBoxCacheTimeStamp;
m_cachedHull = aOther.m_cachedHull;
m_hullCacheTimeStamp = aOther.m_hullCacheTimeStamp;
m_clearance = aOther.m_clearance;
m_solderMaskMargin = aOther.m_solderMaskMargin;
m_solderPasteMargin = aOther.m_solderPasteMargin;
@@ -974,6 +962,9 @@ FOOTPRINT& FOOTPRINT::operator=( const FOOTPRINT& aOther )
{
BOARD_ITEM::operator=( aOther );
m_courtyard_cache.reset();
m_geometry_cache.reset();
m_pos = aOther.m_pos;
m_fpid = aOther.m_fpid;
m_attributes = aOther.m_attributes;
@@ -983,13 +974,6 @@ FOOTPRINT& FOOTPRINT::operator=( const FOOTPRINT& aOther )
m_link = aOther.m_link;
m_path = aOther.m_path;
m_cachedBoundingBox = aOther.m_cachedBoundingBox;
m_boundingBoxCacheTimeStamp = aOther.m_boundingBoxCacheTimeStamp;
m_cachedTextExcludedBBox = aOther.m_cachedTextExcludedBBox;
m_textExcludedBBoxCacheTimeStamp = aOther.m_textExcludedBBoxCacheTimeStamp;
m_cachedHull = aOther.m_cachedHull;
m_hullCacheTimeStamp = aOther.m_hullCacheTimeStamp;
m_clearance = aOther.m_clearance;
m_solderMaskMargin = aOther.m_solderMaskMargin;
m_solderPasteMargin = aOther.m_solderPasteMargin;
@@ -1142,12 +1126,13 @@ void FOOTPRINT::CopyFrom( const BOARD_ITEM* aOther )
void FOOTPRINT::InvalidateGeometryCaches()
{
m_boundingBoxCacheTimeStamp = 0;
m_textExcludedBBoxCacheTimeStamp = 0;
m_hullCacheTimeStamp = 0;
{
std::lock_guard<std::mutex> lock( m_geometry_cache_mutex );
m_geometry_cache.reset();
}
m_courtyard_cache_back_hash.Clear();
m_courtyard_cache_front_hash.Clear();
std::lock_guard<std::mutex> lock( m_courtyard_cache_mutex );
m_courtyard_cache.reset();
}
@@ -1754,19 +1739,22 @@ const BOX2I FOOTPRINT::GetBoundingBox( bool aIncludeText ) const
const BOARD* board = GetBoard();
{
std::lock_guard<std::mutex> lock( m_bboxCacheMutex );
std::lock_guard<std::mutex> lock( m_geometry_cache_mutex );
if( board )
{
if( !m_geometry_cache )
m_geometry_cache = std::make_unique<FOOTPRINT_GEOMETRY_CACHE_DATA>();
if( aIncludeText )
{
if( m_boundingBoxCacheTimeStamp >= board->GetTimeStamp() )
return m_cachedBoundingBox;
if( m_geometry_cache->bounding_box_timestamp >= board->GetTimeStamp() )
return m_geometry_cache->bounding_box;
}
else
{
if( m_textExcludedBBoxCacheTimeStamp >= board->GetTimeStamp() )
return m_cachedTextExcludedBBox;
if( m_geometry_cache->text_excluded_bbox_timestamp >= board->GetTimeStamp() )
return m_geometry_cache->text_excluded_bbox;
}
}
}
@@ -1884,17 +1872,20 @@ const BOX2I FOOTPRINT::GetBoundingBox( bool aIncludeText ) const
if( board )
{
std::lock_guard<std::mutex> lock( m_bboxCacheMutex );
std::lock_guard<std::mutex> lock( m_geometry_cache_mutex );
if( !m_geometry_cache )
m_geometry_cache = std::make_unique<FOOTPRINT_GEOMETRY_CACHE_DATA>();
if( aIncludeText || noDrawItems )
{
m_boundingBoxCacheTimeStamp = board->GetTimeStamp();
m_cachedBoundingBox = bbox;
m_geometry_cache->bounding_box_timestamp = board->GetTimeStamp();
m_geometry_cache->bounding_box = bbox;
}
else
{
m_textExcludedBBoxCacheTimeStamp = board->GetTimeStamp();
m_cachedTextExcludedBBox = bbox;
m_geometry_cache->text_excluded_bbox_timestamp = board->GetTimeStamp();
m_geometry_cache->text_excluded_bbox = bbox;
}
}
@@ -1965,8 +1956,8 @@ SHAPE_POLY_SET FOOTPRINT::GetBoundingHull() const
if( board )
{
if( m_hullCacheTimeStamp >= board->GetTimeStamp() )
return m_cachedHull;
if( m_geometry_cache && m_geometry_cache->hull_timestamp >= board->GetTimeStamp() )
return m_geometry_cache->hull;
}
SHAPE_POLY_SET rawPolys;
@@ -2031,16 +2022,19 @@ SHAPE_POLY_SET FOOTPRINT::GetBoundingHull() const
std::vector<VECTOR2I> convex_hull;
BuildConvexHull( convex_hull, rawPolys );
m_cachedHull.RemoveAllContours();
m_cachedHull.NewOutline();
if( !m_geometry_cache )
m_geometry_cache = std::make_unique<FOOTPRINT_GEOMETRY_CACHE_DATA>();
m_geometry_cache->hull.RemoveAllContours();
m_geometry_cache->hull.NewOutline();
for( const VECTOR2I& pt : convex_hull )
m_cachedHull.Append( pt );
m_geometry_cache->hull.Append( pt );
if( board )
m_hullCacheTimeStamp = board->GetTimeStamp();
m_geometry_cache->hull_timestamp = board->GetTimeStamp();
return m_cachedHull;
return m_geometry_cache->hull;
}
@@ -2952,20 +2946,25 @@ void FOOTPRINT::Flip( const VECTOR2I& aCentre, FLIP_DIRECTION aFlipDirection )
point->Flip( m_pos, FLIP_DIRECTION::TOP_BOTTOM );
// Swap the courtyard sides, then mirror in the same way as everything else.
std::swap( m_courtyard_cache_back, m_courtyard_cache_front );
m_courtyard_cache_back.Mirror( m_pos, FLIP_DIRECTION::TOP_BOTTOM );
m_courtyard_cache_back_hash = m_courtyard_cache_back.GetHash();
if( m_courtyard_cache )
{
std::swap( m_courtyard_cache->back, m_courtyard_cache->front );
m_courtyard_cache->back.Mirror( m_pos, FLIP_DIRECTION::TOP_BOTTOM );
m_courtyard_cache->back_hash = m_courtyard_cache->back.GetHash();
m_courtyard_cache_front.Mirror( m_pos, FLIP_DIRECTION::TOP_BOTTOM );
m_courtyard_cache_front_hash = m_courtyard_cache_front.GetHash();
m_courtyard_cache->front.Mirror( m_pos, FLIP_DIRECTION::TOP_BOTTOM );
m_courtyard_cache->front_hash = m_courtyard_cache->front.GetHash();
}
m_cachedHull.Mirror( m_pos, FLIP_DIRECTION::TOP_BOTTOM );
if( m_geometry_cache )
m_geometry_cache->hull.Mirror( m_pos, FLIP_DIRECTION::TOP_BOTTOM );
// Now rotate 180 deg if required
if( aFlipDirection == FLIP_DIRECTION::LEFT_RIGHT )
Rotate( aCentre, ANGLE_180 );
m_textExcludedBBoxCacheTimeStamp = 0;
if( m_geometry_cache )
m_geometry_cache->text_excluded_bbox_timestamp = 0;
}
@@ -2990,16 +2989,22 @@ void FOOTPRINT::SetPosition( const VECTOR2I& aPos )
for( PCB_POINT* point : m_points )
point->Move( delta );
m_cachedBoundingBox.Move( delta );
m_cachedTextExcludedBBox.Move( delta );
m_cachedHull.Move( delta );
if( m_geometry_cache )
{
m_geometry_cache->bounding_box.Move( delta );
m_geometry_cache->text_excluded_bbox.Move( delta );
m_geometry_cache->hull.Move( delta );
}
// The geometry work has been conserved by using Move(). But the hashes
// need to be updated, otherwise the cached polygons will still be rebuild.
m_courtyard_cache_back.Move( delta );
m_courtyard_cache_back_hash = m_courtyard_cache_back.GetHash();
m_courtyard_cache_front.Move( delta );
m_courtyard_cache_front_hash = m_courtyard_cache_front.GetHash();
if( m_courtyard_cache )
{
m_courtyard_cache->back.Move( delta );
m_courtyard_cache->back_hash = m_courtyard_cache->back.GetHash();
m_courtyard_cache->front.Move( delta );
m_courtyard_cache->front_hash = m_courtyard_cache->front.GetHash();
}
}
@@ -3041,16 +3046,22 @@ void FOOTPRINT::MoveAnchorPosition( const VECTOR2I& aMoveVector )
model.m_Offset.y -= pcbIUScale.IUTomm( moveVector.y );
}
m_cachedBoundingBox.Move( moveVector );
m_cachedTextExcludedBBox.Move( moveVector );
m_cachedHull.Move( moveVector );
if( m_geometry_cache )
{
m_geometry_cache->bounding_box.Move( moveVector );
m_geometry_cache->text_excluded_bbox.Move( moveVector );
m_geometry_cache->hull.Move( moveVector );
}
// The geometry work have been conserved by using Move(). But the hashes
// need to be updated, otherwise the cached polygons will still be rebuild.
m_courtyard_cache_back.Move( moveVector );
m_courtyard_cache_back_hash = m_courtyard_cache_back.GetHash();
m_courtyard_cache_front.Move( moveVector );
m_courtyard_cache_front_hash = m_courtyard_cache_front.GetHash();
if( m_courtyard_cache )
{
m_courtyard_cache->back.Move( moveVector );
m_courtyard_cache->back_hash = m_courtyard_cache->back.GetHash();
m_courtyard_cache->front.Move( moveVector );
m_courtyard_cache->front_hash = m_courtyard_cache->front.GetHash();
}
}
@@ -3078,15 +3089,20 @@ void FOOTPRINT::SetOrientation( const EDA_ANGLE& aNewAngle )
for( PCB_POINT* point : m_points )
point->Rotate( rotationCenter, angleChange );
m_textExcludedBBoxCacheTimeStamp = 0;
if( m_geometry_cache )
m_geometry_cache->text_excluded_bbox_timestamp = 0;
m_courtyard_cache_front.Rotate( angleChange, rotationCenter );
m_courtyard_cache_front_hash = m_courtyard_cache_front.GetHash();
if( m_courtyard_cache )
{
m_courtyard_cache->front.Rotate( angleChange, rotationCenter );
m_courtyard_cache->front_hash = m_courtyard_cache->front.GetHash();
m_courtyard_cache_back.Rotate( angleChange, rotationCenter );
m_courtyard_cache_back_hash = m_courtyard_cache_back.GetHash();
m_courtyard_cache->back.Rotate( angleChange, rotationCenter );
m_courtyard_cache->back_hash = m_courtyard_cache->back.GetHash();
}
m_cachedHull.Rotate( angleChange, rotationCenter );
if( m_geometry_cache )
m_geometry_cache->hull.Rotate( angleChange, rotationCenter );
}
@@ -3561,8 +3577,9 @@ const SHAPE_POLY_SET& FOOTPRINT::GetCourtyard( PCB_LAYER_ID aLayer ) const
{
std::lock_guard<std::mutex> lock( m_courtyard_cache_mutex );
if( m_courtyard_cache_front_hash != m_courtyard_cache_front.GetHash()
|| m_courtyard_cache_back_hash != m_courtyard_cache_back.GetHash() )
if( !m_courtyard_cache
|| m_courtyard_cache->front_hash != m_courtyard_cache->front.GetHash()
|| m_courtyard_cache->back_hash != m_courtyard_cache->back.GetHash() )
{
const_cast<FOOTPRINT*>(this)->BuildCourtyardCaches();
}
@@ -3573,17 +3590,23 @@ const SHAPE_POLY_SET& FOOTPRINT::GetCourtyard( PCB_LAYER_ID aLayer ) const
const SHAPE_POLY_SET& FOOTPRINT::GetCachedCourtyard( PCB_LAYER_ID aLayer ) const
{
if( !m_courtyard_cache )
m_courtyard_cache = std::make_unique<FOOTPRINT_COURTYARD_CACHE_DATA>();
if( IsBackLayer( aLayer ) )
return m_courtyard_cache_back;
return m_courtyard_cache->back;
else
return m_courtyard_cache_front;
return m_courtyard_cache->front;
}
void FOOTPRINT::BuildCourtyardCaches( OUTLINE_ERROR_HANDLER* aErrorHandler )
{
m_courtyard_cache_front.RemoveAllContours();
m_courtyard_cache_back.RemoveAllContours();
if( !m_courtyard_cache )
m_courtyard_cache = std::make_unique<FOOTPRINT_COURTYARD_CACHE_DATA>();
m_courtyard_cache->front.RemoveAllContours();
m_courtyard_cache->back.RemoveAllContours();
ClearFlags( MALFORMED_COURTYARDS );
// Build the courtyard area from graphic items on the courtyard.
@@ -3617,7 +3640,7 @@ void FOOTPRINT::BuildCourtyardCaches( OUTLINE_ERROR_HANDLER* aErrorHandler )
int maxError = pcbIUScale.mmToIU( 0.005 ); // max error for polygonization
int chainingEpsilon = pcbIUScale.mmToIU( 0.02 ); // max dist from one endPt to next startPt
if( ConvertOutlineToPolygon( list_front, m_courtyard_cache_front, maxError, chainingEpsilon,
if( ConvertOutlineToPolygon( list_front, m_courtyard_cache->front, maxError, chainingEpsilon,
true, aErrorHandler ) )
{
int width = 0;
@@ -3625,9 +3648,9 @@ void FOOTPRINT::BuildCourtyardCaches( OUTLINE_ERROR_HANDLER* aErrorHandler )
// Touching courtyards, or courtyards -at- the clearance distance are legal.
// Use maxError here because that is the allowed deviation when transforming arcs/circles to
// polygons.
m_courtyard_cache_front.Inflate( -maxError, CORNER_STRATEGY::CHAMFER_ACUTE_CORNERS, maxError );
m_courtyard_cache->front.Inflate( -maxError, CORNER_STRATEGY::CHAMFER_ACUTE_CORNERS, maxError );
m_courtyard_cache_front.CacheTriangulation( false );
m_courtyard_cache->front.CacheTriangulation( false );
auto max = std::max_element( front_width_histogram.begin(), front_width_histogram.end(),
[]( const std::pair<int, int>& a, const std::pair<int, int>& b )
{
@@ -3640,23 +3663,23 @@ void FOOTPRINT::BuildCourtyardCaches( OUTLINE_ERROR_HANDLER* aErrorHandler )
if( width == 0 )
width = pcbIUScale.mmToIU( DEFAULT_COURTYARD_WIDTH );
if( m_courtyard_cache_front.OutlineCount() > 0 )
m_courtyard_cache_front.Outline( 0 ).SetWidth( width );
if( m_courtyard_cache->front.OutlineCount() > 0 )
m_courtyard_cache->front.Outline( 0 ).SetWidth( width );
}
else
{
SetFlags( MALFORMED_F_COURTYARD );
}
if( ConvertOutlineToPolygon( list_back, m_courtyard_cache_back, maxError, chainingEpsilon, true,
if( ConvertOutlineToPolygon( list_back, m_courtyard_cache->back, maxError, chainingEpsilon, true,
aErrorHandler ) )
{
int width = 0;
// Touching courtyards, or courtyards -at- the clearance distance are legal.
m_courtyard_cache_back.Inflate( -maxError, CORNER_STRATEGY::CHAMFER_ACUTE_CORNERS, maxError );
m_courtyard_cache->back.Inflate( -maxError, CORNER_STRATEGY::CHAMFER_ACUTE_CORNERS, maxError );
m_courtyard_cache_back.CacheTriangulation( false );
m_courtyard_cache->back.CacheTriangulation( false );
auto max = std::max_element( back_width_histogram.begin(), back_width_histogram.end(),
[]( const std::pair<int, int>& a, const std::pair<int, int>& b )
{
@@ -3669,16 +3692,16 @@ void FOOTPRINT::BuildCourtyardCaches( OUTLINE_ERROR_HANDLER* aErrorHandler )
if( width == 0 )
width = pcbIUScale.mmToIU( DEFAULT_COURTYARD_WIDTH );
if( m_courtyard_cache_back.OutlineCount() > 0 )
m_courtyard_cache_back.Outline( 0 ).SetWidth( width );
if( m_courtyard_cache->back.OutlineCount() > 0 )
m_courtyard_cache->back.Outline( 0 ).SetWidth( width );
}
else
{
SetFlags( MALFORMED_B_COURTYARD );
}
m_courtyard_cache_front_hash = m_courtyard_cache_front.GetHash();
m_courtyard_cache_back_hash = m_courtyard_cache_back.GetHash();
m_courtyard_cache->front_hash = m_courtyard_cache->front.GetHash();
m_courtyard_cache->back_hash = m_courtyard_cache->back.GetHash();
}
+24 -12
View File
@@ -136,6 +136,26 @@ public:
};
struct FOOTPRINT_COURTYARD_CACHE_DATA
{
SHAPE_POLY_SET front; // Note that a footprint can have both front and back courtyards populated.
SHAPE_POLY_SET back;
HASH_128 front_hash;
HASH_128 back_hash;
};
struct FOOTPRINT_GEOMETRY_CACHE_DATA
{
BOX2I bounding_box;
int bounding_box_timestamp = 0;
BOX2I text_excluded_bbox;
int text_excluded_bbox_timestamp = 0;
SHAPE_POLY_SET hull;
int hull_timestamp = 0;
};
/**
* Variant information for a footprint.
*
@@ -1325,13 +1345,8 @@ private:
// that any edit that could affect the bounding boxes (including edits to the footprint
// children) marked the bounding boxes dirty. It would definitely be faster -- but also more
// fragile.
mutable std::mutex m_bboxCacheMutex;
mutable BOX2I m_cachedBoundingBox;
mutable int m_boundingBoxCacheTimeStamp;
mutable BOX2I m_cachedTextExcludedBBox;
mutable int m_textExcludedBBoxCacheTimeStamp;
mutable SHAPE_POLY_SET m_cachedHull;
mutable int m_hullCacheTimeStamp;
mutable std::mutex m_geometry_cache_mutex;
mutable std::unique_ptr<FOOTPRINT_GEOMETRY_CACHE_DATA> m_geometry_cache;
// A list of pad groups, each of which is allowed to short nets within their group.
// A pad group is a comma-separated list of pad numbers.
@@ -1377,11 +1392,8 @@ private:
wxArrayString* m_initial_comments; // s-expression comments in the footprint,
// lazily allocated only if needed for speed
SHAPE_POLY_SET m_courtyard_cache_front; // Note that a footprint can have both front and back
SHAPE_POLY_SET m_courtyard_cache_back; // courtyards populated.
mutable HASH_128 m_courtyard_cache_front_hash;
mutable HASH_128 m_courtyard_cache_back_hash;
mutable std::mutex m_courtyard_cache_mutex;
mutable std::unique_ptr<FOOTPRINT_COURTYARD_CACHE_DATA> m_courtyard_cache;
mutable std::mutex m_courtyard_cache_mutex;
std::unordered_set<wxString> m_transientComponentClassNames;
std::unique_ptr<COMPONENT_CLASS_CACHE_PROXY> m_componentClassCacheProxy;
+40 -18
View File
@@ -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,
half_width * 2 );
m_effectiveBoundingBox.Merge( m_effectiveHoleShape->BBox() );
drawCache.m_effectiveHoleShape = std::make_shared<SHAPE_SEGMENT>( m_pos - half_len,
m_pos + half_len,
half_width * 2 );
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
View File
@@ -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;
+32 -6
View File
@@ -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 );
}
}
@@ -1758,4 +1784,4 @@ int PADSTACK::POST_MACHINING_PROPS::Compare( const PADSTACK::POST_MACHINING_PROP
void PADSTACK::SetMode( MODE aMode )
{
m_mode = aMode;
}
}
+4 -1
View File
@@ -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;
+1 -1
View File
@@ -2488,7 +2488,7 @@ void PCB_PAINTER::draw( const PCB_TEXT* aText, int aLayer )
if( aText->IsKnockout() )
{
SHAPE_POLY_SET finalPoly = aText->GetKnockoutCache( font, resolvedText, m_maxError );
const SHAPE_POLY_SET& finalPoly = aText->GetKnockoutCache( font, resolvedText, m_maxError );
m_gal->SetIsStroke( false );
m_gal->SetIsFill( true );
+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 ) )
+39 -15
View File
@@ -79,6 +79,26 @@ PCB_TEXT::PCB_TEXT( FOOTPRINT* aParent, KICAD_T idtype ) :
}
PCB_TEXT::PCB_TEXT( const PCB_TEXT& aOther ) :
BOARD_ITEM( aOther ),
EDA_TEXT( aOther )
{
}
PCB_TEXT& PCB_TEXT::operator=( const PCB_TEXT& aOther )
{
if( this == &aOther )
return *this;
BOARD_ITEM::operator=( aOther );
EDA_TEXT::operator=( aOther );
m_knockout_cache.reset();
return *this;
}
PCB_TEXT::~PCB_TEXT()
{
}
@@ -525,33 +545,37 @@ std::shared_ptr<SHAPE> PCB_TEXT::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHIN
}
SHAPE_POLY_SET PCB_TEXT::GetKnockoutCache( const KIFONT::FONT* aFont, const wxString& forResolvedText,
int aMaxError ) const
const SHAPE_POLY_SET& PCB_TEXT::GetKnockoutCache( const KIFONT::FONT* aFont, const wxString& forResolvedText,
int aMaxError ) const
{
TEXT_ATTRIBUTES attrs = GetAttributes();
EDA_ANGLE drawAngle = GetDrawRotation();
VECTOR2I drawPos = GetDrawPos();
if( m_knockout_cache.IsEmpty() || m_knockout_cache_text_attrs != attrs || m_knockout_cache_text != forResolvedText
|| m_knockout_cache_angle != drawAngle )
if( !m_knockout_cache )
m_knockout_cache = std::make_unique<PCB_TEXT_KNOCKOUT_CACHE_DATA>();
if( m_knockout_cache->cache.IsEmpty() || m_knockout_cache->text_attrs != attrs
|| m_knockout_cache->text != forResolvedText
|| m_knockout_cache->angle != drawAngle )
{
m_knockout_cache.RemoveAllContours();
m_knockout_cache->cache.RemoveAllContours();
TransformTextToPolySet( m_knockout_cache, 0, aMaxError, ERROR_INSIDE );
m_knockout_cache.Fracture();
TransformTextToPolySet( m_knockout_cache->cache, 0, aMaxError, ERROR_INSIDE );
m_knockout_cache->cache.Fracture();
m_knockout_cache_text_attrs = attrs;
m_knockout_cache_angle = drawAngle;
m_knockout_cache_text = forResolvedText;
m_knockout_cache_pos = drawPos;
m_knockout_cache->text_attrs = attrs;
m_knockout_cache->angle = drawAngle;
m_knockout_cache->text = forResolvedText;
m_knockout_cache->pos = drawPos;
}
else if( m_knockout_cache_pos != drawPos )
else if( m_knockout_cache->pos != drawPos )
{
m_knockout_cache.Move( drawPos - m_knockout_cache_pos );
m_knockout_cache_pos = drawPos;
m_knockout_cache->cache.Move( drawPos - m_knockout_cache->pos );
m_knockout_cache->pos = drawPos;
}
return m_knockout_cache;
return m_knockout_cache->cache;
}
+19 -8
View File
@@ -25,6 +25,8 @@
#ifndef PCB_TEXT_H
#define PCB_TEXT_H
#include <memory>
#include <eda_text.h>
#include <board_item.h>
@@ -35,6 +37,16 @@ class FOOTPRINT;
class HTML_MESSAGE_BOX;
struct PCB_TEXT_KNOCKOUT_CACHE_DATA
{
wxString text;
TEXT_ATTRIBUTES text_attrs;
EDA_ANGLE angle;
VECTOR2I pos;
SHAPE_POLY_SET cache;
};
class PCB_TEXT : public BOARD_ITEM, public EDA_TEXT
{
public:
@@ -42,8 +54,11 @@ public:
PCB_TEXT( FOOTPRINT* aParent, KICAD_T idtype = PCB_TEXT_T );
// Do not create a copy constructor & operator=.
// The ones generated by the compiler are adequate.
PCB_TEXT( const PCB_TEXT& aOther );
PCB_TEXT& operator=( const PCB_TEXT& aOther );
PCB_TEXT( PCB_TEXT&& ) noexcept = default;
PCB_TEXT& operator=( PCB_TEXT&& ) noexcept = default;
~PCB_TEXT();
@@ -131,7 +146,7 @@ public:
virtual std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER,
FLASHING aFlash = FLASHING::DEFAULT ) const override;
SHAPE_POLY_SET GetKnockoutCache( const KIFONT::FONT* aFont, const wxString& forResolvedText, int aMaxError ) const;
const SHAPE_POLY_SET& GetKnockoutCache( const KIFONT::FONT* aFont, const wxString& forResolvedText, int aMaxError ) const;
virtual wxString GetTextTypeDescription() const;
@@ -187,11 +202,7 @@ protected:
const KIFONT::METRICS& getFontMetrics() const override { return GetFontMetrics(); }
private:
mutable wxString m_knockout_cache_text;
mutable TEXT_ATTRIBUTES m_knockout_cache_text_attrs;
mutable EDA_ANGLE m_knockout_cache_angle;
mutable VECTOR2I m_knockout_cache_pos;
mutable SHAPE_POLY_SET m_knockout_cache;
mutable std::unique_ptr<PCB_TEXT_KNOCKOUT_CACHE_DATA> m_knockout_cache;
};
#endif // #define PCB_TEXT_H
+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 ) );
+1
View File
@@ -62,6 +62,7 @@ warnings.warn("The SWIG-based Python interface to the PCB editor is deprecated a
// ignore a couple of items that generate warnings from swig built code
%ignore BOARD_ITEM::ZeroOffset;
%ignore PAD::m_PadSketchModePenSize;
%ignore PCB_TEXT_KNOCKOUT_CACHE_DATA;
class BASE_SET {};
%ignore BASE_SET;
+267 -360
View File
@@ -31,14 +31,6 @@
#include <core/kicad_algo.h>
#include <advanced_config.h>
#include <board.h>
#include <core/profile.h>
/**
* Trace mask for zone filler timing information.
* Use "KICAD_ZONE_FILLER" to enable via WXTRACE environment variable.
* @ingroup trace_env_vars
*/
static const wxChar traceZoneFiller[] = wxT( "KICAD_ZONE_FILLER" );
#include <board_design_settings.h>
#include <drc/drc_engine.h>
#include <zone.h>
@@ -311,6 +303,41 @@ struct TRACK_KNOCKOUT_KEY_HASH
}
};
template<typename Func>
void forEachBoardAndFootprintZone( BOARD* aBoard, Func&& aFunc )
{
for( ZONE* zone : aBoard->Zones() )
aFunc( zone );
for( FOOTPRINT* footprint : aBoard->Footprints() )
{
for( ZONE* zone : footprint->Zones() )
aFunc( zone );
}
}
bool isZoneFillKeepout( const ZONE* aZone, PCB_LAYER_ID aLayer, const BOX2I& aBBox )
{
return aZone->GetIsRuleArea()
&& aZone->HasKeepoutParametersSet()
&& aZone->GetDoNotAllowZoneFills()
&& aZone->IsOnLayer( aLayer )
&& aZone->GetBoundingBox().Intersects( aBBox );
}
void appendZoneOutlineWithoutArcs( const ZONE* aZone, SHAPE_POLY_SET& aPolys )
{
if( aZone->Outline()->ArcCount() == 0 )
{
aPolys.Append( *aZone->Outline() );
return;
}
SHAPE_POLY_SET outline( *aZone->Outline() );
outline.ClearArcs();
aPolys.Append( outline );
}
} // anonymous namespace
@@ -610,15 +637,16 @@ bool ZONE_FILLER::Fill( const std::vector<ZONE*>& aZones, bool aCheck, wxWindow*
zone->UnFill();
}
auto check_fill_dependency =
[&]( ZONE* aZone, PCB_LAYER_ID aLayer, ZONE* aOtherZone ) -> bool
auto zone_fill_dependency =
[&]( ZONE* aZone, PCB_LAYER_ID aLayer, ZONE* aOtherZone,
bool aRequireCompletedOtherFill ) -> bool
{
// Check to see if we have to knock-out the filled areas of a higher-priority
// zone. If so we have to wait until said zone is filled before we can fill.
// If the other zone is already filled on the requested layer then we're
// good-to-go
if( aOtherZone->GetFillFlag( aLayer ) )
if( aRequireCompletedOtherFill && aOtherZone->GetFillFlag( aLayer ) )
return false;
// Even if keepouts exclude copper pours, the exclusion is by outline rather than
@@ -652,42 +680,37 @@ bool ZONE_FILLER::Fill( const std::vector<ZONE*>& aZones, bool aCheck, wxWindow*
return aZone->Outline()->Collide( aOtherZone->Outline(), m_worstClearance );
};
auto check_fill_dependency =
[&]( ZONE* aZone, PCB_LAYER_ID aLayer, ZONE* aOtherZone ) -> bool
{
return zone_fill_dependency( aZone, aLayer, aOtherZone, true );
};
auto fill_item_dependency =
[&]( const std::pair<ZONE*, PCB_LAYER_ID>& aWaiter,
const std::pair<ZONE*, PCB_LAYER_ID>& aDependency ) -> bool
{
if( aWaiter.first == aDependency.first || aWaiter.second != aDependency.second )
return false;
return check_fill_dependency( aWaiter.first, aWaiter.second, aDependency.first );
};
auto fill_lambda =
[&]( std::pair<ZONE*, PCB_LAYER_ID> aFillItem ) -> int
{
PCB_LAYER_ID layer = aFillItem.second;
ZONE* zone = aFillItem.first;
bool canFill = true;
// Check for any fill dependencies. If our zone needs to be clipped by
// another zone then we can't fill until that zone is filled.
for( ZONE* otherZone : aZones )
{
if( otherZone == zone )
continue;
if( check_fill_dependency( zone, layer, otherZone ) )
{
canFill = false;
break;
}
}
if( m_progressReporter && m_progressReporter->IsCancelled() )
return 0;
if( !canFill )
PCB_LAYER_ID layer = aFillItem.second;
ZONE* zone = aFillItem.first;
SHAPE_POLY_SET fillPolys;
if( !fillSingleZone( zone, layer, fillPolys ) )
return 0;
// Now we're ready to fill.
{
SHAPE_POLY_SET fillPolys;
if( !fillSingleZone( zone, layer, fillPolys ) )
return 0;
zone->SetFilledPolysList( layer, fillPolys );
}
zone->SetFilledPolysList( layer, fillPolys );
if( m_progressReporter )
m_progressReporter->AdvanceProgress();
@@ -710,98 +733,143 @@ bool ZONE_FILLER::Fill( const std::vector<ZONE*>& aZones, bool aCheck, wxWindow*
return 1;
};
// Calculate the copper fills (NB: this is multi-threaded)
//
std::vector<std::pair<std::future<int>, int>> returns;
returns.reserve( toFill.size() );
size_t finished = 0;
std::atomic<bool> cancelled( false );
thread_pool& tp = GetKiCadThreadPool();
std::atomic<bool> cancelled = false;
thread_pool& tp = GetKiCadThreadPool();
for( const std::pair<ZONE*, PCB_LAYER_ID>& fillItem : toFill )
{
returns.emplace_back( std::make_pair( tp.submit_task(
[&, fillItem]()
{
return fill_lambda( fillItem );
} ), 0 ) );
}
while( !cancelled && finished != 2 * toFill.size() )
{
for( size_t ii = 0; ii < returns.size(); ++ii )
{
auto& ret = returns[ii];
if( ret.second > 1 )
continue;
std::future_status status = ret.first.wait_for( std::chrono::seconds( 0 ) );
if( status == std::future_status::ready )
auto waitForFutures =
[&]( std::vector<std::future<int>>& aFutures, std::vector<int>* aResults = nullptr )
{
if( ret.first.get() ) // lambda completed
{
++finished;
ret.second++; // go to next step
}
if( aResults )
aResults->clear();
if( !cancelled )
for( auto& future : aFutures )
{
// Queue the next step (will re-queue the existing step if it didn't complete)
if( ret.second == 0 )
while( future.wait_for( std::chrono::milliseconds( 100 ) )
!= std::future_status::ready )
{
returns[ii].first = tp.submit_task(
[&, idx = ii]()
{
return fill_lambda( toFill[idx] );
} );
if( m_progressReporter )
{
m_progressReporter->KeepRefreshing();
if( m_progressReporter->IsCancelled() )
cancelled = true;
}
}
else if( ret.second == 1 )
int result = future.get();
if( aResults )
aResults->push_back( result );
}
};
struct FILL_DAG
{
std::vector<std::vector<size_t>> successors;
std::vector<int> inDegree;
std::vector<size_t> currentWave;
};
auto build_fill_dag =
[&]( const std::vector<std::pair<ZONE*, PCB_LAYER_ID>>& aFillItems,
auto&& aHasDependency ) -> FILL_DAG
{
FILL_DAG dag;
dag.successors.resize( aFillItems.size() );
dag.inDegree.assign( aFillItems.size(), 0 );
dag.currentWave.reserve( aFillItems.size() );
for( size_t i = 0; i < aFillItems.size(); ++i )
{
for( size_t j = 0; j < aFillItems.size(); ++j )
{
returns[ii].first = tp.submit_task(
[&, idx = ii]()
{
return tesselate_lambda( toFill[idx] );
} );
if( i == j )
continue;
if( aHasDependency( aFillItems[j], aFillItems[i] ) )
{
dag.successors[i].push_back( j );
dag.inDegree[j]++;
}
}
}
}
}
std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) );
for( size_t i = 0; i < aFillItems.size(); ++i )
{
if( dag.inDegree[i] == 0 )
dag.currentWave.push_back( i );
}
if( m_progressReporter )
{
m_progressReporter->KeepRefreshing();
return dag;
};
if( m_progressReporter->IsCancelled() )
cancelled = true;
}
}
// Make sure that all futures have finished.
// This can happen when the user cancels the above operation
for( auto& ret : returns )
{
if( ret.first.valid() )
{
std::future_status status = ret.first.wait_for( std::chrono::seconds( 0 ) );
while( status != std::future_status::ready )
auto run_fill_waves =
[&]( const std::vector<std::pair<ZONE*, PCB_LAYER_ID>>& aFillItems, auto&& aFillFn,
auto&& aTessFn, auto&& aHasDependency )
{
if( m_progressReporter )
m_progressReporter->KeepRefreshing();
FILL_DAG dag = build_fill_dag( aFillItems, aHasDependency );
status = ret.first.wait_for( std::chrono::milliseconds( 100 ) );
}
}
}
while( !dag.currentWave.empty() && !cancelled.load() )
{
std::vector<std::future<int>> fillFutures;
std::vector<int> fillResults;
fillFutures.reserve( dag.currentWave.size() );
for( size_t idx : dag.currentWave )
{
fillFutures.emplace_back( tp.submit_task(
[&aFillFn, &aFillItems, idx]()
{
return aFillFn( aFillItems[idx] );
} ) );
}
waitForFutures( fillFutures, &fillResults );
std::vector<std::future<int>> tessFutures;
tessFutures.reserve( dag.currentWave.size() );
for( size_t ii = 0; ii < fillResults.size(); ++ii )
{
if( fillResults[ii] == 0 )
continue;
size_t idx = dag.currentWave[ii];
tessFutures.emplace_back( tp.submit_task(
[&aTessFn, &aFillItems, idx]()
{
return aTessFn( aFillItems[idx] );
} ) );
}
waitForFutures( tessFutures );
if( cancelled.load() )
break;
std::vector<size_t> nextWave;
for( size_t idx : dag.currentWave )
{
for( size_t succ : dag.successors[idx] )
{
if( --dag.inDegree[succ] == 0 )
nextWave.push_back( succ );
}
}
dag.currentWave = std::move( nextWave );
}
};
run_fill_waves( toFill, fill_lambda, tesselate_lambda, fill_item_dependency );
// Now update the connectivity to check for isolated copper islands
// (NB: FindIsolatedCopperIslands() is multi-threaded)
//
if( m_progressReporter )
{
if( m_progressReporter->IsCancelled() )
@@ -870,26 +938,17 @@ bool ZONE_FILLER::Fill( const std::vector<ZONE*>& aZones, bool aCheck, wxWindow*
long long int minArea = zone->GetMinIslandArea();
ISLAND_REMOVAL_MODE mode = zone->GetIslandRemovalMode();
wxLogTrace( traceZoneFiller, wxT( "Zone %s layer %d: %zu islands to process, mode=%d, poly has %d outlines, area %.0f" ),
zone->GetNetname(), static_cast<int>( layer ), islands.size(),
static_cast<int>( mode ), poly->OutlineCount(), poly->Area() );
for( int idx : islands )
{
SHAPE_LINE_CHAIN& outline = poly->Outline( idx );
if( mode == ISLAND_REMOVAL_MODE::ALWAYS )
{
wxLogTrace( traceZoneFiller, wxT( "Removing island %d from zone %s (ALWAYS mode)" ),
idx, zone->GetNetname() );
poly->DeletePolygonAndTriangulationData( idx, false );
zonesWithRemovedIslands.insert( zone );
}
else if ( mode == ISLAND_REMOVAL_MODE::AREA && outline.Area( true ) < minArea )
{
wxLogTrace( traceZoneFiller, wxT( "Removing island %d from zone %s (AREA mode, area=%.0f < min=%.0f)" ),
idx, zone->GetNetname(), outline.Area( true ),
static_cast<double>( minArea ) );
poly->DeletePolygonAndTriangulationData( idx, false );
zonesWithRemovedIslands.insert( zone );
}
@@ -902,11 +961,6 @@ bool ZONE_FILLER::Fill( const std::vector<ZONE*>& aZones, bool aCheck, wxWindow*
poly->UpdateTriangulationDataHash();
zone->CalculateFilledArea();
BOX2I bbox = poly->BBox();
wxLogTrace( traceZoneFiller, wxT( "After island removal, zone %s: %d outlines, area %.0f, bbox (%d,%d)-(%d,%d)" ),
zone->GetNetname(), poly->OutlineCount(), poly->Area(),
bbox.GetX(), bbox.GetY(), bbox.GetRight(), bbox.GetBottom() );
if( m_progressReporter && m_progressReporter->IsCancelled() )
return false;
}
@@ -914,16 +968,10 @@ bool ZONE_FILLER::Fill( const std::vector<ZONE*>& aZones, bool aCheck, wxWindow*
// Iterative refill: If islands were removed from higher-priority zones, lower-priority zones
// may need to be refilled to occupy the now-available space (issue 21746).
//
const bool iterativeRefill = ADVANCED_CFG::GetCfg().m_ZoneFillIterativeRefill;
if( iterativeRefill && !zonesWithRemovedIslands.empty() )
{
PROF_TIMER timer;
wxLogTrace( traceZoneFiller, wxT( "Iterative refill: %zu zones had islands removed, cache size: %zu" ),
zonesWithRemovedIslands.size(), m_preKnockoutFillCache.size() );
// Find lower-priority zones that may need refilling.
// A zone needs refilling if it overlaps with a zone that had islands removed
// and has lower priority than that zone.
@@ -973,9 +1021,6 @@ bool ZONE_FILLER::Fill( const std::vector<ZONE*>& aZones, bool aCheck, wxWindow*
if( !zonesToRefill.empty() )
{
wxLogTrace( traceZoneFiller, wxT( "Iterative refill: refilling %zu zone/layer pairs" ),
zonesToRefill.size() );
if( m_progressReporter )
{
m_progressReporter->AdvancePhase();
@@ -985,7 +1030,7 @@ bool ZONE_FILLER::Fill( const std::vector<ZONE*>& aZones, bool aCheck, wxWindow*
// Refill using cached pre-knockout fills - much faster than full refill
// since we only need to re-apply the higher-priority zone knockout
auto cached_refill_lambda =
auto cached_refill_fill_lambda =
[&]( const std::pair<ZONE*, PCB_LAYER_ID>& aFillItem ) -> int
{
ZONE* zone = aFillItem.first;
@@ -995,95 +1040,35 @@ bool ZONE_FILLER::Fill( const std::vector<ZONE*>& aZones, bool aCheck, wxWindow*
if( !refillZoneFromCache( zone, layer, fillPolys ) )
return 0;
wxLogTrace( traceZoneFiller, wxT( "Cached refill for zone %s: %d outlines, area %.0f" ),
zone->GetNetname(), fillPolys.OutlineCount(), fillPolys.Area() );
zone->SetFilledPolysList( layer, fillPolys );
zone->SetFillFlag( layer, false );
return 1;
};
auto cached_refill_tessellate_lambda =
[&]( const std::pair<ZONE*, PCB_LAYER_ID>& aFillItem ) -> int
{
ZONE* zone = aFillItem.first;
PCB_LAYER_ID layer = aFillItem.second;
zone->CacheTriangulation( layer );
zone->SetFillFlag( layer, true );
return 1;
};
std::vector<std::pair<std::future<int>, int>> refillReturns;
refillReturns.reserve( zonesToRefill.size() );
size_t refillFinished = 0;
for( const auto& fillItem : zonesToRefill )
{
refillReturns.emplace_back( std::make_pair( tp.submit_task(
[&, fillItem]()
{
return cached_refill_lambda( fillItem );
} ), 0 ) );
}
while( !cancelled && refillFinished != 2 * zonesToRefill.size() )
{
for( size_t ii = 0; ii < refillReturns.size(); ++ii )
{
auto& ret = refillReturns[ii];
if( ret.second > 1 )
continue;
std::future_status status = ret.first.wait_for( std::chrono::seconds( 0 ) );
if( status == std::future_status::ready )
auto refill_item_dependency =
[&]( const std::pair<ZONE*, PCB_LAYER_ID>& aWaiter,
const std::pair<ZONE*, PCB_LAYER_ID>& aDependency ) -> bool
{
if( ret.first.get() )
{
++refillFinished;
ret.second++;
}
else if( ret.second == 0 )
{
// Cache miss is a permanent failure. Skip both phases to avoid
// an infinite retry loop.
refillFinished += 2;
ret.second = 2;
continue;
}
if( aWaiter.first == aDependency.first || aWaiter.second != aDependency.second )
return false;
if( !cancelled )
{
if( ret.second == 1 )
{
refillReturns[ii].first = tp.submit_task(
[&, idx = ii]()
{
return tesselate_lambda( zonesToRefill[idx] );
} );
}
}
}
}
return zone_fill_dependency( aWaiter.first, aWaiter.second,
aDependency.first, false );
};
std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) );
if( m_progressReporter )
{
m_progressReporter->KeepRefreshing();
if( m_progressReporter->IsCancelled() )
cancelled = true;
}
}
// Wait for all refill tasks to complete
for( auto& ret : refillReturns )
{
if( ret.first.valid() )
{
std::future_status status = ret.first.wait_for( std::chrono::seconds( 0 ) );
while( status != std::future_status::ready )
{
if( m_progressReporter )
m_progressReporter->KeepRefreshing();
status = ret.first.wait_for( std::chrono::milliseconds( 100 ) );
}
}
}
run_fill_waves( zonesToRefill, cached_refill_fill_lambda,
cached_refill_tessellate_lambda, refill_item_dependency );
// Re-run island detection for refilled zones
std::map<ZONE*, std::map<PCB_LAYER_ID, ISOLATED_ISLANDS>> refillIslandsMap;
@@ -1152,7 +1137,6 @@ bool ZONE_FILLER::Fill( const std::vector<ZONE*>& aZones, bool aCheck, wxWindow*
}
}
wxLogTrace( traceZoneFiller, wxT( "Iterative refill completed in %0.3f ms" ), timer.msecs() );
}
}
@@ -1191,7 +1175,7 @@ bool ZONE_FILLER::Fill( const std::vector<ZONE*>& aZones, bool aCheck, wxWindow*
{
island_check_return retval;
for( int ii = aStart; ii < aEnd && !cancelled; ++ii )
for( int ii = aStart; ii < aEnd && !cancelled.load(); ++ii )
{
auto [poly, minArea] = polys_to_check[ii];
@@ -1249,7 +1233,7 @@ bool ZONE_FILLER::Fill( const std::vector<ZONE*>& aZones, bool aCheck, wxWindow*
}
}
if( cancelled )
if( cancelled.load() )
return false;
for( size_t ii = 0; ii < island_returns.size(); ++ii )
@@ -2409,14 +2393,7 @@ void ZONE_FILLER::buildDifferentNetZoneClearances( const ZONE* aZone, PCB_LAYER_
}
};
for( ZONE* otherZone : m_board->Zones() )
knockoutZoneClearance( otherZone );
for( FOOTPRINT* footprint : m_board->Footprints() )
{
for( ZONE* otherZone : footprint->Zones() )
knockoutZoneClearance( otherZone );
}
forEachBoardAndFootprintZone( m_board, knockoutZoneClearance );
aHoles.Simplify();
}
@@ -2426,54 +2403,38 @@ void ZONE_FILLER::buildDifferentNetZoneClearances( const ZONE* aZone, PCB_LAYER_
* Removes the outlines of higher-proirity zones with the same net. These zones should be
* in charge of the fill parameters within their own outlines.
*/
void ZONE_FILLER::subtractHigherPriorityZones( const ZONE* aZone, PCB_LAYER_ID aLayer, SHAPE_POLY_SET& aRawFill )
void ZONE_FILLER::subtractHigherPriorityZones( const ZONE* aZone, PCB_LAYER_ID aLayer,
SHAPE_POLY_SET& aRawFill )
{
BOX2I zoneBBox = aZone->GetBoundingBox();
BOX2I zoneBBox = aZone->GetBoundingBox();
SHAPE_POLY_SET knockouts;
auto knockoutZoneOutline =
auto collectZoneOutline =
[&]( ZONE* aKnockout )
{
// If the zones share no common layers
if( !aKnockout->GetLayerSet().test( aLayer ) )
return;
if( aKnockout->GetBoundingBox().Intersects( zoneBBox ) )
{
// Processing of arc shapes in zones is not yet supported because Clipper
// can't do boolean operations on them. The poly outline must be converted to
// segments first.
SHAPE_POLY_SET outline = aKnockout->Outline()->CloneDropTriangulation();
outline.ClearArcs();
aRawFill.BooleanSubtract( outline );
}
appendZoneOutlineWithoutArcs( aKnockout, knockouts );
};
for( ZONE* otherZone : m_board->Zones() )
{
// Don't use the `HigherPriority()` check here because we _only_ want to knock out zones
// with explicitly higher priorities, not those with equal priorities
if( otherZone->SameNet( aZone )
&& otherZone->GetAssignedPriority() > aZone->GetAssignedPriority() )
{
// Do not remove teardrop area: it is not useful and not good
if( !otherZone->IsTeardropArea() )
knockoutZoneOutline( otherZone );
}
}
for( FOOTPRINT* footprint : m_board->Footprints() )
{
for( ZONE* otherZone : footprint->Zones() )
{
if( otherZone->SameNet( aZone ) && otherZone->HigherPriority( aZone ) )
forEachBoardAndFootprintZone(
m_board,
[&]( ZONE* otherZone )
{
// Do not remove teardrop area: it is not useful and not good
if( !otherZone->IsTeardropArea() )
knockoutZoneOutline( otherZone );
}
}
}
// Don't use `HigherPriority()` here because we only want explicitly-higher
// priorities, not equal-priority zones.
bool higherPrioritySameNet =
otherZone->SameNet( aZone )
&& otherZone->GetAssignedPriority() > aZone->GetAssignedPriority();
if( higherPrioritySameNet && !otherZone->IsTeardropArea() )
collectZoneOutline( otherZone );
} );
if( knockouts.OutlineCount() > 0 )
aRawFill.BooleanSubtract( knockouts );
}
@@ -2877,15 +2838,6 @@ bool ZONE_FILLER::fillCopperZone( const ZONE* aZone, PCB_LAYER_ID aLayer, PCB_LA
m_preKnockoutFillCache[{ aZone, aLayer }] = aFillPolys;
}
BOX2I cacheBBox = aFillPolys.BBox();
wxLogTrace( traceZoneFiller,
wxT( "Cached pre-knockout fill for zone %s layer %d: %d outlines, area %.0f, "
"bbox (%d,%d)-(%d,%d)" ),
aZone->GetNetname(), static_cast<int>( aLayer ),
aFillPolys.OutlineCount(), aFillPolys.Area(),
cacheBBox.GetX(), cacheBBox.GetY(), cacheBBox.GetRight(), cacheBBox.GetBottom() );
// Now apply zone-to-zone knockouts for different-net zones
SHAPE_POLY_SET zoneClearances;
buildDifferentNetZoneClearances( aZone, aLayer, zoneClearances );
@@ -2961,49 +2913,40 @@ bool ZONE_FILLER::fillNonCopperZone( const ZONE* aZone, PCB_LAYER_ID aLayer,
aFillPolys = aSmoothedOutline;
aFillPolys.BooleanSubtract( clearanceHoles );
auto subtractKeepout =
SHAPE_POLY_SET keepoutHoles;
auto collectKeepout =
[&]( ZONE* candidate )
{
if( !candidate->GetIsRuleArea() )
if( !isZoneFillKeepout( candidate, aLayer, zone_boundingbox ) )
return;
if( !candidate->HasKeepoutParametersSet() )
return;
if( candidate->GetDoNotAllowZoneFills() && candidate->IsOnLayer( aLayer ) )
{
if( candidate->GetBoundingBox().Intersects( zone_boundingbox ) )
{
if( candidate->Outline()->ArcCount() == 0 )
{
aFillPolys.BooleanSubtract( *candidate->Outline() );
}
else
{
SHAPE_POLY_SET keepoutOutline( *candidate->Outline() );
keepoutOutline.ClearArcs();
aFillPolys.BooleanSubtract( keepoutOutline );
}
}
}
appendZoneOutlineWithoutArcs( candidate, keepoutHoles );
};
for( ZONE* keepout : m_board->Zones() )
{
if( checkForCancel( m_progressReporter ) )
return false;
bool cancelledKeepoutScan = false;
subtractKeepout( keepout );
}
forEachBoardAndFootprintZone(
m_board,
[&]( ZONE* keepout )
{
if( cancelledKeepoutScan )
return;
for( FOOTPRINT* footprint : m_board->Footprints() )
{
if( checkForCancel( m_progressReporter ) )
return false;
if( checkForCancel( m_progressReporter ) )
{
cancelledKeepoutScan = true;
return;
}
for( ZONE* keepout : footprint->Zones() )
subtractKeepout( keepout );
}
collectKeepout( keepout );
} );
if( cancelledKeepoutScan )
return false;
if( keepoutHoles.OutlineCount() > 0 )
aFillPolys.BooleanSubtract( keepoutHoles );
// Features which are min_width should survive pruning; features that are *less* than
// min_width should not. Therefore we subtract epsilon from the min_width when
@@ -3800,14 +3743,7 @@ bool ZONE_FILLER::refillZoneFromCache( ZONE* aZone, PCB_LAYER_ID aLayer, SHAPE_P
auto it = m_preKnockoutFillCache.find( cacheKey );
if( it == m_preKnockoutFillCache.end() )
{
wxLogTrace( traceZoneFiller, wxT( "Cache miss for zone %s layer %d (cache size: %zu)" ),
aZone->GetNetname(), static_cast<int>( aLayer ), m_preKnockoutFillCache.size() );
return false;
}
wxLogTrace( traceZoneFiller, wxT( "Cache hit for zone %s layer %d: pre-knockout %d outlines" ),
aZone->GetNetname(), static_cast<int>( aLayer ), it->second.OutlineCount() );
// Restore the cached pre-knockout fill
aFillPolys = it->second;
@@ -3835,9 +3771,10 @@ bool ZONE_FILLER::refillZoneFromCache( ZONE* aZone, PCB_LAYER_ID aLayer, SHAPE_P
return c.GetValue().Min();
};
bool knockoutsApplied = false;
bool knockoutsApplied = false;
SHAPE_POLY_SET knockouts;
auto knockoutZoneFill =
auto collectZoneKnockout =
[&]( ZONE* otherZone )
{
if( otherZone == aZone )
@@ -3865,7 +3802,7 @@ bool ZONE_FILLER::refillZoneFromCache( ZONE* aZone, PCB_LAYER_ID aLayer, SHAPE_P
if( otherZone->SameNet( aZone ) )
{
aFillPolys.BooleanSubtract( *otherFill );
knockouts.Append( *otherFill );
}
else
{
@@ -3881,58 +3818,28 @@ bool ZONE_FILLER::refillZoneFromCache( ZONE* aZone, PCB_LAYER_ID aLayer, SHAPE_P
SHAPE_POLY_SET inflatedFill = *otherFill;
inflatedFill.Inflate( gap + extra_margin + m_maxError,
CORNER_STRATEGY::ROUND_ALL_CORNERS, m_maxError );
aFillPolys.BooleanSubtract( inflatedFill );
knockouts.Append( inflatedFill );
knockoutsApplied = true;
}
};
for( ZONE* otherZone : m_board->Zones() )
knockoutZoneFill( otherZone );
forEachBoardAndFootprintZone( m_board, collectZoneKnockout );
for( FOOTPRINT* footprint : m_board->Footprints() )
{
for( ZONE* otherZone : footprint->Zones() )
knockoutZoneFill( otherZone );
}
// Subtract keepout zones (rule areas with do-not-fill)
auto subtractKeepout =
// Collect keepout zones (rule areas with do-not-fill) into the same accumulator
auto collectKeepout =
[&]( ZONE* candidate )
{
if( !candidate->GetIsRuleArea() )
if( !isZoneFillKeepout( candidate, aLayer, zoneBBox ) )
return;
if( !candidate->HasKeepoutParametersSet() )
return;
if( candidate->GetDoNotAllowZoneFills() && candidate->IsOnLayer( aLayer ) )
{
if( candidate->GetBoundingBox().Intersects( zoneBBox ) )
{
if( candidate->Outline()->ArcCount() == 0 )
{
aFillPolys.BooleanSubtract( *candidate->Outline() );
}
else
{
SHAPE_POLY_SET keepoutOutline( *candidate->Outline() );
keepoutOutline.ClearArcs();
aFillPolys.BooleanSubtract( keepoutOutline );
}
knockoutsApplied = true;
}
}
appendZoneOutlineWithoutArcs( candidate, knockouts );
knockoutsApplied = true;
};
for( ZONE* keepout : m_board->Zones() )
subtractKeepout( keepout );
forEachBoardAndFootprintZone( m_board, collectKeepout );
for( FOOTPRINT* footprint : m_board->Footprints() )
{
for( ZONE* keepout : footprint->Zones() )
subtractKeepout( keepout );
}
if( knockouts.OutlineCount() > 0 )
aFillPolys.BooleanSubtract( knockouts );
if( knockoutsApplied )
postKnockoutMinWidthPrune( aZone, aFillPolys );
+404
View File
@@ -0,0 +1,404 @@
{
"appearance": {
"color_theme": "_builtin_default",
"custom_toolbars": false
},
"aui": {
"right_panel_width": -1,
"show_layer_manager": true
},
"camera": {
"animation_enabled": true,
"moving_speed_multiplier": 3,
"projection_mode": 1,
"rotation_increment": 10.0
},
"color_picker": {
"default_tab": 0
},
"cross_probing": {
"auto_highlight": true,
"center_on_items": true,
"flash_selection": false,
"on_selection": true,
"zoom_to_fit": true
},
"current_layer_preset": "legacy_preset_flag",
"design_block_chooser": {
"height": -1,
"keep_annotations": false,
"lib_tree": {
"column_widths": null
},
"place_as_group": true,
"place_as_sheet": false,
"repeated_placement": false,
"sash_pos_h": -1,
"sash_pos_v": -1,
"sort_mode": 0,
"width": -1
},
"find_replace": {
"find_history": [],
"find_string": "",
"match_case": false,
"match_mode": 0,
"replace_history": [],
"replace_string": "",
"search_and_replace": false
},
"graphics": {
"highlight_factor": 0.5,
"select_factor": 0.75
},
"layer_presets": [],
"lib_tree": {
"column_widths": null,
"columns": [],
"open_libs": []
},
"meta": {
"version": 4
},
"plugins": {
"actions": []
},
"printing": {
"as_item_checkboxes": false,
"background": false,
"color_theme": "",
"drill_marks": 1,
"edge_cuts_on_all_pages": true,
"layers": [],
"mirror": false,
"monochrome": true,
"pagination": 1,
"scale": 1.0,
"title_block": false,
"use_theme": false
},
"render": {
"clip_silk_on_via_annulus": false,
"engine": 0,
"grid_type": 0,
"material_mode": 0,
"opengl_AA_disableOnMove": false,
"opengl_AA_mode": 3,
"opengl_copper_thickness": false,
"opengl_highlight_on_rollover": true,
"opengl_holes_disableOnMove": false,
"opengl_render_bbox_only_OnMove": false,
"opengl_selection_color": "rgb(0, 255, 0)",
"opengl_show_model_bbox": false,
"opengl_show_off_board_silk": false,
"opengl_thickness_disableOnMove": false,
"opengl_vias_disableOnMove": false,
"plated_and_bare_copper": false,
"preview_show_board_body": true,
"raytrace_anti_aliasing": true,
"raytrace_backfloor": false,
"raytrace_lightAzimuth": [
45,
135,
225,
315,
45,
135,
225,
315
],
"raytrace_lightColor": [
"rgb(43, 43, 43)",
"rgb(43, 43, 43)",
"rgb(43, 43, 43)",
"rgb(43, 43, 43)",
"rgb(43, 43, 43)",
"rgb(43, 43, 43)",
"rgb(43, 43, 43)",
"rgb(43, 43, 43)"
],
"raytrace_lightColorBottom": "rgb(63, 63, 63)",
"raytrace_lightColorCamera": "rgb(51, 51, 51)",
"raytrace_lightColorTop": "rgb(63, 63, 63)",
"raytrace_lightElevation": [
67,
67,
67,
67,
-67,
-67,
-67,
-67
],
"raytrace_nrsamples_reflections": 3,
"raytrace_nrsamples_refractions": 4,
"raytrace_nrsamples_shadows": 3,
"raytrace_post_processing": true,
"raytrace_procedural_textures": true,
"raytrace_recursivelevel_reflections": 3,
"raytrace_recursivelevel_refractions": 2,
"raytrace_reflections": true,
"raytrace_refractions": true,
"raytrace_shadows": true,
"raytrace_spread_reflections": 0.02500000037252903,
"raytrace_spread_refractions": 0.02500000037252903,
"raytrace_spread_shadows": 0.05000000074505806,
"show_adhesive": true,
"show_board_body": true,
"show_comments": true,
"show_copper_bottom": true,
"show_copper_top": true,
"show_drawings": true,
"show_eco1": true,
"show_eco2": true,
"show_footprints_dnp": false,
"show_footprints_insert": true,
"show_footprints_normal": true,
"show_footprints_not_in_posfile": true,
"show_footprints_virtual": true,
"show_fp_references": true,
"show_fp_text": true,
"show_fp_values": true,
"show_navigator": true,
"show_plated_barrels": true,
"show_silkscreen_bottom": true,
"show_silkscreen_top": true,
"show_soldermask_bottom": true,
"show_soldermask_top": true,
"show_solderpaste": true,
"show_user1": false,
"show_user10": false,
"show_user11": false,
"show_user12": false,
"show_user13": false,
"show_user14": false,
"show_user15": false,
"show_user16": false,
"show_user17": false,
"show_user18": false,
"show_user19": false,
"show_user2": false,
"show_user20": false,
"show_user21": false,
"show_user22": false,
"show_user23": false,
"show_user24": false,
"show_user25": false,
"show_user26": false,
"show_user27": false,
"show_user28": false,
"show_user29": false,
"show_user3": false,
"show_user30": false,
"show_user31": false,
"show_user32": false,
"show_user33": false,
"show_user34": false,
"show_user35": false,
"show_user36": false,
"show_user37": false,
"show_user38": false,
"show_user39": false,
"show_user4": false,
"show_user40": false,
"show_user41": false,
"show_user42": false,
"show_user43": false,
"show_user44": false,
"show_user45": false,
"show_user5": false,
"show_user6": false,
"show_user7": false,
"show_user8": false,
"show_user9": false,
"show_zones": true,
"subtract_mask_from_silk": false,
"use_board_editor_copper_colors": false
},
"search_pane": {
"search_hidden_fields": true,
"search_metadata": false,
"selection_zoom": 1
},
"system": {
"file_history": [],
"first_run_shown": false,
"last_imperial_units": 5,
"last_metric_units": 1,
"max_undo_items": 0,
"show_import_issues": true,
"units": 1
},
"use_stackup_colors": true,
"window": {
"aui_state": null,
"cursor": {
"always_show_cursor": true,
"cross_hair_mode": 0
},
"display": 0,
"grid": {
"axes_enabled": false,
"fast_grid_1": 15,
"fast_grid_2": 16,
"last_size": 15,
"line_width": 1.0,
"min_spacing": 10.0,
"override_connected": false,
"override_connected_idx": 16,
"override_graphics": false,
"override_graphics_idx": 15,
"override_text": false,
"override_text_idx": 18,
"override_vias": false,
"override_vias_idx": 18,
"override_wires": false,
"override_wires_idx": 19,
"overrides_enabled": true,
"show": true,
"sizes": [
{
"name": "",
"x": "1000 mil",
"y": "1000 mil"
},
{
"name": "",
"x": "500 mil",
"y": "500 mil"
},
{
"name": "",
"x": "250 mil",
"y": "250 mil"
},
{
"name": "",
"x": "200 mil",
"y": "200 mil"
},
{
"name": "",
"x": "100 mil",
"y": "100 mil"
},
{
"name": "",
"x": "50 mil",
"y": "50 mil"
},
{
"name": "",
"x": "25 mil",
"y": "25 mil"
},
{
"name": "",
"x": "20 mil",
"y": "20 mil"
},
{
"name": "",
"x": "10 mil",
"y": "10 mil"
},
{
"name": "",
"x": "5 mil",
"y": "5 mil"
},
{
"name": "",
"x": "2 mil",
"y": "2 mil"
},
{
"name": "",
"x": "1 mil",
"y": "1 mil"
},
{
"name": "",
"x": "5.0 mm",
"y": "5.0 mm"
},
{
"name": "",
"x": "2.5 mm",
"y": "2.5 mm"
},
{
"name": "",
"x": "1.0 mm",
"y": "1.0 mm"
},
{
"name": "",
"x": "0.5 mm",
"y": "0.5 mm"
},
{
"name": "",
"x": "0.25 mm",
"y": "0.25 mm"
},
{
"name": "",
"x": "0.2 mm",
"y": "0.2 mm"
},
{
"name": "",
"x": "0.1 mm",
"y": "0.1 mm"
},
{
"name": "",
"x": "0.05 mm",
"y": "0.05 mm"
},
{
"name": "",
"x": "0.025 mm",
"y": "0.025 mm"
},
{
"name": "",
"x": "0.01 mm",
"y": "0.01 mm"
}
],
"snap": 0,
"style": 0,
"user_grid_x": "",
"user_grid_y": ""
},
"maximized": false,
"mru_path": "",
"perspective": "",
"pos_x": 0,
"pos_y": 0,
"size_x": 0,
"size_y": 0,
"zoom_factors": [
0.13,
0.22,
0.35,
0.6,
1.0,
1.5,
2.2,
3.5,
5.0,
8.0,
13.0,
20.0,
35.0,
50.0,
80.0,
130.0,
220.0,
300.0
]
}
}
+435
View File
@@ -0,0 +1,435 @@
{
"appearance": {
"color_theme": "_builtin_default",
"custom_toolbars": false
},
"color_picker": {
"default_tab": 0
},
"cross_probing": {
"auto_highlight": true,
"center_on_items": true,
"flash_selection": false,
"on_selection": true,
"zoom_to_fit": true
},
"design_block_chooser": {
"height": -1,
"keep_annotations": false,
"lib_tree": {
"column_widths": null
},
"place_as_group": true,
"place_as_sheet": false,
"repeated_placement": false,
"sash_pos_h": -1,
"sash_pos_v": -1,
"sort_mode": 0,
"width": -1
},
"filter_footprint": 0,
"filter_footprint_text": "",
"find_replace": {
"find_history": [],
"find_string": "",
"match_case": false,
"match_mode": 0,
"replace_history": [],
"replace_string": "",
"search_and_replace": false
},
"footprint_viewer": {
"angle_snap_mode": 1,
"aui_state": null,
"autozoom": true,
"cursor": {
"always_show_cursor": true,
"cross_hair_mode": 0
},
"display": 0,
"grid": {
"axes_enabled": false,
"fast_grid_1": 15,
"fast_grid_2": 16,
"last_size": 15,
"line_width": 1.0,
"min_spacing": 10.0,
"override_connected": false,
"override_connected_idx": 16,
"override_graphics": false,
"override_graphics_idx": 15,
"override_text": false,
"override_text_idx": 18,
"override_vias": false,
"override_vias_idx": 18,
"override_wires": false,
"override_wires_idx": 19,
"overrides_enabled": true,
"show": true,
"sizes": [
{
"name": "",
"x": "1000 mil",
"y": "1000 mil"
},
{
"name": "",
"x": "500 mil",
"y": "500 mil"
},
{
"name": "",
"x": "250 mil",
"y": "250 mil"
},
{
"name": "",
"x": "200 mil",
"y": "200 mil"
},
{
"name": "",
"x": "100 mil",
"y": "100 mil"
},
{
"name": "",
"x": "50 mil",
"y": "50 mil"
},
{
"name": "",
"x": "25 mil",
"y": "25 mil"
},
{
"name": "",
"x": "20 mil",
"y": "20 mil"
},
{
"name": "",
"x": "10 mil",
"y": "10 mil"
},
{
"name": "",
"x": "5 mil",
"y": "5 mil"
},
{
"name": "",
"x": "2 mil",
"y": "2 mil"
},
{
"name": "",
"x": "1 mil",
"y": "1 mil"
},
{
"name": "",
"x": "5.0 mm",
"y": "5.0 mm"
},
{
"name": "",
"x": "2.5 mm",
"y": "2.5 mm"
},
{
"name": "",
"x": "1.0 mm",
"y": "1.0 mm"
},
{
"name": "",
"x": "0.5 mm",
"y": "0.5 mm"
},
{
"name": "",
"x": "0.25 mm",
"y": "0.25 mm"
},
{
"name": "",
"x": "0.2 mm",
"y": "0.2 mm"
},
{
"name": "",
"x": "0.1 mm",
"y": "0.1 mm"
},
{
"name": "",
"x": "0.05 mm",
"y": "0.05 mm"
},
{
"name": "",
"x": "0.025 mm",
"y": "0.025 mm"
},
{
"name": "",
"x": "0.01 mm",
"y": "0.01 mm"
}
],
"snap": 0,
"style": 0,
"user_grid_x": "",
"user_grid_y": ""
},
"maximized": false,
"mru_path": "",
"perspective": "",
"pos_x": 0,
"pos_y": 0,
"show_graphic_fill": true,
"show_pad_fill": true,
"show_pad_number": true,
"show_text_fill": true,
"size_x": 0,
"size_y": 0,
"zoom": 1.0,
"zoom_factors": [
0.13,
0.22,
0.35,
0.6,
1.0,
1.5,
2.2,
3.5,
5.0,
8.0,
13.0,
20.0,
35.0,
50.0,
80.0,
130.0,
220.0,
300.0
]
},
"footprints_pane_width": 0,
"graphics": {
"highlight_factor": 0.5,
"select_factor": 0.75
},
"lib_tree": {
"column_widths": null,
"columns": [],
"open_libs": []
},
"libraries_pane_width": 0,
"meta": {
"version": 0
},
"plugins": {
"actions": []
},
"printing": {
"as_item_checkboxes": false,
"background": false,
"color_theme": "",
"drill_marks": 1,
"edge_cuts_on_all_pages": true,
"layers": [],
"mirror": false,
"monochrome": true,
"pagination": 1,
"scale": 1.0,
"title_block": false,
"use_theme": false
},
"search_pane": {
"search_hidden_fields": true,
"search_metadata": false,
"selection_zoom": 1
},
"system": {
"file_history": [],
"first_run_shown": false,
"last_imperial_units": 5,
"last_metric_units": 1,
"max_undo_items": 0,
"show_import_issues": true,
"units": 1
},
"window": {
"aui_state": null,
"cursor": {
"always_show_cursor": true,
"cross_hair_mode": 0
},
"display": 0,
"grid": {
"axes_enabled": false,
"fast_grid_1": 15,
"fast_grid_2": 16,
"last_size": 15,
"line_width": 1.0,
"min_spacing": 10.0,
"override_connected": false,
"override_connected_idx": 16,
"override_graphics": false,
"override_graphics_idx": 15,
"override_text": false,
"override_text_idx": 18,
"override_vias": false,
"override_vias_idx": 18,
"override_wires": false,
"override_wires_idx": 19,
"overrides_enabled": true,
"show": true,
"sizes": [
{
"name": "",
"x": "1000 mil",
"y": "1000 mil"
},
{
"name": "",
"x": "500 mil",
"y": "500 mil"
},
{
"name": "",
"x": "250 mil",
"y": "250 mil"
},
{
"name": "",
"x": "200 mil",
"y": "200 mil"
},
{
"name": "",
"x": "100 mil",
"y": "100 mil"
},
{
"name": "",
"x": "50 mil",
"y": "50 mil"
},
{
"name": "",
"x": "25 mil",
"y": "25 mil"
},
{
"name": "",
"x": "20 mil",
"y": "20 mil"
},
{
"name": "",
"x": "10 mil",
"y": "10 mil"
},
{
"name": "",
"x": "5 mil",
"y": "5 mil"
},
{
"name": "",
"x": "2 mil",
"y": "2 mil"
},
{
"name": "",
"x": "1 mil",
"y": "1 mil"
},
{
"name": "",
"x": "5.0 mm",
"y": "5.0 mm"
},
{
"name": "",
"x": "2.5 mm",
"y": "2.5 mm"
},
{
"name": "",
"x": "1.0 mm",
"y": "1.0 mm"
},
{
"name": "",
"x": "0.5 mm",
"y": "0.5 mm"
},
{
"name": "",
"x": "0.25 mm",
"y": "0.25 mm"
},
{
"name": "",
"x": "0.2 mm",
"y": "0.2 mm"
},
{
"name": "",
"x": "0.1 mm",
"y": "0.1 mm"
},
{
"name": "",
"x": "0.05 mm",
"y": "0.05 mm"
},
{
"name": "",
"x": "0.025 mm",
"y": "0.025 mm"
},
{
"name": "",
"x": "0.01 mm",
"y": "0.01 mm"
}
],
"snap": 0,
"style": 0,
"user_grid_x": "",
"user_grid_y": ""
},
"maximized": false,
"mru_path": "",
"perspective": "",
"pos_x": 0,
"pos_y": 0,
"size_x": 0,
"size_y": 0,
"zoom_factors": [
0.13,
0.22,
0.35,
0.6,
1.0,
1.5,
2.2,
3.5,
5.0,
8.0,
13.0,
20.0,
35.0,
50.0,
80.0,
130.0,
220.0,
300.0
]
}
}
@@ -0,0 +1,3 @@
(design_block_lib_table
(version 7)
)
+543
View File
@@ -0,0 +1,543 @@
{
"ERC": {
"crossprobe": true,
"scroll_on_crossprobe": true,
"show_all_errors": false
},
"annotation": {
"automatic": true,
"messages_filter": -1,
"options": 0,
"recursive": true,
"regroup_units": false,
"scope": 0
},
"appearance": {
"color_theme": "_builtin_default",
"custom_toolbars": false,
"default_font": "KiCad Font",
"footprint_preview": true,
"mark_sim_exclusions": true,
"print_sheet_reference": true,
"show_directive_labels": true,
"show_erc_errors": true,
"show_erc_exclusions": false,
"show_erc_warnings": true,
"show_hidden_fields": false,
"show_hidden_pins": false,
"show_illegal_symbol_lib_dialog": true,
"show_op_currents": true,
"show_op_voltages": true,
"show_page_limits": true,
"show_pin_alt_icons": true,
"show_sexpr_file_convert_warning": true,
"show_sheet_filename_case_sensitivity_dialog": true
},
"aui": {
"design_blocks_panel_docked_width": -1,
"design_blocks_panel_float_height": -1,
"design_blocks_panel_float_width": -1,
"design_blocks_show": false,
"float_net_nav_panel": false,
"hierarchy_panel_docked_height": -1,
"hierarchy_panel_docked_width": -1,
"hierarchy_panel_float_height": -1,
"hierarchy_panel_float_width": -1,
"net_nav_panel_docked_size": {
"height": -1,
"width": 120
},
"net_nav_panel_float_pos": {
"x": 50,
"y": 200
},
"net_nav_panel_float_size": {
"height": 200,
"width": 200
},
"net_nav_search_mode_wildcard": true,
"properties_panel_width": -1,
"properties_splitter_proportion": 0.5,
"remote_symbol_panel_docked_width": -1,
"remote_symbol_panel_float_height": -1,
"remote_symbol_panel_float_width": -1,
"remote_symbol_show": false,
"schematic_hierarchy_float": false,
"search_panel_dock_direction": 3,
"search_panel_height": -1,
"search_panel_width": -1,
"show_net_nav_panel": false,
"show_properties": true,
"show_schematic_hierarchy": true,
"show_search": false
},
"autoplace_fields": {
"align_to_grid": true,
"allow_rejustify": true,
"enable": true
},
"bom": {
"plugins": [
{
"command": "",
"name": "bom_csv_grouped_extra",
"path": "bom_csv_grouped_extra.py"
},
{
"command": "",
"name": "bom_csv_grouped_by_value",
"path": "bom_csv_grouped_by_value.py"
},
{
"command": "",
"name": "bom_csv_grouped_by_value_with_fp",
"path": "bom_csv_grouped_by_value_with_fp.py"
}
],
"selected_plugin": ""
},
"change_symbols": {
"update_references": false,
"update_values": false
},
"color_picker": {
"default_tab": 0
},
"cross_probing": {
"auto_highlight": true,
"center_on_items": true,
"flash_selection": false,
"on_selection": true,
"zoom_to_fit": true
},
"design_block_chooser": {
"height": -1,
"keep_annotations": false,
"lib_tree": {
"column_widths": null
},
"place_as_group": true,
"place_as_sheet": false,
"repeated_placement": false,
"sash_pos_h": -1,
"sash_pos_v": -1,
"sort_mode": 0,
"width": -1
},
"drawing": {
"auto_start_wires": true,
"default_bus_thickness": 12,
"default_junction_size": 36,
"default_line_thickness": 6,
"default_repeat_offset_x": 0,
"default_repeat_offset_y": 100,
"default_sheet_background_color": "rgba(0, 0, 0, 0.000)",
"default_sheet_border_color": "rgba(0, 0, 0, 0.000)",
"default_text_size": 50,
"default_wire_thickness": 6,
"field_names": "",
"hop_over_size_choice": 0,
"junction_size_choice": 3,
"junction_size_mult_list": [
0.0,
1.7,
4.0,
6.0,
9.0,
12.0
],
"line_mode": 1,
"new_power_symbols": 0,
"pin_symbol_size": 25,
"repeat_label_increment": 1,
"text_offset_ratio": 0.08
},
"editing": {
"arc_edit_mode": 0
},
"field_editor": {
"export_filename": "",
"field_widths": {},
"sash_pos": 400,
"selection_mode": 0,
"sidebar_collapsed": false,
"variant_sash_pos": 500
},
"find_replace": {
"find_history": [],
"find_string": "",
"match_case": false,
"match_mode": 0,
"replace_history": [],
"replace_references": false,
"replace_string": "",
"search_all_fields": false,
"search_all_pins": false,
"search_and_replace": false,
"search_current_sheet_only": false
},
"graphics": {
"highlight_factor": 0.5,
"select_factor": 0.75
},
"input": {
"allow_unconstrained_pin_swaps": false,
"drag_is_move": false,
"esc_clears_net_highlight": true
},
"lib_tree": {
"column_widths": null,
"columns": [],
"open_libs": []
},
"lib_view": {
"cmp_list_width": 150,
"lib_list_width": 150,
"show_pin_electrical_type": true,
"window": {
"aui_state": null,
"cursor": {
"always_show_cursor": true,
"cross_hair_mode": 0
},
"display": 0,
"grid": {
"axes_enabled": false,
"fast_grid_1": 1,
"fast_grid_2": 2,
"last_size": 1,
"line_width": 1.0,
"min_spacing": 10.0,
"override_connected": true,
"override_connected_idx": 1,
"override_graphics": false,
"override_graphics_idx": 2,
"override_text": true,
"override_text_idx": 3,
"override_vias": false,
"override_vias_idx": 0,
"override_wires": true,
"override_wires_idx": 1,
"overrides_enabled": true,
"show": true,
"sizes": [
{
"name": "",
"x": "100 mil",
"y": "100 mil"
},
{
"name": "",
"x": "50 mil",
"y": "50 mil"
},
{
"name": "",
"x": "25 mil",
"y": "25 mil"
},
{
"name": "",
"x": "10 mil",
"y": "10 mil"
}
],
"snap": 0,
"style": 0,
"user_grid_x": "",
"user_grid_y": ""
},
"maximized": false,
"mru_path": "",
"perspective": "",
"pos_x": 0,
"pos_y": 0,
"size_x": 500,
"size_y": 400,
"zoom_factors": [
0.05,
0.07,
0.1,
0.15,
0.2,
0.3,
0.5,
0.7,
1.0,
1.5,
2.0,
3.0,
4.5,
6.5,
10.0,
15.0,
20.0,
30.0,
45.0,
65.0,
100.0
]
}
},
"meta": {
"version": 3
},
"netlist": {
"plugins": []
},
"page_settings": {
"export_comment1": false,
"export_comment2": false,
"export_comment3": false,
"export_comment4": false,
"export_comment5": false,
"export_comment6": false,
"export_comment7": false,
"export_comment8": false,
"export_comment9": false,
"export_company": false,
"export_date": false,
"export_paper": false,
"export_revision": false,
"export_title": false
},
"plugins": {
"actions": []
},
"printing": {
"as_item_checkboxes": false,
"background": false,
"color_theme": "",
"drill_marks": 1,
"edge_cuts_on_all_pages": true,
"layers": [],
"mirror": false,
"monochrome": true,
"pagination": 1,
"scale": 1.0,
"title_block": false,
"use_theme": false
},
"remote_symbols": {
"add_to_global_table": false,
"destination_dir": "${KIPRJMOD}/RemoteLibrary",
"library_prefix": "remote",
"user_ids": {}
},
"search_pane": {
"search_hidden_fields": true,
"search_metadata": false,
"selection_zoom": 1
},
"selection": {
"drag_net_collision_width": 4,
"draw_selected_children": true,
"fill_shapes": false,
"highlight_netclass_colors": false,
"highlight_netclass_colors_alpha": 0.6,
"highlight_netclass_colors_thickness": 15,
"highlight_thickness": 2,
"thickness": 3
},
"simulator": {
"cursors_panel_height": 0,
"measurements_panel_height": 0,
"mouse_wheel_actions": {
"horizontal": 0,
"vertical_unmodified": 4,
"vertical_with_alt": 0,
"vertical_with_ctrl": 1,
"vertical_with_shift": 3
},
"plot_panel_height": 0,
"plot_panel_width": 0,
"signal_panel_height": 0,
"white_background": false,
"window": {
"aui_state": null,
"cursor": {
"always_show_cursor": true,
"cross_hair_mode": 0
},
"display": 0,
"grid": {
"axes_enabled": false,
"fast_grid_1": 1,
"fast_grid_2": 2,
"last_size": 1,
"line_width": 1.0,
"min_spacing": 10.0,
"override_connected": true,
"override_connected_idx": 1,
"override_graphics": false,
"override_graphics_idx": 2,
"override_text": true,
"override_text_idx": 3,
"override_vias": false,
"override_vias_idx": 0,
"override_wires": true,
"override_wires_idx": 1,
"overrides_enabled": true,
"show": true,
"sizes": [
{
"name": "",
"x": "100 mil",
"y": "100 mil"
},
{
"name": "",
"x": "50 mil",
"y": "50 mil"
},
{
"name": "",
"x": "25 mil",
"y": "25 mil"
},
{
"name": "",
"x": "10 mil",
"y": "10 mil"
}
],
"snap": 0,
"style": 0,
"user_grid_x": "",
"user_grid_y": ""
},
"maximized": false,
"mru_path": "",
"perspective": "",
"pos_x": 0,
"pos_y": 0,
"size_x": 500,
"size_y": 400,
"zoom_factors": [
0.05,
0.07,
0.1,
0.15,
0.2,
0.3,
0.5,
0.7,
1.0,
1.5,
2.0,
3.0,
4.5,
6.5,
10.0,
15.0,
20.0,
30.0,
45.0,
65.0,
100.0
]
}
},
"symbol_chooser": {
"height": -1,
"sash_pos_h": -1,
"sash_pos_v": -1,
"sort_mode": 0,
"width": -1
},
"system": {
"file_history": [],
"first_run_shown": false,
"last_imperial_units": 5,
"last_metric_units": 1,
"last_symbol_lib_dir": "",
"max_undo_items": 0,
"never_show_rescue_dialog": false,
"show_import_issues": true,
"units": 5
},
"window": {
"aui_state": null,
"cursor": {
"always_show_cursor": true,
"cross_hair_mode": 0
},
"display": 0,
"grid": {
"axes_enabled": false,
"fast_grid_1": 1,
"fast_grid_2": 2,
"last_size": 1,
"line_width": 1.0,
"min_spacing": 10.0,
"override_connected": true,
"override_connected_idx": 1,
"override_graphics": false,
"override_graphics_idx": 2,
"override_text": true,
"override_text_idx": 3,
"override_vias": false,
"override_vias_idx": 0,
"override_wires": true,
"override_wires_idx": 1,
"overrides_enabled": true,
"show": true,
"sizes": [
{
"name": "",
"x": "100 mil",
"y": "100 mil"
},
{
"name": "",
"x": "50 mil",
"y": "50 mil"
},
{
"name": "",
"x": "25 mil",
"y": "25 mil"
},
{
"name": "",
"x": "10 mil",
"y": "10 mil"
}
],
"snap": 0,
"style": 0,
"user_grid_x": "",
"user_grid_y": ""
},
"maximized": false,
"mru_path": "",
"perspective": "",
"pos_x": 0,
"pos_y": 0,
"size_x": 0,
"size_y": 0,
"zoom_factors": [
0.05,
0.07,
0.1,
0.15,
0.2,
0.3,
0.5,
0.7,
1.0,
1.5,
2.0,
3.0,
4.5,
6.5,
10.0,
15.0,
20.0,
30.0,
45.0,
65.0,
100.0
]
}
}
+148
View File
@@ -0,0 +1,148 @@
(fp_lib_table
(lib (name Audio_Module)(type Kicad)(uri ${KICAD8_FOOTPRINT_DIR}/Audio_Module.pretty)(options "")(descr "Audio Module footprints"))
(lib (name Battery)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Battery.pretty)(options "")(descr "Battery and battery holder footprints"))
(lib (name Button_Switch_Keyboard)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Button_Switch_Keyboard.pretty)(options "")(descr "Buttons and switches for keyboard applications"))
(lib (name Button_Switch_SMD)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Button_Switch_SMD.pretty)(options "")(descr "Buttons and switches, surface mount"))
(lib (name Button_Switch_THT)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Button_Switch_THT.pretty)(options "")(descr "Buttons and switches, through hole"))
(lib (name Buzzer_Beeper)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Buzzer_Beeper.pretty)(options "")(descr "Audio signalling devices"))
(lib (name Calibration_Scale)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Calibration_Scale.pretty)(options "")(descr "Scales and grids intended for calibration and measurement"))
(lib (name Capacitor_SMD)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Capacitor_SMD.pretty)(options "")(descr "Capacitor, surface mount"))
(lib (name Capacitor_THT)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Capacitor_THT.pretty)(options "")(descr "Capacitor, through hole"))
(lib (name Capacitor_Tantalum_SMD)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Capacitor_Tantalum_SMD.pretty)(options "")(descr "Tantalum Capacitor, surface mount"))
(lib (name Connector)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector.pretty)(options "")(descr "Generic/unsorted connector footprints"))
(lib (name Connector_AMASS)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_AMASS.pretty)(options "")(descr "AMASS connector footprints"))
(lib (name Connector_Amphenol)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_Amphenol.pretty)(options "")(descr "Amphenol LTW connector footprints"))
(lib (name Connector_Audio)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_Audio.pretty)(options "")(descr "Audio connector footprints"))
(lib (name Connector_BarrelJack)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_BarrelJack.pretty)(options "")(descr "(DC) barrel jack connector footprints"))
(lib (name Connector_Card)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_Card.pretty)(options "")(descr "Card and card holder footprints"))
(lib (name Connector_Coaxial)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_Coaxial.pretty)(options "")(descr "Coaxial and RF connector footprints"))
(lib (name Connector_DIN)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_DIN.pretty)(options "")(descr "DIN connector footprints"))
(lib (name Connector_Dsub)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_Dsub.pretty)(options "")(descr "DSub connector footprints"))
(lib (name Connector_FFC-FPC)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_FFC-FPC.pretty)(options "")(descr "FFC (Flexible Flat Cable) and FPC (Flexible Printed Circuit) connector footprints"))
(lib (name Connector_Harting)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_Harting.pretty)(options "")(descr "Harting connector footprints"))
(lib (name Connector_Harwin)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_Harwin.pretty)(options "")(descr "Harwin connector footprints"))
(lib (name Connector_Hirose)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_Hirose.pretty)(options "")(descr "Hirose connector footprints"))
(lib (name Connector_Hirose_FX8)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_Hirose_FX8.pretty)(options "")(descr "Hirose FX8 series connector footprints"))
(lib (name Connector_IDC)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_IDC.pretty)(options "")(descr "IDC connector footprints"))
(lib (name Connector_JAE)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_JAE.pretty)(options "")(descr "JAE connector footprints"))
(lib (name Connector_JAE_WP7B)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_JAE_WP7B.pretty)(options "")(descr "JAE WP7B series FPC connector footprints"))
(lib (name Connector_JST)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_JST.pretty)(options "")(descr "JST connector footprints www.jst.com"))
(lib (name Connector_Molex)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_Molex.pretty)(options "")(descr "Molex connector footprints www.molex.com"))
(lib (name Connector_PCBEdge)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_PCBEdge.pretty)(options "")(descr "PCB edge connectors (e.g. PCI, ISA, PCIe, ...)"))
(lib (name Connector_Pin)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_Pin.pretty)(options "")(descr "Single (solder) pin conectors"))
(lib (name Connector_PinHeader_1.00mm)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_PinHeader_1.00mm.pretty)(options "")(descr "Pin headers, 1.0mm pitch"))
(lib (name Connector_PinHeader_1.27mm)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_PinHeader_1.27mm.pretty)(options "")(descr "Pin headers, 1.27mm pitch"))
(lib (name Connector_PinHeader_2.00mm)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_PinHeader_2.00mm.pretty)(options "")(descr "Pin headers, 2.0mm pitch"))
(lib (name Connector_PinHeader_2.54mm)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_PinHeader_2.54mm.pretty)(options "")(descr "Pin headers, 2.54mm pitch"))
(lib (name Connector_PinSocket_1.00mm)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_PinSocket_1.00mm.pretty)(options "")(descr "Pin sockets, 1.00mm pitch"))
(lib (name Connector_PinSocket_1.27mm)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_PinSocket_1.27mm.pretty)(options "")(descr "Pin sockets, 1.27mm pitch"))
(lib (name Connector_PinSocket_2.00mm)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_PinSocket_2.00mm.pretty)(options "")(descr "Pin sockets, 2.0mm pitch"))
(lib (name Connector_PinSocket_2.54mm)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_PinSocket_2.54mm.pretty)(options "")(descr "Pin sockets, 2.54mm pitch"))
(lib (name Connector_Phoenix_MC)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_Phoenix_MC.pretty)(options "")(descr "Phoenix MC connector footprints"))
(lib (name Connector_Phoenix_MC_HighVoltage)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_Phoenix_MC_HighVoltage.pretty)(options "")(descr "Phoenix high voltage (320V, 5.08mm pitch) MC connector footprints"))
(lib (name Connector_Phoenix_MSTB)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_Phoenix_MSTB.pretty)(options "")(descr "Phoenix MSTB connector footprints"))
(lib (name Connector_Phoenix_GMSTB)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_Phoenix_GMSTB.pretty)(options "")(descr "Phoenix GMSTB series (high voltage MSTB) connector footprints"))
(lib (name Connector_Phoenix_SPT)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_Phoenix_SPT.pretty)(options "")(descr "Phoenix SPT connector footprints"))
(lib (name Connector_Samtec)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_Samtec.pretty)(options "")(descr "Samtec connector footprints"))
(lib (name Connector_Samtec_HLE_SMD)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_Samtec_HLE_SMD.pretty)(options "")(descr "Samtec surface mount HLE series connector footprints"))
(lib (name Connector_Samtec_HLE_THT)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_Samtec_HLE_THT.pretty)(options "")(descr "Samtec through hole HLE series connector footprints"))
(lib (name Connector_Samtec_HPM_THT)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_Samtec_HPM_THT.pretty)(options "")(descr "Samtec through hole HPM series power header footprints"))
(lib (name Connector_Samtec_HSEC8)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_Samtec_HSEC8.pretty)(options "")(descr "Samtec HSEC8 0.8mm high speed card edge connector footprints"))
(lib (name Connector_Samtec_MicroMate)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_Samtec_MicroMate.pretty)(options "")(descr "Samtec MicroMate discrete wire terminal strips, 1.0mm pitch"))
(lib (name Connector_Samtec_MicroPower)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_Samtec_MicroPower.pretty)(options "")(descr "Samtec 2.00mm mPOWER Ultra Micro Power connector footprints"))
(lib (name Connector_RJ)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_RJ.pretty)(options "")(descr "Registered Jack (RJ) connector footprints (e.g. RJ11, RJ45, ...)"))
(lib (name Connector_SATA_SAS)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_SATA_SAS.pretty)(options "")(descr "SATA/SAS connector footprints"))
(lib (name Connector_Stocko)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_Stocko.pretty)(options "")(descr "Stocko connector footprints"))
(lib (name Connector_TE-Connectivity)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_TE-Connectivity.pretty)(options "")(descr "Footprints for connectors by TE Connectivity"))
(lib (name Connector_USB)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_USB.pretty)(options "")(descr "USB connector footprints"))
(lib (name Connector_Video)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_Video.pretty)(options "")(descr "Video connector footprints like DVI and HDMI"))
(lib (name Connector_Wago)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_Wago.pretty)(options "")(descr "Wago connector footprints"))
(lib (name Connector_Wire)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_Wire.pretty)(options "")(descr "Footprints for solder wire pads"))
(lib (name Connector_Wuerth)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Connector_Wuerth.pretty)(options "")(descr "Wuerth connector footprints"))
(lib (name Converter_ACDC)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Converter_ACDC.pretty)(options "")(descr "AC/DC converter footprints"))
(lib (name Converter_DCDC)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Converter_DCDC.pretty)(options "")(descr "DC/DC converter footprints"))
(lib (name Crystal)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Crystal.pretty)(options "")(descr "Crystal footprints"))
(lib (name Diode_SMD)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Diode_SMD.pretty)(options "")(descr "Diode footprints, surface mount"))
(lib (name Diode_THT)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Diode_THT.pretty)(options "")(descr "Diode footprints, through hole"))
(lib (name Display_7Segment)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Display_7Segment.pretty)(options "")(descr "Seven segment Display"))
(lib (name Display)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Display.pretty)(options "")(descr "Display modules"))
(lib (name Ferrite_THT)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Ferrite_THT.pretty)(options "")(descr "Ferrite bead, through hole"))
(lib (name Fiducial)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Fiducial.pretty)(options "")(descr "Fiducial markings"))
(lib (name Filter)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Filter.pretty)(options "")(descr "Filter footprints"))
(lib (name Fuse)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Fuse.pretty)(options "")(descr "Fuse and fuse holder footprints"))
(lib (name Heatsink)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Heatsink.pretty)(options "")(descr "Heatsinks and thermal products"))
(lib (name Inductor_SMD)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Inductor_SMD.pretty)(options "")(descr "Inductor footprints, surface mount"))
(lib (name Inductor_SMD_Wurth)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Inductor_SMD_Wurth.pretty)(options "")(descr "Würth Elektronik inductor footprints, surface mount"))
(lib (name Inductor_THT)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Inductor_THT.pretty)(options "")(descr "Inductor footprints, through hole"))
(lib (name Inductor_THT_Wurth)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Inductor_THT_Wurth.pretty)(options "")(descr "Würth Elektronik inductor footprints, through hole"))
(lib (name Jumper)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Jumper.pretty)(options "")(descr "Jumpers, solder jumpers, ... footprints"))
(lib (name LED_SMD)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/LED_SMD.pretty)(options "")(descr "Light emitting diodes (LED), surface mount"))
(lib (name LED_THT)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/LED_THT.pretty)(options "")(descr "Light emitting diodes (LED), through hole"))
(lib (name Module)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Module.pretty)(options "")(descr "Footprints for SoM (System on Module)"))
(lib (name Motors)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Motors.pretty)(options "")(descr "Footprints for Motors"))
(lib (name MountingHole)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/MountingHole.pretty)(options "")(descr "Mechanical fasteners"))
(lib (name Mounting_Wuerth)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Mounting_Wuerth.pretty)(options "")(descr "Mechanical fasteners by wuerth electronics"))
(lib (name MountingEquipment)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/MountingEquipment.pretty)(options "")(descr "Mechanical parts"))
(lib (name NetTie)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/NetTie.pretty)(options "")(descr "Net ties"))
(lib (name OptoDevice)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/OptoDevice.pretty)(options "")(descr "Optical devices (light sensors, opto isolators/interrupters, laser diodes, fiber optical components, lightpipes, lenses ...)"))
(lib (name Oscillator)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Oscillator.pretty)(options "")(descr "Footprints for oscillator devices"))
(lib (name Package_BGA)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Package_BGA.pretty)(options "")(descr "Ball Grid Array (BGA)"))
(lib (name Package_CSP)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Package_CSP.pretty)(options "")(descr "Chip Scale Packages (CSP)"))
(lib (name Package_DFN_QFN)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Package_DFN_QFN.pretty)(options "")(descr "Surface mount IC packages, DFN / LGA / QFN"))
(lib (name Package_DIP)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Package_DIP.pretty)(options "")(descr "Through hole IC packages, DIP"))
(lib (name Package_DirectFET)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Package_DirectFET.pretty)(options "")(descr "DirectFET packages from International Rectifier"))
(lib (name Package_LCC)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Package_LCC.pretty)(options "")(descr "Leaded Chip Carriers (LCC)"))
(lib (name Package_LGA)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Package_LGA.pretty)(options "")(descr "Land Grid Array (LGA)"))
(lib (name Package_QFP)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Package_QFP.pretty)(options "")(descr "Quad Flat Package (QFP)"))
(lib (name Package_SIP)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Package_SIP.pretty)(options "")(descr "Single Inline Package(SIP)"))
(lib (name Package_SO)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Package_SO.pretty)(options "")(descr "Small Outline Integrated Circuits (SOIC, SSOP, xSOP, xSO)"))
(lib (name Package_SO_J-Lead)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Package_SO_J-Lead.pretty)(options "")(descr "Small Outline Integrated Circuits J-Lead"))
(lib (name Package_SON)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Package_SON.pretty)(options "")(descr "Small Outline No-Lead (SON)"))
(lib (name Package_TO_SOT_SMD)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Package_TO_SOT_SMD.pretty)(options "")(descr "Surface mount transistor packages"))
(lib (name Package_TO_SOT_THT)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Package_TO_SOT_THT.pretty)(options "")(descr "Through hole transistor packages"))
(lib (name Potentiometer_SMD)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Potentiometer_SMD.pretty)(options "")(descr "Potentiometer footprints, surface mount (SMD)"))
(lib (name Potentiometer_THT)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Potentiometer_THT.pretty)(options "")(descr "Potentiometer footprints, through hole (THT)"))
(lib (name Relay_SMD)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Relay_SMD.pretty)(options "")(descr "Surface mount relay packages"))
(lib (name Relay_THT)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Relay_THT.pretty)(options "")(descr "Through hole relay packages"))
(lib (name Resistor_SMD)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Resistor_SMD.pretty)(options "")(descr "Resistor footprints, surface mount (SMD)"))
(lib (name Resistor_THT)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Resistor_THT.pretty)(options "")(descr "Resistor footprints, through hole (THT)"))
(lib (name RF)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/RF.pretty)(options "")(descr "Specialized footprints for RF components that don't fit in the other RF libraries."))
(lib (name RF_Antenna)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/RF_Antenna.pretty)(options "")(descr "Radio-frequency / wireless antenna footprints"))
(lib (name RF_Converter)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/RF_Converter.pretty)(options "")(descr "Specialized footprints for RF signal converters (Like Attenuators, Baluns, Mixers, Couplers, etc.)"))
(lib (name RF_GPS)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/RF_GPS.pretty)(options "")(descr "GNSS footprints"))
(lib (name RF_GSM)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/RF_GSM.pretty)(options "")(descr "GSM Modules footprints"))
(lib (name RF_Mini-Circuits)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/RF_Mini-Circuits.pretty)(options "")(descr "Footprints for Mini-Circuits RF parts."))
(lib (name RF_Module)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/RF_Module.pretty)(options "")(descr "Radio-frequency / wireless modules"))
(lib (name RF_WiFi)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/RF_WiFi.pretty)(options "")(descr "WiFi modules"))
(lib (name RF_Shielding)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/RF_Shielding.pretty)(options "")(descr "Specialied footprints for EMI shields and covers"))
(lib (name Rotary_Encoder)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Rotary_Encoder.pretty)(options "")(descr "Rotary Encoder Footprints"))
(lib (name Sensor)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Sensor.pretty)(options "")(descr "Specialized footprints for multi-function sensors"))
(lib (name Sensor_Audio)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Sensor_Audio.pretty)(options "")(descr "Specialized footprints for audio sensors"))
(lib (name Sensor_Distance)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Sensor_Distance.pretty)(options "")(descr "Specialized footprints for distance sensors"))
(lib (name Sensor_Current)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Sensor_Current.pretty)(options "")(descr "Specialized footprints for current sensors"))
(lib (name Sensor_Humidity)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Sensor_Humidity.pretty)(options "")(descr "Specialized footprints for humidity sensors"))
(lib (name Sensor_Motion)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Sensor_Motion.pretty)(options "")(descr "Specialized footprints for motion sensors"))
(lib (name Sensor_Pressure)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Sensor_Pressure.pretty)(options "")(descr "Specialized footprints for pressure sensors"))
(lib (name Sensor_Voltage)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Sensor_Voltage.pretty)(options "")(descr "Specialized footprints for voltage sensors"))
(lib (name Socket)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Socket.pretty)(options "")(descr "Sockets"))
(lib (name Symbol)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Symbol.pretty)(options "")(descr "PCB symbols"))
(lib (name TerminalBlock_Altech)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/TerminalBlock_Altech.pretty)(options "")(descr "Altech terminal block footprints"))
(lib (name TerminalBlock)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/TerminalBlock.pretty)(options "")(descr "Footprints for terminal blocks that do not have their own manufacturer specific library."))
(lib (name TerminalBlock_4Ucon)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/TerminalBlock_4Ucon.pretty)(options "")(descr "4UCON terminal blocks"))
(lib (name TerminalBlock_CUI)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/TerminalBlock_CUI.pretty)(options "")(descr "CUI terminal blocks"))
(lib (name TerminalBlock_Dinkle)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/TerminalBlock_Dinkle.pretty)(options "")(descr "Dinkle terminal blocks"))
(lib (name TerminalBlock_MetzConnect)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/TerminalBlock_MetzConnect.pretty)(options "")(descr "Metz Connect terminal blocks"))
(lib (name TerminalBlock_Philmore)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/TerminalBlock_Philmore.pretty)(options "")(descr "Philmore terminal blocks"))
(lib (name TerminalBlock_Phoenix)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/TerminalBlock_Phoenix.pretty)(options "")(descr "Phoenix Contact terminal blocks"))
(lib (name TerminalBlock_RND)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/TerminalBlock_RND.pretty)(options "")(descr "RND terminal blocks"))
(lib (name TerminalBlock_TE-Connectivity)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/TerminalBlock_TE-Connectivity.pretty)(options "")(descr "TE Connectivity terminal blocks"))
(lib (name TerminalBlock_WAGO)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/TerminalBlock_WAGO.pretty)(options "")(descr "WAGO terminal blocks"))
(lib (name TerminalBlock_Wuerth)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/TerminalBlock_Wuerth.pretty)(options "")(descr "Wuerth Elektronik terminal blocks"))
(lib (name TestPoint)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/TestPoint.pretty)(options "")(descr "Test points, measurement points, probe connection points"))
(lib (name Transformer_SMD)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Transformer_SMD.pretty)(options "")(descr "Surface mount transformers"))
(lib (name Transformer_THT)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Transformer_THT.pretty)(options "")(descr "Through hole transformers"))
(lib (name Transistor_Power)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Transistor_Power.pretty)(options "")(descr "Power Transistors"))
(lib (name Transistor_Power_Module)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Transistor_Power_Module.pretty)(options "")(descr "Transistor Power Modules"))
(lib (name Valve)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Valve.pretty)(options "")(descr "Valve"))
(lib (name Varistor)(type KiCad)(uri ${KICAD8_FOOTPRINT_DIR}/Varistor.pretty)(options "")(descr "Varistor"))
)
+351
View File
@@ -0,0 +1,351 @@
{
"appearance": {
"color_theme": "_builtin_default",
"custom_toolbars": false
},
"aui": {
"appearance_panel_tab": 0,
"properties_panel_width": -1,
"properties_splitter_proportion": 0.5,
"right_panel_width": -1,
"show_layer_manager": true,
"show_properties": false
},
"color_picker": {
"default_tab": 0
},
"cross_probing": {
"auto_highlight": true,
"center_on_items": true,
"flash_selection": false,
"on_selection": true,
"zoom_to_fit": true
},
"design_block_chooser": {
"height": -1,
"keep_annotations": false,
"lib_tree": {
"column_widths": null
},
"place_as_group": true,
"place_as_sheet": false,
"repeated_placement": false,
"sash_pos_h": -1,
"sash_pos_v": -1,
"sort_mode": 0,
"width": -1
},
"design_settings": {
"copper_line_width": 0.2,
"copper_text_italic": false,
"copper_text_size_h": 1.5,
"copper_text_size_v": 1.5,
"copper_text_thickness": 0.3,
"courtyard_line_width": 0.05,
"default_footprint_layer_names": {},
"default_footprint_text_items": [
[
"REF**",
true,
"F.SilkS"
],
[
"",
true,
"F.Fab"
],
[
"${REFERENCE}",
true,
"F.Fab"
]
],
"dimensions": {
"arrow_length": 1270000,
"extension_offset": 500000,
"keep_text_aligned": true,
"precision": 4,
"suppress_zeroes": true,
"text_position": 0,
"units": 3,
"units_format": 0
},
"edge_line_width": 0.05,
"fab_line_width": 0.1,
"fab_text_italic": false,
"fab_text_size_h": 1.0,
"fab_text_size_v": 1.0,
"fab_text_thickness": 0.15,
"others_line_width": 0.1,
"others_text_italic": false,
"others_text_size_h": 1.0,
"others_text_size_v": 1.0,
"others_text_thickness": 0.15,
"silk_line_width": 0.1,
"silk_text_italic": false,
"silk_text_size_h": 1.0,
"silk_text_size_v": 1.0,
"silk_text_thickness": 0.1,
"user_layer_count": 4
},
"editing": {
"fp_angle_snap_mode": 1,
"magnetic_all_layers": false,
"magnetic_graphics": true,
"magnetic_pads": 2,
"polar_coords": false,
"rotation_angle": 900,
"selection_filter": {
"dimensions": true,
"footprints": true,
"graphics": true,
"keepouts": true,
"lockedItems": false,
"otherItems": true,
"pads": true,
"points": true,
"text": true,
"tracks": true,
"vias": true,
"zones": true
}
},
"find_replace": {
"find_history": [],
"find_string": "",
"match_case": false,
"match_mode": 0,
"replace_history": [],
"replace_string": "",
"search_and_replace": false
},
"graphics": {
"highlight_factor": 0.5,
"select_factor": 0.75
},
"lib_tree": {
"column_widths": null,
"columns": [],
"open_libs": []
},
"library": {
"sort_mode": 0
},
"meta": {
"version": 5
},
"origin_invert_x_axis": false,
"origin_invert_y_axis": false,
"pcb_display": {
"active_layer_preset": "",
"graphics_fill": true,
"layer_presets": [],
"pad_fill": true,
"pad_numbers": true,
"text_fill": true
},
"plugins": {
"actions": []
},
"printing": {
"as_item_checkboxes": false,
"background": false,
"color_theme": "",
"drill_marks": 1,
"edge_cuts_on_all_pages": true,
"layers": [],
"mirror": false,
"monochrome": true,
"pagination": 1,
"scale": 1.0,
"title_block": false,
"use_theme": false
},
"search_pane": {
"search_hidden_fields": true,
"search_metadata": false,
"selection_zoom": 1
},
"system": {
"file_history": [],
"first_run_shown": false,
"last_imperial_units": 5,
"last_import_export_path": "",
"last_metric_units": 1,
"max_undo_items": 0,
"show_import_issues": true,
"units": 1
},
"window": {
"aui_state": null,
"cursor": {
"always_show_cursor": true,
"cross_hair_mode": 0
},
"display": 0,
"grid": {
"axes_enabled": false,
"fast_grid_1": 15,
"fast_grid_2": 16,
"last_size": 15,
"line_width": 1.0,
"min_spacing": 10.0,
"override_connected": false,
"override_connected_idx": 16,
"override_graphics": false,
"override_graphics_idx": 15,
"override_text": false,
"override_text_idx": 18,
"override_vias": false,
"override_vias_idx": 18,
"override_wires": false,
"override_wires_idx": 19,
"overrides_enabled": true,
"show": true,
"sizes": [
{
"name": "",
"x": "1000 mil",
"y": "1000 mil"
},
{
"name": "",
"x": "500 mil",
"y": "500 mil"
},
{
"name": "",
"x": "250 mil",
"y": "250 mil"
},
{
"name": "",
"x": "200 mil",
"y": "200 mil"
},
{
"name": "",
"x": "100 mil",
"y": "100 mil"
},
{
"name": "",
"x": "50 mil",
"y": "50 mil"
},
{
"name": "",
"x": "25 mil",
"y": "25 mil"
},
{
"name": "",
"x": "20 mil",
"y": "20 mil"
},
{
"name": "",
"x": "10 mil",
"y": "10 mil"
},
{
"name": "",
"x": "5 mil",
"y": "5 mil"
},
{
"name": "",
"x": "2 mil",
"y": "2 mil"
},
{
"name": "",
"x": "1 mil",
"y": "1 mil"
},
{
"name": "",
"x": "5.0 mm",
"y": "5.0 mm"
},
{
"name": "",
"x": "2.5 mm",
"y": "2.5 mm"
},
{
"name": "",
"x": "1.0 mm",
"y": "1.0 mm"
},
{
"name": "",
"x": "0.5 mm",
"y": "0.5 mm"
},
{
"name": "",
"x": "0.25 mm",
"y": "0.25 mm"
},
{
"name": "",
"x": "0.2 mm",
"y": "0.2 mm"
},
{
"name": "",
"x": "0.1 mm",
"y": "0.1 mm"
},
{
"name": "",
"x": "0.05 mm",
"y": "0.05 mm"
},
{
"name": "",
"x": "0.025 mm",
"y": "0.025 mm"
},
{
"name": "",
"x": "0.01 mm",
"y": "0.01 mm"
}
],
"snap": 0,
"style": 0,
"user_grid_x": "",
"user_grid_y": ""
},
"lib_width": 250,
"maximized": false,
"mru_path": "",
"perspective": "",
"pos_x": 0,
"pos_y": 0,
"size_x": 0,
"size_y": 0,
"zoom_factors": [
0.13,
0.22,
0.35,
0.6,
1.0,
1.5,
2.2,
3.5,
5.0,
8.0,
13.0,
20.0,
35.0,
50.0,
80.0,
130.0,
220.0,
300.0
]
}
}
+290
View File
@@ -0,0 +1,290 @@
{
"appearance": {
"color_theme": "_builtin_default",
"custom_toolbars": false,
"left_frame_width": 200
},
"aui": {
"show_history_panel": false
},
"color_picker": {
"default_tab": 0
},
"cross_probing": {
"auto_highlight": true,
"center_on_items": true,
"flash_selection": false,
"on_selection": true,
"zoom_to_fit": true
},
"design_block_chooser": {
"height": -1,
"keep_annotations": false,
"lib_tree": {
"column_widths": null
},
"place_as_group": true,
"place_as_sheet": false,
"repeated_placement": false,
"sash_pos_h": -1,
"sash_pos_v": -1,
"sort_mode": 0,
"width": -1
},
"find_replace": {
"find_history": [],
"find_string": "",
"match_case": false,
"match_mode": 0,
"replace_history": [],
"replace_string": "",
"search_and_replace": false
},
"graphics": {
"highlight_factor": 0.5,
"select_factor": 0.75
},
"lib_tree": {
"column_widths": null,
"columns": [],
"open_libs": []
},
"meta": {
"version": 0
},
"pcm": {
"check_for_updates": true,
"last_download_dir": "",
"lib_auto_add": true,
"lib_auto_remove": true,
"lib_prefix": "PCM_",
"repositories": [
{
"name": "KiCad official repository",
"url": "https://repository.kicad.org/repository.json"
}
]
},
"plugins": {
"actions": []
},
"printing": {
"as_item_checkboxes": false,
"background": false,
"color_theme": "",
"drill_marks": 1,
"edge_cuts_on_all_pages": true,
"layers": [],
"mirror": false,
"monochrome": true,
"pagination": 1,
"scale": 1.0,
"title_block": false,
"use_theme": false
},
"search_pane": {
"search_hidden_fields": true,
"search_metadata": false,
"selection_zoom": 1
},
"system": {
"check_for_kicad_updates": true,
"file_history": [],
"first_run_shown": false,
"last_design_block_lib_dir": "",
"last_imperial_units": 5,
"last_metric_units": 1,
"last_received_update": "",
"last_update_check_time": "",
"max_undo_items": 0,
"open_projects": [],
"show_import_issues": true,
"units": 1
},
"template": {
"filter": 0,
"last_used": "",
"recent_templates": [],
"window": {
"pos": {
"x": -1,
"y": -1
},
"size": {
"height": -1,
"width": -1
}
}
},
"window": {
"aui_state": null,
"cursor": {
"always_show_cursor": true,
"cross_hair_mode": 0
},
"display": 0,
"grid": {
"axes_enabled": false,
"fast_grid_1": 15,
"fast_grid_2": 16,
"last_size": 15,
"line_width": 1.0,
"min_spacing": 10.0,
"override_connected": false,
"override_connected_idx": 16,
"override_graphics": false,
"override_graphics_idx": 15,
"override_text": false,
"override_text_idx": 18,
"override_vias": false,
"override_vias_idx": 18,
"override_wires": false,
"override_wires_idx": 19,
"overrides_enabled": true,
"show": true,
"sizes": [
{
"name": "",
"x": "1000 mil",
"y": "1000 mil"
},
{
"name": "",
"x": "500 mil",
"y": "500 mil"
},
{
"name": "",
"x": "250 mil",
"y": "250 mil"
},
{
"name": "",
"x": "200 mil",
"y": "200 mil"
},
{
"name": "",
"x": "100 mil",
"y": "100 mil"
},
{
"name": "",
"x": "50 mil",
"y": "50 mil"
},
{
"name": "",
"x": "25 mil",
"y": "25 mil"
},
{
"name": "",
"x": "20 mil",
"y": "20 mil"
},
{
"name": "",
"x": "10 mil",
"y": "10 mil"
},
{
"name": "",
"x": "5 mil",
"y": "5 mil"
},
{
"name": "",
"x": "2 mil",
"y": "2 mil"
},
{
"name": "",
"x": "1 mil",
"y": "1 mil"
},
{
"name": "",
"x": "5.0 mm",
"y": "5.0 mm"
},
{
"name": "",
"x": "2.5 mm",
"y": "2.5 mm"
},
{
"name": "",
"x": "1.0 mm",
"y": "1.0 mm"
},
{
"name": "",
"x": "0.5 mm",
"y": "0.5 mm"
},
{
"name": "",
"x": "0.25 mm",
"y": "0.25 mm"
},
{
"name": "",
"x": "0.2 mm",
"y": "0.2 mm"
},
{
"name": "",
"x": "0.1 mm",
"y": "0.1 mm"
},
{
"name": "",
"x": "0.05 mm",
"y": "0.05 mm"
},
{
"name": "",
"x": "0.025 mm",
"y": "0.025 mm"
},
{
"name": "",
"x": "0.01 mm",
"y": "0.01 mm"
}
],
"snap": 0,
"style": 0,
"user_grid_x": "",
"user_grid_y": ""
},
"maximized": false,
"mru_path": "",
"perspective": "",
"pos_x": 0,
"pos_y": 0,
"size_x": 0,
"size_y": 0,
"zoom_factors": [
0.13,
0.22,
0.35,
0.6,
1.0,
1.5,
2.2,
3.5,
5.0,
8.0,
13.0,
20.0,
35.0,
50.0,
80.0,
130.0,
220.0,
300.0
]
}
}
+100
View File
@@ -0,0 +1,100 @@
{
"api": {
"enable_server": false,
"interpreter_path": "/home/seth/.pyenv/shims/python3"
},
"appearance": {
"grid_striping": false,
"hicontrast_dimming_factor": 0.800000011920929,
"icon_theme": 2,
"show_scrollbars": false,
"text_editor_zoom": 0,
"toolbar_icon_size": 24,
"use_custom_cursors": true,
"use_icons_in_menus": true,
"zoom_correction_factor": 1.0
},
"auto_backup": {
"enabled": true,
"limit_total_size": 104857600
},
"dialog": {
"controls": {}
},
"do_not_show_again": {
"data_collection_prompt": false,
"env_var_overwrite_warning": false,
"scaled_3d_models_warning": false,
"update_check_prompt": false,
"zone_fill_warning": false
},
"environment": {
"vars": null
},
"git": {
"authorEmail": "",
"authorName": "",
"enableGit": true,
"repositories": null,
"updatInterval": 5,
"useDefaultAuthor": true
},
"graphics": {
"antialiasing_mode": 2,
"canvas_type": 1
},
"input": {
"auto_pan": false,
"auto_pan_acceleration": 5,
"center_on_zoom": true,
"focus_follow_sch_pcb": false,
"horizontal_pan": false,
"hotkey_feedback": true,
"immediate_actions": true,
"motion_pan_modifier": 0,
"mouse_left": -1,
"mouse_middle": 2,
"mouse_right": 2,
"reverse_scroll_pan_h": false,
"reverse_scroll_zoom": false,
"scroll_modifier_pan_h": 308,
"scroll_modifier_pan_v": 306,
"scroll_modifier_zoom": 0,
"warp_mouse_on_move": true,
"zoom_acceleration": false,
"zoom_speed": 1,
"zoom_speed_auto": true
},
"meta": {
"version": 5
},
"package_manager": {
"sash_pos": 380
},
"session": {
"pinned_design_block_libs": [],
"pinned_fp_libs": [],
"pinned_symbol_libs": [],
"remember_open_files": false
},
"spacemouse": {
"pan_speed": 5,
"reverse_pan_x": false,
"reverse_pan_y": false,
"reverse_rotate": false,
"reverse_zoom": false,
"rotate_speed": 5
},
"system": {
"clear_3d_cache_interval": 30,
"file_explorer": "",
"file_history_size": 9,
"language": "Default",
"local_history_debounce": 5,
"local_history_enabled": true,
"pdf_viewer_name": "",
"text_editor": "",
"use_system_pdf_viewer": true,
"working_dir": "/home/seth/Develop/kicad/worktrees/header-optimization/qa/tests"
}
}
+680
View File
@@ -0,0 +1,680 @@
{
"DRC": {
"crossprobe": true,
"report_all_track_errors": false,
"scroll_on_crossprobe": true
},
"action_plugins": [],
"appearance": {
"color_theme": "_builtin_default",
"custom_toolbars": false
},
"aui": {
"appearance_expand_layer_display": false,
"appearance_expand_net_display": false,
"appearance_panel_tab": 0,
"design_blocks_panel_docked_width": -1,
"design_blocks_panel_float_height": -1,
"design_blocks_panel_float_width": -1,
"design_blocks_show": false,
"net_inspector_width": -1,
"properties_panel_width": -1,
"properties_splitter_proportion": 0.5,
"right_panel_width": -1,
"search_panel_dock_direction": 3,
"search_panel_height": -1,
"search_panel_width": -1,
"show_layer_manager": true,
"show_net_inspector": false,
"show_properties": false,
"show_search": false
},
"color_picker": {
"default_tab": 0
},
"cross_probing": {
"auto_highlight": true,
"center_on_items": true,
"flash_selection": false,
"on_selection": true,
"zoom_to_fit": true
},
"design_block_chooser": {
"height": -1,
"keep_annotations": false,
"lib_tree": {
"column_widths": null
},
"place_as_group": true,
"place_as_sheet": false,
"repeated_placement": false,
"sash_pos_h": -1,
"sash_pos_v": -1,
"sort_mode": 0,
"width": -1
},
"editing": {
"allow_free_pads": false,
"arc_edit_mode": 0,
"auto_fill_zones": false,
"ctrl_click_highlight": false,
"esc_clears_net_highlight": true,
"flip_left_right": false,
"magnetic_all_layers": false,
"magnetic_graphics": true,
"magnetic_pads": 1,
"magnetic_tracks": 1,
"pcb_angle_snap_mode": 0,
"polar_coords": false,
"rotation_angle": 900,
"show_courtyard_collisions": true,
"track_drag_action": 1
},
"export_d356": {
"doNotExportUnconnectedPads": false
},
"find_replace": {
"find_history": [],
"find_string": "",
"match_case": false,
"match_mode": 0,
"replace_history": [],
"replace_string": "",
"search_and_replace": false
},
"footprint_chooser": {
"filter_on_pin_count": false,
"height": -1,
"sash_h": -1,
"sash_v": -1,
"sort_mode": 0,
"use_fp_filters": false,
"width": -1
},
"footprint_viewer": {
"aui_state": null,
"autozoom": true,
"cursor": {
"always_show_cursor": true,
"cross_hair_mode": 0
},
"display": 0,
"fp_list_width": 300,
"grid": {
"axes_enabled": false,
"fast_grid_1": 15,
"fast_grid_2": 16,
"last_size": 15,
"line_width": 1.0,
"min_spacing": 10.0,
"override_connected": false,
"override_connected_idx": 16,
"override_graphics": false,
"override_graphics_idx": 15,
"override_text": false,
"override_text_idx": 18,
"override_vias": false,
"override_vias_idx": 18,
"override_wires": false,
"override_wires_idx": 19,
"overrides_enabled": true,
"show": true,
"sizes": [
{
"name": "",
"x": "1000 mil",
"y": "1000 mil"
},
{
"name": "",
"x": "500 mil",
"y": "500 mil"
},
{
"name": "",
"x": "250 mil",
"y": "250 mil"
},
{
"name": "",
"x": "200 mil",
"y": "200 mil"
},
{
"name": "",
"x": "100 mil",
"y": "100 mil"
},
{
"name": "",
"x": "50 mil",
"y": "50 mil"
},
{
"name": "",
"x": "25 mil",
"y": "25 mil"
},
{
"name": "",
"x": "20 mil",
"y": "20 mil"
},
{
"name": "",
"x": "10 mil",
"y": "10 mil"
},
{
"name": "",
"x": "5 mil",
"y": "5 mil"
},
{
"name": "",
"x": "2 mil",
"y": "2 mil"
},
{
"name": "",
"x": "1 mil",
"y": "1 mil"
},
{
"name": "",
"x": "5.0 mm",
"y": "5.0 mm"
},
{
"name": "",
"x": "2.5 mm",
"y": "2.5 mm"
},
{
"name": "",
"x": "1.0 mm",
"y": "1.0 mm"
},
{
"name": "",
"x": "0.5 mm",
"y": "0.5 mm"
},
{
"name": "",
"x": "0.25 mm",
"y": "0.25 mm"
},
{
"name": "",
"x": "0.2 mm",
"y": "0.2 mm"
},
{
"name": "",
"x": "0.1 mm",
"y": "0.1 mm"
},
{
"name": "",
"x": "0.05 mm",
"y": "0.05 mm"
},
{
"name": "",
"x": "0.025 mm",
"y": "0.025 mm"
},
{
"name": "",
"x": "0.01 mm",
"y": "0.01 mm"
}
],
"snap": 0,
"style": 0,
"user_grid_x": "",
"user_grid_y": ""
},
"lib_list_width": 200,
"maximized": false,
"mru_path": "",
"perspective": "",
"pos_x": 0,
"pos_y": 0,
"size_x": 0,
"size_y": 0,
"zoom": 1.0,
"zoom_factors": [
0.13,
0.22,
0.35,
0.6,
1.0,
1.5,
2.2,
3.5,
5.0,
8.0,
13.0,
20.0,
35.0,
50.0,
80.0,
130.0,
220.0,
300.0
]
},
"footprint_wizard": {
"aui_state": null,
"cursor": {
"always_show_cursor": true,
"cross_hair_mode": 0
},
"display": 0,
"grid": {
"axes_enabled": false,
"fast_grid_1": 15,
"fast_grid_2": 16,
"last_size": 15,
"line_width": 1.0,
"min_spacing": 10.0,
"override_connected": false,
"override_connected_idx": 16,
"override_graphics": false,
"override_graphics_idx": 15,
"override_text": false,
"override_text_idx": 18,
"override_vias": false,
"override_vias_idx": 18,
"override_wires": false,
"override_wires_idx": 19,
"overrides_enabled": true,
"show": true,
"sizes": [
{
"name": "",
"x": "1000 mil",
"y": "1000 mil"
},
{
"name": "",
"x": "500 mil",
"y": "500 mil"
},
{
"name": "",
"x": "250 mil",
"y": "250 mil"
},
{
"name": "",
"x": "200 mil",
"y": "200 mil"
},
{
"name": "",
"x": "100 mil",
"y": "100 mil"
},
{
"name": "",
"x": "50 mil",
"y": "50 mil"
},
{
"name": "",
"x": "25 mil",
"y": "25 mil"
},
{
"name": "",
"x": "20 mil",
"y": "20 mil"
},
{
"name": "",
"x": "10 mil",
"y": "10 mil"
},
{
"name": "",
"x": "5 mil",
"y": "5 mil"
},
{
"name": "",
"x": "2 mil",
"y": "2 mil"
},
{
"name": "",
"x": "1 mil",
"y": "1 mil"
},
{
"name": "",
"x": "5.0 mm",
"y": "5.0 mm"
},
{
"name": "",
"x": "2.5 mm",
"y": "2.5 mm"
},
{
"name": "",
"x": "1.0 mm",
"y": "1.0 mm"
},
{
"name": "",
"x": "0.5 mm",
"y": "0.5 mm"
},
{
"name": "",
"x": "0.25 mm",
"y": "0.25 mm"
},
{
"name": "",
"x": "0.2 mm",
"y": "0.2 mm"
},
{
"name": "",
"x": "0.1 mm",
"y": "0.1 mm"
},
{
"name": "",
"x": "0.05 mm",
"y": "0.05 mm"
},
{
"name": "",
"x": "0.025 mm",
"y": "0.025 mm"
},
{
"name": "",
"x": "0.01 mm",
"y": "0.01 mm"
}
],
"snap": 0,
"style": 0,
"user_grid_x": "",
"user_grid_y": ""
},
"maximized": false,
"mru_path": "",
"perspective": "",
"pos_x": 0,
"pos_y": 0,
"size_x": 0,
"size_y": 0,
"zoom_factors": [
0.13,
0.22,
0.35,
0.6,
1.0,
1.5,
2.2,
3.5,
5.0,
8.0,
13.0,
20.0,
35.0,
50.0,
80.0,
130.0,
220.0,
300.0
]
},
"graphics": {
"highlight_factor": 0.5,
"select_factor": 0.75
},
"lib_tree": {
"column_widths": null,
"columns": [],
"open_libs": []
},
"meta": {
"version": 5
},
"pcb_display": {
"force_show_fields_when_fp_selected": true,
"graphic_items_fill": true,
"graphics_fill": true,
"live_3d_refresh": false,
"max_links_shown": 3,
"net_names_mode": 3,
"origin_invert_x_axis": false,
"origin_invert_y_axis": false,
"origin_mode": 0,
"pad_clearance": true,
"pad_fill": true,
"pad_numbers": true,
"pad_use_via_color_for_normal_th_padstacks": false,
"ratsnest_curved": false,
"ratsnest_footprint": true,
"ratsnest_global": true,
"ratsnest_thickness": 0.5,
"show_page_borders": true,
"text_fill": true,
"track_clearance_mode": 2,
"track_fill": true,
"via_fill": true
},
"plugins": {
"actions": []
},
"printing": {
"as_item_checkboxes": false,
"background": false,
"color_theme": "",
"drill_marks": 1,
"edge_cuts_on_all_pages": true,
"layers": [],
"mirror": false,
"monochrome": true,
"pagination": 1,
"scale": 1.0,
"title_block": false,
"use_theme": false
},
"search_pane": {
"search_hidden_fields": true,
"search_metadata": false,
"selection_zoom": 1
},
"system": {
"file_history": [],
"first_run_shown": false,
"last_footprint3d_dir": "",
"last_footprint_lib_dir": "",
"last_imperial_units": 5,
"last_metric_units": 1,
"max_undo_items": 0,
"show_import_issues": true,
"units": 1
},
"window": {
"aui_state": null,
"cursor": {
"always_show_cursor": true,
"cross_hair_mode": 0
},
"display": 0,
"grid": {
"axes_enabled": false,
"fast_grid_1": 15,
"fast_grid_2": 16,
"last_size": 15,
"line_width": 1.0,
"min_spacing": 10.0,
"override_connected": false,
"override_connected_idx": 16,
"override_graphics": false,
"override_graphics_idx": 15,
"override_text": false,
"override_text_idx": 18,
"override_vias": false,
"override_vias_idx": 18,
"override_wires": false,
"override_wires_idx": 19,
"overrides_enabled": true,
"show": true,
"sizes": [
{
"name": "",
"x": "1000 mil",
"y": "1000 mil"
},
{
"name": "",
"x": "500 mil",
"y": "500 mil"
},
{
"name": "",
"x": "250 mil",
"y": "250 mil"
},
{
"name": "",
"x": "200 mil",
"y": "200 mil"
},
{
"name": "",
"x": "100 mil",
"y": "100 mil"
},
{
"name": "",
"x": "50 mil",
"y": "50 mil"
},
{
"name": "",
"x": "25 mil",
"y": "25 mil"
},
{
"name": "",
"x": "20 mil",
"y": "20 mil"
},
{
"name": "",
"x": "10 mil",
"y": "10 mil"
},
{
"name": "",
"x": "5 mil",
"y": "5 mil"
},
{
"name": "",
"x": "2 mil",
"y": "2 mil"
},
{
"name": "",
"x": "1 mil",
"y": "1 mil"
},
{
"name": "",
"x": "5.0 mm",
"y": "5.0 mm"
},
{
"name": "",
"x": "2.5 mm",
"y": "2.5 mm"
},
{
"name": "",
"x": "1.0 mm",
"y": "1.0 mm"
},
{
"name": "",
"x": "0.5 mm",
"y": "0.5 mm"
},
{
"name": "",
"x": "0.25 mm",
"y": "0.25 mm"
},
{
"name": "",
"x": "0.2 mm",
"y": "0.2 mm"
},
{
"name": "",
"x": "0.1 mm",
"y": "0.1 mm"
},
{
"name": "",
"x": "0.05 mm",
"y": "0.05 mm"
},
{
"name": "",
"x": "0.025 mm",
"y": "0.025 mm"
},
{
"name": "",
"x": "0.01 mm",
"y": "0.01 mm"
}
],
"snap": 0,
"style": 0,
"user_grid_x": "",
"user_grid_y": ""
},
"maximized": false,
"mru_path": "",
"perspective": "",
"pos_x": 0,
"pos_y": 0,
"size_x": 0,
"size_y": 0,
"zoom_factors": [
0.13,
0.22,
0.35,
0.6,
1.0,
1.5,
2.2,
3.5,
5.0,
8.0,
13.0,
20.0,
35.0,
50.0,
80.0,
130.0,
220.0,
300.0
]
}
}
+6
View File
@@ -0,0 +1,6 @@
(sym_lib_table
(version 7)
(lib (name "Device")(type "KiCad")(uri "${KICAD9_SYMBOL_DIR}/Device.kicad_sym")(options "")(descr "Generic symbols for common devices"))
(lib (name "power")(type "KiCad")(uri "${KICAD9_SYMBOL_DIR}/power.kicad_sym")(options "")(descr "Power symbols, special power flags"))
(lib (name "future")(type "Unknown")(uri "${KICAD_CONFIG_HOME}/../libraries/unknown.kicad_sym")(options "")(descr "An unknown type of library"))
)
+211
View File
@@ -0,0 +1,211 @@
{
"appearance": {
"color_theme": "_builtin_default",
"custom_toolbars": false
},
"aui": {
"properties_panel_width": -1,
"properties_splitter_proportion": 0.5,
"show_properties": true
},
"color_picker": {
"default_tab": 0
},
"cross_probing": {
"auto_highlight": true,
"center_on_items": true,
"flash_selection": false,
"on_selection": true,
"zoom_to_fit": true
},
"defaults": {
"line_width": 0,
"pin_length": 100,
"pin_name_size": 50,
"pin_num_size": 50,
"text_size": 50
},
"design_block_chooser": {
"height": -1,
"keep_annotations": false,
"lib_tree": {
"column_widths": null
},
"place_as_group": true,
"place_as_sheet": false,
"repeated_placement": false,
"sash_pos_h": -1,
"sash_pos_v": -1,
"sort_mode": 0,
"width": -1
},
"drag_pins_along_with_edges": true,
"find_replace": {
"find_history": [],
"find_string": "",
"match_case": false,
"match_mode": 0,
"replace_history": [],
"replace_string": "",
"search_and_replace": false
},
"graphics": {
"highlight_factor": 0.5,
"select_factor": 0.75
},
"lib_field_editor": {
"field_widths": {},
"sash_pos": 400,
"sidebar_collapsed": false
},
"lib_table_width": 250,
"lib_tree": {
"column_widths": null,
"columns": [],
"open_libs": []
},
"library": {
"sort_mode": 0
},
"meta": {
"version": 1
},
"pin_table": {
"crossprobe_on_selection": true
},
"plugins": {
"actions": []
},
"printing": {
"as_item_checkboxes": false,
"background": false,
"color_theme": "",
"drill_marks": 1,
"edge_cuts_on_all_pages": true,
"layers": [],
"mirror": false,
"monochrome": true,
"pagination": 1,
"scale": 1.0,
"title_block": false,
"use_theme": false
},
"repeat": {
"label_delta": 1,
"pin_step": 100
},
"search_pane": {
"search_hidden_fields": true,
"search_metadata": false,
"selection_zoom": 1
},
"selection_filter": {
"graphics": true,
"images": true,
"labels": true,
"lockedItems": false,
"otherItems": true,
"pins": true,
"symbols": true,
"text": true,
"wires": true
},
"show_hidden_lib_fields": true,
"show_hidden_lib_pins": true,
"show_pin_alt_icons": true,
"show_pin_electrical_type": true,
"system": {
"file_history": [],
"first_run_shown": false,
"last_imperial_units": 5,
"last_metric_units": 1,
"max_undo_items": 0,
"show_import_issues": true,
"units": 5
},
"use_eeschema_color_settings": true,
"window": {
"aui_state": null,
"cursor": {
"always_show_cursor": true,
"cross_hair_mode": 0
},
"display": 0,
"grid": {
"axes_enabled": false,
"fast_grid_1": 1,
"fast_grid_2": 2,
"last_size": 1,
"line_width": 1.0,
"min_spacing": 10.0,
"override_connected": true,
"override_connected_idx": 1,
"override_graphics": false,
"override_graphics_idx": 2,
"override_text": true,
"override_text_idx": 3,
"override_vias": false,
"override_vias_idx": 0,
"override_wires": true,
"override_wires_idx": 1,
"overrides_enabled": true,
"show": true,
"sizes": [
{
"name": "",
"x": "100 mil",
"y": "100 mil"
},
{
"name": "",
"x": "50 mil",
"y": "50 mil"
},
{
"name": "",
"x": "25 mil",
"y": "25 mil"
},
{
"name": "",
"x": "10 mil",
"y": "10 mil"
}
],
"snap": 0,
"style": 0,
"user_grid_x": "",
"user_grid_y": ""
},
"maximized": false,
"mru_path": "",
"perspective": "",
"pos_x": 0,
"pos_y": 0,
"size_x": 0,
"size_y": 0,
"zoom_factors": [
0.05,
0.07,
0.1,
0.15,
0.2,
0.3,
0.5,
0.7,
1.0,
1.5,
2.0,
3.0,
4.5,
6.5,
10.0,
15.0,
20.0,
30.0,
45.0,
65.0,
100.0
]
}
}