97 std::ifstream file( aFileName.fn_str() );
104 if( std::getline( file, line ) )
106 if( line.find(
"!PADS-" ) != std::string::npos )
115 const std::map<std::string, UTF8>* aProperties,
PROJECT* aProject )
129 parser.
Parse( aFileName );
131 catch(
const std::exception& e )
184 const auto& nets =
m_parser->GetNets();
186 for(
const auto& pads_net : nets )
189 for(
const auto& pads_net : nets )
191 for(
const auto&
pin : pads_net.pins )
193 std::string key =
pin.ref_des +
"." +
pin.pin_name;
198 const auto& route_nets =
m_parser->GetRoutes();
200 for(
const auto& route : route_nets )
202 for(
const auto&
pin : route.pins )
204 std::string key =
pin.ref_des +
"." +
pin.pin_name;
211 for(
const auto& route : route_nets )
214 for(
const auto& pour_def :
m_parser->GetPours() )
217 for(
const auto& copper :
m_parser->GetCopperShapes() )
223 const auto& reuse_blocks =
m_parser->GetReuseBlocks();
225 for(
const auto& [blockName, block] : reuse_blocks )
227 for(
const std::string& partName : block.part_names )
237 const auto& decals =
m_parser->GetPartDecals();
238 const auto& part_types =
m_parser->GetPartTypes();
239 const auto& partInstanceAttrs =
m_parser->GetPartInstanceAttrs();
240 const auto& parts =
m_parser->GetParts();
242 for(
const auto& pads_part : parts )
251 path.push_back( symbolUuid );
255 std::string decal_name = pads_part.decal;
261 if( !pads_part.explicit_decal )
263 auto part_type_it = part_types.find( decal_name );
265 if( part_type_it != part_types.end() )
266 decal_name = part_type_it->second.decal_name;
271 std::stringstream ss( decal_name );
273 std::vector<std::string> decal_list;
275 while( std::getline( ss, segment,
':' ) )
277 decal_list.push_back( segment );
280 std::string actual_decal_name;
281 bool found_valid_decal =
false;
283 if( pads_part.alt_decal_index >= 0
284 &&
static_cast<size_t>( pads_part.alt_decal_index ) < decal_list.size() )
286 const std::string& alt_decal = decal_list[pads_part.alt_decal_index];
288 if( decals.find( alt_decal ) != decals.end() )
290 actual_decal_name = alt_decal;
291 found_valid_decal =
true;
295 if( !found_valid_decal )
297 for(
const std::string& decal : decal_list )
299 if( decals.find( decal ) != decals.end() )
301 actual_decal_name = decal;
302 found_valid_decal =
true;
308 if( found_valid_decal )
310 decal_name = actual_decal_name;
317 footprint->
SetValue( pads_part.decal );
319 if( !pads_part.alternate_decals.empty() )
323 for(
size_t i = 0; i < pads_part.alternate_decals.size(); ++i )
326 alternates += wxT(
", " );
335 footprint->
Add( field );
338 auto partCoordScaler =
339 [&](
double val,
bool is_x )
343 double part_factor =
m_converter->GetScaleFactor();
353 long long origin_nm =
354 static_cast<long long>( std::round( origin *
m_converter->GetScaleFactor() ) );
355 long long val_nm =
static_cast<long long>( std::round( val * part_factor ) );
357 long long res_nm = val_nm - origin_nm;
362 return static_cast<int>( std::clamp<long long>( res_nm, INT_MIN, INT_MAX ) );
366 partCoordScaler( pads_part.location.y,
false ) ) );
380 auto ptIt = part_types.find( pads_part.decal );
382 if( ptIt != part_types.end() )
383 partType = &ptIt->second;
385 const std::map<std::string, std::string>* instanceAttrs =
nullptr;
386 auto iaIt = partInstanceAttrs.find( pads_part.name );
388 if( iaIt != partInstanceAttrs.end() )
389 instanceAttrs = &iaIt->second;
391 auto applyAttributes =
392 [&](
const std::vector<PADS_IO::ATTRIBUTE>& attrs, std::function<int(
double)> scaler )
394 for(
const auto& attr : attrs )
397 bool ownsField =
false;
399 if( attr.name ==
"Ref.Des." )
403 else if( attr.name ==
"Part Type" || attr.name ==
"VALUE" )
405 field = &footprint->
Value();
409 std::string attrValue;
413 auto valIt = instanceAttrs->find( attr.name );
415 if( valIt != instanceAttrs->end() )
416 attrValue = valIt->second;
419 if( attrValue.empty() && partType )
421 auto valIt = partType->
attributes.find( attr.name );
424 attrValue = valIt->second;
427 if( !attrValue.empty() )
450 int scaledSize = scaler( attr.height );
462 VECTOR2I offset( scaler( attr.x ), -scaler( attr.y ) );
478 if( attr.hjust ==
"LEFT" )
480 else if( attr.hjust ==
"RIGHT" )
485 if( attr.vjust ==
"UP" )
487 else if( attr.vjust ==
"DOWN" )
493 footprint->
Add( field );
497 auto decal_it = decals.find( decal_name );
499 double decalScale = ( decal_it != decals.end() ) ?
decalUnitScale( decal_it->second.units )
503 [&, decalScale](
double val )
508 if( decal_it != decals.end() )
510 applyAttributes( decal_it->second.attributes, decalScaler );
516 m_reporter->Report( wxString::Format(
_(
"Footprint '%s' not found in decal list, part skipped" ),
527 if( pads_part.units ==
"M" )
531 if( pads_part.units ==
"M" )
537 applyAttributes( pads_part.attributes, partScaler );
553 footprint->
Add( blockField );
556 if( decal_it == decals.end() )
566 auto applyCornerRadius =
568 const VECTOR2I& aSize,
bool aDefaultRound )
572 int min_dim = std::min( aSize.x, aSize.y );
574 double ratio = ( min_dim > 0 ) ? std::min(
radius / min_dim, 0.5 ) : 0.25;
579 pad->SetRoundRectRadiusRatio( kicad_layer, 0.0 );
580 pad->SetChamferRectRatio( kicad_layer, ratio );
586 pad->SetRoundRectRadiusRatio( kicad_layer, ratio );
589 else if( aDefaultRound )
592 pad->SetRoundRectRadiusRatio( kicad_layer, 0.25 );
600 auto convertPadShape =
603 const std::string& shape = layer_def.
shape;
610 if( shape ==
"R" || shape ==
"C" || shape ==
"A" || shape ==
"RT" )
614 else if( shape ==
"S" || shape ==
"ST" )
618 int side = ( layer_def.
sizeB > 0 ) ? size.
x : size.
y;
620 applyCornerRadius( layer_def,
pad, kicad_layer, sq_size,
false );
621 pad->SetSize( kicad_layer, sq_size );
623 else if( shape ==
"O" || shape ==
"OT" )
625 pad->SetSize( kicad_layer, size );
627 else if( shape ==
"RF" )
629 applyCornerRadius( layer_def,
pad, kicad_layer, size,
false );
630 pad->SetSize( kicad_layer, size );
632 else if( shape ==
"OF" )
634 pad->SetSize( kicad_layer, size );
636 else if( shape ==
"RC" || shape ==
"OC" )
638 applyCornerRadius( layer_def,
pad, kicad_layer, size,
true );
639 pad->SetSize( kicad_layer, size );
658 for(
size_t term_idx = 0; term_idx < decal.
terminals.size(); ++term_idx )
660 const auto& term = decal.
terminals[term_idx];
664 pad->SetNumber( term.name );
666 VECTOR2I pad_pos( decalScaler( term.x ), -decalScaler( term.y ) );
672 int pin_num =
static_cast<int>( term_idx + 1 );
674 auto stack_it = decal.
pad_stacks.find( pin_num );
679 if( stack_it != decal.
pad_stacks.end() && !stack_it->second.empty() )
681 const std::vector<PADS_IO::PAD_STACK_LAYER>& stack = stack_it->second;
685 double slot_length = 0.0;
686 double slot_orientation = 0.0;
687 double pad_rotation = 0.0;
691 if( layer_def.
drill > 0 )
693 drill = layer_def.
drill;
694 plated = layer_def.
plated;
707 if( pads_layer == -2 || pads_layer == 1 )
711 else if( pads_layer == -1 || pads_layer ==
m_parser->GetParameters().layer_count )
715 else if( pads_layer > 1 && pads_layer < m_parser->GetParameters().layer_count )
717 int inner_idx = pads_layer - 2;
719 if( inner_idx >= 0 && inner_idx < 30 )
726 bool has_explicit_layers =
false;
730 if( layer_def.
layer == -2 || layer_def.
layer == -1
731 || layer_def.
layer == 1
732 || layer_def.
layer ==
m_parser->GetParameters().layer_count )
734 has_explicit_layers =
true;
742 double shape_rotation = 0.0;
743 bool shape_rotation_set =
false;
745 auto convertGeometry =
748 convertPadShape( aLayerDef,
pad, aKicadLayer );
750 if( !shape_rotation_set )
752 shape_rotation = aLayerDef.
rotation;
753 shape_rotation_set =
true;
760 LSET explicitly_seen_tech;
764 if( layer_def.
layer > 0 )
769 explicitly_seen_tech.
set( check );
780 if( has_explicit_layers )
790 +
"|" + std::to_string( aLayerDef.
chamfered );
793 std::string front_shape;
794 std::string back_shape;
798 if( layer_def.
sizeA <= 0 )
806 if( mapped ==
F_Cu && front_shape.empty() )
807 front_shape = shapeKey( layer_def );
808 else if( mapped ==
B_Cu && back_shape.empty() )
809 back_shape = shapeKey( layer_def );
817 if( !front_shape.empty() && !back_shape.empty() && front_shape != back_shape )
825 bool normal_copper_set =
false;
829 if( layer_def.
layer == 0 )
831 if( !has_explicit_layers )
835 convertGeometry( layer_def,
F_Cu );
850 if( layer_def.
sizeA <= 0 )
869 int scaledGap = decalScaler( gap );
874 pad->SetLocalThermalGapOverride( scaledGap );
900 layer_set.
set( tech_layer );
905 layer_set.
set( kicad_layer );
920 convertGeometry( layer_def, kicad_layer );
923 normal_copper_set =
true;
927 if( layer_set.none() )
930 convertGeometry( stack[0],
F_Cu );
943 if( layer_set.test(
F_Cu ) && !layer_set.test(
F_Mask )
944 && !explicitly_seen_tech.test(
F_Mask ) )
949 if( layer_set.test(
F_Cu ) && !layer_set.test(
F_Paste )
950 && !explicitly_seen_tech.test(
F_Paste ) )
955 if( layer_set.test(
B_Cu ) && !layer_set.test(
B_Mask )
956 && !explicitly_seen_tech.test(
B_Mask ) )
961 if( layer_set.test(
B_Cu ) && !layer_set.test(
B_Paste )
962 && !explicitly_seen_tech.test(
B_Paste ) )
968 if( slot_length > 0 && slot_length != drill )
972 int drillMinor = decalScaler( drill );
973 int drillMajor = decalScaler( slot_length );
978 double relAngle = slot_orientation - pad_rotation;
980 relAngle = fmod( relAngle, 360.0 );
985 bool vertical = ( relAngle > 45.0 && relAngle < 135.0 )
986 || ( relAngle > 225.0 && relAngle < 315.0 );
989 pad->SetDrillSize(
VECTOR2I( drillMinor, drillMajor ) );
991 pad->SetDrillSize(
VECTOR2I( drillMajor, drillMinor ) );
995 pad->SetDrillSize(
VECTOR2I( decalScaler( drill ), decalScaler( drill ) ) );
1022 pad->SetLayerSet( layer_set );
1037 std::string pinKey = pads_part.name +
"." + term.name;
1053 if( item.
points.empty() )
1060 if( item.
layer == 0 )
1070 if( mapped_layer ==
B_Cu )
1077 shape_layer = mapped_layer;
1085 m_reporter->Report( wxString::Format(
_(
"Skipping decal item on unmapped layer %d" ),
1092 bool is_circle = ( item.
type ==
"CIRCLE" );
1093 bool is_closed = ( item.
type ==
"CLOSED" || is_circle );
1097 if( is_circle && item.
points.size() >= 2 )
1102 double x1 = item.
points[0].x;
1103 double y1 = item.
points[0].y;
1104 double x2 = item.
points[1].x;
1105 double y2 = item.
points[1].y;
1107 double cx = ( x1 + x2 ) / 2.0;
1108 double cy = ( y1 + y2 ) / 2.0;
1110 double radius = std::sqrt( ( x2 - x1 ) * ( x2 - x1 )
1111 + ( y2 - y1 ) * ( y2 - y1 ) )
1123 shape->
SetEnd( fp_pos + pt_on_circle );
1126 footprint->
Add( shape );
1131 if( item.
points.size() < 2 )
1134 for(
size_t i = 0; i < item.
points.size() - 1; ++i )
1147 VECTOR2I start( decalScaler( p1.
x ), -decalScaler( p1.
y ) );
1152 std::swap( start,
end );
1166 VECTOR2I start( decalScaler( p1.
x ), -decalScaler( p1.
y ) );
1177 footprint->
Add( shape );
1180 if( is_closed && item.
points.size() > 2 )
1193 VECTOR2I start( decalScaler( pLast.
x ), -decalScaler( pLast.
y ) );
1194 VECTOR2I end( decalScaler( pFirst.
x ), -decalScaler( pFirst.
y ) );
1197 std::swap( start,
end );
1211 VECTOR2I start( decalScaler( pLast.
x ), -decalScaler( pLast.
y ) );
1212 VECTOR2I end( decalScaler( pFirst.
x ), -decalScaler( pFirst.
y ) );
1222 footprint->
Add( shape );
1227 if( pads_part.bottom_layer )
1235 const auto& reuse_blocks =
m_parser->GetReuseBlocks();
1237 if( reuse_blocks.empty() )
1240 std::map<std::string, PCB_GROUP*> blockGroups;
1242 for(
const auto& [blockName, block] : reuse_blocks )
1244 if( !block.instances.empty() || !block.part_names.empty() )
1249 blockGroups[blockName] =
group;
1255 for(
PCB_FIELD* field : fp->GetFields() )
1257 if( field->GetName() == wxT(
"PADS_Reuse_Block" ) )
1259 std::string blockName = field->GetText().ToStdString();
1260 auto groupIt = blockGroups.find( blockName );
1262 if( groupIt != blockGroups.end() )
1263 groupIt->second->AddItem( fp );
1274 const std::vector<PADS_IO::TEST_POINT>& test_points =
m_parser->GetTestPoints();
1275 const std::map<std::string, PADS_IO::VIA_DEF>& via_defs =
m_parser->GetViaDefs();
1292 auto it = via_defs.find(
tp.symbol_name );
1294 if( it != via_defs.end() )
1304 double stackSize = def.
size;
1305 bool hasTopPad =
false;
1306 bool hasBottomPad =
false;
1307 bool hasMaskTop =
false;
1308 bool hasMaskBot =
false;
1312 if( def.
size <= 0.0 && stackLayer.
sizeA > stackSize )
1313 stackSize = stackLayer.
sizeA;
1316 && stackLayer.
sizeA > 0.0 )
1321 && stackLayer.
sizeA > 0.0 )
1323 hasBottomPad =
true;
1335 if( stackSize > 0.0 )
1338 if( hasTopPad && !hasBottomPad )
1340 else if( hasBottomPad && !hasTopPad )
1342 else if( hasMaskBot && !hasMaskTop )
1344 else if( hasMaskTop && !hasMaskBot )
1352 pad->SetNumber( wxT(
"1" ) );
1353 pad->SetPosition( pos );
1359 if( !
tp.net_name.empty() )
1375 footprint->
Add( tpField );
1384 const std::vector<PADS_IO::ROUTE>& routes =
m_parser->GetRoutes();
1385 std::set<std::pair<int, int>> placedThroughVias;
1389 std::set<std::pair<int, int>> testPointPositions;
1393 if(
tp.type ==
"VIA" )
1406 if( track_def.
points.size() < 2 )
1415 m_reporter->Report( wxString::Format(
_(
"Skipping track on non-copper layer %d" ),
1425 for(
size_t i = 0; i < track_def.
points.size() - 1; ++i )
1436 if( ( start -
end ).EuclideanNorm() < 1000 )
1467 if( testPointPositions.count( { pos.x, pos.y } ) )
1473 if( it !=
m_parser->GetViaDefs().end() )
1475 switch( it->second.via_type )
1488 auto key = std::make_pair( pos.
x, pos.
y );
1490 if( placedThroughVias.count( key ) )
1493 placedThroughVias.insert( key );
1498 via->SetPosition( pos );
1502 if( it !=
m_parser->GetViaDefs().end() )
1516 via->SetLayerPair( startLayer, endLayer );
1517 via->SetViaType( viaType );
1547 const std::vector<PADS_IO::COPPER_SHAPE>& copperShapes =
m_parser->GetCopperShapes();
1551 auto isRectCandidate =
1554 return cs.outline.size() == 2 && !cs.outline[1].is_arc
1555 && !cs.filled && !cs.is_cutout;
1561 auto tryFormRectangle =
1564 if( idx + 3 >= copperShapes.size() )
1572 if( !isRectCandidate( c0 ) || !isRectCandidate( c1 )
1573 || !isRectCandidate( c2 ) || !isRectCandidate( c3 ) )
1588 for(
int i = 0; i < 4; ++i )
1591 scaleCoord( segs[i]->outline[0].y,
false ) );
1593 scaleCoord( segs[i]->outline[1].y,
false ) );
1597 for(
int i = 0; i < 4; ++i )
1602 if( s.
x != e.
x && s.
y != e.
y )
1607 for(
int i = 0; i < 3; ++i )
1609 if( pts[i * 2 + 1] != pts[( i + 1 ) * 2] )
1614 if( pts[7] != pts[0] )
1618 int minX = pts[0].
x, maxX = pts[0].
x;
1619 int minY = pts[0].
y, maxY = pts[0].
y;
1621 for(
int i = 0; i < 8; ++i )
1623 minX = std::min( minX, pts[i].x );
1624 maxX = std::max( maxX, pts[i].x );
1625 minY = std::min( minY, pts[i].y );
1626 maxY = std::max( maxY, pts[i].y );
1629 minCorner =
VECTOR2I( minX, minY );
1630 maxCorner =
VECTOR2I( maxX, maxY );
1634 for(
size_t idx = 0; idx < copperShapes.size(); ++idx )
1638 if( copper.
outline.size() < 2 )
1650 m_reporter->Report( wxString::Format(
_(
"COPPER item on unmapped layer %d defaulting to F.Cu" ),
1665 if( tryFormRectangle( idx, minCorner, maxCorner ) )
1670 rect->
SetEnd( maxCorner );
1682 for(
size_t i = 0; i < copper.
outline.size() - 1; ++i )
1690 if( ( start -
end ).EuclideanNorm() < 1000 )
1721 if( copper.
outline.size() < 3 )
1741 for(
size_t i = 0; i < copper.
outline.size() - 1; ++i )
1749 if( ( start -
end ).EuclideanNorm() < 1000 )
1786 const std::vector<PADS_IO::CLUSTER>& clusters =
m_parser->GetClusters();
1788 if( clusters.empty() )
1791 std::map<std::string, const PADS_IO::CLUSTER*> netToClusterMap;
1795 for(
const std::string& netName : cluster.net_names )
1798 netToClusterMap[converted] = &cluster;
1802 std::map<int, PCB_GROUP*> clusterGroups;
1809 clusterGroups[cluster.id] =
group;
1818 std::string netName = net->
GetNetname().ToStdString();
1819 auto clusterIt = netToClusterMap.find( netName );
1821 if( clusterIt != netToClusterMap.end() )
1823 int clusterId = clusterIt->second->id;
1824 auto groupIt = clusterGroups.find( clusterId );
1826 if( groupIt != clusterGroups.end() )
1827 groupIt->second->AddItem( track );
1836 const std::vector<PADS_IO::POUR>& pours =
m_parser->GetPours();
1842 [](
const std::vector<PADS_IO::ARC_POINT>& pts )
1844 if( pts.size() >= 3 )
1847 if( pts.size() == 1 && pts[0].is_arc &&
std::abs( pts[0].arc.delta_angle ) >= 359.0 )
1855 int maxPriority = 0;
1859 if( pour_def.priority > maxPriority )
1860 maxPriority = pour_def.priority;
1864 std::map<std::string, ZONE*> pourZoneMap;
1867 std::map<std::string, std::string> hatoutToParent;
1874 hatoutToParent[pour_def.name] = pour_def.owner_pour;
1884 if( !isValidPoly( pour_def.points ) )
1893 m_reporter->Report( wxString::Format(
_(
"Skipping pour on unmapped layer %d" ), pour_def.layer ),
1907 m_converter->ApplyPourSettings( zone, pour_def, maxPriority, params );
1909 pourZoneMap[pour_def.name] = zone;
1919 if( !isValidPoly( pour_def.points ) )
1922 auto zoneIt = pourZoneMap.find( pour_def.owner_pour );
1924 if( zoneIt == pourZoneMap.end() )
1927 ZONE* zone = zoneIt->second;
1956 if( !isValidPoly( void_def.points ) )
1961 auto parentIt = hatoutToParent.find( void_def.owner_pour );
1963 if( parentIt == hatoutToParent.end() )
1966 if( parentIt->second != pour_def.owner_pour )
1974 allVoids.
Append( voidPoly );
1990 const auto& pts = polyline.points;
1992 if( pts.size() < 2 )
1995 for(
size_t i = 0; i < pts.size() - 1; ++i )
2023 if( polyline.closed && pts.size() > 2 )
2028 bool needsClosing = (
std::abs( pLast.
x - pFirst.
x ) > 0.001
2059 const std::vector<PADS_IO::ARC_POINT>& pts = graphic.points;
2066 if( pts.size() == 1 && pts[0].is_arc &&
std::abs( pts[0].arc.delta_angle - 360.0 ) < 0.1 )
2080 if( pts.size() < 2 )
2083 for(
size_t i = 0; i < pts.size() - 1; ++i )
2109 if( graphic.closed && pts.size() > 2 )
2114 bool needsClosing = (
std::abs( pLast.
x - pFirst.
x ) > 0.001
2142 const std::vector<INPUT_LAYER_DESC>& aInputLayerDescriptionVector )
2144 std::map<wxString, PCB_LAYER_ID> layer_map;
2147 layer_map[layer.Name] = layer.AutoMapLayer;
2158 if( aUnits ==
"I" || aUnits ==
"MIL" || aUnits ==
"MILS" )
2161 if( aUnits ==
"M" || aUnits ==
"MM" || aUnits ==
"METRIC" )
2164 if( aUnits ==
"INCH" || aUnits ==
"INCHES" )
2193 std::swap( start,
end );
2203 std::vector<PADS_IO::LAYER_INFO> padsLayerInfos =
m_parser->GetLayerInfos();
2211 m_converter->UnitConverter().SetBasicUnitsMode(
true );
2215 switch(
m_parser->GetParameters().units )
2254 if( defaultNetclass )
2262 const std::map<std::string, PADS_IO::VIA_DEF>& viaDefs =
m_parser->GetViaDefs();
2264 if( !viaDefs.empty() )
2268 const std::string& defaultViaName =
m_parser->GetParameters().default_signal_via;
2269 auto defaultIt = viaDefs.find( defaultViaName );
2271 if( defaultIt == viaDefs.end() )
2272 defaultIt = viaDefs.begin();
2274 int viaDia =
scaleSize( defaultIt->second.size );
2275 int viaDrill =
scaleSize( defaultIt->second.drill );
2280 if( defaultNetclass )
2282 defaultNetclass->SetViaDiameter( viaDia );
2283 defaultNetclass->SetViaDrill( viaDrill );
2286 for(
const auto& [
name, def] : viaDefs )
2290 const std::vector<PADS_IO::NET_CLASS_DEF>& netClasses =
m_parser->GetNetClasses();
2294 if( nc.name.empty() )
2298 std::shared_ptr<NETCLASS> netclass = std::make_shared<NETCLASS>( ncName );
2300 if( nc.clearance > 0 )
2301 netclass->SetClearance(
scaleSize( nc.clearance ) );
2303 if( nc.track_width > 0 )
2304 netclass->SetTrackWidth(
scaleSize( nc.track_width ) );
2306 if( nc.via_size > 0 )
2307 netclass->SetViaDiameter(
scaleSize( nc.via_size ) );
2309 if( nc.via_drill > 0 )
2310 netclass->SetViaDrill(
scaleSize( nc.via_drill ) );
2312 if( nc.diff_pair_width > 0 )
2313 netclass->SetDiffPairWidth(
scaleSize( nc.diff_pair_width ) );
2315 if( nc.diff_pair_gap > 0 )
2316 netclass->SetDiffPairGap(
scaleSize( nc.diff_pair_gap ) );
2320 for(
const std::string& netName : nc.net_names )
2327 const std::vector<PADS_IO::DIFF_PAIR_DEF>& diffPairs =
m_parser->GetDiffPairs();
2331 if( dp.name.empty() )
2335 std::shared_ptr<NETCLASS> dpNetclass = std::make_shared<NETCLASS>( dpClassName );
2338 dpNetclass->SetDiffPairGap(
scaleSize( dp.gap ) );
2342 dpNetclass->SetDiffPairWidth(
scaleSize( dp.width ) );
2343 dpNetclass->SetTrackWidth(
scaleSize( dp.width ) );
2348 if( !dp.positive_net.empty() )
2354 if( !dp.negative_net.empty() )
constexpr int ARC_HIGH_DEF
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
BASE_SET & set(size_t pos)
virtual void SetNet(NETINFO_ITEM *aNetInfo)
Set a NET_INFO object for the item.
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
Container for design settings for a BOARD object.
std::shared_ptr< NET_SETTINGS > m_NetSettings
void SetCustomTrackWidth(int aWidth)
Sets custom width for track (i.e.
int m_CopperEdgeClearance
void SetCustomViaSize(int aSize)
Set custom size for via diameter (i.e.
int m_SolderMaskExpansion
void SetCustomViaDrill(int aDrill)
Sets custom size for via drill (i.e.
std::vector< VIA_DIMENSION > m_ViasDimensionsList
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Information pertinent to a Pcbnew printed circuit board.
void SetCenter(const VECTOR2I &aCenter)
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
virtual void SetVisible(bool aVisible)
void SetKeepUpright(bool aKeepUpright)
virtual void SetText(const wxString &aText)
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
REPORTER * m_reporter
Reporter to log errors/warnings to, may be nullptr.
PROGRESS_REPORTER * m_progressReporter
Progress reporter to track the progress of the operation, may be nullptr.
virtual void RegisterCallback(LAYER_MAPPING_HANDLER aLayerMappingHandler)
Register a different handler to be called when mapping of input layers to KiCad layers occurs.
LAYER_MAPPING_HANDLER m_layer_mapping_handler
Callback to get layer mapping.
A logical library item identifier and consists of various portions much like a URI.
int SetLibItemName(const UTF8 &aLibItemName)
Override the library item name portion of the LIB_ID to aLibItemName.
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
LSET is a set of PCB_LAYER_IDs.
static LSET AllCuMask(int aCuLayerCount)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Handle the data for a net.
const wxString & GetNetname() const
void SetNetclassPatternAssignment(const wxString &pattern, const wxString &netclass)
Sets a netclass pattern assignment Calling this method will reset the effective netclass calculation ...
std::shared_ptr< NETCLASS > GetDefaultNetclass() const
Gets the default netclass for the project.
void SetNetclass(const wxString &netclassName, std::shared_ptr< NETCLASS > &netclass)
Sets the given netclass Calling user is responsible for resetting the effective netclass calculation ...
@ 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)
static constexpr PCB_LAYER_ID ALL_LAYERS
! The layer identifier to use for the single defintion on normal padstacks
void Parse(const wxString &aFileName)
static constexpr int LAYER_SOLDERMASK_TOP
static constexpr int LAYER_PAD_STACK_BOTTOM
static constexpr int LAYER_PAD_STACK_TOP
static constexpr int LAYER_SOLDERMASK_BOTTOM
static constexpr double MILS_TO_NM
static constexpr double INCHES_TO_NM
static constexpr double BASIC_TO_NM
static constexpr double MM_TO_NM
static LSET PTHMask()
layer set for a through hole pad
static LSET UnplatedHoleMask()
layer set for a mechanical unplated through hole pad
A set of BOARD_ITEMs (i.e., without duplicates).
const IO_FILE_DESC GetBoardFileDesc() const override
Returns board file description for the PCB_IO.
int scaleSize(double aVal) const
Shorthands for the converter's transform, which the loaders below use everywhere.
std::map< std::string, std::string > m_partToBlockMap
int scaleCoord(double aVal, bool aIsX) const
void setPcbShapeArc(PCB_SHAPE *aShape, const PADS_IO::ARC_POINT &aPrev, const PADS_IO::ARC_POINT &aCurr)
Configure a PCB_SHAPE as an arc from two consecutive PADS points, applying the Y-axis winding fix.
std::map< std::string, std::string > m_pinToNetMap
PCB_LAYER_ID getMappedLayer(int aPadsLayer) const
bool CanReadBoard(const wxString &aFileName) const override
Checks if this PCB_IO can read the specified board file.
long long GetLibraryTimestamp(const wxString &aLibraryPath) const override
Generate a timestamp representing all the files in the library (including the library directory).
const IO_FILE_DESC GetLibraryDesc() const override
Get the descriptor for the library container that this IO plugin operates on.
void loadBoard(const wxString &aFileName, BOARD &aBoard, bool aIsNewLoad, const std::map< std::string, UTF8 > *aProperties, PROJECT *aProject) override
Parse aFileName into aBoard.
double decalUnitScale(const std::string &aUnits) const
Resolve a PADS decal/part UNITS letter to a nm-per-unit scale factor, or 0.0 to use the file's primar...
std::map< wxString, PCB_LAYER_ID > DefaultLayerMappingCallback(const std::vector< INPUT_LAYER_DESC > &aInputLayerDescriptionVector)
Return the automapped layers.
const PADS_IO::PARSER * m_parser
void loadReuseBlockGroups()
std::unique_ptr< PADS_PCB_CONVERTER > m_converter
virtual bool CanReadBoard(const wxString &aFileName) const
Checks if this PCB_IO can read the specified board file.
PCB_IO(const wxString &aName)
void SetWidth(int aWidth) override
void SetShape(SHAPE_T aShape) override
void SetEnd(const VECTOR2I &aEnd) override
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
void SetStart(const VECTOR2I &aStart) override
void SetStroke(const STROKE_PARAMS &aStroke) override
void SetTextThickness(int aWidth) override
The TextThickness is that set by the user.
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true) override
void SetPosition(const VECTOR2I &aPos) override
void SetTextAngle(const EDA_ANGLE &aAngle) override
void SetEnd(const VECTOR2I &aEnd)
void SetStart(const VECTOR2I &aStart)
virtual void SetWidth(int aWidth)
Container for project specific data.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
int PointCount() const
Return the number of points (vertices) in this line chain.
Represent a set of closed polygons.
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new outline to the set and returns its index.
bool IsPolygonSelfIntersecting(int aPolygonIndex) const
Check whether the aPolygonIndex-th polygon in the set is self intersecting.
void Inflate(int aAmount, CORNER_STRATEGY aCornerStrategy, int aMaxError, bool aSimplify=false)
Perform outline inflation/deflation.
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline)
void Simplify()
Simplify the polyset (merges overlapping polys, eliminates degeneracy/self-intersections)
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
int NewOutline()
Creates a new empty polygon in the set and returns its index.
int OutlineCount() const
Return the number of outlines in the set.
void BooleanSubtract(const SHAPE_POLY_SET &b)
Perform boolean polyset difference.
Simple container to manage line stroke parameters.
Handle a list of polygons defining a copper zone.
virtual PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
virtual void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
SHAPE_POLY_SET * Outline()
void SetIsRuleArea(bool aEnable)
void SetFilledPolysList(PCB_LAYER_ID aLayer, const SHAPE_POLY_SET &aPolysList)
Set the list of filled polygons.
void SetIsFilled(bool isFilled)
void SetNet(NETINFO_ITEM *aNetInfo) override
Override that drops aNetInfo when this zone is in copper-thieving fill mode.
static int GetDefaultHatchPitch()
void SetBorderDisplayStyle(ZONE_BORDER_DISPLAY_STYLE aBorderHatchStyle, int aBorderHatchPitch, bool aRebuilBorderHatch)
Set all hatch parameters for the zone.
@ ROUND_ALL_CORNERS
All angles are rounded.
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
double m_PadsPcbTextWidthScale
PADS text width scale factor for PCB imports.
double m_PadsPcbTextHeightScale
PADS text height scale factor for PCB imports.
int m_PcbImportMinObjectSizeNm
Minimum object size in nanometers for PCB imports.
#define THROW_IO_ERRORF(msg,...)
bool IsBackLayer(PCB_LAYER_ID aLayerId)
Layer classification: check if it's a back layer.
bool IsCopperLayer(int aLayerId)
Test whether a layer is a copper layer.
PCB_LAYER_ID
A quick note on layer IDs:
@ LEFT_RIGHT
Flip left to right (around the Y axis)
wxString ConvertText(const std::string &aText)
Decode text from a PADS file, which uses an 8-bit codepage rather than UTF-8.
wxString ConvertInvertedNetName(const std::string &aNetName)
Convert a PADS net name to KiCad notation.
KIID GenerateDeterministicUuid(const std::string &aIdentifier)
Generate a deterministic KIID from a PADS component identifier.
@ BURIED
Inner layers only.
@ THROUGH
Spans all copper layers.
@ BLIND
Surface to inner layer.
@ MICROVIA
Single-layer blind, typically HDI.
bool IsAntiPadRow(const PAD_STACK_LAYER &aLayer)
RA and SA rows carry a plane's anti-pad clearance rather than the pad's own copper.
bool IsThermalReliefPadRow(const PAD_STACK_LAYER &aLayer)
RT and ST rows carry a plane's thermal-relief spoke pattern rather than the pad's own copper.
bool IsCopperPadRow(const PAD_STACK_LAYER &aLayer)
True when the row describes pad or via copper.
PAD_SHAPE PadsShapeToKiCad(const std::string &aShape)
Map a PADS pad-stack shape code to a KiCad pad shape, shared by both PADS PCB importers.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
@ MILS
Thousandths of an inch.
@ 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.
Class to handle a set of BOARD_ITEMs.
Container that describes file type info.
wxString m_Description
Description shown in the file picker dialog.
std::vector< std::string > m_FileExtensions
Filter used for file pickers if m_IsFile is true.
A polyline point that may instead be an arc segment.
ARC arc
Only valid when is_arc is true.
Standalone copper area from the LINES section (type=COPPER), not part of a pour.
std::vector< ARC_POINT > outline
bool is_cutout
COPCUT, COPCCO.
std::string net_name
Empty if unconnected.
bool filled
COPCLS, COPCIR.
double width
For open polylines.
std::vector< ARC_POINT > points
std::string type
CLOSED, OPEN, CIRCLE, COPCLS, TAG, etc.
double silk_clearance
SILKCLEAR.
double default_track_width
DEFAULTTRACKWID.
double default_via_drill
DEFAULTVIADRILL.
double min_track_width
MINTRACKWID.
double min_via_size
MINVIASIZE.
double min_via_drill
MINVIADRILL.
double min_clearance
MINCLEAR.
double default_via_size
DEFAULTVIASIZE.
double copper_edge_clearance
OUTLINE_TO_*.
double default_clearance
DEFAULTCLEAR.
double hole_to_hole
HOLEHOLE.
double mask_clearance
MASKCLEAR.
Non-electrical drawing item from the LINES section (type=LINES).
bool chamfered
Negative corner value in PADS.
std::string shape
R, S, A, O, OF, RF, RT, ST, RA, SA, RC, OC.
double thermal_outer_diameter
Thermal or void in plane.
double slot_orientation
0-179.999 degrees
double thermal_spoke_orientation
First spoke.
double thermal_spoke_width
double finger_offset
Along orientation axis.
double sizeB
Height for rectangles/ovals.
double corner_radius
Always positive.
double sizeA
Diameter or width.
std::vector< DECAL_ITEM > items
std::vector< TERMINAL > terminals
std::map< int, std::vector< PAD_STACK_LAYER > > pad_stacks
std::map< std::string, std::string > attributes
From {...} block.
A polyline that may contain arc segments, used for board outlines and graphics.
std::vector< ARC_POINT > points
bool has_mask_front
Stack includes top soldermask, layer 25.
int start_layer
First PADS layer in span.
int end_layer
Last PADS layer in span.
std::vector< PAD_STACK_LAYER > stack
bool has_mask_back
Stack includes bottom soldermask, layer 28.
@ USER
The field ID hasn't been set yet; field is invalid.
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.
VECTOR2< int32_t > VECTOR2I
@ THERMAL
Use thermal relief for pads.