29#include <wx/mstream.h>
75using namespace PCB_KEYS_T;
100 THROW_IO_ERROR( wxString::Format(
_(
"Cannot create footprint library '%s'." ),
106 THROW_IO_ERROR( wxString::Format(
_(
"Footprint library '%s' is read only." ),
113 std::unique_ptr<FOOTPRINT>& footprint = fpCacheEntry->
GetFootprint();
115 if( aFootprintFilter && footprint.get() != aFootprintFilter )
120 if( footprint->GetAreFontsEmbedded() )
121 footprint->EmbedFonts();
123 footprint->GetEmbeddedFiles()->ClearEmbeddedFonts();
136 m_owner->SetOutputFormatter( &formatter );
137 m_owner->Format( footprint.get() );
148 if( !aFootprintFilter )
160 if( !dir.IsOpened() )
162 wxString msg = wxString::Format(
_(
"Footprint library '%s' not found." ),
174 if( dir.GetFirst( &fullName, fileSpec ) )
189 wxString fpName = fn.
GetName();
200 if( !cacheError.IsEmpty() )
201 cacheError += wxT(
"\n\n" );
203 cacheError += wxString::Format(
_(
"Warning in file '%s'" ) +
'\n',
205 cacheError += warning;
210 if( !cacheError.IsEmpty() )
211 cacheError += wxT(
"\n\n" );
213 cacheError += wxString::Format(
_(
"Unable to read file '%s'" ) +
'\n',
215 cacheError += ioe.
What();
217 }
while( dir.GetNext( &fullName ) );
221 if( !cacheError.IsEmpty() )
233 wxString msg = wxString::Format(
_(
"Library '%s' has no footprint '%s'." ),
240 wxString fullPath = it->second->GetFileName().GetFullPath();
242 wxRemoveFile( fullPath );
259 footprint.second->SetFilePath( aPath );
300 const std::map<std::string, UTF8>* aProperties )
307 _(
"Internal Group Data Error" ), wxICON_ERROR,
308 wxString::Format(
_(
"Please report this bug. Error validating group "
309 "structure: %s\n\nSave anyway?" ), sanityResult ),
310 _(
"Save Anyway" ) ) )
323 const std::map<std::string, UTF8>* aProperties )
331 if(
m_board->GetAreFontsEmbedded() )
334 m_board->GetEmbeddedFiles()->ClearEmbeddedFonts();
338 m_out->Print(
"(kicad_pcb (version %d) (generator \"pcbnew\") (generator_version %s)",
352 std::string input =
TO_UTF8( aClipboardSourceInput );
359 return parser.
Parse();
373 switch( aItem->
Type() )
408 format(
static_cast<const PAD*
>( aItem ) );
450 wxFAIL_MSG( wxT(
"Cannot format item " ) + aItem->
GetClass() );
482 m_out->Print(
"(layer %s %s)",
484 aIsKnockout ?
"knockout" :
"" );
491 m_out->Print(
"(pts" );
493 for(
int ii = 0; ii < outline.
PointCount(); ++ii )
499 m_out->Print(
"(xy %s)",
505 m_out->Print(
"(arc (start %s) (mid %s) (end %s))",
529 m_out->Print(
"(render_cache %s %s",
530 m_out->Quotew( resolvedText ).c_str(),
539 m_out->Print(
"(polygon" );
545 callback_gal.DrawGlyphs( *cache );
554 m_out->Print(
"(setup" );
564 m_out->Print(
"(pad_to_mask_clearance %s)",
569 m_out->Print(
"(solder_mask_min_width %s)",
575 m_out->Print(
"(pad_to_paste_clearance %s)",
581 m_out->Print(
"(pad_to_paste_clearance_ratio %s)",
588 m_out->Print( 0,
" (tenting " );
591 m_out->Print( 0,
")" );
593 m_out->Print( 0,
" (covering " );
596 m_out->Print( 0,
")" );
598 m_out->Print( 0,
" (plugging " );
601 m_out->Print( 0,
")" );
609 m_out->Print( 0,
" (zone_defaults" );
612 format( properties, 0, layer );
614 m_out->Print( 0,
")\n" );
621 m_out->Print(
"(aux_axis_origin %s %s)",
630 m_out->Print(
"(grid_origin %s %s)",
645 m_out->Print(
"(general" );
647 m_out->Print(
"(thickness %s)",
661 m_out->Print(
"(layers" );
667 m_out->Print(
"(%d %s %s %s)",
673 :
m_out->Quotew(
m_board->GetLayerName( layer ) ).c_str() );
682 bool print_type =
false;
696 m_out->Print(
"(%d %s %s %s)",
704 :
m_out->Quotew(
m_board->GetLayerName( layer ) ).c_str() );
713 for(
const std::pair<const wxString, wxString>& prop : aBoard->
GetProperties() )
715 m_out->Print(
"(property %s %s)",
716 m_out->Quotew( prop.first ).c_str(),
717 m_out->Quotew( prop.second ).c_str() );
726 if( variantNames.empty() )
729 m_out->Print(
"(variants" );
731 for(
const wxString& variantName : variantNames )
733 m_out->Print(
"(variant (name %s)",
m_out->Quotew( variantName ).c_str() );
737 if( !description.IsEmpty() )
738 m_out->Print(
"(description %s)",
m_out->Quotew( description ).c_str() );
783 m_out->Print(
"(teardrops (best_length_ratio %s) (max_length %s) (best_width_ratio %s) "
792 m_out->Print(
"(filter_ratio %s)",
804 std::set<BOARD_ITEM*, BOARD_ITEM::ptr_cmp> sorted_footprints( aBoard->
Footprints().begin(),
806 std::set<BOARD_ITEM*, BOARD::cmp_drawings> sorted_drawings( aBoard->
Drawings().begin(),
808 std::set<PCB_TRACK*, PCB_TRACK::cmp_tracks> sorted_tracks( aBoard->
Tracks().begin(),
810 std::set<PCB_POINT*, PCB_POINT::cmp_points> sorted_points( aBoard->
Points().begin(),
812 std::set<BOARD_ITEM*, BOARD_ITEM::ptr_cmp> sorted_zones( aBoard->
Zones().begin(),
813 aBoard->
Zones().end() );
814 std::set<BOARD_ITEM*, BOARD_ITEM::ptr_cmp> sorted_groups( aBoard->
Groups().begin(),
816 std::set<BOARD_ITEM*, BOARD_ITEM::ptr_cmp> sorted_generators( aBoard->
Generators().begin(),
821 for(
BOARD_ITEM* footprint : sorted_footprints )
839 for(
auto zone : sorted_zones )
853 std::vector<NETINFO_ITEM*> nets;
854 PAD* pads[2] = {
nullptr,
nullptr };
858 auto cmp = [](
const wxString& a,
const wxString& b )
863 std::map<wxString, CHAIN_INFO,
decltype( cmp )> chains( cmp );
870 if( net->GetNetChain().IsEmpty() && !net->GetTerminalPad( 0 ) && !net->GetTerminalPad( 1 ) )
873 wxString chainName = net->GetNetChain();
875 if( chainName.IsEmpty() && ( net->GetTerminalPad( 0 ) || net->GetTerminalPad( 1 ) ) )
876 chainName = net->GetNetname();
878 CHAIN_INFO&
info = chains[chainName];
879 info.nets.push_back( net );
880 for(
int i = 0; i < 2; ++i )
882 if( net->GetTerminalPad( i ) && !
info.pads[i] )
883 info.pads[i] = net->GetTerminalPad( i );
888 for(
const auto&
kv : chains )
890 const CHAIN_INFO& si =
kv.second;
891 const wxString& chainName =
kv.first;
893 if( si.nets.size() > 1 || si.pads[0] || si.pads[1] || !chainName.IsEmpty() )
899 m_out->Print(
"(net_chains" );
900 for(
const auto&
kv : chains )
902 const wxString&
name =
kv.first;
903 const CHAIN_INFO& si =
kv.second;
905 if( si.nets.size() == 1 && !si.pads[0] && !si.pads[1] &&
name.IsEmpty() )
908 m_out->Print(
" (net_chain (name %s)",
m_out->Quotew(
name ).c_str() );
909 m_out->Print(
" (members" );
916 for(
int i = 0; i < 2; ++i )
919 m_out->Print(
" (terminal_pad %s)",
920 m_out->Quotew( si.pads[i]->m_Uuid.AsString() ).c_str() );
934 files_to_write.
AddFile( file.second );
941 files_to_write.
AddFile( file.second );
944 m_out->Print(
"(embedded_fonts %s)",
947 if( !files_to_write.
IsEmpty() )
963 m_out->Print(
"(dimension" );
967 m_out->Print(
"(type orthogonal)" );
969 m_out->Print(
"(type aligned)" );
971 m_out->Print(
"(type leader)" );
973 m_out->Print(
"(type center)" );
975 m_out->Print(
"(type radial)" );
977 wxFAIL_MSG( wxT(
"Cannot format unknown dimension type!" ) );
986 m_out->Print(
"(pts (xy %s %s) (xy %s %s))",
997 m_out->Print(
"(leader_length %s)",
1002 m_out->Print(
"(orientation %d)",
static_cast<int>(
ortho->GetOrientation() ) );
1006 m_out->Print(
"(format (prefix %s) (suffix %s) (units %d) (units_format %d) (precision %d)",
1015 m_out->Print(
"(override_value %s)",
1022 m_out->Print(
")" );
1025 m_out->Print(
"(style (thickness %s) (arrow_length %s) (text_position_mode %d)",
1030 if(
ortho || aligned )
1035 m_out->Print(
"(arrow_direction outward)" );
1038 m_out->Print(
"(arrow_direction inward)" );
1046 m_out->Print(
"(extension_height %s)",
1053 m_out->Print(
"(extension_offset %s)",
1059 m_out->Print(
")" );
1066 m_out->Print(
")" );
1073 std::string prefix = parentFP ?
"fp" :
"gr";
1078 m_out->Print(
"(%s_line (start %s) (end %s)",
1085 m_out->Print(
"(%s_rect (start %s) (end %s)",
1095 m_out->Print(
"(%s_circle (center %s) (end %s)",
1102 m_out->Print(
"(%s_arc (start %s) (mid %s) (end %s)",
1115 m_out->Print(
"(%s_poly", prefix.c_str() );
1126 m_out->Print(
"(%s_curve (pts (xy %s) (xy %s) (xy %s) (xy %s))",
1135 m_out->Print(
"(%s_ellipse (center %s) (major_radius %s) (minor_radius %s) "
1136 "(rotation_angle %s)",
1144 m_out->Print(
"(%s_ellipse_arc (center %s) (major_radius %s) (minor_radius %s) "
1145 "(rotation_angle %s) (start_angle %s) (end_angle %s)",
1168 m_out->Print(
"(fill hatch)" );
1172 m_out->Print(
"(fill reverse_hatch)" );
1176 m_out->Print(
"(fill cross_hatch)" );
1201 m_out->Print(
"(solder_mask_margin %s)",
1209 m_out->Print(
")" );
1215 wxCHECK_RET( aBitmap !=
nullptr &&
m_out !=
nullptr,
"" );
1221 wxCHECK_RET(
image !=
nullptr,
"wxImage* is NULL" );
1223 m_out->Print(
"(image (at %s %s)",
1235 wxMemoryOutputStream ostream;
1241 m_out->Print(
")" );
1247 m_out->Print(
"(point (at %s) (size %s)",
1255 m_out->Print(
")" );
1261 m_out->Print(
"(target %s (at %s) (size %s)",
1262 ( aTarget->
GetShape() ) ?
"x" :
"plus",
1271 m_out->Print(
")" );
1281 if( initial_comments )
1283 for(
unsigned i = 0; i < initial_comments->GetCount(); ++i )
1284 m_out->Print(
"%s\n",
TO_UTF8( (*initial_comments)[i] ) );
1290 m_out->Print(
"(footprint %s",
1295 m_out->Print(
"(footprint %s",
1301 m_out->Print(
"(version %d) (generator \"pcbnew\") (generator_version %s)",
1319 m_out->Print(
"(at %s %s)",
1337 m_out->Print(
"(property %s %s",
1338 m_out->Quotew( field->GetCanonicalName() ).c_str(),
1339 m_out->Quotew( field->GetText() ).c_str() );
1343 m_out->Print(
")" );
1348 if( !compClass->IsEmpty() )
1350 m_out->Print(
"(component_classes" );
1353 m_out->Print(
"(class %s)",
m_out->Quotew( constituent->GetName() ).c_str() );
1355 m_out->Print(
")" );
1361 m_out->Print(
"(property ki_fp_filters %s)",
1377 m_out->Print(
"(units" );
1381 m_out->Print(
"(unit (name %s)",
m_out->Quotew( u.m_unitName ).c_str() );
1382 m_out->Print(
"(pins" );
1384 for(
const wxString& n : u.m_pins )
1385 m_out->Print(
" %s",
m_out->Quotew( n ).c_str() );
1387 m_out->Print(
")" );
1388 m_out->Print(
")" );
1391 m_out->Print(
")" );
1396 m_out->Print(
"(solder_mask_margin %s)",
1402 m_out->Print(
"(solder_paste_margin %s)",
1408 m_out->Print(
"(solder_paste_margin_ratio %s)",
1414 m_out->Print(
"(clearance %s)",
1420 m_out->Print(
"(zone_connect %d)",
1429 m_out->Print(
"(attr" );
1432 m_out->Print(
" smd" );
1435 m_out->Print(
" through_hole" );
1438 m_out->Print(
" board_only" );
1441 m_out->Print(
" exclude_from_pos_files" );
1444 m_out->Print(
" exclude_from_bom" );
1447 m_out->Print(
" allow_missing_courtyard" );
1450 m_out->Print(
" dnp" );
1453 m_out->Print(
" allow_soldermask_bridges" );
1455 m_out->Print(
")" );
1461 m_out->Print(
"(stackup" );
1466 wxString canonicalName(
LSET::Name( layer ) );
1467 m_out->Print(
"(layer %s)",
m_out->Quotew( canonicalName ).c_str() );
1470 m_out->Print(
")" );
1475 m_out->Print(
"(private_layers" );
1479 wxString canonicalName(
LSET::Name( layer ) );
1480 m_out->Print(
" %s",
m_out->Quotew( canonicalName ).c_str() );
1483 m_out->Print(
")" );
1488 m_out->Print(
"(net_tie_pad_groups" );
1493 m_out->Print(
")" );
1499 const std::vector<std::set<wxString>>& jumperGroups = aFootprint->
JumperPadGroups();
1501 if( !jumperGroups.empty() )
1503 m_out->Print(
"(jumper_pad_groups" );
1505 for(
const std::set<wxString>&
group : jumperGroups )
1507 m_out->Print(
"(" );
1509 for(
const wxString& padName :
group )
1510 m_out->Print(
"%s ",
m_out->Quotew( padName ).c_str() );
1512 m_out->Print(
")" );
1515 m_out->Print(
")" );
1521 std::set<PAD*, FOOTPRINT::cmp_pads> sorted_pads( aFootprint->
Pads().begin(),
1522 aFootprint->
Pads().end() );
1523 std::set<BOARD_ITEM*, FOOTPRINT::cmp_drawings> sorted_drawings(
1526 std::set<PCB_POINT*, PCB_POINT::cmp_points> sorted_points(
1527 aFootprint->
Points().begin(),
1528 aFootprint->
Points().end() );
1529 std::set<ZONE*, FOOTPRINT::cmp_zones> sorted_zones( aFootprint->
Zones().begin(),
1530 aFootprint->
Zones().end() );
1531 std::set<BOARD_ITEM*, PCB_GROUP::ptr_cmp> sorted_groups( aFootprint->
Groups().begin(),
1532 aFootprint->
Groups().end() );
1543 for(
PAD*
pad : sorted_pads )
1555 const bool baseDnp = aFootprint->
IsDNP();
1559 for(
const auto& [variantName, variant] : aFootprint->
GetVariants() )
1561 m_out->Print(
"(variant (name %s)",
m_out->Quotew( variantName ).c_str() );
1563 if( variant.GetDNP() != baseDnp )
1566 if( variant.GetExcludedFromBOM() != baseExcludedFromBOM )
1569 if( variant.GetExcludedFromPosFiles() != baseExcludedFromPosFiles )
1572 variant.GetExcludedFromPosFiles() );
1575 for(
const auto& [fieldName, fieldValue] : variant.GetFields() )
1578 const wxString baseValue = baseField ? baseField->
GetText() : wxString();
1580 if( fieldValue == baseValue )
1583 m_out->Print(
"(field (name %s) (value %s))",
1584 m_out->Quotew( fieldName ).c_str(),
1585 m_out->Quotew( fieldValue ).c_str() );
1588 m_out->Print(
")" );
1600 m_out->Print(
"(model" );
1601 m_out->Print(
"(type extruded)" );
1607 m_out->Print(
"(layer pad_bbox)" );
1611 m_out->Print(
"(layer auto)" );
1614 static const char* matNames[] = {
"plastic",
"matte",
"metal",
"copper" };
1615 m_out->Print(
"(material %s)", matNames[
static_cast<int>( body->m_material )] );
1626 m_out->Print(
"(color unspecified)" );
1638 m_out->Print(
")" );
1642 auto bs3D = aFootprint->
Models().begin();
1643 auto es3D = aFootprint->
Models().end();
1645 while( bs3D != es3D )
1647 if( !bs3D->m_Filename.IsEmpty() )
1649 m_out->Print(
"(model %s",
m_out->Quotew( bs3D->m_Filename ).c_str() );
1654 if( bs3D->m_Opacity != 1.0 )
1655 m_out->Print(
"%s", fmt::format(
"(opacity {:.4f})", bs3D->m_Opacity).c_str() );
1657 m_out->Print(
"(offset (xyz %s %s %s))",
1662 m_out->Print(
"(scale (xyz %s %s %s))",
1667 m_out->Print(
"(rotate (xyz %s %s %s))",
1672 m_out->Print(
")" );
1678 m_out->Print(
")" );
1697 if( !aEnumerateLayers )
1700 if( ( aLayerMask & cu_board_mask ) == cu_board_mask )
1707 aLayerMask &= ~cu_all;
1709 else if( ( aLayerMask & cu_board_mask ) == fr_bk )
1716 aLayerMask &= ~fr_bk;
1719 if( ( aLayerMask & adhes ) == adhes )
1722 aLayerMask &= ~adhes;
1731 if( ( aLayerMask & silks ) == silks )
1734 aLayerMask &= ~silks;
1737 if( ( aLayerMask & mask ) == mask )
1740 aLayerMask &= ~mask;
1743 if( ( aLayerMask & crt_yd ) == crt_yd )
1746 aLayerMask &= ~crt_yd;
1749 if( ( aLayerMask & fab ) == fab )
1759 if( aLayerMask[layer] )
1800 THROW_IO_ERROR( wxString::Format( wxT(
"unknown pad attribute: %d" ),
1804 const char*
property =
nullptr;
1819 THROW_IO_ERROR( wxString::Format( wxT(
"unknown pad property: %d" ),
1823 m_out->Print(
"(pad %s %s %s",
1828 m_out->Print(
"(at %s %s)",
1839 m_out->Print(
"(rect_delta %s)",
1845 bool forceShapeOffsetOutput =
false;
1850 if( aPad->
GetOffset( layer ) != shapeoffset )
1851 forceShapeOffsetOutput =
true;
1854 if( drill.
x > 0 || drill.
y > 0 || shapeoffset.
x != 0 || shapeoffset.
y != 0 || forceShapeOffsetOutput )
1856 m_out->Print(
"(drill" );
1859 m_out->Print(
" oval" );
1864 if( drill.
y > 0 && drill.
x != drill.
y )
1871 if( shapeoffset.
x != 0 || shapeoffset.
y != 0 || forceShapeOffsetOutput )
1874 m_out->Print(
")" );
1879 m_out->Print(
"(backdrill (size %s) (layers %s %s))",
1887 m_out->Print(
"(tertiary_drill (size %s) (layers %s %s))",
1893 auto formatPostMachining =
1899 m_out->Print(
"(%s %s",
1904 if( aProps.size > 0 )
1907 if( aProps.depth > 0 )
1910 if( aProps.angle > 0 )
1913 m_out->Print(
")" );
1921 m_out->Print(
"(property %s)", property );
1935 m_out->Print(
"(zone_layer_connections" );
1943 m_out->Print(
")" );
1948 auto formatCornerProperties =
1955 m_out->Print(
"(roundrect_rratio %s)",
1962 m_out->Print(
"(chamfer_ratio %s)",
1965 m_out->Print(
"(chamfer" );
1968 m_out->Print(
" top_left" );
1971 m_out->Print(
" top_right" );
1974 m_out->Print(
" bottom_left" );
1977 m_out->Print(
" bottom_right" );
1979 m_out->Print(
")" );
2005 m_out->Print(
"(die_length %s)",
2011 m_out->Print(
"(die_delay %s)",
2017 m_out->Print(
"(solder_mask_margin %s)",
2023 m_out->Print(
"(solder_paste_margin %s)",
2029 m_out->Print(
"(solder_paste_margin_ratio %s)",
2035 m_out->Print(
"(clearance %s)",
2041 m_out->Print(
"(zone_connect %d)",
2047 m_out->Print(
"(thermal_bridge_width %s)",
2057 defaultThermalSpokeAngle =
ANGLE_45;
2062 m_out->Print(
"(thermal_bridge_angle %s)",
2068 m_out->Print(
"(thermal_gap %s)",
2083 auto formatPrimitives =
2086 m_out->Print(
"(primitives" );
2089 for(
const std::shared_ptr<PCB_SHAPE>& primitive : aPad->
GetPrimitives( aLayer ) )
2091 switch( primitive->GetShape() )
2094 if( primitive->IsProxyItem() )
2096 m_out->Print(
"(gr_vector (start %s) (end %s)",
2102 m_out->Print(
"(gr_line (start %s) (end %s)",
2109 if( primitive->IsProxyItem() )
2111 m_out->Print(
"(gr_bbox (start %s) (end %s)",
2117 m_out->Print(
"(gr_rect (start %s) (end %s)",
2121 if( primitive->GetCornerRadius() > 0 )
2123 m_out->Print(
" (radius %s)",
2130 m_out->Print(
"(gr_arc (start %s) (mid %s) (end %s)",
2137 m_out->Print(
"(gr_circle (center %s) (end %s)",
2143 m_out->Print(
"(gr_curve (pts (xy %s) (xy %s) (xy %s) (xy %s))",
2151 if( primitive->IsPolyShapeValid() )
2156 m_out->Print(
"(gr_poly" );
2165 if( !primitive->IsProxyItem() )
2177 m_out->Print(
")" );
2180 m_out->Print(
")" );
2185 m_out->Print(
"(options" );
2188 m_out->Print(
"(clearance convexhull)" );
2190 m_out->Print(
"(clearance outline)" );
2207 m_out->Print( 0,
" (tenting " );
2212 m_out->Print( 0,
")" );
2218 auto formatPadLayer =
2223 m_out->Print(
"(shape %s)", shapeName( aLayer ) );
2231 shapeoffset = aPad->
GetOffset( aLayer );
2233 if( shapeoffset.
x != 0 || shapeoffset.
y != 0 )
2236 formatCornerProperties( aLayer );
2240 m_out->Print(
"(options" );
2243 m_out->Print(
"(anchor %s)", anchorShape( aLayer ) );
2245 m_out->Print(
")" );
2248 formatPrimitives( aLayer );
2262 if( layerSpokeAngle != defaultLayerAngle )
2264 m_out->Print(
"(thermal_bridge_angle %s)",
2268 if( padstack.
ThermalGap( aLayer ).has_value() )
2270 m_out->Print(
"(thermal_gap %s)",
2276 m_out->Print(
"(thermal_bridge_width %s)",
2280 if( padstack.
Clearance( aLayer ).has_value() )
2282 m_out->Print(
"(clearance %s)",
2288 m_out->Print(
"(zone_connect %d)",
2298 m_out->Print(
"(padstack (mode front_inner_back)" );
2300 m_out->Print(
"(layer \"Inner\"" );
2302 m_out->Print(
")" );
2303 m_out->Print(
"(layer \"B.Cu\"" );
2304 formatPadLayer(
B_Cu );
2305 m_out->Print(
")" );
2309 m_out->Print(
"(padstack (mode custom)" );
2319 formatPadLayer( layer );
2320 m_out->Print(
")" );
2324 m_out->Print(
")" );
2327 m_out->Print(
")" );
2333 wxCHECK_RET( aBarcode !=
nullptr &&
m_out !=
nullptr,
"" );
2335 m_out->Print(
"(barcode" );
2340 m_out->Print(
"(at %s %s)",
2346 m_out->Print(
"(size %s %s)",
2354 const char* typeStr =
"code39";
2365 m_out->Print(
"(type %s)", typeStr );
2370 const char* eccStr =
"L";
2379 m_out->Print(
"(ecc_level %s)", eccStr );
2393 m_out->Print(
")" );
2424 m_out->Print(
"(%s_text %s %s",
2433 m_out->Print(
"(at %s %s)",
2451 aText->EDA_TEXT::Format(
m_out, ctl_flags );
2457 m_out->Print(
")" );
2465 m_out->Print(
"(%s %s",
2467 : parentFP ?
"fp_text_box"
2476 m_out->Print(
"(start %s) (end %s)",
2492 m_out->Print(
"(margins %s %s %s %s)",
2499 m_out->Print(
"(span %d %d)", cell->GetColSpan(), cell->GetRowSpan() );
2516 aTextBox->EDA_TEXT::Format(
m_out, 0 );
2529 m_out->Print(
")" );
2535 wxCHECK_RET( aTable !=
nullptr &&
m_out !=
nullptr,
"" );
2546 m_out->Print(
"(border" );
2553 m_out->Print(
")" );
2555 m_out->Print(
"(separators" );
2562 m_out->Print(
")" );
2564 m_out->Print(
"(column_widths" );
2566 for(
int col = 0; col < aTable->
GetColCount(); ++col )
2569 m_out->Print(
")" );
2571 m_out->Print(
"(row_heights" );
2573 for(
int row = 0; row < aTable->
GetRowCount(); ++row )
2576 m_out->Print(
")" );
2578 m_out->Print(
"(cells" );
2583 m_out->Print(
")" );
2584 m_out->Print(
")" );
2590 wxArrayString memberIds;
2597 bool validateAgainstBoard =
false;
2598 std::unordered_set<const EDA_ITEM*> validPtrs;
2602 const auto& cache =
m_board->GetItemByIdCache();
2604 for(
const auto& [uuid, item] : cache )
2605 validPtrs.insert( item );
2607 validateAgainstBoard = validPtrs.count( aGroup ) > 0;
2610 if( validateAgainstBoard )
2614 if( validPtrs.count( member ) )
2615 memberIds.Add( member->m_Uuid.AsString() );
2621 memberIds.Add( member->m_Uuid.AsString() );
2624 if( memberIds.empty() )
2639 m_out->Print(
"(members" );
2641 for(
const wxString& memberId : memberIds )
2642 m_out->Print(
" %s",
m_out->Quotew( memberId ).c_str() );
2644 m_out->Print(
")" );
2645 m_out->Print(
")" );
2653 && aGenerator->
GetItems().empty() )
2658 m_out->Print(
"(generated" );
2662 m_out->Print(
"(type %s) (name %s) (layer %s)",
2670 for(
const auto& [key, value] : aGenerator->
GetProperties() )
2672 if( value.CheckType<
double>() || value.CheckType<
int>() || value.CheckType<
long>()
2673 || value.CheckType<
long long>() )
2677 if( !value.GetAs( &val ) )
2680 std::string buf = fmt::format(
"{:.10g}", val );
2683 m_out->Print(
"(%s %s)", key.c_str(), buf.c_str() );
2685 else if( value.CheckType<
bool>() )
2688 value.GetAs( &val );
2692 else if( value.CheckType<
VECTOR2I>() )
2695 value.GetAs( &val );
2697 m_out->Print(
"(%s (xy %s))",
2704 value.GetAs( &val );
2706 m_out->Print(
"(%s ", key.c_str() );
2708 m_out->Print(
")" );
2714 if( value.CheckType<wxString>() )
2716 value.GetAs( &val );
2718 else if( value.CheckType<std::string>() )
2721 value.GetAs( &str );
2723 val = wxString::FromUTF8( str );
2726 m_out->Print(
"(%s %s)", key.c_str(),
m_out->Quotew( val ).c_str() );
2730 wxArrayString memberIds;
2733 memberIds.Add( member->m_Uuid.AsString() );
2737 m_out->Print(
"(members" );
2739 for(
const wxString& memberId : memberIds )
2740 m_out->Print(
" %s",
m_out->Quotew( memberId ).c_str() );
2742 m_out->Print(
")" );
2743 m_out->Print(
")" );
2754 const BOARD* board =
via->GetBoard();
2756 wxCHECK_RET( board !=
nullptr, wxT(
"Via has no parent." ) );
2758 m_out->Print(
"(via" );
2760 via->LayerPair( &layer1, &layer2 );
2762 switch(
via->GetViaType() )
2768 m_out->Print(
" blind " );
2772 m_out->Print(
" buried " );
2776 m_out->Print(
" micro " );
2783 m_out->Print(
"(at %s) (size %s)",
2797 if(
via->Padstack().SecondaryDrill().size.x > 0 )
2799 m_out->Print(
"(backdrill (size %s) (layers %s %s))",
2805 if(
via->Padstack().TertiaryDrill().size.x > 0 )
2807 m_out->Print(
"(tertiary_drill (size %s) (layers %s %s))",
2818 m_out->Print(
"(%s %s", aName,
2821 if( aProps.size > 0 )
2824 if( aProps.depth > 0 )
2827 if( aProps.angle > 0 )
2830 m_out->Print(
")" );
2833 formatPostMachining(
"front_post_machining",
via->Padstack().FrontPostMachining() );
2834 formatPostMachining(
"back_post_machining",
via->Padstack().BackPostMachining() );
2836 m_out->Print(
"(layers %s %s)",
2840 switch(
via->Padstack().UnconnectedLayerMode() )
2860 if(
via->IsLocked() )
2863 if(
via->GetIsFree() )
2866 if(
via->GetRemoveUnconnected() )
2868 m_out->Print(
"(zone_layer_connections" );
2876 m_out->Print(
")" );
2884 m_out->Print( 0,
" (tenting " );
2889 m_out->Print( 0,
")" );
2898 m_out->Print( 0,
" (covering " );
2903 m_out->Print( 0,
")" );
2909 m_out->Print( 0,
" (plugging " );
2914 m_out->Print( 0,
")" );
2922 m_out->Print(
"(padstack" );
2926 m_out->Print(
"(mode front_inner_back)" );
2928 m_out->Print(
"(layer \"Inner\"" );
2929 m_out->Print(
"(size %s)",
2931 m_out->Print(
")" );
2932 m_out->Print(
"(layer \"B.Cu\"" );
2933 m_out->Print(
"(size %s)",
2935 m_out->Print(
")" );
2939 m_out->Print(
"(mode custom)" );
2947 m_out->Print(
"(size %s)",
2949 m_out->Print(
")" );
2953 m_out->Print(
")" );
2965 m_out->Print(
"(arc (start %s) (mid %s) (end %s) (width %s)",
2973 m_out->Print(
"(segment (start %s) (end %s) (width %s)",
2991 m_out->Print(
"(solder_mask_margin %s)",
3000 m_out->Print(
")" );
3006 m_out->Print(
"(zone" );
3024 if( layers.count() > 1 )
3046 m_out->Print(
"(hatch %s %s)", hatch.c_str(),
3057 m_out->Print(
"(attr (teardrop (type %s)))",
3062 m_out->Print(
"(connect_pads" );
3071 m_out->Print(
" thru_hole_only" );
3075 m_out->Print(
" yes" );
3079 m_out->Print(
" no" );
3083 m_out->Print(
"(clearance %s)",
3086 m_out->Print(
")" );
3088 m_out->Print(
"(min_thickness %s)",
3094 m_out->Print(
"(keepout (tracks %s) (vias %s) (pads %s) (copperpour %s) (footprints %s))",
3102 m_out->Print(
"(placement" );
3121 m_out->Print(
")" );
3124 m_out->Print(
"(fill" );
3128 m_out->Print(
" yes" );
3132 m_out->Print(
"(mode hatch)" );
3134 m_out->Print(
"(mode thieving)" );
3138 m_out->Print(
"(thermal_gap %s) (thermal_bridge_width %s)",
3148 m_out->Print(
"(smoothing chamfer)" );
3152 m_out->Print(
"(smoothing fillet)" );
3156 THROW_IO_ERROR( wxString::Format(
_(
"unknown zone corner smoothing type %d" ),
3164 m_out->Print(
"(island_removal_mode %d)",
3169 m_out->Print(
"(island_area_min %s)",
3175 m_out->Print(
"(hatch_thickness %s) (hatch_gap %s) (hatch_orientation %s)",
3182 m_out->Print(
"(hatch_smoothing_level %d) (hatch_smoothing_value %s)",
3187 m_out->Print(
"(hatch_border_algorithm %s) (hatch_min_hole_area %s)",
3194 const char* patternStr =
"dots";
3201 default: patternStr =
"dots";
break;
3204 m_out->Print(
"(thieving (type %s) (size %s) (gap %s) (width %s) "
3205 "(stagger %s) (orientation %s))",
3210 thieving.
stagger ?
"yes" :
"no",
3214 m_out->Print(
")" );
3218 format( properties, 0, layer );
3227 if(
chain.PointCount() == 0 )
3230 m_out->Print(
"(polygon" );
3232 m_out->Print(
")" );
3241 for(
int ii = 0; ii < fv->OutlineCount(); ++ii )
3243 m_out->Print(
"(filled_polygon" );
3252 m_out->Print(
")" );
3256 m_out->Print(
")" );
3267 m_out->Print( aNestLevel,
"(property\n" );
3272 m_out->Print( aNestLevel,
"(hatch_position (xy %s))",
3276 m_out->Print( aNestLevel,
")\n" );
3282 m_ctl( aControlFlags )
3296 const std::map<std::string, UTF8>* aProperties,
3301 unsigned lineCount = 0;
3330 const std::map<std::string, UTF8>* aProperties,
3333 init( aProperties );
3335 bool preserveDestinationStackup =
3339 preserveDestinationStackup );
3344 board =
dynamic_cast<BOARD*
>( parser.
Parse() );
3363 parser.CurLine(), parser.CurLineNumber(), parser.CurOffset() );
3398 const wxString& aLibPath,
bool aBestEfforts,
3399 const std::map<std::string, UTF8>* aProperties )
3401 wxDir dir( aLibPath );
3404 init( aProperties );
3412 errorMsg = ioe.
What();
3418 for(
const auto& footprint :
m_cache->GetFootprints() )
3419 aFootprintNames.Add( footprint.first );
3421 if( !errorMsg.IsEmpty() && !aBestEfforts )
3427 const wxString& aFootprintName,
3428 const std::map<std::string, UTF8>* aProperties,
3429 bool checkModified )
3431 init( aProperties );
3442 auto it =
m_cache->GetFootprints().find( aFootprintName );
3444 if( it ==
m_cache->GetFootprints().end() )
3447 return it->second->GetFootprint().get();
3452 const wxString& aFootprintName,
3453 const std::map<std::string, UTF8>* aProperties )
3455 return getFootprint( aLibraryPath, aFootprintName, aProperties,
false );
3460 const wxString& aFootprintName,
3461 const std::map<std::string, UTF8>* aProperties )
3472 return footprintFile.Exists();
3477 wxString& aFootprintNameOut,
3478 const std::map<std::string, UTF8>* aProperties )
3481 wxFFile f( aFootprintPath );
3489 f.ReadAll( &fcontents );
3491 aFootprintNameOut = wxFileName( aFootprintPath ).GetName();
3498 const wxString& aFootprintName,
3500 const std::map<std::string, UTF8>* aProperties )
3516 copy->SetParent(
nullptr );
3525 const std::map<std::string, UTF8>* aProperties )
3527 init( aProperties );
3535 wxString libPath = aLibraryPath;
3536 wxString singleFileBaseName;
3537 bool saveSingleFile =
false;
3540 wxFileName asFile( aLibraryPath );
3544 saveSingleFile =
true;
3545 libPath = asFile.GetPath();
3546 singleFileBaseName = asFile.GetName();
3550 validateCache( libPath, !aProperties || !aProperties->contains(
"skip_cache_validation" ) );
3556 const wxString msg = wxString::Format(
_(
"Library '%s' does not exist.\n"
3557 "Would you like to create it?"),
3560 if( !
Pgm().IsGUI() || wxMessageBox( msg,
_(
"Library Not Found" ), wxYES_NO | wxICON_QUESTION ) != wxYES )
3568 wxString msg = wxString::Format(
_(
"Library '%s' is read only." ), libPath );
3574 wxString footprintName = saveSingleFile ? singleFileBaseName
3577 wxString fpName = saveSingleFile ? singleFileBaseName
3589 THROW_IO_ERROR( wxString::Format(
_(
"Footprint file name '%s' is not valid." ), fn.GetFullPath() ) );
3592 if( fn.FileExists() && !fn.IsFileWritable() )
3594 THROW_IO_ERROR( wxString::Format(
_(
"Insufficient permissions to delete '%s'." ),
3595 fn.GetFullPath() ) );
3598 wxString fullPath = fn.GetFullPath();
3599 wxString fullName = fn.GetFullName();
3600 auto it =
m_cache->GetFootprints().find( footprintName );
3602 if( it !=
m_cache->GetFootprints().end() )
3606 m_cache->GetFootprints().erase( footprintName );
3634 wxLogTrace(
traceKicadPcbPlugin, wxT(
"Creating s-expr footprint file '%s'." ), fullPath );
3635 m_cache->GetFootprints().insert( footprintName,
3643 const wxString& aFootprintName,
3644 const std::map<std::string, UTF8>* aProperties )
3646 init( aProperties );
3653 aLibraryPath.GetData() ) );
3656 m_cache->Remove( aFootprintName );
3677 const std::map<std::string, UTF8>* aProperties )
3679 if( wxDir::Exists( aLibraryPath ) )
3681 THROW_IO_ERROR( wxString::Format(
_(
"Cannot overwrite library path '%s'." ),
3682 aLibraryPath.GetData() ) );
3685 init( aProperties );
3694 const std::map<std::string, UTF8>* aProperties )
3697 fn.SetPath( aLibraryPath );
3700 if( !fn.DirExists() )
3703 if( !fn.IsDirWritable() )
3705 THROW_IO_ERROR( wxString::Format(
_(
"Insufficient permissions to delete folder '%s'." ),
3706 aLibraryPath.GetData() ) );
3709 wxDir dir( aLibraryPath );
3711 if( dir.HasSubDirs() )
3713 THROW_IO_ERROR( wxString::Format(
_(
"Library folder '%s' has unexpected sub-folders." ),
3714 aLibraryPath.GetData() ) );
3718 if( dir.HasFiles() )
3722 wxArrayString files;
3724 wxDir::GetAllFiles( aLibraryPath, &files );
3726 for( i = 0; i < files.GetCount(); i++ )
3732 THROW_IO_ERROR( wxString::Format(
_(
"Unexpected file '%s' found in library "
3735 aLibraryPath.GetData() ) );
3739 for( i = 0; i < files.GetCount(); i++ )
3740 wxRemoveFile( files[i] );
3744 aLibraryPath.GetData() );
3748 if( !wxRmdir( aLibraryPath ) )
3750 THROW_IO_ERROR( wxString::Format(
_(
"Footprint library '%s' cannot be deleted." ),
3751 aLibraryPath.GetData() ) );
3758 wxMilliSleep( 250L );
constexpr EDA_IU_SCALE pcbIUScale
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
wxString GetMajorMinorVersion()
Get only the major and minor version in a string major.minor.
bool SaveImageData(wxOutputStream &aOutStream) const
Write the bitmap data to aOutStream.
wxString GetNetname() const
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
TEARDROP_PARAMETERS & GetTeardropParams()
Container for design settings for a BOARD object.
std::map< PCB_LAYER_ID, ZONE_LAYER_PROPERTIES > m_ZoneLayerProperties
const VECTOR2I & GetGridOrigin() const
int GetBoardThickness() const
The full thickness of the board including copper and masks.
bool m_AllowSoldermaskBridgesInFPs
const VECTOR2I & GetAuxOrigin() const
int m_SolderMaskExpansion
BOARD_STACKUP & GetStackupDescriptor()
double m_SolderPasteMarginRatio
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
virtual bool IsKnockout() const
bool IsLocked() const override
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
FOOTPRINT * GetParentFootprint() const
VECTOR2I GetFPRelativePosition() const
Manage layers needed to make a physical board.
void FormatBoardStackup(OUTPUTFORMATTER *aFormatter, const BOARD *aBoard) const
Write the stackup info on board file.
Information pertinent to a Pcbnew printed circuit board.
const NETINFO_LIST & GetNetInfo() const
EMBEDDED_FILES * GetEmbeddedFiles() override
const std::vector< wxString > & GetVariantNames() const
const GENERATORS & Generators() const
void SetFileName(const wxString &aFileName)
const PCB_POINTS & Points() const
const PAGE_INFO & GetPageSettings() const
const ZONES & Zones() const
const GROUPS & Groups() const
The groups must maintain the following invariants.
LAYER_T GetLayerType(PCB_LAYER_ID aLayer) const
Return the type of the copper layer given by aLayer.
TITLE_BLOCK & GetTitleBlock()
int GetCopperLayerCount() const
const std::map< wxString, wxString > & GetProperties() const
const FOOTPRINTS & Footprints() const
const TRACKS & Tracks() const
wxString GetVariantDescription(const wxString &aVariantName) const
const PCB_PLOT_PARAMS & GetPlotOptions() const
bool LegacyTeardrops() const
wxString GroupsSanityCheck(bool repair=false)
Consistency check of internal m_groups structure.
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
const LSET & GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
const DRAWINGS & Drawings() const
A lightweight representation of a component class.
const std::vector< COMPONENT_CLASS * > & GetConstituentClasses() const
Fetches a vector of the constituent classes for this (effective) class.
const LIB_ID & GetDesignBlockLibId() const
std::unordered_set< EDA_ITEM * > & GetItems()
bool HasDesignBlockLink() const
A base class for most all the KiCad significant classes used in schematics and boards.
KICAD_T Type() const
Returns the type of object.
virtual void SetParentGroup(EDA_GROUP *aGroup)
virtual void SetParent(EDA_ITEM *aParent)
int GetEllipseMinorRadius() const
const VECTOR2I & GetBezierC2() const
const VECTOR2I & GetEllipseCenter() const
EDA_ANGLE GetEllipseEndAngle() const
FILL_T GetFillMode() const
int GetEllipseMajorRadius() const
SHAPE_POLY_SET & GetPolyShape()
EDA_ANGLE GetEllipseRotation() const
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
EDA_ANGLE GetEllipseStartAngle() const
wxString SHAPE_T_asString() const
const VECTOR2I & GetBezierC1() const
int GetCornerRadius() const
bool IsPolyShapeValid() const
VECTOR2I GetArcMid() const
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
const VECTOR2I & GetTextPos() const
const EDA_ANGLE & GetTextAngle() const
virtual const wxString & GetText() const
Return the string associated with the text object.
bool IsKeepUpright() const
virtual bool IsVisible() const
KIFONT::FONT * GetFont() const
std::vector< std::unique_ptr< KIFONT::GLYPH > > * GetRenderCache(const KIFONT::FONT *aFont, const wxString &forResolvedText, const VECTOR2I &aOffset={ 0, 0 }) const
virtual EDA_ANGLE GetDrawRotation() const
virtual wxString GetShownText(bool aAllowExtraText, int aDepth=0) const
Return the string actually shown after processing of the base text.
int GetTextThickness() const
void WriteEmbeddedFiles(OUTPUTFORMATTER &aOut, bool aWriteData) const
Output formatter for the embedded files.
void ClearEmbeddedFiles(bool aDeleteFiles=true)
EMBEDDED_FILE * AddFile(const wxFileName &aName, bool aOverwrite)
Load a file from disk and adds it to the collection.
const std::map< wxString, EMBEDDED_FILE * > & EmbeddedFileMap() const
bool GetAreFontsEmbedded() const
A LINE_READER that reads from an open file.
void Rewind()
Rewind the file and resets the line number back to zero.
char * ReadLine() override
Read a line of text into the buffer and increments the line number counter.
RAII class to set and restore the fontconfig reporter.
Helper class for creating a footprint library cache.
std::unique_ptr< FOOTPRINT > m_footprint
FP_CACHE_ENTRY(FOOTPRINT *aFootprint, const WX_FILENAME &aFileName)
const WX_FILENAME & GetFileName() const
std::unique_ptr< FOOTPRINT > & GetFootprint()
static long long GetTimestamp(const wxString &aLibPath)
Generate a timestamp representing all source files in the cache (including the parent directory).
boost::ptr_map< wxString, FP_CACHE_ENTRY > m_footprints
PCB_IO_KICAD_SEXPR * m_owner
bool IsModified()
Return true if the cache is not up-to-date.
long long m_cache_timestamp
void SetPath(const wxString &aPath)
bool IsPath(const wxString &aPath) const
Check if aPath is the same as the current cache path.
void Save(FOOTPRINT *aFootprintFilter=nullptr)
Save the footprint cache or a single footprint from it to disk.
FP_CACHE(PCB_IO_KICAD_SEXPR *aOwner, const wxString &aLibraryPath)
boost::ptr_map< wxString, FP_CACHE_ENTRY > & GetFootprints()
void Remove(const wxString &aFootprintName)
PROGRESS_REPORTER * m_progressReporter
Progress reporter to track the progress of the operation, may be nullptr.
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
APP_SETTINGS_BASE * KifaceSettings() const
virtual bool IsOutline() const
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
virtual void SetLineWidth(float aLineWidth)
Set the line width.
virtual wxString GetClass() const =0
Return the class name.
wxString AsString() const
A logical library item identifier and consists of various portions much like a URI.
const wxString GetUniStringLibItemName() const
Get strings for display messages in dialogs.
const UTF8 & GetLibItemName() const
An abstract class from which implementation specific LINE_READERs may be derived to read single lines...
static LOAD_INFO_REPORTER & GetInstance()
REPORTER & Report(const wxString &aMsg, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Report a string with a given severity.
LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
LSET is a set of PCB_LAYER_IDs.
static const LSET & AllCuMask()
return AllCuMask( MAX_CU_LAYERS );
LSEQ CuStack() const
Return a sequence of copper layers in starting from the front/top and extending to the back/bottom.
LSEQ TechAndUserUIOrder() const
Return the technical and user layers in the order shown in layer widget.
LSEQ Seq(const LSEQ &aSequence) const
Return an LSEQ from the union of this LSET and a desired sequence.
static LSET AllCuMask(int aCuLayerCount)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
static wxString Name(PCB_LAYER_ID aLayerId)
Return the fixed name association with aLayerId.
Handle the data for a net.
const wxString & GetNetname() const
A PADSTACK defines the characteristics of a single or multi-layer pad, in the IPC sense of the word.
std::optional< int > & Clearance(PCB_LAYER_ID aLayer=F_Cu)
MASK_LAYER_PROPS & FrontOuterLayers()
void ForEachUniqueLayer(const std::function< void(PCB_LAYER_ID)> &aMethod) const
Runs the given callable for each active unique copper layer in this padstack, meaning F_Cu for MODE::...
std::optional< int > & ThermalSpokeWidth(PCB_LAYER_ID aLayer=F_Cu)
EDA_ANGLE ThermalSpokeAngle(PCB_LAYER_ID aLayer=F_Cu) const
POST_MACHINING_PROPS & FrontPostMachining()
std::optional< int > & ThermalGap(PCB_LAYER_ID aLayer=F_Cu)
DRILL_PROPS & TertiaryDrill()
const VECTOR2I & Size(PCB_LAYER_ID aLayer) const
@ NORMAL
Shape is the same on all layers.
@ FRONT_INNER_BACK
Up to three shapes can be defined (F_Cu, inner copper layers, B_Cu)
DRILL_PROPS & SecondaryDrill()
POST_MACHINING_PROPS & BackPostMachining()
MASK_LAYER_PROPS & BackOuterLayers()
static constexpr PCB_LAYER_ID ALL_LAYERS
! Temporary layer identifier to identify code that is not padstack-aware
static constexpr PCB_LAYER_ID INNER_LAYERS
! The layer identifier to use for "inner layers" on top/inner/bottom padstacks
std::optional< ZONE_CONNECTION > & ZoneConnection(PCB_LAYER_ID aLayer=F_Cu)
PAD_PROP GetProperty() const
bool GetRemoveUnconnected() const
LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
const std::vector< std::shared_ptr< PCB_SHAPE > > & GetPrimitives(PCB_LAYER_ID aLayer) const
Accessor to the basic shape list for custom-shaped pads.
const ZONE_LAYER_OVERRIDE & GetZoneLayerOverride(PCB_LAYER_ID aLayer) const
std::optional< double > GetLocalSolderPasteMarginRatio() const
const wxString & GetPinType() const
const VECTOR2I & GetDrillSize() const
PAD_ATTRIB GetAttribute() const
const wxString & GetPinFunction() const
const wxString & GetNumber() const
const VECTOR2I & GetDelta(PCB_LAYER_ID aLayer) const
EDA_ANGLE GetThermalSpokeAngle() const
double GetRoundRectRadiusRatio(PCB_LAYER_ID aLayer) const
PAD_SHAPE GetShape(PCB_LAYER_ID aLayer) const
bool GetKeepTopBottom() const
int GetPadToDieDelay() const
std::optional< int > GetLocalClearance() const override
Return any local clearances set in the "classic" (ie: pre-rule) system.
const PADSTACK & Padstack() const
const VECTOR2I & GetOffset(PCB_LAYER_ID aLayer) const
EDA_ANGLE GetOrientation() const
Return the rotation angle of the pad.
PAD_DRILL_SHAPE GetDrillShape() const
int GetChamferPositions(PCB_LAYER_ID aLayer) const
std::optional< int > GetLocalSolderPasteMargin() const
std::optional< int > GetLocalSolderMaskMargin() const
double GetChamferRectRatio(PCB_LAYER_ID aLayer) const
std::optional< int > GetLocalThermalSpokeWidthOverride() const
ZONE_CONNECTION GetLocalZoneConnection() const
CUSTOM_SHAPE_ZONE_MODE GetCustomShapeInZoneOpt() const
int GetLocalThermalGapOverride(wxString *aSource) const
PAD_SHAPE GetAnchorPadShape(PCB_LAYER_ID aLayer) const
int GetPadToDieLength() const
const VECTOR2I & GetSize(PCB_LAYER_ID aLayer) const
void Format(OUTPUTFORMATTER *aFormatter) const
Output the page class to aFormatter in s-expression form.
FLIP_DIRECTION m_FlipDirection
const VECTOR2I & GetMid() const
const VECTOR2I & GetMargin() const
Get the barcode margin (in internal units).
VECTOR2I GetPosition() const override
Get the position (center) of the barcode in internal units.
bool IsKnockout() const override
int GetHeight() const
Get the barcode height (in internal units).
BARCODE_ECC_T GetErrorCorrection() const
EDA_ANGLE GetAngle() const
BARCODE_T GetKind() const
Returns the type of the barcode (QR, CODE_39, etc.).
int GetWidth() const
Get the barcode width (in internal units).
wxString GetOverrideText() const
wxString GetSuffix() const
int GetLineThickness() const
DIM_TEXT_POSITION GetTextPositionMode() const
bool GetKeepTextAligned() const
DIM_PRECISION GetPrecision() const
wxString GetPrefix() const
DIM_UNITS_MODE GetUnitsMode() const
DIM_UNITS_FORMAT GetUnitsFormat() const
virtual const VECTOR2I & GetStart() const
The dimension's origin is the first feature point for the dimension.
DIM_ARROW_DIRECTION GetArrowDirection() const
bool GetSuppressZeroes() const
int GetExtensionOffset() const
int GetArrowLength() const
bool GetOverrideTextEnabled() const
virtual const VECTOR2I & GetEnd() const
For better understanding of the points that make a dimension:
int GetExtensionHeight() const
Mark the center of a circle or arc with a cross shape.
A leader is a dimension-like object pointing to a specific point.
DIM_TEXT_BORDER GetTextBorder() const
An orthogonal dimension is like an aligned dimension, but the extension lines are locked to the X or ...
A radial dimension indicates either the radius or diameter of an arc or circle.
int GetLeaderLength() const
virtual const STRING_ANY_MAP GetProperties() const
virtual wxString GetGeneratorType() const
A set of BOARD_ITEMs (i.e., without duplicates).
Read a Pcbnew s-expression formatted LINE_READER object and returns the appropriate BOARD_ITEM object...
const std::vector< wxString > & GetParseWarnings() const
Return any non-fatal parse warnings that occurred during parsing.
bool IsTooRecent()
Return whether a version number, if any was parsed, was too recent.
bool IsValidBoardHeader()
Partially parse the input and check if it matches expected header.
wxString GetRequiredVersion()
Return a string representing the version of KiCad required to open this file.
A #PLUGIN derivation for saving and loading Pcbnew s-expression formatted files.
BOARD * DoLoad(LINE_READER &aReader, BOARD *aAppendToMe, const std::map< std::string, UTF8 > *aProperties, PROGRESS_REPORTER *aProgressReporter, unsigned aLineCount)
bool CanReadBoard(const wxString &aFileName) const override
Checks if this PCB_IO can read the specified board file.
void formatProperties(const BOARD *aBoard) const
formats the Nets and Netclasses
FOOTPRINT * ImportFootprint(const wxString &aFootprintPath, wxString &aFootprintNameOut, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Load a single footprint from aFootprintPath and put its name in aFootprintNameOut.
void FootprintDelete(const wxString &aLibraryPath, const wxString &aFootprintName, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Delete aFootprintName from the library at aLibraryPath.
long long GetLibraryTimestamp(const wxString &aLibraryPath) const override
Generate a timestamp representing all the files in the library (including the library directory).
bool IsLibraryWritable(const wxString &aLibraryPath) override
Return true if the library at aLibraryPath is writable.
void formatTeardropParameters(const TEARDROP_PARAMETERS &tdParams) const
bool DeleteLibrary(const wxString &aLibraryPath, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Delete an existing library and returns true, or if library does not exist returns false,...
const FOOTPRINT * GetEnumeratedFootprint(const wxString &aLibraryPath, const wxString &aFootprintName, const std::map< std::string, UTF8 > *aProperties=nullptr) override
A version of FootprintLoad() for use after FootprintEnumerate() for more efficient cache management.
void CreateLibrary(const wxString &aLibraryPath, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Create a new empty library at aLibraryPath empty.
void FootprintEnumerate(wxArrayString &aFootprintNames, const wxString &aLibraryPath, bool aBestEfforts, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Return a list of footprint names contained within the library at aLibraryPath.
void formatPolyPts(const SHAPE_LINE_CHAIN &outline, const FOOTPRINT *aParentFP=nullptr) const
FP_CACHE * m_cache
Footprint library cache.
void formatBoardLayers(const BOARD *aBoard) const
formats the board layer information
FOOTPRINT * FootprintLoad(const wxString &aLibraryPath, const wxString &aFootprintName, bool aKeepUUID=false, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Load a footprint having aFootprintName from the aLibraryPath containing a library format that this PC...
BOARD * LoadBoard(const wxString &aFileName, BOARD *aAppendToMe, const std::map< std::string, UTF8 > *aProperties=nullptr, PROJECT *aProject=nullptr) override
Load information from some input file format that this PCB_IO implementation knows about into either ...
bool FootprintExists(const wxString &aLibraryPath, const wxString &aFootprintName, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Check for the existence of a footprint.
void FootprintSave(const wxString &aLibraryPath, const FOOTPRINT *aFootprint, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Write aFootprint to an existing library located at aLibraryPath.
void format(const BOARD *aBoard) const
void SaveBoard(const wxString &aFileName, BOARD *aBoard, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Write aBoard to a storage file in a format that this PCB_IO implementation knows about or it can be u...
void formatLayers(LSET aLayerMask, bool aEnumerateLayers, bool aIsZone=false) const
void formatGeneral(const BOARD *aBoard) const
formats the General section of the file
void formatVariants(const BOARD *aBoard) const
formats the board variant registry
void ClearCachedFootprints(const wxString &aLibraryPath) override
Clear any cached footprint data for the given library path.
void formatSetup(const BOARD *aBoard) const
formats the board setup information
void FormatBoardToFormatter(OUTPUTFORMATTER *aOut, BOARD *aBoard, const std::map< std::string, UTF8 > *aProperties=nullptr)
Serialize a BOARD to an OUTPUTFORMATTER without file I/O or Prettify.
std::function< bool(wxString aTitle, int aIcon, wxString aMsg, wxString aAction)> m_queryUserCallback
BOARD_ITEM * Parse(const wxString &aClipboardSourceInput)
void init(const std::map< std::string, UTF8 > *aProperties)
void Format(const BOARD_ITEM *aItem) const
Output aItem to aFormatter in s-expression format.
void formatLayer(PCB_LAYER_ID aLayer, bool aIsKnockout=false) const
void formatHeader(const BOARD *aBoard) const
writes everything that comes before the board_items, like settings and layers etc
const FOOTPRINT * getFootprint(const wxString &aLibraryPath, const wxString &aFootprintName, const std::map< std::string, UTF8 > *aProperties, bool checkModified)
PCB_IO_KICAD_SEXPR(int aControlFlags=CTL_FOR_BOARD)
OUTPUTFORMATTER * m_out
output any Format()s to this, no ownership
void validateCache(const wxString &aLibraryPath, bool checkModified=true)
virtual ~PCB_IO_KICAD_SEXPR()
void formatRenderCache(const EDA_TEXT *aText) const
LINE_READER * m_reader
no ownership
BOARD * m_board
The board BOARD being worked on, no ownership here.
virtual bool CanReadBoard(const wxString &aFileName) const
Checks if this PCB_IO can read the specified board file.
PCB_IO(const wxString &aName)
const std::map< std::string, UTF8 > * m_props
Properties passed via Save() or Load(), no ownership, may be NULL.
void Format(OUTPUTFORMATTER *aFormatter) const
A PCB_POINT is a 0-dimensional point that is used to mark a position on a PCB, or more usually a foot...
VECTOR2I GetPosition() const override
Object to handle a bitmap image that can be inserted in a PCB.
VECTOR2I GetPosition() const override
Get the position of the image (this is the center of the image).
REFERENCE_IMAGE & GetReferenceImage()
std::optional< int > GetLocalSolderMaskMargin() const
bool HasSolderMask() const
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
STROKE_PARAMS GetStroke() const override
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
bool StrokeHeaderSeparator() const
bool StrokeColumns() const
bool StrokeExternal() const
std::vector< PCB_TABLECELL * > GetCells() const
const STROKE_PARAMS & GetSeparatorsStroke() const
const STROKE_PARAMS & GetBorderStroke() const
int GetColWidth(int aCol) const
int GetRowHeight(int aRow) const
VECTOR2I GetPosition() const override
bool IsBorderEnabled() const
Disables the border, this is done by changing the stroke internally.
int GetMarginBottom() const
int GetMarginLeft() const
int GetMarginRight() const
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
bool HasSolderMask() const
std::optional< int > GetLocalSolderMaskMargin() const
const VECTOR2I & GetStart() const
const VECTOR2I & GetEnd() const
virtual int GetWidth() const
A progress reporter interface for use in multi-threaded environments.
Container for project specific data.
A REFERENCE_IMAGE is a wrapper around a BITMAP_IMAGE that is displayed in an editor as a reference fo...
const BITMAP_BASE & GetImage() const
Get the underlying image.
double GetImageScale() const
const VECTOR2I & GetArcMid() const
const VECTOR2I & GetP1() const
const VECTOR2I & GetP0() const
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
const SHAPE_ARC & Arc(size_t aArc) const
int PointCount() const
Return the number of points (vertices) in this line chain.
ssize_t ArcIndex(size_t aSegment) const
Return the arc index for the given segment index.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
Represent a set of closed polygons.
POLYGON & Polygon(int aIndex)
Return the aIndex-th subpolygon in the set.
std::vector< SHAPE_LINE_CHAIN > POLYGON
represents a single polygon outline with holes.
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
Is a LINE_READER that reads from a multiline 8 bit wide std::string.
void Format(OUTPUTFORMATTER *out, const EDA_IU_SCALE &aIuScale) const
TEARDROP_PARAMETARS is a helper class to handle parameters needed to build teardrops for a board thes...
double m_BestWidthRatio
The height of a teardrop as ratio between height and size of pad/via.
int m_TdMaxLen
max allowed length for teardrops in IU. <= 0 to disable
bool m_AllowUseTwoTracks
True to create teardrops using 2 track segments if the first in too small.
int m_TdMaxWidth
max allowed height for teardrops in IU. <= 0 to disable
double m_BestLengthRatio
The length of a teardrop as ratio between length and size of pad/via.
double m_WidthtoSizeFilterRatio
The ratio (H/D) between the via/pad size and the track width max value to create a teardrop 1....
bool m_TdOnPadsInZones
A filter to exclude pads inside zone fills.
bool m_Enabled
Flag to enable teardrops.
bool m_CurvedEdges
True if the teardrop should be curved.
virtual void Format(OUTPUTFORMATTER *aFormatter) const
Output the object to aFormatter in s-expression form.
const char * c_str() const
A wrapper around a wxFileName which is much more performant with a subset of the API.
void SetFullName(const wxString &aFileNameAndExtension)
static void ResolvePossibleSymlinks(wxFileName &aFilename)
wxString GetFullPath() const
Handle a list of polygons defining a copper zone.
int GetHatchBorderAlgorithm() const
bool GetIsRuleArea() const
Accessors to parameters used in Rule Area zones:
std::optional< int > GetLocalClearance() const override
const THIEVING_SETTINGS & GetThievingSettings() const
bool GetDoNotAllowVias() const
ZONE_LAYER_PROPERTIES & LayerProperties(PCB_LAYER_ID aLayer)
wxString GetPlacementAreaSource() const
std::shared_ptr< SHAPE_POLY_SET > GetFilledPolysList(PCB_LAYER_ID aLayer) const
bool GetDoNotAllowPads() const
PLACEMENT_SOURCE_T GetPlacementAreaSourceType() const
bool GetDoNotAllowTracks() const
ISLAND_REMOVAL_MODE GetIslandRemovalMode() const
SHAPE_POLY_SET * Outline()
bool IsIsland(PCB_LAYER_ID aLayer, int aPolyIdx) const
Check if a given filled polygon is an insulated island.
long long int GetMinIslandArea() const
const wxString & GetZoneName() const
int GetMinThickness() const
ZONE_CONNECTION GetPadConnection() const
int GetHatchThickness() const
double GetHatchHoleMinArea() const
bool GetPlacementAreaEnabled() const
bool IsTeardropArea() const
int GetThermalReliefSpokeWidth() const
int GetBorderHatchPitch() const
HatchBorder related methods.
ZONE_BORDER_DISPLAY_STYLE GetHatchStyle() const
EDA_ANGLE GetHatchOrientation() const
bool GetDoNotAllowFootprints() const
ZONE_FILL_MODE GetFillMode() const
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
TEARDROP_TYPE GetTeardropAreaType() const
double GetHatchSmoothingValue() const
bool GetDoNotAllowZoneFills() const
int GetHatchSmoothingLevel() const
unsigned int GetCornerRadius() const
int GetCornerSmoothingType() const
bool IsOnCopperLayer() const override
PCB_LAYER_ID GetFirstLayer() const
int GetThermalReliefGap() const
unsigned GetAssignedPriority() const
int GetNumCorners(void) const
Access to m_Poly parameters.
This file is part of the common library.
@ RECT_CHAMFER_BOTTOM_RIGHT
@ RECT_CHAMFER_BOTTOM_LEFT
#define CTL_OMIT_HYPERLINK
Omit the hyperlink attribute in .kicad_xxx files.
#define CTL_OMIT_UUIDS
Omit component unique ids (useless in library)
#define CTL_OMIT_FOOTPRINT_VERSION
Omit the version string from the (footprint) sexpr group.
#define CTL_OMIT_INITIAL_COMMENTS
Omit FOOTPRINT initial comments.
#define CTL_OMIT_LIBNAME
Omit lib alias when saving (used for board/not library).
#define CTL_OMIT_PATH
Omit component sheet time stamp (useless in library).
#define CTL_OMIT_AT
Omit position and rotation.
#define CTL_OMIT_PAD_NETS
Omit pads net names (useless in library).
#define CTL_OMIT_COLOR
Omit the color attribute in .kicad_xxx files.
static constexpr EDA_ANGLE ANGLE_0
static constexpr EDA_ANGLE ANGLE_90
static constexpr EDA_ANGLE ANGLE_45
#define IGNORE_PARENT_GROUP
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
@ FILLED_SHAPE
Fill with object color.
EDA_DATA_TYPE
The type of unit.
static const std::string KiCadFootprintFileExtension
const wxChar *const traceKicadPcbPlugin
Flag to enable KiCad PCB plugin debug output.
#define THROW_IO_ERROR(msg)
macro which captures the "call site" values of FILE_, __FUNCTION & LINE
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
bool IsCopperLayer(int aLayerId)
Test whether a layer is a copper layer.
bool IsExternalCopperLayer(int aLayerId)
Test whether a layer is an external (F_Cu or B_Cu) copper layer.
PCB_LAYER_ID
A quick note on layer IDs:
This file contains miscellaneous commonly used macros and functions.
#define UNIMPLEMENTED_FOR(type)
@ TOP_BOTTOM
Flip top to bottom (around the X axis)
KICOMMON_API std::string FormatAngle(const EDA_ANGLE &aAngle)
Convert aAngle from board units to a string appropriate for writing to file.
KICOMMON_API std::string FormatInternalUnits(const EDA_IU_SCALE &aIuScale, int aValue, EDA_DATA_TYPE aDataType=EDA_DATA_TYPE::DISTANCE)
Converts aValue from internal units to a string appropriate for writing to file.
constexpr char APPEND_PRESERVE_DESTINATION_STACKUP[]
@ NPTH
like PAD_PTH, but not plated mechanical use only, no connection allowed
@ SMD
Smd pad, appears on the solder paste layer (default)
@ PTH
Plated through hole pad.
@ CONN
Like smd, does not appear on the solder paste layer (default) Note: also has a special attribute in G...
@ FIDUCIAL_LOCAL
a fiducial (usually a smd) local to the parent footprint
@ FIDUCIAL_GLBL
a fiducial (usually a smd) for the full board
@ MECHANICAL
a pad used for mechanical support
@ PRESSFIT
a PTH with a hole diameter with tight tolerances for press fit pin
@ HEATSINK
a pad used as heat sink, usually in SMD footprints
@ NONE
no special fabrication property
@ TESTPOINT
a test point pad
@ CASTELLATED
a pad with a castellated through hole
@ BGA
Smd pad, used in BGA footprints.
@ REMOVE_EXCEPT_START_AND_END
BARCODE class definition.
Class to handle a set of BOARD_ITEMs.
bool isDefaultTeardropParameters(const TEARDROP_PARAMETERS &tdParams)
std::string formatInternalUnits(const int aValue, const EDA_DATA_TYPE aDataType=EDA_DATA_TYPE::DISTANCE)
#define SEXPR_BOARD_FILE_VERSION
Current s-expression file format version. 2 was the last legacy format version.
#define CTL_FOR_BOARD
The zero arg constructor when PCB_PLUGIN is used for PLUGIN::Load() and PLUGIN::Save()ing a BOARD fil...
#define CTL_FOR_LIBRARY
Format output for a footprint library instead of clipboard or BOARD.
Pcbnew s-expression file format parser definition.
#define UNDEFINED_DRILL_DIAMETER
PGM_BASE & Pgm()
The global program "get" accessor.
std::string FormatDouble2Str(double aValue)
Print a float number without using scientific notation and no trailing 0 This function is intended in...
bool ReplaceIllegalFileNameChars(std::string &aName, int aReplaceChar)
Checks aName for illegal file name characters.
int ValueStringCompare(const wxString &strFWord, const wxString &strSWord)
Compare strings like the strcmp function but handle numbers and modifiers within the string text corr...
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
VECTOR2I size
Drill diameter (x == y) or slot dimensions (x != y)
std::optional< bool > is_capped
True if the drill hole should be capped.
std::optional< bool > is_filled
True if the drill hole should be filled completely.
std::optional< bool > has_covering
True if the pad on this side should have covering.
std::optional< bool > has_solder_mask
True if this outer layer has mask (is not tented)
std::optional< bool > has_plugging
True if the drill hole should be plugged on this side.
A filename or source description, a problem input line, a line number, a byte offset,...
Parameters that drive copper-thieving fill generation.
std::optional< VECTOR2I > hatching_offset
const SHAPE_LINE_CHAIN chain
wxLogTrace helper definitions.
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
@ PCB_DIM_ORTHOGONAL_T
class PCB_DIM_ORTHOGONAL, a linear dimension constrained to x/y
@ PCB_DIM_LEADER_T
class PCB_DIM_LEADER, a leader dimension (graphic item)
@ PCB_GENERATOR_T
class PCB_GENERATOR, generator on a layer
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
@ PCB_DIM_CENTER_T
class PCB_DIM_CENTER, a center point marking (graphic item)
@ PCB_GROUP_T
class PCB_GROUP, a set of BOARD_ITEMs
@ PCB_TEXTBOX_T
class PCB_TEXTBOX, wrapped text on a layer
@ PCB_ZONE_T
class ZONE, a copper pour area
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
@ PCB_REFERENCE_IMAGE_T
class PCB_REFERENCE_IMAGE, bitmap on a layer
@ PCB_FIELD_T
class PCB_FIELD, text associated with a footprint property
@ PCB_BARCODE_T
class PCB_BARCODE, a barcode (graphic item)
@ PCB_TARGET_T
class PCB_TARGET, a target (graphic item)
@ PCB_TABLECELL_T
class PCB_TABLECELL, PCB_TEXTBOX for use in tables
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
@ PCB_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
@ PCB_PAD_T
class PAD, a pad in a footprint
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
@ PCB_TABLE_T
class PCB_TABLE, table of PCB_TABLECELLs
@ PCB_POINT_T
class PCB_POINT, a 0-dimensional point
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
@ PCB_DIM_RADIAL_T
class PCB_DIM_RADIAL, a radius or diameter dimension
VECTOR2< int32_t > VECTOR2I
Definition of file extensions used in Kicad.
@ THERMAL
Use thermal relief for pads.
@ THT_THERMAL
Thermal relief only for THT pads.
@ NONE
Pads are not covered.
@ FULL
pads are covered by copper