diff --git a/3d-viewer/3d_canvas/create_layer_items.cpp b/3d-viewer/3d_canvas/create_layer_items.cpp index ddafc41411..fa3d49a11a 100644 --- a/3d-viewer/3d_canvas/create_layer_items.cpp +++ b/3d-viewer/3d_canvas/create_layer_items.cpp @@ -303,7 +303,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter ) const PCB_VIA* via = static_cast( track ); const VIATYPE viatype = via->GetViaType(); const double holediameter = via->GetDrillValue() * BiuTo3dUnits(); - const double viasize = via->GetWidth() * BiuTo3dUnits(); + const double viasize = via->GetWidth( layer ) * BiuTo3dUnits(); const double plating = GetHolePlatingThickness() * BiuTo3dUnits(); // holes and layer copper extend half info cylinder wall to hide transition @@ -428,7 +428,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter ) { const int holediameter = via->GetDrillValue(); const int hole_outer_radius = (holediameter / 2) + GetHolePlatingThickness(); - const int hole_outer_ring_radius = KiROUND( via->GetWidth() / 2.0 ); + const int hole_outer_ring_radius = KiROUND( via->GetWidth( layer ) / 2.0 ); // Add through hole contours TransformCircleToPolygon( m_TH_ODPolys, via->GetStart(), hole_outer_radius, diff --git a/common/hash_eda.cpp b/common/hash_eda.cpp index 3c2b19c628..9606181e4e 100644 --- a/common/hash_eda.cpp +++ b/common/hash_eda.cpp @@ -80,14 +80,15 @@ size_t hash_fp_item( const EDA_ITEM* aItem, int aFlags ) case PCB_VIA_T: { const PCB_VIA* via = static_cast( aItem ); - ret = hash_val( via->GetWidth() ); - hash_combine( ret, via->GetDrillValue() ); + + ret = hash{}( via->GetDrillValue() ); hash_combine( ret, via->TopLayer() ); hash_combine( ret, via->BottomLayer() ); via->GetLayerSet().RunOnLayers( [&]( PCB_LAYER_ID layer ) { + hash_combine( ret, via->GetWidth( layer ) ); hash_combine( ret, via->FlashLayer( layer ) ); } ); diff --git a/pcbnew/connectivity/connectivity_data.cpp b/pcbnew/connectivity/connectivity_data.cpp index 0c936fed34..c37e889c70 100644 --- a/pcbnew/connectivity/connectivity_data.cpp +++ b/pcbnew/connectivity/connectivity_data.cpp @@ -485,8 +485,9 @@ bool CONNECTIVITY_DATA::IsConnectedOnLayer( const BOARD_CONNECTED_ITEM *aItem, i if( zone->IsFilled() ) { - const SHAPE_POLY_SET* zoneFill = zone->GetFill( ToLAYER_ID( aLayer ) ); - SHAPE_CIRCLE viaHull( via->GetCenter(), via->GetWidth() / 2 ); + PCB_LAYER_ID lyr = ToLAYER_ID( aLayer ); + const SHAPE_POLY_SET* zoneFill = zone->GetFill( lyr ); + SHAPE_CIRCLE viaHull( via->GetCenter(), via->GetWidth( lyr ) / 2 ); for( const VECTOR2I& pt : zoneFill->COutline( islandIdx ).CPoints() ) { diff --git a/pcbnew/dialogs/dialog_track_via_properties.cpp b/pcbnew/dialogs/dialog_track_via_properties.cpp index 03390b8f54..4475d3c7ba 100644 --- a/pcbnew/dialogs/dialog_track_via_properties.cpp +++ b/pcbnew/dialogs/dialog_track_via_properties.cpp @@ -212,7 +212,8 @@ DIALOG_TRACK_VIA_PROPERTIES::DIALOG_TRACK_VIA_PROPERTIES( PCB_BASE_FRAME* aParen { m_viaX.SetValue( v->GetPosition().x ); m_viaY.SetValue( v->GetPosition().y ); - m_viaDiameter.SetValue( v->GetWidth() ); + // TODO(JE) padstacks + m_viaDiameter.SetValue( v->GetWidth( PADSTACK::ALL_LAYERS ) ); m_viaDrill.SetValue( v->GetDrillValue() ); m_vias = true; viaType = v->GetViaType(); @@ -249,7 +250,7 @@ DIALOG_TRACK_VIA_PROPERTIES::DIALOG_TRACK_VIA_PROPERTIES( PCB_BASE_FRAME* aParen if( m_viaY.GetValue() != v->GetPosition().y ) m_viaY.SetValue( INDETERMINATE_STATE ); - if( m_viaDiameter.GetValue() != v->GetWidth() ) + if( m_viaDiameter.GetValue() != v->GetWidth( PADSTACK::ALL_LAYERS ) ) m_viaDiameter.SetValue( INDETERMINATE_STATE ); if( m_viaDrill.GetValue() != v->GetDrillValue() ) @@ -709,7 +710,7 @@ bool DIALOG_TRACK_VIA_PROPERTIES::TransferDataFromWindow() v->SanitizeLayers(); if( !m_viaDiameter.IsIndeterminate() ) - v->SetWidth( m_viaDiameter.GetIntValue() ); + v->SetWidth( PADSTACK::ALL_LAYERS, m_viaDiameter.GetIntValue() ); if( !m_viaDrill.IsIndeterminate() ) v->SetDrill( m_viaDrill.GetIntValue() ); diff --git a/pcbnew/drc/drc_test_provider_annular_width.cpp b/pcbnew/drc/drc_test_provider_annular_width.cpp index d4a2cd9909..0050f1c7a4 100644 --- a/pcbnew/drc/drc_test_provider_annular_width.cpp +++ b/pcbnew/drc/drc_test_provider_annular_width.cpp @@ -259,7 +259,8 @@ bool DRC_TEST_PROVIDER_ANNULAR_WIDTH::Run() case PCB_VIA_T: { PCB_VIA* via = static_cast( item ); - annularWidth = ( via->GetWidth() - via->GetDrillValue() ) / 2; + // TODO(JE) padstacks + annularWidth = ( via->GetWidth( PADSTACK::ALL_LAYERS ) - via->GetDrillValue() ) / 2; break; } diff --git a/pcbnew/drc/drc_test_provider_via_diameter.cpp b/pcbnew/drc/drc_test_provider_via_diameter.cpp index 3e4a7f944c..227e12b629 100644 --- a/pcbnew/drc/drc_test_provider_via_diameter.cpp +++ b/pcbnew/drc/drc_test_provider_via_diameter.cpp @@ -91,7 +91,8 @@ bool DRC_TEST_PROVIDER_VIA_DIAMETER::Run() bool fail_min = false; bool fail_max = false; int constraintDiameter = 0; - int actual = via->GetWidth(); + // TODO(JE) padstacks + int actual = via->GetWidth( PADSTACK::ALL_LAYERS ); if( constraint.GetSeverity() != RPT_SEVERITY_IGNORE ) { diff --git a/pcbnew/exporters/export_d356.cpp b/pcbnew/exporters/export_d356.cpp index 0beb9bcc29..abcd1e53bc 100644 --- a/pcbnew/exporters/export_d356.cpp +++ b/pcbnew/exporters/export_d356.cpp @@ -204,7 +204,8 @@ static void build_via_testpoints( BOARD *aPcb, std::vector & aRecor rk.access = via_access_code( aPcb, top_layer, bottom_layer ); rk.x_location = via->GetPosition().x - origin.x; rk.y_location = origin.y - via->GetPosition().y; - rk.x_size = via->GetWidth(); + // TODO(JE) padstacks + rk.x_size = via->GetWidth( PADSTACK::ALL_LAYERS ); rk.y_size = 0; // Round so height = 0 rk.rotation = 0; rk.soldermask = 3; // XXX always tented? diff --git a/pcbnew/exporters/export_gencad_writer.cpp b/pcbnew/exporters/export_gencad_writer.cpp index 93e5ba52b5..7015fc5d5a 100644 --- a/pcbnew/exporters/export_gencad_writer.cpp +++ b/pcbnew/exporters/export_gencad_writer.cpp @@ -233,8 +233,8 @@ bool GENCAD_EXPORTER::WriteFile( const wxString& aFullFileName ) // Sort vias for uniqueness static bool ViaSort( const PCB_VIA* aPadref, const PCB_VIA* aPadcmp ) { - if( aPadref->GetWidth() != aPadcmp->GetWidth() ) - return aPadref->GetWidth() < aPadcmp->GetWidth(); + if( aPadref->GetWidth( PADSTACK::ALL_LAYERS ) != aPadcmp->GetWidth( PADSTACK::ALL_LAYERS ) ) + return aPadref->GetWidth( PADSTACK::ALL_LAYERS ) < aPadcmp->GetWidth( PADSTACK::ALL_LAYERS ); if( aPadref->GetDrillValue() != aPadcmp->GetDrillValue() ) return aPadref->GetDrillValue() < aPadcmp->GetDrillValue(); @@ -302,10 +302,10 @@ void GENCAD_EXPORTER::CreatePadsShapesSection() { viastacks.push_back( via ); fprintf( m_file, "PAD V%d.%d.%s ROUND %g\nCIRCLE 0 0 %g\n", - via->GetWidth(), via->GetDrillValue(), + via->GetWidth( PADSTACK::ALL_LAYERS ), via->GetDrillValue(), fmt_mask( via->GetLayerSet() & master_layermask ).c_str(), via->GetDrillValue() / SCALE_FACTOR, - via->GetWidth() / (SCALE_FACTOR * 2) ); + via->GetWidth( PADSTACK::ALL_LAYERS ) / (SCALE_FACTOR * 2) ); } // Emit component pads @@ -554,14 +554,14 @@ void GENCAD_EXPORTER::CreatePadsShapesSection() LSET mask = via->GetLayerSet() & master_layermask; fprintf( m_file, "PADSTACK VIA%d.%d.%s %g\n", - via->GetWidth(), via->GetDrillValue(), + via->GetWidth( PADSTACK::ALL_LAYERS ), via->GetDrillValue(), fmt_mask( mask ).c_str(), via->GetDrillValue() / SCALE_FACTOR ); for( PCB_LAYER_ID layer : mask.Seq( gc_seq ) ) { fprintf( m_file, "PAD V%d.%d.%s %s 0 0\n", - via->GetWidth(), via->GetDrillValue(), + via->GetWidth( PADSTACK::ALL_LAYERS ), via->GetDrillValue(), fmt_mask( mask ).c_str(), GenCADLayerName( cu_count, layer ).c_str() ); } @@ -984,7 +984,7 @@ void GENCAD_EXPORTER::CreateRoutesSection() LSET vset = via->GetLayerSet() & master_layermask; fprintf( m_file, "VIA VIA%d.%d.%s %g %g ALL %g via%d\n", - via->GetWidth(), via->GetDrillValue(), + via->GetWidth( PADSTACK::ALL_LAYERS ), via->GetDrillValue(), fmt_mask( vset ).c_str(), MapXTo( via->GetStart().x ), MapYTo( via->GetStart().y ), via->GetDrillValue() / SCALE_FACTOR, vianum++ ); diff --git a/pcbnew/exporters/export_hyperlynx.cpp b/pcbnew/exporters/export_hyperlynx.cpp index 2ba6de3358..04e22dab22 100644 --- a/pcbnew/exporters/export_hyperlynx.cpp +++ b/pcbnew/exporters/export_hyperlynx.cpp @@ -233,8 +233,8 @@ HYPERLYNX_PAD_STACK::HYPERLYNX_PAD_STACK( BOARD* aBoard, const PAD* aPad ) HYPERLYNX_PAD_STACK::HYPERLYNX_PAD_STACK( BOARD* aBoard, const PCB_VIA* aVia ) { m_board = aBoard; - m_sx = aVia->GetWidth(); - m_sy = aVia->GetWidth(); + // TODO(JE) padstacks + m_sx = m_sy = aVia->GetWidth( PADSTACK::ALL_LAYERS ); m_angle = 0; m_layers = aVia->GetLayerSet(); m_drill = aVia->GetDrillValue(); diff --git a/pcbnew/pad.cpp b/pcbnew/pad.cpp index 222d0f37e3..80ce0ce031 100644 --- a/pcbnew/pad.cpp +++ b/pcbnew/pad.cpp @@ -1345,11 +1345,11 @@ bool PAD::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const Padstack().ForEachUniqueLayer( [&]( PCB_LAYER_ID l ) { - if( GetEffectivePolygon( l, ERROR_INSIDE )->Contains( aPosition, -1, aAccuracy ) ) - { - contains = true; + if( contains ) return; - } + + if( GetEffectivePolygon( l, ERROR_INSIDE )->Contains( aPosition, -1, aAccuracy ) ) + contains = true; } ); return contains; @@ -1380,6 +1380,9 @@ bool PAD::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const Padstack().ForEachUniqueLayer( [&]( PCB_LAYER_ID aLayer ) { + if( hit ) + return; + const std::shared_ptr& poly = GetEffectivePolygon( aLayer, ERROR_INSIDE ); diff --git a/pcbnew/pcb_io/altium/altium_pcb.cpp b/pcbnew/pcb_io/altium/altium_pcb.cpp index 39f5a01d2a..014160b5eb 100644 --- a/pcbnew/pcb_io/altium/altium_pcb.cpp +++ b/pcbnew/pcb_io/altium/altium_pcb.cpp @@ -3829,7 +3829,8 @@ void ALTIUM_PCB::ParseVias6Data( const ALTIUM_PCB_COMPOUND_FILE& aAltiumPcbF std::unique_ptr via = std::make_unique( m_board ); via->SetPosition( elem.position ); - via->SetWidth( elem.diameter ); + // TODO(JE) padstacks + via->SetWidth( PADSTACK::ALL_LAYERS, elem.diameter ); via->SetDrill( elem.holesize ); via->SetNetCode( GetNetCode( elem.net ) ); via->SetLocked( elem.is_locked ); diff --git a/pcbnew/pcb_io/cadstar/cadstar_pcb_archive_loader.cpp b/pcbnew/pcb_io/cadstar/cadstar_pcb_archive_loader.cpp index daa9154abb..c1e618f079 100644 --- a/pcbnew/pcb_io/cadstar/cadstar_pcb_archive_loader.cpp +++ b/pcbnew/pcb_io/cadstar/cadstar_pcb_archive_loader.cpp @@ -2603,7 +2603,7 @@ int CADSTAR_PCB_ARCHIVE_LOADER::loadNetVia( (double) ( (double) getKiCadLength( csViaCode.Shape.Size ) / 1E6 ) ); } - via->SetWidth( getKiCadLength( csViaCode.Shape.Size ) ); + via->SetWidth( PADSTACK::ALL_LAYERS, getKiCadLength( csViaCode.Shape.Size ) ); bool start_layer_outside = csLayerPair.PhysicalLayerStart == 1 @@ -2630,7 +2630,7 @@ int CADSTAR_PCB_ARCHIVE_LOADER::loadNetVia( via->SetNet( getKiCadNet( aCadstarNetID ) ); ///todo add netcode to the via - return via->GetWidth(); + return via->GetWidth( PADSTACK::ALL_LAYERS ); } diff --git a/pcbnew/pcb_io/eagle/pcb_io_eagle.cpp b/pcbnew/pcb_io/eagle/pcb_io_eagle.cpp index 6afbc17864..7ebafa5c85 100644 --- a/pcbnew/pcb_io/eagle/pcb_io_eagle.cpp +++ b/pcbnew/pcb_io/eagle/pcb_io_eagle.cpp @@ -2812,7 +2812,7 @@ void PCB_IO_EAGLE::loadSignals( wxXmlNode* aSignals ) if( v.diam ) { kidiam = v.diam->ToPcbUnits(); - via->SetWidth( kidiam ); + via->SetWidth( PADSTACK::ALL_LAYERS, kidiam ); } else { @@ -2820,20 +2820,21 @@ void PCB_IO_EAGLE::loadSignals( wxXmlNode* aSignals ) annulus = eagleClamp( m_rules->rlMinViaOuter, annulus, m_rules->rlMaxViaOuter ); kidiam = KiROUND( drillz + 2 * annulus ); - via->SetWidth( kidiam ); + via->SetWidth( PADSTACK::ALL_LAYERS, kidiam ); } via->SetDrill( drillz ); // make sure the via diameter respects the restring rules - if( !v.diam || via->GetWidth() <= via->GetDrill() ) + if( !v.diam || via->GetWidth( PADSTACK::ALL_LAYERS ) <= via->GetDrill() ) { - double annulus = - eagleClamp( m_rules->rlMinViaOuter, - (double) ( via->GetWidth() / 2 - via->GetDrill() ), - m_rules->rlMaxViaOuter ); - via->SetWidth( drillz + 2 * annulus ); + double annulus = eagleClamp( + m_rules->rlMinViaOuter, + static_cast( via->GetWidth( PADSTACK::ALL_LAYERS ) / 2 + - via->GetDrill() ), + m_rules->rlMaxViaOuter ); + via->SetWidth( PADSTACK::ALL_LAYERS, drillz + 2 * annulus ); } if( kidiam < m_min_via ) diff --git a/pcbnew/pcb_io/easyeda/pcb_io_easyeda_parser.cpp b/pcbnew/pcb_io/easyeda/pcb_io_easyeda_parser.cpp index 0d9c319025..ed8730fc26 100644 --- a/pcbnew/pcb_io/easyeda/pcb_io_easyeda_parser.cpp +++ b/pcbnew/pcb_io/easyeda/pcb_io_easyeda_parser.cpp @@ -863,7 +863,7 @@ void PCB_IO_EASYEDA_PARSER::ParseToBoardItemContainer( via->SetPosition( center ); - via->SetWidth( kdia ); + via->SetWidth( PADSTACK::ALL_LAYERS, kdia ); via->SetNet( getOrAddNetItem( arr[4] ) ); via->SetDrill( kdrill ); diff --git a/pcbnew/pcb_io/easyedapro/pcb_io_easyedapro_parser.cpp b/pcbnew/pcb_io/easyedapro/pcb_io_easyedapro_parser.cpp index a91b7cc14a..7c2e4c536a 100644 --- a/pcbnew/pcb_io/easyedapro/pcb_io_easyedapro_parser.cpp +++ b/pcbnew/pcb_io/easyedapro/pcb_io_easyedapro_parser.cpp @@ -1063,7 +1063,7 @@ void PCB_IO_EASYEDAPRO_PARSER::ParseBoard( via->SetPosition( ScalePos( center ) ); via->SetDrill( ScaleSize( drill ) ); - via->SetWidth( ScaleSize( dia ) ); + via->SetWidth( PADSTACK::ALL_LAYERS, ScaleSize( dia ) ); via->SetNet( aBoard->FindNet( netname ) ); diff --git a/pcbnew/pcb_io/fabmaster/import_fabmaster.cpp b/pcbnew/pcb_io/fabmaster/import_fabmaster.cpp index a3c0a9f06a..e38357f035 100644 --- a/pcbnew/pcb_io/fabmaster/import_fabmaster.cpp +++ b/pcbnew/pcb_io/fabmaster/import_fabmaster.cpp @@ -2526,19 +2526,19 @@ bool FABMASTER::loadVias( BOARD* aBoard ) if( !ds.m_ViasDimensionsList.empty() ) { - new_via->SetWidth( ds.m_ViasDimensionsList[0].m_Diameter ); + new_via->SetWidth( PADSTACK::ALL_LAYERS, ds.m_ViasDimensionsList[0].m_Diameter ); new_via->SetDrill( ds.m_ViasDimensionsList[0].m_Drill ); } else { new_via->SetDrillDefault(); - new_via->SetWidth( ds.m_ViasMinSize ); + new_via->SetWidth( PADSTACK::ALL_LAYERS, ds.m_ViasMinSize ); } } else { new_via->SetDrill( padstack->second.drill_size_x ); - new_via->SetWidth( padstack->second.width ); + new_via->SetWidth( PADSTACK::ALL_LAYERS, padstack->second.width ); } aBoard->Add( new_via, ADD_MODE::APPEND ); diff --git a/pcbnew/pcb_io/ipc2581/pcb_io_ipc2581.cpp b/pcbnew/pcb_io/ipc2581/pcb_io_ipc2581.cpp index b0ef404f47..b25b1e8aee 100644 --- a/pcbnew/pcb_io/ipc2581/pcb_io_ipc2581.cpp +++ b/pcbnew/pcb_io/ipc2581/pcb_io_ipc2581.cpp @@ -1671,7 +1671,7 @@ void PCB_IO_IPC2581::addVia( wxXmlNode* aContentNode, const PCB_VIA* aVia, PCB_L int hole = aVia->GetDrillValue(); dummy.SetDrillSize( VECTOR2I( hole, hole ) ); dummy.SetPosition( aVia->GetStart() ); - dummy.SetSize( PADSTACK::ALL_LAYERS, VECTOR2I( aVia->GetWidth(), aVia->GetWidth() ) ); + dummy.SetSize( aLayer, VECTOR2I( aVia->GetWidth( aLayer ), aVia->GetWidth( aLayer ) ) ); addShape( padNode, dummy, aLayer ); } @@ -1777,7 +1777,7 @@ void PCB_IO_IPC2581::addPadStack( wxXmlNode* aContentNode, const PCB_VIA* aVia ) PCB_SHAPE shape( nullptr, SHAPE_T::CIRCLE ); - shape.SetEnd( { KiROUND( aVia->GetWidth() / 2.0 ), 0 } ); + shape.SetEnd( { KiROUND( aVia->GetWidth( layer ) / 2.0 ), 0 } ); wxXmlNode* padStackPadDefNode = appendNode( padStackDefNode, "PadstackPadDef" ); addAttribute( padStackPadDefNode, "layerRef", m_layer_name_map[layer] ); diff --git a/pcbnew/pcb_io/kicad_legacy/pcb_io_kicad_legacy.cpp b/pcbnew/pcb_io/kicad_legacy/pcb_io_kicad_legacy.cpp index fa13e9fbde..c60978949c 100644 --- a/pcbnew/pcb_io/kicad_legacy/pcb_io_kicad_legacy.cpp +++ b/pcbnew/pcb_io/kicad_legacy/pcb_io_kicad_legacy.cpp @@ -2231,12 +2231,11 @@ void PCB_IO_KICAD_LEGACY::loadTrackList( int aStructType ) newTrack->SetPosition( VECTOR2I( start_x, start_y ) ); newTrack->SetEnd( VECTOR2I( end_x, end_y ) ); - newTrack->SetWidth( width ); - if( makeType == PCB_VIA_T ) // Ensure layers are OK when possible: { PCB_VIA *via = static_cast( newTrack ); via->SetViaType( viatype ); + via->SetWidth( PADSTACK::ALL_LAYERS, width ); if( drill < 0 ) via->SetDrillDefault(); @@ -2266,6 +2265,8 @@ void PCB_IO_KICAD_LEGACY::loadTrackList( int aStructType ) } else { + newTrack->SetWidth( width ); + // A few legacy boards can have tracks on non existent layers, because // reducing the number of layers does not remove tracks on removed layers // If happens, skip them diff --git a/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.cpp b/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.cpp index 35196e5ed4..56baebf046 100644 --- a/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.cpp +++ b/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.cpp @@ -2489,7 +2489,42 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_TRACK* aTrack, int aNestLevel ) const m_out->Print( 0, ")" ); } - formatTenting( via->Padstack() ); + const PADSTACK& padstack = via->Padstack(); + + formatTenting( padstack ); + + if( padstack.Mode() != PADSTACK::MODE::NORMAL ) + { + std::string mode = + padstack.Mode() == PADSTACK::MODE::CUSTOM ? "custom" : "front_inner_back"; + m_out->Print( 0, "(padstack (mode %s)", mode.c_str() ); + + if( padstack.Mode() == PADSTACK::MODE::FRONT_INNER_BACK ) + { + m_out->Print( 0, "(layer \"Inner\"" ); + m_out->Print( 0, " (size %s)", + formatInternalUnits( padstack.Size( PADSTACK::INNER_LAYERS ).x ).c_str() ); + m_out->Print( 0, ")(layer \"B.Cu\"" ); + m_out->Print( 0, " (size %s)", + formatInternalUnits( padstack.Size( B_Cu ).x ).c_str() ); + m_out->Print( 0, ")" ); + } + else + { + for( PCB_LAYER_ID layer : LAYER_RANGE( F_Cu, B_Cu, board->GetCopperLayerCount() ) ) + { + if( layer == F_Cu ) + continue; + + m_out->Print( 0, "(layer %s", m_out->Quotew( LSET::Name( layer ) ).c_str() ); + m_out->Print( 0, " (size %s)", + formatInternalUnits( padstack.Size( layer ).x ).c_str() ); + m_out->Print( 0, ")" ); + } + } + + m_out->Print( 0, ")" ); + } if( !isDefaultTeardropParameters( via->GetTeardropParams() ) ) { diff --git a/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.h b/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.h index a5df29a4e6..43eaafcd9d 100644 --- a/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.h +++ b/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.h @@ -164,7 +164,8 @@ class PCB_IO_KICAD_SEXPR; // forward decl //#define SEXPR_BOARD_FILE_VERSION 20240706 // Embedded Files //#define SEXPR_BOARD_FILE_VERSION 20240819 // Embedded Files - Update hash algorithm to Murmur3 //#define SEXPR_BOARD_FILE_VERSION 20240928 // Component classes -#define SEXPR_BOARD_FILE_VERSION 20240929 // Complex padstacks +//#define SEXPR_BOARD_FILE_VERSION 20240929 // Complex padstacks +#define SEXPR_BOARD_FILE_VERSION 20241006 // Via stacks #define BOARD_FILE_HOST_VERSION 20200825 ///< Earlier files than this include the host tag #define LEGACY_ARC_FORMATTING 20210925 ///< These were the last to use old arc formatting diff --git a/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr_parser.cpp b/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr_parser.cpp index 4ee463bf1c..05c2f8e23c 100644 --- a/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr_parser.cpp +++ b/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr_parser.cpp @@ -6262,7 +6262,7 @@ PCB_VIA* PCB_IO_KICAD_SEXPR_PARSER::parsePCB_VIA() break; case T_size: - via->SetWidth( parseBoardUnits( "via width" ) ); + via->SetWidth( PADSTACK::ALL_LAYERS, parseBoardUnits( "via width" ) ); NeedRIGHT(); break; @@ -6333,6 +6333,10 @@ PCB_VIA* PCB_IO_KICAD_SEXPR_PARSER::parsePCB_VIA() } break; + case T_padstack: + parseViastack( via.get() ); + break; + case T_teardrops: parseTEARDROP_PARAMETERS( &via->GetTeardropParams() ); break; @@ -6393,6 +6397,103 @@ void PCB_IO_KICAD_SEXPR_PARSER::parseTenting( PADSTACK& aPadstack ) } +void PCB_IO_KICAD_SEXPR_PARSER::parseViastack( PCB_VIA* aVia ) +{ + PADSTACK& padstack = aVia->Padstack(); + + for( T token = NextTok(); token != T_RIGHT; token = NextTok() ) + { + if( token != T_LEFT ) + Expecting( T_LEFT ); + + token = NextTok(); + + switch( token ) + { + case T_mode: + token = NextTok(); + + switch( token ) + { + case T_front_inner_back: + padstack.SetMode( PADSTACK::MODE::FRONT_INNER_BACK ); + break; + + case T_custom: + padstack.SetMode( PADSTACK::MODE::CUSTOM ); + break; + + default: + Expecting( "front_inner_back or custom" ); + } + + NeedRIGHT(); + break; + + case T_layer: + { + NextTok(); + PCB_LAYER_ID curLayer = UNDEFINED_LAYER; + + if( curText == "Inner" ) + { + if( padstack.Mode() != PADSTACK::MODE::FRONT_INNER_BACK ) + { + THROW_IO_ERROR( wxString::Format( _( "Invalid padstack layer in\nfile: %s\n" + "line: %d\noffset: %d." ), + CurSource(), CurLineNumber(), CurOffset() ) ); + } + + curLayer = PADSTACK::INNER_LAYERS; + } + else + { + curLayer = lookUpLayer( m_layerIndices ); + } + + if( !IsCopperLayer( curLayer ) ) + { + wxString error; + error.Printf( _( "Invalid padstack layer '%s' in file '%s' at line %d, offset %d." ), + curText, CurSource().GetData(), CurLineNumber(), CurOffset() ); + THROW_IO_ERROR( error ); + } + + for( token = NextTok(); token != T_RIGHT; token = NextTok() ) + { + if( token != T_LEFT ) + Expecting( T_LEFT ); + + token = NextTok(); + + switch( token ) + { + + case T_size: + { + int diameter = parseBoardUnits( "via width" ); + padstack.SetSize( { diameter, diameter }, curLayer ); + NeedRIGHT(); + break; + } + + default: + // Currently only supporting custom via diameter per layer, not other properties + Expecting( "size" ); + } + } + + break; + } + + default: + Expecting( "mode or layer" ); + break; + } + } +} + + ZONE* PCB_IO_KICAD_SEXPR_PARSER::parseZONE( BOARD_ITEM_CONTAINER* aParent ) { wxCHECK_MSG( CurTok() == T_zone, nullptr, diff --git a/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr_parser.h b/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr_parser.h index 3c176929a4..4b2fb052e8 100644 --- a/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr_parser.h +++ b/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr_parser.h @@ -237,6 +237,7 @@ private: PCB_ARC* parseARC(); PCB_TRACK* parsePCB_TRACK(); PCB_VIA* parsePCB_VIA(); + void parseViastack( PCB_VIA* aVia ); ZONE* parseZONE( BOARD_ITEM_CONTAINER* aParent ); PCB_TARGET* parsePCB_TARGET(); BOARD* parseBOARD(); diff --git a/pcbnew/pcb_io/odbpp/odb_feature.cpp b/pcbnew/pcb_io/odbpp/odb_feature.cpp index 2d757d3f52..cd09bdd988 100644 --- a/pcbnew/pcb_io/odbpp/odb_feature.cpp +++ b/pcbnew/pcb_io/odbpp/odb_feature.cpp @@ -406,7 +406,7 @@ void FEATURES_MANAGER::InitFeatureList( PCB_LAYER_ID aLayer, std::vectorGetWidth() ) } ); + + std::to_string( via->GetWidth( aLayer ) ) } ); } } else @@ -428,7 +428,7 @@ void FEATURES_MANAGER::InitFeatureList( PCB_LAYER_ID aLayer, std::vectorGetWidth() ) } ); + + std::to_string( via->GetWidth( aLayer ) ) } ); } } } diff --git a/pcbnew/pcb_io/pcad/pcad_pad.cpp b/pcbnew/pcb_io/pcad/pcad_pad.cpp index 5f0e4b5178..5b7f4d7319 100644 --- a/pcbnew/pcb_io/pcad/pcad_pad.cpp +++ b/pcbnew/pcb_io/pcad/pcad_pad.cpp @@ -359,7 +359,7 @@ void PCAD_PAD::AddToBoard( FOOTPRINT* aFootprint ) via->SetPosition( VECTOR2I( m_PositionX, m_PositionY ) ); via->SetEnd( VECTOR2I( m_PositionX, m_PositionY ) ); - via->SetWidth( height ); + via->SetWidth( PADSTACK::ALL_LAYERS, height ); via->SetViaType( VIATYPE::THROUGH ); via->SetLayerPair( F_Cu, B_Cu ); via->SetDrill( m_Hole ); diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp index ce47b38ad5..ab4314cb40 100644 --- a/pcbnew/pcb_painter.cpp +++ b/pcbnew/pcb_painter.cpp @@ -936,6 +936,7 @@ void PCB_PAINTER::draw( const PCB_VIA* aVia, int aLayer ) if( color == COLOR4D::CLEAR ) return; + PCB_LAYER_ID currentLayer = ToLAYER_ID( aLayer ); PCB_LAYER_ID layerTop, layerBottom; aVia->LayerPair( &layerTop, &layerBottom ); @@ -958,7 +959,7 @@ void PCB_PAINTER::draw( const PCB_VIA* aVia, int aLayer ) return; double maxSize = PCB_RENDER_SETTINGS::MAX_FONT_SIZE; - double size = aVia->GetWidth(); + double size = aVia->GetWidth( currentLayer ); // Font size limits if( size > maxSize ) @@ -1106,12 +1107,12 @@ void PCB_PAINTER::draw( const PCB_VIA* aVia, int aLayer ) m_gal->SetIsStroke( false ); m_gal->SetLineWidth( margin ); - m_gal->DrawCircle( center, aVia->GetWidth() / 2.0 + margin ); + m_gal->DrawCircle( center, aVia->GetWidth( currentLayer ) / 2.0 + margin ); } else if( m_pcbSettings.IsPrinting() || IsCopperLayer( aLayer ) ) { - int annular_width = ( aVia->GetWidth() - getViaDrillSize( aVia ) ) / 2.0; - double radius = aVia->GetWidth() / 2.0; + int annular_width = ( aVia->GetWidth( currentLayer ) - getViaDrillSize( aVia ) ) / 2.0; + double radius = aVia->GetWidth( currentLayer ) / 2.0; bool draw = false; if( m_pcbSettings.IsPrinting() ) @@ -1143,7 +1144,8 @@ void PCB_PAINTER::draw( const PCB_VIA* aVia, int aLayer ) { m_gal->SetLineWidth( m_lockedShadowMargin ); - m_gal->DrawCircle( center, ( aVia->GetWidth() + m_lockedShadowMargin ) / 2.0 ); + m_gal->DrawCircle( center, + ( aVia->GetWidth( currentLayer ) + m_lockedShadowMargin ) / 2.0 ); } // Clearance lines @@ -1165,7 +1167,7 @@ void PCB_PAINTER::draw( const PCB_VIA* aVia, int aLayer ) double radius; if( aVia->FlashLayer( activeLayer ) ) - radius = aVia->GetWidth() / 2.0; + radius = aVia->GetWidth( activeLayer ) / 2.0; else radius = getViaDrillSize( aVia ) / 2.0 + m_holePlatingThickness; diff --git a/pcbnew/pcb_track.cpp b/pcbnew/pcb_track.cpp index fc694115e9..75016713ea 100644 --- a/pcbnew/pcb_track.cpp +++ b/pcbnew/pcb_track.cpp @@ -308,17 +308,34 @@ double PCB_VIA::Similarity( const BOARD_ITEM& aOther ) const return similarity; } - +#if 0 void PCB_VIA::SetWidth( int aWidth ) { + // This is present because of the parent class. It should never be actually called on a via. + wxASSERT_MSG( false, "Warning: PCB_VIA::SetWidth called without a layer argument" ); m_padStack.SetSize( { aWidth, aWidth }, PADSTACK::ALL_LAYERS ); } int PCB_VIA::GetWidth() const { + // This is present because of the parent class. It should never be actually called on a via. + wxASSERT_MSG( false, "Warning: PCB_VIA::GetWidth called without a layer argument" ); return m_padStack.Size( PADSTACK::ALL_LAYERS ).x; } +#endif + + +void PCB_VIA::SetWidth( PCB_LAYER_ID aLayer, int aWidth ) +{ + m_padStack.SetSize( { aWidth, aWidth }, aLayer ); +} + + +int PCB_VIA::GetWidth( PCB_LAYER_ID aLayer ) const +{ + return m_padStack.Size( aLayer ).x; +} void PCB_TRACK::Serialize( google::protobuf::Any &aContainer ) const @@ -447,7 +464,7 @@ bool PCB_VIA::Deserialize( const google::protobuf::Any &aContainer ) return false; // We don't yet support complex padstacks for vias - SetWidth( m_padStack.Size( PADSTACK::ALL_LAYERS ).x ); + SetWidth( PADSTACK::ALL_LAYERS, m_padStack.Size( PADSTACK::ALL_LAYERS ).x ); SetViaType( FromProtoEnum( via.type() ) ); SetNetCode( via.net().code().value() ); SetLocked( via.locked() == kiapi::common::types::LockedState::LS_LOCKED ); @@ -1307,7 +1324,7 @@ double PCB_VIA::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const if( const BOARD* board = GetBoard() ) visible = board->GetVisibleLayers() & board->GetEnabledLayers(); - int width = GetWidth(); + int width = GetWidth( ToLAYER_ID( aLayer ) ); // In high contrast mode don't show vias that don't cross the high-contrast layer if( renderSettings->GetHighContrast() ) @@ -1465,7 +1482,9 @@ void PCB_VIA::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vectorMessageTextFromValue( GetWidth() ) ); + // TODO(JE) padstacks + aList.emplace_back( _( "Diameter" ), + aFrame->MessageTextFromValue( GetWidth( PADSTACK::ALL_LAYERS ) ) ); aList.emplace_back( _( "Hole" ), aFrame->MessageTextFromValue( GetDrillValue() ) ); wxString source; @@ -1565,12 +1584,25 @@ bool PCB_ARC::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const bool PCB_VIA::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const { - int max_dist = aAccuracy + ( GetWidth() / 2 ); + bool hit = false; - // rel_pos is aPosition relative to m_Start (or the center of the via) - VECTOR2I rel_pos = aPosition - m_Start; - double dist = (double) rel_pos.x * rel_pos.x + (double) rel_pos.y * rel_pos.y; - return dist <= (double) max_dist * max_dist; + Padstack().ForEachUniqueLayer( + [&]( PCB_LAYER_ID aLayer ) + { + if( hit ) + return; + + int max_dist = aAccuracy + ( GetWidth( aLayer ) / 2 ); + + // rel_pos is aPosition relative to m_Start (or the center of the via) + VECTOR2D rel_pos = aPosition - m_Start; + double dist = rel_pos.x * rel_pos.x + rel_pos.y * rel_pos.y; + + if( dist <= static_cast( max_dist ) * max_dist ) + hit = true; + } ); + + return hit; } @@ -1609,13 +1641,24 @@ bool PCB_VIA::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) cons BOX2I arect = aRect; arect.Inflate( aAccuracy ); - BOX2I box( GetStart() ); - box.Inflate( GetWidth() / 2 ); + bool hit = false; - if( aContained ) - return arect.Contains( box ); - else - return arect.IntersectsCircle( GetStart(), GetWidth() / 2 ); + Padstack().ForEachUniqueLayer( + [&]( PCB_LAYER_ID aLayer ) + { + if( hit ) + return; + + BOX2I box( GetStart() ); + box.Inflate( GetWidth( aLayer ) / 2 ); + + if( aContained ) + hit = arect.Contains( box ); + else + hit = arect.IntersectsCircle( GetStart(), GetWidth( aLayer ) / 2 ); + } ); + + return hit; } @@ -1739,7 +1782,8 @@ std::shared_ptr PCB_VIA::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING if( aFlash == FLASHING::ALWAYS_FLASHED || ( aFlash == FLASHING::DEFAULT && FlashLayer( aLayer ) ) ) { - return std::make_shared( m_Start, GetWidth() / 2 ); + PCB_LAYER_ID cuLayer = m_padStack.EffectiveLayerFor( aLayer ); + return std::make_shared( m_Start, GetWidth( cuLayer ) / 2 ); } else { @@ -1765,7 +1809,7 @@ void PCB_TRACK::TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID a { case PCB_VIA_T: { - int radius = ( static_cast( this )->GetWidth() / 2 ) + aClearance; + int radius = ( static_cast( this )->GetWidth( aLayer ) / 2 ) + aClearance; TransformCircleToPolygon( aBuffer, m_Start, radius, aError, aErrorLoc ); break; } @@ -1854,7 +1898,7 @@ static struct TRACK_VIA_DESC propMgr.Mask( TYPE_HASH( PCB_VIA ), TYPE_HASH( BOARD_CONNECTED_ITEM ), _HKI( "Layer" ) ); propMgr.AddProperty( new PROPERTY( _HKI( "Diameter" ), - &PCB_VIA::SetWidth, &PCB_VIA::GetWidth, PROPERTY_DISPLAY::PT_SIZE ), groupVia ); + &PCB_VIA::SetFrontWidth, &PCB_VIA::GetFrontWidth, PROPERTY_DISPLAY::PT_SIZE ), groupVia ); propMgr.AddProperty( new PROPERTY( _HKI( "Hole" ), &PCB_VIA::SetDrill, &PCB_VIA::GetDrillValue, PROPERTY_DISPLAY::PT_SIZE ), groupVia ); propMgr.AddProperty( new PROPERTY_ENUM( _HKI( "Layer Top" ), diff --git a/pcbnew/pcb_track.h b/pcbnew/pcb_track.h index dbc649c7cf..492b87b724 100644 --- a/pcbnew/pcb_track.h +++ b/pcbnew/pcb_track.h @@ -385,9 +385,16 @@ public: const PADSTACK& Padstack() const { return m_padStack; } PADSTACK& Padstack() { return m_padStack; } void SetPadstack( const PADSTACK& aPadstack ) { m_padStack = aPadstack; } - +#if 0 void SetWidth( int aWidth ) override; int GetWidth() const override; +#endif + void SetWidth( PCB_LAYER_ID aLayer, int aWidth ); + int GetWidth( PCB_LAYER_ID aLayer ) const; + + // For properties panel + void SetFrontWidth( int aWidth ) { SetWidth( F_Cu, aWidth ); } + int GetFrontWidth() const { return GetWidth( F_Cu ); } bool HasHole() const override { diff --git a/pcbnew/plot_board_layers.cpp b/pcbnew/plot_board_layers.cpp index 171383e987..34837985b8 100644 --- a/pcbnew/plot_board_layers.cpp +++ b/pcbnew/plot_board_layers.cpp @@ -635,7 +635,8 @@ void PlotStandardLayer( BOARD* aBoard, PLOTTER* aPlotter, LSET aLayerMask, if( ( aLayerMask & LSET::AllCuMask() ).any() ) width_adj = itemplotter.getFineWidthAdj(); - int diameter = via->GetWidth() + 2 * via_margin + width_adj; + // TODO(JE) padstacks + int diameter = via->GetWidth( PADSTACK::ALL_LAYERS ) + 2 * via_margin + width_adj; /// Vias not connected to copper are optionally not drawn if( onCopperLayer && !via->FlashLayer( aLayerMask ) ) diff --git a/pcbnew/plot_brditems_plotter.cpp b/pcbnew/plot_brditems_plotter.cpp index 76030a010a..2f568c384d 100644 --- a/pcbnew/plot_brditems_plotter.cpp +++ b/pcbnew/plot_brditems_plotter.cpp @@ -1201,7 +1201,8 @@ void BRDITEMS_PLOTTER::PlotDrillMarks() continue; plotOneDrillMark( PAD_DRILL_SHAPE::CIRCLE, via->GetStart(), - VECTOR2I( via->GetDrillValue(), 0 ), VECTOR2I( via->GetWidth(), 0 ), + VECTOR2I( via->GetDrillValue(), 0 ), + VECTOR2I( via->GetWidth( PADSTACK::ALL_LAYERS ), 0 ), ANGLE_0, smallDrill ); } } diff --git a/pcbnew/router/pns_kicad_iface.cpp b/pcbnew/router/pns_kicad_iface.cpp index e3cb1a72bd..036b93b67d 100644 --- a/pcbnew/router/pns_kicad_iface.cpp +++ b/pcbnew/router/pns_kicad_iface.cpp @@ -1158,7 +1158,6 @@ std::vector> PNS_KICAD_IFACE_BASE::syncPad( PAD* aPa return solids; } - // TODO(JE) padstacks - need to make multiple solids for custom padstack situations auto makeSolidFromPadLayer = [&]( PCB_LAYER_ID aLayer ) { @@ -1280,33 +1279,40 @@ std::unique_ptr PNS_KICAD_IFACE_BASE::syncArc( PCB_ARC* aArc ) } -std::unique_ptr PNS_KICAD_IFACE_BASE::syncVia( PCB_VIA* aVia ) +std::vector> PNS_KICAD_IFACE_BASE::syncVia( PCB_VIA* aVia ) { + std::vector> vias; PCB_LAYER_ID top, bottom; aVia->LayerPair( &top, &bottom ); - auto via = std::make_unique( aVia->GetPosition(), + aVia->Padstack().ForEachUniqueLayer( + [&]( PCB_LAYER_ID aLayer ) + { + auto via = std::make_unique( aVia->GetPosition(), SetLayersFromPCBNew( aVia->TopLayer(), aVia->BottomLayer() ), - aVia->GetWidth(), + aVia->GetWidth( aLayer ), aVia->GetDrillValue(), aVia->GetNet(), aVia->GetViaType() ); - via->SetParent( aVia ); + via->SetParent( aVia ); - if( aVia->IsLocked() ) - via->Mark( PNS::MK_LOCKED ); + if( aVia->IsLocked() ) + via->Mark( PNS::MK_LOCKED ); - if( PCB_GENERATOR* generator = dynamic_cast( aVia->GetParentGroup() ) ) - { - if( !generator->HasFlag( IN_EDIT ) ) - via->Mark( PNS::MK_LOCKED ); - } + if( PCB_GENERATOR* generator = dynamic_cast( aVia->GetParentGroup() ) ) + { + if( !generator->HasFlag( IN_EDIT ) ) + via->Mark( PNS::MK_LOCKED ); + } - via->SetIsFree( aVia->GetIsFree() ); - via->SetHole( PNS::HOLE::MakeCircularHole( aVia->GetPosition(), aVia->GetDrillValue() / 2 ) ); + via->SetIsFree( aVia->GetIsFree() ); + via->SetHole( PNS::HOLE::MakeCircularHole( aVia->GetPosition(), + aVia->GetDrillValue() / 2 ) ); + vias.emplace_back( std::move( via ) ); + } ); - return via; + return vias; } @@ -1694,7 +1700,9 @@ void PNS_KICAD_IFACE_BASE::SyncWorld( PNS::NODE *aWorld ) } else if( type == PCB_VIA_T ) { - if( std::unique_ptr via = syncVia( static_cast( t ) ) ) + std::vector> vias = syncVia( static_cast( t ) ); + + for( std::unique_ptr& via : vias ) aWorld->Add( std::move( via ) ); } } @@ -1946,7 +1954,7 @@ void PNS_KICAD_IFACE::modifyBoardItem( PNS::ITEM* aItem ) m_commit->Modify( via_board ); via_board->SetPosition( VECTOR2I( via->Pos().x, via->Pos().y ) ); - via_board->SetWidth( via->Diameter() ); + via_board->SetWidth( PADSTACK::ALL_LAYERS, via->Diameter() ); via_board->SetDrill( via->Drill() ); via_board->SetNet( static_cast( via->Net() ) ); via_board->SetViaType( via->ViaType() ); // MUST be before SetLayerPair() @@ -2026,7 +2034,7 @@ BOARD_CONNECTED_ITEM* PNS_KICAD_IFACE::createBoardItem( PNS::ITEM* aItem ) PCB_VIA* via_board = new PCB_VIA( m_board ); PNS::VIA* via = static_cast( aItem ); via_board->SetPosition( VECTOR2I( via->Pos().x, via->Pos().y ) ); - via_board->SetWidth( via->Diameter() ); + via_board->SetWidth( PADSTACK::ALL_LAYERS, via->Diameter() ); via_board->SetDrill( via->Drill() ); via_board->SetNet( net ); via_board->SetViaType( via->ViaType() ); // MUST be before SetLayerPair() diff --git a/pcbnew/router/pns_kicad_iface.h b/pcbnew/router/pns_kicad_iface.h index 2e05c1d8cc..0f9a87335a 100644 --- a/pcbnew/router/pns_kicad_iface.h +++ b/pcbnew/router/pns_kicad_iface.h @@ -107,7 +107,7 @@ protected: std::vector> syncPad( PAD* aPad ); std::unique_ptr syncTrack( PCB_TRACK* aTrack ); std::unique_ptr syncArc( PCB_ARC* aArc ); - std::unique_ptr syncVia( PCB_VIA* aVia ); + std::vector> syncVia( PCB_VIA* aVia ); bool syncTextItem( PNS::NODE* aWorld, PCB_TEXT* aText, PCB_LAYER_ID aLayer ); bool syncGraphicalItem( PNS::NODE* aWorld, PCB_SHAPE* aItem ); bool syncZone( PNS::NODE* aWorld, ZONE* aZone, SHAPE_POLY_SET* aBoardOutline ); diff --git a/pcbnew/specctra_import_export/specctra_export.cpp b/pcbnew/specctra_import_export/specctra_export.cpp index 5bf4fc57d3..afbe449059 100644 --- a/pcbnew/specctra_import_export/specctra_export.cpp +++ b/pcbnew/specctra_import_export/specctra_export.cpp @@ -1028,7 +1028,9 @@ PADSTACK* SPECCTRA_DB::makeVia( const PCB_VIA* aVia ) if( topLayer > botLayer ) std::swap( topLayer, botLayer ); - return makeVia( aVia->GetWidth(), aVia->GetDrillValue(), topLayer, botLayer ); + // TODO(JE) padstacks + return makeVia( aVia->GetWidth( ::PADSTACK::ALL_LAYERS ), aVia->GetDrillValue(), + topLayer, botLayer ); } diff --git a/pcbnew/specctra_import_export/specctra_import.cpp b/pcbnew/specctra_import_export/specctra_import.cpp index f67bedf52c..1ed04063e4 100644 --- a/pcbnew/specctra_import_export/specctra_import.cpp +++ b/pcbnew/specctra_import_export/specctra_import.cpp @@ -228,7 +228,7 @@ PCB_VIA* SPECCTRA_DB::makeVIA( WIRE_VIA*aVia, PADSTACK* aPadstack, const POINT& via->SetPosition( mapPt( aPoint, m_routeResolution ) ); via->SetDrill( drill_diam_iu ); via->SetViaType( VIATYPE::THROUGH ); - via->SetWidth( viaDiam ); + via->SetWidth( ::PADSTACK::ALL_LAYERS, viaDiam ); via->SetLayerPair( F_Cu, B_Cu ); } else if( shapeCount == copperLayerCount ) @@ -249,7 +249,7 @@ PCB_VIA* SPECCTRA_DB::makeVIA( WIRE_VIA*aVia, PADSTACK* aPadstack, const POINT& via->SetPosition( mapPt( aPoint, m_routeResolution ) ); via->SetDrill( drill_diam_iu ); via->SetViaType( VIATYPE::THROUGH ); - via->SetWidth( viaDiam ); + via->SetWidth( ::PADSTACK::ALL_LAYERS, viaDiam ); via->SetLayerPair( F_Cu, B_Cu ); } else // VIA_MICROVIA or VIA_BLIND_BURIED @@ -304,7 +304,7 @@ PCB_VIA* SPECCTRA_DB::makeVIA( WIRE_VIA*aVia, PADSTACK* aPadstack, const POINT& via->SetViaType( VIATYPE::BLIND_BURIED ); } - via->SetWidth( viaDiam ); + via->SetWidth( ::PADSTACK::ALL_LAYERS, viaDiam ); via->SetLayerPair( m_pcbLayer2kicad[ topLayerNdx ], m_pcbLayer2kicad[ botLayerNdx ] ); } diff --git a/pcbnew/teardrop/teardrop.cpp b/pcbnew/teardrop/teardrop.cpp index 1156f84b89..979715e15a 100644 --- a/pcbnew/teardrop/teardrop.cpp +++ b/pcbnew/teardrop/teardrop.cpp @@ -241,7 +241,7 @@ void TEARDROP_MANAGER::UpdateTeardrops( BOARD_COMMIT& aCommit, continue; TEARDROP_PARAMETERS tdParams = via->GetTeardropParams(); - int annularWidth = via->GetWidth(); + int annularWidth = via->GetWidth( track->GetLayer() ); if( !tdParams.m_Enabled ) continue; diff --git a/pcbnew/teardrop/teardrop_utils.cpp b/pcbnew/teardrop/teardrop_utils.cpp index a5838d0321..2fdcfe3d83 100644 --- a/pcbnew/teardrop/teardrop_utils.cpp +++ b/pcbnew/teardrop/teardrop_utils.cpp @@ -66,8 +66,9 @@ int TEARDROP_MANAGER::GetWidth( BOARD_ITEM* aItem ) { if( aItem->Type() == PCB_VIA_T ) { + // TODO(JE) padstacks PCB_VIA* via = static_cast( aItem ); - return via->GetWidth(); + return via->GetWidth( PADSTACK::ALL_LAYERS ); } else if( aItem->Type() == PCB_PAD_T ) { diff --git a/pcbnew/tools/board_editor_control.cpp b/pcbnew/tools/board_editor_control.cpp index 99fcbc53e5..d03ee95a00 100644 --- a/pcbnew/tools/board_editor_control.cpp +++ b/pcbnew/tools/board_editor_control.cpp @@ -912,10 +912,11 @@ int BOARD_EDITOR_CONTROL::ViaSizeInc( const TOOL_EVENT& aEvent ) if( i> 0 ) dims = bds.m_ViasDimensionsList[ i ]; - if( dims.m_Diameter > via->GetWidth() ) + // TODO(JE) padstacks + if( dims.m_Diameter > via->GetWidth( PADSTACK::ALL_LAYERS ) ) { commit.Modify( via ); - via->SetWidth( dims.m_Diameter ); + via->SetWidth( PADSTACK::ALL_LAYERS, dims.m_Diameter ); via->SetDrill( dims.m_Drill ); break; } @@ -967,10 +968,11 @@ int BOARD_EDITOR_CONTROL::ViaSizeDec( const TOOL_EVENT& aEvent ) if( i > 0 ) dims = bds.m_ViasDimensionsList[ i ]; - if( dims.m_Diameter < via->GetWidth() ) + // TODO(JE) padstacks + if( dims.m_Diameter < via->GetWidth( PADSTACK::ALL_LAYERS ) ) { commit.Modify( via ); - via->SetWidth( dims.m_Diameter ); + via->SetWidth( PADSTACK::ALL_LAYERS, dims.m_Diameter ); via->SetDrill( dims.m_Drill ); break; } diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index 83a7d81079..71f61561a5 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -3467,7 +3467,8 @@ int DRAWING_TOOL::DrawVia( const TOOL_EVENT& aEvent ) PCB_TRACK* track = static_cast( item ); if( TestSegmentHit( position, track->GetStart(), track->GetEnd(), - ( track->GetWidth() + aVia->GetWidth() ) / 2 ) ) + ( track->GetWidth() + + aVia->GetWidth( track->GetLayer() ) ) / 2 ) ) { possible_tracks.push_back( track ); } @@ -3476,7 +3477,7 @@ int DRAWING_TOOL::DrawVia( const TOOL_EVENT& aEvent ) { PCB_ARC* arc = static_cast( item ); - if( arc->HitTest( position, aVia->GetWidth() / 2 ) ) + if( arc->HitTest( position, aVia->GetWidth( arc->GetLayer() ) / 2 ) ) possible_tracks.push_back( arc ); } } @@ -3501,6 +3502,8 @@ int DRAWING_TOOL::DrawVia( const TOOL_EVENT& aEvent ) bool hasDRCViolation( PCB_VIA* aVia, BOARD_ITEM* aOther ) { + PCB_LAYER_ID activeLayer = m_frame->GetActiveLayer(); + DRC_CONSTRAINT constraint; int clearance; BOARD_CONNECTED_ITEM* connectedItem = dynamic_cast( aOther ); @@ -3509,7 +3512,24 @@ int DRAWING_TOOL::DrawVia( const TOOL_EVENT& aEvent ) if( zone && zone->GetIsRuleArea() ) { if( zone->GetDoNotAllowVias() ) - return zone->Outline()->Collide( aVia->GetPosition(), aVia->GetWidth() / 2 ); + { + bool hit = false; + + aVia->Padstack().ForEachUniqueLayer( + [&]( PCB_LAYER_ID aLayer ) + { + if( hit ) + return; + + if( zone->Outline()->Collide( aVia->GetPosition(), + aVia->GetWidth( aLayer ) / 2 ) ) + { + hit = true; + } + } ); + + return hit; + } return false; } @@ -3638,6 +3658,7 @@ int DRAWING_TOOL::DrawVia( const TOOL_EVENT& aEvent ) std::vector items; KIGFX::PCB_VIEW* view = m_frame->GetCanvas()->GetView(); + PCB_LAYER_ID activeLayer = m_frame->GetActiveLayer(); std::vector possible_shapes; view->Query( bbox, items ); @@ -3653,7 +3674,7 @@ int DRAWING_TOOL::DrawVia( const TOOL_EVENT& aEvent ) { PCB_SHAPE* shape = static_cast( item ); - if( shape->HitTest( position, aVia->GetWidth() / 2 ) ) + if( shape->HitTest( position, aVia->GetWidth( activeLayer ) / 2 ) ) possible_shapes.push_back( shape ); } } @@ -4020,12 +4041,13 @@ int DRAWING_TOOL::DrawVia( const TOOL_EVENT& aEvent ) if( via->GetViaType() == VIATYPE::MICROVIA ) { - via->SetWidth( via->GetEffectiveNetClass()->GetuViaDiameter() ); + via->SetWidth( PADSTACK::ALL_LAYERS, + via->GetEffectiveNetClass()->GetuViaDiameter() ); via->SetDrill( via->GetEffectiveNetClass()->GetuViaDrill() ); } else { - via->SetWidth( bds.GetCurrentViaSize() ); + via->SetWidth( PADSTACK::ALL_LAYERS, bds.GetCurrentViaSize() ); via->SetDrill( bds.GetCurrentViaDrill() ); } diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 2ce29b33d6..d7f9aff990 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -960,7 +960,8 @@ int EDIT_TOOL::ChangeTrackWidth( const TOOL_EVENT& aEvent ) } via->SetDrill( new_drill ); - via->SetWidth( new_width ); + // TODO(JE) padstacks - is this correct behavior already? If so, also change stack mode + via->SetWidth( PADSTACK::ALL_LAYERS, new_width ); } else if( item->Type() == PCB_TRACE_T || item->Type() == PCB_ARC_T ) {