From ec020dd19f57e1ec4c2ce0ed21931df529661ffd Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Sat, 14 Nov 2020 01:16:02 +0000 Subject: [PATCH] First-class support for filled shapes. --- .../3d_canvas/create_3Dgraphic_brd_items.cpp | 109 +- common/hash_eda.cpp | 9 +- common/plotters/plotter.cpp | 11 +- include/hash_eda.h | 2 +- ...board_items_to_polygon_shape_transform.cpp | 102 +- .../dialog_graphic_item_properties.cpp | 20 + .../dialog_graphic_item_properties_base.cpp | 135 +- .../dialog_graphic_item_properties_base.fbp | 2918 ++++++----------- .../dialog_graphic_item_properties_base.h | 22 +- .../dialog_pad_basicshapes_properties.cpp | 19 +- pcbnew/dialogs/dialog_pad_properties.cpp | 10 +- pcbnew/dialogs/dialog_pad_properties_base.cpp | 41 +- pcbnew/dialogs/dialog_pad_properties_base.fbp | 415 ++- pcbnew/dialogs/dialog_pad_properties_base.h | 4 +- pcbnew/exporters/export_gencad.cpp | 4 +- pcbnew/files.cpp | 42 - pcbnew/graphics_cleaner.cpp | 1 + .../import_gfx/graphics_importer_pcbnew.cpp | 2 + pcbnew/microwave/microwave_footprint.cpp | 2 +- pcbnew/microwave/microwave_polygon.cpp | 1 + pcbnew/pad.h | 9 +- pcbnew/pad_custom_shape_functions.cpp | 18 +- pcbnew/pcb_edit_frame.h | 5 - pcbnew/pcb_painter.cpp | 185 +- pcbnew/pcb_shape.cpp | 40 +- pcbnew/pcb_shape.h | 27 +- pcbnew/plot_board_layers.cpp | 2 +- pcbnew/plot_brditems_plotter.cpp | 52 +- pcbnew/plugins/altium/altium_pcb.cpp | 38 +- .../cadstar/cadstar_pcb_archive_loader.cpp | 4 +- pcbnew/plugins/eagle/eagle_plugin.cpp | 8 +- pcbnew/plugins/kicad/kicad_plugin.cpp | 46 +- pcbnew/plugins/kicad/kicad_plugin.h | 3 +- pcbnew/plugins/kicad/pcb_parser.cpp | 119 +- pcbnew/plugins/kicad/pcb_parser.h | 7 +- pcbnew/plugins/legacy/legacy_plugin.cpp | 1 + pcbnew/plugins/pcad/pcb_arc.cpp | 1 + pcbnew/router/pns_kicad_iface.cpp | 2 +- pcbnew/tools/convert_tool.cpp | 2 + pcbnew/tools/drawing_tool.cpp | 5 + pcbnew/tools/pad_tool.cpp | 3 + pcbnew/tools/zone_create_helper.cpp | 3 +- 42 files changed, 1886 insertions(+), 2563 deletions(-) diff --git a/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp b/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp index 80a771c7b9..3263386449 100644 --- a/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp +++ b/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp @@ -587,14 +587,12 @@ void BOARD_ADAPTER::TransformArcToSegments( const wxPoint &aCentre, if( Is_segment_a_circle( start3DU, end3DU ) ) { - aDstContainer->Add( new CFILLEDCIRCLE2D( start3DU, - ( aWidth / 2 ) * m_biuTo3Dunits, + aDstContainer->Add( new CFILLEDCIRCLE2D( start3DU, ( aWidth / 2 ) * m_biuTo3Dunits, aBoardItem ) ); } else { - aDstContainer->Add( new CROUNDSEGMENT2D( start3DU, end3DU, - aWidth * m_biuTo3Dunits, + aDstContainer->Add( new CROUNDSEGMENT2D( start3DU, end3DU, aWidth * m_biuTo3Dunits, aBoardItem ) ); } @@ -625,40 +623,51 @@ void BOARD_ADAPTER::TransformArcToSegments( const wxPoint &aCentre, // Based on // TransformShapeWithClearanceToPolygon // board_items_to_polygon_shape_transform.cpp#L431 -void BOARD_ADAPTER::AddShapeWithClearanceToContainer( const PCB_SHAPE* aDrawSegment, +void BOARD_ADAPTER::AddShapeWithClearanceToContainer( const PCB_SHAPE* aShape, CGENERICCONTAINER2D *aDstContainer, PCB_LAYER_ID aLayerId, int aClearanceValue ) { // The full width of the lines to create // The extra 1 protects the inner/outer radius values from degeneracy - const int linewidth = aDrawSegment->GetWidth() + (2 * aClearanceValue) + 1; + const int linewidth = aShape->GetWidth() + ( 2 * aClearanceValue ) + 1; - switch( aDrawSegment->GetShape() ) + switch( aShape->GetShape() ) { case S_CIRCLE: { - const SFVEC2F center3DU( aDrawSegment->GetCenter().x * m_biuTo3Dunits, - -aDrawSegment->GetCenter().y * m_biuTo3Dunits ); + const SFVEC2F center3DU( aShape->GetCenter().x * m_biuTo3Dunits, + -aShape->GetCenter().y * m_biuTo3Dunits ); - float inner_radius = ( aDrawSegment->GetRadius() - linewidth / 2 ) * m_biuTo3Dunits; - float outer_radius = ( aDrawSegment->GetRadius() + linewidth / 2 ) * m_biuTo3Dunits; + float inner_radius = ( aShape->GetRadius() - linewidth / 2 ) * m_biuTo3Dunits; + float outer_radius = ( aShape->GetRadius() + linewidth / 2 ) * m_biuTo3Dunits; if( inner_radius < 0 ) inner_radius = 0; - if( aDrawSegment->GetWidth() > 0 ) - aDstContainer->Add( new CRING2D( center3DU, inner_radius, outer_radius, *aDrawSegment ) ); + if( aShape->IsFilled() ) + aDstContainer->Add( new CFILLEDCIRCLE2D( center3DU, outer_radius, *aShape ) ); else - aDstContainer->Add( new CFILLEDCIRCLE2D( center3DU, outer_radius, *aDrawSegment ) ); + aDstContainer->Add( new CRING2D( center3DU, inner_radius, outer_radius, *aShape ) ); } - break; + break; case S_RECT: - { - if( aDrawSegment->GetWidth() > 0 ) + if( aShape->IsFilled() ) { - std::vector pts = aDrawSegment->GetRectCorners(); + SHAPE_POLY_SET polyList; + + aShape->TransformShapeWithClearanceToPolygon( polyList, aLayerId, linewidth / 2, + ARC_HIGH_DEF, ERROR_INSIDE ); + + polyList.Simplify( SHAPE_POLY_SET::PM_FAST ); + + Convert_shape_line_polygon_to_triangles( polyList, *aDstContainer, m_biuTo3Dunits, + *aShape ); + } + else + { + std::vector pts = aShape->GetRectCorners(); const SFVEC2F topLeft3DU( pts[0].x * m_biuTo3Dunits, -pts[0].y * m_biuTo3Dunits ); const SFVEC2F topRight3DU( pts[1].x * m_biuTo3Dunits, -pts[1].y * m_biuTo3Dunits ); @@ -666,68 +675,42 @@ void BOARD_ADAPTER::AddShapeWithClearanceToContainer( const PCB_SHAPE* aDrawSegm const SFVEC2F botLeft3DU( pts[3].x * m_biuTo3Dunits, -pts[3].y * m_biuTo3Dunits ); aDstContainer->Add( new CROUNDSEGMENT2D( topLeft3DU, topRight3DU, - linewidth * m_biuTo3Dunits, - *aDrawSegment ) ); + linewidth * m_biuTo3Dunits, *aShape ) ); aDstContainer->Add( new CROUNDSEGMENT2D( topRight3DU, botRight3DU, - linewidth * m_biuTo3Dunits, - *aDrawSegment ) ); + linewidth * m_biuTo3Dunits, *aShape ) ); aDstContainer->Add( new CROUNDSEGMENT2D( botRight3DU, botLeft3DU, - linewidth * m_biuTo3Dunits, - *aDrawSegment ) ); + linewidth * m_biuTo3Dunits, *aShape ) ); aDstContainer->Add( new CROUNDSEGMENT2D( botLeft3DU, topLeft3DU, - linewidth * m_biuTo3Dunits, - *aDrawSegment ) ); + linewidth * m_biuTo3Dunits, *aShape ) ); } - else - { - SHAPE_POLY_SET polyList; - - aDrawSegment->TransformShapeWithClearanceToPolygon( polyList, aLayerId, - aClearanceValue, - ARC_HIGH_DEF, ERROR_INSIDE ); - - polyList.Simplify( SHAPE_POLY_SET::PM_FAST ); - - Convert_shape_line_polygon_to_triangles( polyList, *aDstContainer, m_biuTo3Dunits, - *aDrawSegment ); - } - } break; case S_ARC: { - const unsigned int nr_segments = - GetNrSegmentsCircle( aDrawSegment->GetBoundingBox().GetSizeMax() ); + unsigned int segCount = GetNrSegmentsCircle( aShape->GetBoundingBox().GetSizeMax() ); - TransformArcToSegments( aDrawSegment->GetCenter(), - aDrawSegment->GetArcStart(), - aDrawSegment->GetAngle(), - nr_segments, - aDrawSegment->GetWidth(), - aDstContainer, - *aDrawSegment ); + TransformArcToSegments( aShape->GetCenter(), aShape->GetArcStart(), aShape->GetAngle(), + segCount, linewidth, aDstContainer, *aShape ); } break; case S_SEGMENT: { - const SFVEC2F start3DU( aDrawSegment->GetStart().x * m_biuTo3Dunits, - -aDrawSegment->GetStart().y * m_biuTo3Dunits ); + const SFVEC2F start3DU( aShape->GetStart().x * m_biuTo3Dunits, + -aShape->GetStart().y * m_biuTo3Dunits ); - const SFVEC2F end3DU ( aDrawSegment->GetEnd().x * m_biuTo3Dunits, - -aDrawSegment->GetEnd().y * m_biuTo3Dunits ); + const SFVEC2F end3DU ( aShape->GetEnd().x * m_biuTo3Dunits, + -aShape->GetEnd().y * m_biuTo3Dunits ); if( Is_segment_a_circle( start3DU, end3DU ) ) { - aDstContainer->Add( new CFILLEDCIRCLE2D( start3DU, - ( linewidth / 2 ) * m_biuTo3Dunits, - *aDrawSegment ) ); + aDstContainer->Add( new CFILLEDCIRCLE2D( start3DU, ( linewidth / 2 ) * m_biuTo3Dunits, + *aShape ) ); } else { - aDstContainer->Add( new CROUNDSEGMENT2D( start3DU, end3DU, - linewidth * m_biuTo3Dunits, - *aDrawSegment ) ); + aDstContainer->Add( new CROUNDSEGMENT2D( start3DU, end3DU, linewidth * m_biuTo3Dunits, + *aShape ) ); } } break; @@ -737,8 +720,8 @@ void BOARD_ADAPTER::AddShapeWithClearanceToContainer( const PCB_SHAPE* aDrawSegm { SHAPE_POLY_SET polyList; - aDrawSegment->TransformShapeWithClearanceToPolygon( polyList, aLayerId, aClearanceValue, - ARC_HIGH_DEF, ERROR_INSIDE ); + aShape->TransformShapeWithClearanceToPolygon( polyList, aLayerId, linewidth / 2, + ARC_HIGH_DEF, ERROR_INSIDE ); polyList.Simplify( SHAPE_POLY_SET::PM_FAST ); @@ -746,13 +729,13 @@ void BOARD_ADAPTER::AddShapeWithClearanceToContainer( const PCB_SHAPE* aDrawSegm break; Convert_shape_line_polygon_to_triangles( polyList, *aDstContainer, m_biuTo3Dunits, - *aDrawSegment ); + *aShape ); } break; default: wxFAIL_MSG( "BOARD_ADAPTER::AddShapeWithClearanceToContainer no implementation for " - + PCB_SHAPE_TYPE_T_asString( aDrawSegment->GetShape()) ); + + PCB_SHAPE_TYPE_T_asString( aShape->GetShape()) ); break; } } diff --git a/common/hash_eda.cpp b/common/hash_eda.cpp index 3c685f7510..dfa74e8882 100644 --- a/common/hash_eda.cpp +++ b/common/hash_eda.cpp @@ -46,7 +46,7 @@ static inline size_t hash_board_item( const BOARD_ITEM* aItem, int aFlags ) } -size_t hash_eda( const EDA_ITEM* aItem, int aFlags ) +size_t hash_fp_item( const EDA_ITEM* aItem, int aFlags ) { size_t ret = 0; @@ -65,10 +65,10 @@ size_t hash_eda( const EDA_ITEM* aItem, int aFlags ) hash_combine( ret, footprint->GetOrientation() ); for( BOARD_ITEM* item : footprint->GraphicalItems() ) - hash_combine( ret, hash_eda( item, aFlags ) ); + hash_combine( ret, hash_fp_item( item, aFlags ) ); for( PAD* pad : footprint->Pads() ) - hash_combine( ret, hash_eda( static_cast( pad ), aFlags ) ); + hash_combine( ret, hash_fp_item( static_cast( pad ), aFlags ) ); } break; @@ -142,6 +142,7 @@ size_t hash_eda( const EDA_ITEM* aItem, int aFlags ) ret = hash_board_item( segment, aFlags ); hash_combine( ret, segment->GetShape() ); hash_combine( ret, segment->GetWidth() ); + hash_combine( ret, segment->IsFilled() ); hash_combine( ret, segment->GetRadius() ); if( aFlags & HASH_POS ) @@ -168,7 +169,7 @@ size_t hash_eda( const EDA_ITEM* aItem, int aFlags ) break; default: - wxASSERT_MSG( false, "Unhandled type in function hashModItem() (exporter_gencad.cpp)" ); + wxASSERT_MSG( false, "Unhandled type in function hash_fp_item() (exporter_gencad.cpp)" ); } return ret; diff --git a/common/plotters/plotter.cpp b/common/plotters/plotter.cpp index aa9c68577e..60dfb9426a 100644 --- a/common/plotters/plotter.cpp +++ b/common/plotters/plotter.cpp @@ -565,11 +565,13 @@ void PLOTTER::ThickRect( const wxPoint& p1, const wxPoint& p2, int width, } -void PLOTTER::ThickCircle( const wxPoint& pos, int diametre, int width, - OUTLINE_MODE tracemode, void* aData ) +void PLOTTER::ThickCircle( const wxPoint& pos, int diametre, int width, OUTLINE_MODE tracemode, + void* aData ) { if( tracemode == FILLED ) + { Circle( pos, diametre, FILL_TYPE::NO_FILL, width ); + } else { SetCurrentLineWidth( -1 ); @@ -579,11 +581,12 @@ void PLOTTER::ThickCircle( const wxPoint& pos, int diametre, int width, } -void PLOTTER::FilledCircle( const wxPoint& pos, int diametre, - OUTLINE_MODE tracemode, void* aData ) +void PLOTTER::FilledCircle( const wxPoint& pos, int diametre, OUTLINE_MODE tracemode, void* aData ) { if( tracemode == FILLED ) + { Circle( pos, diametre, FILL_TYPE::FILLED_SHAPE, 0 ); + } else { SetCurrentLineWidth( -1 ); diff --git a/include/hash_eda.h b/include/hash_eda.h index 2eab81c1a1..7ea56f7df5 100644 --- a/include/hash_eda.h +++ b/include/hash_eda.h @@ -55,7 +55,7 @@ enum HASH_FLAGS * @param aItem is the item for which the hash will be computed. * @return Hash value. */ -std::size_t hash_eda( const EDA_ITEM* aItem, int aFlags = HASH_FLAGS::HASH_ALL ); +std::size_t hash_fp_item( const EDA_ITEM* aItem, int aFlags = HASH_FLAGS::HASH_ALL ); /** * This is a dummy function to take the final case of hash_combine below diff --git a/pcbnew/board_items_to_polygon_shape_transform.cpp b/pcbnew/board_items_to_polygon_shape_transform.cpp index 5410d33f43..23697c0acb 100644 --- a/pcbnew/board_items_to_polygon_shape_transform.cpp +++ b/pcbnew/board_items_to_polygon_shape_transform.cpp @@ -406,9 +406,9 @@ void PCB_SHAPE::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuf switch( m_shape ) { case S_CIRCLE: - if( width == 0 ) + if( IsFilled() ) { - TransformCircleToPolygon( aCornerBuffer, GetCenter(), GetRadius(), aError, + TransformCircleToPolygon( aCornerBuffer, GetCenter(), GetRadius() + width / 2, aError, aErrorLoc ); } else @@ -422,7 +422,7 @@ void PCB_SHAPE::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuf { std::vector pts = GetRectCorners(); - if( width == 0 ) + if( IsFilled() ) { aCornerBuffer.NewOutline(); @@ -430,7 +430,7 @@ void PCB_SHAPE::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuf aCornerBuffer.Append( pt ); } - if( width > 0 ) + if( width > 0 || !IsFilled() ) { // Add in segments TransformOvalToPolygon( aCornerBuffer, pts[0], pts[1], width, aError, aErrorLoc ); @@ -451,69 +451,63 @@ void PCB_SHAPE::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuf break; case S_POLYGON: - if( IsPolyShapeValid() ) + { + if( !IsPolyShapeValid() ) + break; + + // The polygon is expected to be a simple polygon; not self intersecting, no hole. + FOOTPRINT* footprint = GetParentFootprint(); + double orientation = footprint ? footprint->GetOrientation() : 0.0; + wxPoint offset; + + if( footprint ) + offset = footprint->GetPosition(); + + // Build the polygon with the actual position and orientation: + std::vector< wxPoint> poly; + poly = BuildPolyPointsList(); + + for( wxPoint& point : poly ) { - // The polygon is expected to be a simple polygon - // not self intersecting, no hole. - FOOTPRINT* footprint = GetParentFootprint(); // NULL for items not in footprints - double orientation = footprint ? footprint->GetOrientation() : 0.0; - wxPoint offset; + RotatePoint( &point, orientation ); + point += offset; + } - if( footprint ) - offset = footprint->GetPosition(); - - // Build the polygon with the actual position and orientation: - std::vector< wxPoint> poly; - poly = BuildPolyPointsList(); + if( IsFilled() ) + { + aCornerBuffer.NewOutline(); for( wxPoint& point : poly ) + aCornerBuffer.Append( point.x, point.y ); + } + + if( width > 0 || !IsFilled() ) + { + wxPoint pt1( poly[ poly.size() - 1] ); + + for( wxPoint pt2 : poly ) { - RotatePoint( &point, orientation ); - point += offset; - } + if( pt2 != pt1 ) + TransformOvalToPolygon( aCornerBuffer, pt1, pt2, width, aError, aErrorLoc ); - if( IsPolygonFilled() || width == 0 ) - { - aCornerBuffer.NewOutline(); - - for( wxPoint& point : poly ) - aCornerBuffer.Append( point.x, point.y ); - } - - if( width > 0 ) - { - wxPoint pt1( poly[ poly.size() - 1] ); - - for( wxPoint pt2 : poly ) - { - if( pt2 != pt1 ) - { - TransformOvalToPolygon( aCornerBuffer, pt1, pt2, width, - aError, aErrorLoc ); - } - - pt1 = pt2; - } + pt1 = pt2; } } + } break; case S_CURVE: // Bezier curve - { - std::vector ctrlPoints = { m_start, m_bezierC1, m_bezierC2, m_end }; - BEZIER_POLY converter( ctrlPoints ); - std::vector< wxPoint> poly; - converter.GetPoly( poly, m_width ); + { + std::vector ctrlPoints = { m_start, m_bezierC1, m_bezierC2, m_end }; + BEZIER_POLY converter( ctrlPoints ); + std::vector< wxPoint> poly; + converter.GetPoly( poly, m_width ); - if( width != 0 ) - { - for( unsigned ii = 1; ii < poly.size(); ii++ ) - { - TransformOvalToPolygon( aCornerBuffer, poly[ii-1], poly[ii], width, - aError, aErrorLoc ); - } - } + for( unsigned ii = 1; ii < poly.size(); ii++ ) + { + TransformOvalToPolygon( aCornerBuffer, poly[ii-1], poly[ii], width, aError, aErrorLoc ); } + } break; default: diff --git a/pcbnew/dialogs/dialog_graphic_item_properties.cpp b/pcbnew/dialogs/dialog_graphic_item_properties.cpp index 57596a1d59..8c9823ca7e 100644 --- a/pcbnew/dialogs/dialog_graphic_item_properties.cpp +++ b/pcbnew/dialogs/dialog_graphic_item_properties.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -175,20 +176,28 @@ bool DIALOG_GRAPHIC_ITEM_PROPERTIES::TransferDataToWindow() m_endX.SetCoordType( ORIGIN_TRANSFORMS::NOT_A_COORD ); m_endY.Show( false ); + + m_filledCtrl->Show( true ); break; case S_ARC: SetTitle( _( "Arc Properties" ) ); m_AngleValue = m_item->GetAngle() / 10.0; + + m_filledCtrl->Show( false ); break; case S_POLYGON: SetTitle( _( "Polygon Properties" ) ); m_sizerLeft->Show( false ); + + m_filledCtrl->Show( true ); break; case S_RECT: SetTitle( _( "Rectangle Properties" ) ); + + m_filledCtrl->Show( true ); break; case S_SEGMENT: @@ -198,6 +207,8 @@ bool DIALOG_GRAPHIC_ITEM_PROPERTIES::TransferDataToWindow() m_flipStartEnd = m_item->GetStart().x > m_item->GetEnd().x; SetTitle( _( "Line Segment Properties" ) ); + + m_filledCtrl->Show( false ); break; default: @@ -246,6 +257,7 @@ bool DIALOG_GRAPHIC_ITEM_PROPERTIES::TransferDataToWindow() m_bezierCtrl2X.SetValue( m_item->GetBezControl2().x ); m_bezierCtrl2Y.SetValue( m_item->GetBezControl2().y ); + m_filledCtrl->SetValue( m_item->IsFilled() ); m_thickness.SetValue( m_item->GetWidth() ); m_LayerSelectionCtrl->SetLayerSelection( m_item->GetLayer() ); @@ -262,6 +274,13 @@ bool DIALOG_GRAPHIC_ITEM_PROPERTIES::TransferDataFromWindow() if( !m_thickness.Validate( 0, Millimeter2iu( 1000.0 ) ) ) return false; + if( m_thickness.GetValue() == 0 && !m_filledCtrl->GetValue() ) + { + DisplayError( this, _( "Line width may not be 0 for unfilled shapes." ) ); + m_thicknessCtrl->SetFocus(); + return false; + } + LAYER_NUM layer = m_LayerSelectionCtrl->GetLayerSelection(); BOARD_COMMIT commit( m_parent ); @@ -321,6 +340,7 @@ bool DIALOG_GRAPHIC_ITEM_PROPERTIES::TransferDataFromWindow() } } + m_item->SetFilled( m_filledCtrl->GetValue() ); m_item->SetWidth( m_thickness.GetValue() ); m_item->SetLayer( ToLAYER_ID( layer ) ); diff --git a/pcbnew/dialogs/dialog_graphic_item_properties_base.cpp b/pcbnew/dialogs/dialog_graphic_item_properties_base.cpp index e941b0ccb6..00eb7d5b30 100644 --- a/pcbnew/dialogs/dialog_graphic_item_properties_base.cpp +++ b/pcbnew/dialogs/dialog_graphic_item_properties_base.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Dec 30 2017) +// C++ code generated with wxFormBuilder (version Oct 26 2018) // http://www.wxformbuilder.org/ // // PLEASE DO *NOT* EDIT THIS FILE! @@ -14,194 +14,203 @@ DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE::DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style ) { this->SetSizeHints( wxSize( -1,-1 ), wxDefaultSize ); - + wxBoxSizer* bMainSizer; bMainSizer = new wxBoxSizer( wxVERTICAL ); - + wxBoxSizer* bUpperSizer; bUpperSizer = new wxBoxSizer( wxVERTICAL ); - + m_sizerLeft = new wxGridBagSizer( 5, 5 ); m_sizerLeft->SetFlexibleDirection( wxBOTH ); m_sizerLeft->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); m_sizerLeft->SetEmptyCellSize( wxSize( 5,5 ) ); - + m_startPointLabel = new wxStaticText( this, wxID_ANY, _("Start Point"), wxDefaultPosition, wxDefaultSize, 0 ); m_startPointLabel->Wrap( -1 ); m_sizerLeft->Add( m_startPointLabel, wxGBPosition( 0, 0 ), wxGBSpan( 1, 3 ), wxALIGN_CENTER_HORIZONTAL|wxALL, 5 ); - + m_startXLabel = new wxStaticText( this, wxID_ANY, _("X:"), wxDefaultPosition, wxDefaultSize, 0 ); m_startXLabel->Wrap( -1 ); m_sizerLeft->Add( m_startXLabel, wxGBPosition( 1, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); - + m_startXCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); m_sizerLeft->Add( m_startXCtrl, wxGBPosition( 1, 1 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 ); - + m_startXUnits = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 ); m_startXUnits->Wrap( -1 ); m_sizerLeft->Add( m_startXUnits, wxGBPosition( 1, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxRIGHT, 15 ); - + m_startYLabel = new wxStaticText( this, wxID_ANY, _("Y:"), wxDefaultPosition, wxDefaultSize, 0 ); m_startYLabel->Wrap( -1 ); m_sizerLeft->Add( m_startYLabel, wxGBPosition( 2, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); - + m_startYCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); m_sizerLeft->Add( m_startYCtrl, wxGBPosition( 2, 1 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 ); - + m_startYUnits = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 ); m_startYUnits->Wrap( -1 ); m_sizerLeft->Add( m_startYUnits, wxGBPosition( 2, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxRIGHT, 15 ); - + m_endPointLabel = new wxStaticText( this, wxID_ANY, _("End Point"), wxDefaultPosition, wxDefaultSize, 0 ); m_endPointLabel->Wrap( -1 ); m_sizerLeft->Add( m_endPointLabel, wxGBPosition( 0, 3 ), wxGBSpan( 1, 3 ), wxALIGN_CENTER_HORIZONTAL|wxALL, 5 ); - + m_endXLabel = new wxStaticText( this, wxID_ANY, _("X:"), wxDefaultPosition, wxDefaultSize, 0 ); m_endXLabel->Wrap( -1 ); m_sizerLeft->Add( m_endXLabel, wxGBPosition( 1, 3 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); - + m_endXCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); m_sizerLeft->Add( m_endXCtrl, wxGBPosition( 1, 4 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 ); - + m_endXUnits = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 ); m_endXUnits->Wrap( -1 ); m_sizerLeft->Add( m_endXUnits, wxGBPosition( 1, 5 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); - + m_endYLabel = new wxStaticText( this, wxID_ANY, _("Y:"), wxDefaultPosition, wxDefaultSize, 0 ); m_endYLabel->Wrap( -1 ); m_sizerLeft->Add( m_endYLabel, wxGBPosition( 2, 3 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); - + m_endYCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); m_sizerLeft->Add( m_endYCtrl, wxGBPosition( 2, 4 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 ); - + m_endYUnits = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 ); m_endYUnits->Wrap( -1 ); m_sizerLeft->Add( m_endYUnits, wxGBPosition( 2, 5 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); - + m_bezierCtrlPt1Label = new wxStaticText( this, wxID_ANY, _("Bezier Control Pt"), wxDefaultPosition, wxDefaultSize, 0 ); m_bezierCtrlPt1Label->Wrap( -1 ); m_sizerLeft->Add( m_bezierCtrlPt1Label, wxGBPosition( 4, 0 ), wxGBSpan( 1, 3 ), wxALIGN_CENTER_HORIZONTAL|wxALL, 5 ); - + m_BezierPointC1XLabel = new wxStaticText( this, wxID_ANY, _("X:"), wxDefaultPosition, wxDefaultSize, 0 ); m_BezierPointC1XLabel->Wrap( -1 ); m_sizerLeft->Add( m_BezierPointC1XLabel, wxGBPosition( 5, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); - + m_BezierC1X_Ctrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); m_sizerLeft->Add( m_BezierC1X_Ctrl, wxGBPosition( 5, 1 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 ); - + m_BezierPointC1XUnit = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 ); m_BezierPointC1XUnit->Wrap( -1 ); m_sizerLeft->Add( m_BezierPointC1XUnit, wxGBPosition( 5, 2 ), wxGBSpan( 1, 1 ), wxRIGHT|wxALIGN_CENTER_VERTICAL, 5 ); - + m_BezierPointC1YLabel = new wxStaticText( this, wxID_ANY, _("Y:"), wxDefaultPosition, wxDefaultSize, 0 ); m_BezierPointC1YLabel->Wrap( -1 ); m_sizerLeft->Add( m_BezierPointC1YLabel, wxGBPosition( 6, 0 ), wxGBSpan( 1, 1 ), wxLEFT|wxALIGN_CENTER_VERTICAL, 5 ); - + m_BezierC1Y_Ctrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); m_sizerLeft->Add( m_BezierC1Y_Ctrl, wxGBPosition( 6, 1 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 ); - + m_BezierPointC1YUnit = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 ); m_BezierPointC1YUnit->Wrap( -1 ); m_sizerLeft->Add( m_BezierPointC1YUnit, wxGBPosition( 6, 2 ), wxGBSpan( 1, 1 ), wxRIGHT|wxALIGN_CENTER_VERTICAL, 5 ); - + m_bezierCtrlPt2Label = new wxStaticText( this, wxID_ANY, _("Bezier Control Pt"), wxDefaultPosition, wxDefaultSize, 0 ); m_bezierCtrlPt2Label->Wrap( -1 ); m_sizerLeft->Add( m_bezierCtrlPt2Label, wxGBPosition( 4, 3 ), wxGBSpan( 1, 3 ), wxALL|wxALIGN_CENTER_HORIZONTAL, 5 ); - + m_BezierPointC2XLabel = new wxStaticText( this, wxID_ANY, _("X:"), wxDefaultPosition, wxDefaultSize, 0 ); m_BezierPointC2XLabel->Wrap( -1 ); m_sizerLeft->Add( m_BezierPointC2XLabel, wxGBPosition( 5, 3 ), wxGBSpan( 1, 1 ), wxLEFT|wxALIGN_CENTER_VERTICAL, 5 ); - + m_BezierC2X_Ctrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); m_sizerLeft->Add( m_BezierC2X_Ctrl, wxGBPosition( 5, 4 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 ); - + m_BezierPointC2XUnit = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 ); m_BezierPointC2XUnit->Wrap( -1 ); m_sizerLeft->Add( m_BezierPointC2XUnit, wxGBPosition( 5, 5 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); - + m_BezierPointC2YLabel = new wxStaticText( this, wxID_ANY, _("Y:"), wxDefaultPosition, wxDefaultSize, 0 ); m_BezierPointC2YLabel->Wrap( -1 ); m_sizerLeft->Add( m_BezierPointC2YLabel, wxGBPosition( 6, 3 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); - + m_BezierC2Y_Ctrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); m_sizerLeft->Add( m_BezierC2Y_Ctrl, wxGBPosition( 6, 4 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 ); - + m_BezierPointC2YUnit = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 ); m_BezierPointC2YUnit->Wrap( -1 ); m_sizerLeft->Add( m_BezierPointC2YUnit, wxGBPosition( 6, 5 ), wxGBSpan( 1, 1 ), wxRIGHT|wxALIGN_CENTER_VERTICAL, 5 ); - - + + bUpperSizer->Add( m_sizerLeft, 1, wxEXPAND|wxBOTTOM, 20 ); - + wxBoxSizer* bUpperRightSizer; bUpperRightSizer = new wxBoxSizer( wxVERTICAL ); - + wxFlexGridSizer* fgUpperRightGridSizer; - fgUpperRightGridSizer = new wxFlexGridSizer( 0, 3, 5, 0 ); + fgUpperRightGridSizer = new wxFlexGridSizer( 0, 3, 3, 0 ); fgUpperRightGridSizer->AddGrowableCol( 1 ); fgUpperRightGridSizer->SetFlexibleDirection( wxBOTH ); fgUpperRightGridSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); - + m_angleLabel = new wxStaticText( this, wxID_ANY, _("Arc angle:"), wxDefaultPosition, wxDefaultSize, 0 ); m_angleLabel->Wrap( -1 ); fgUpperRightGridSizer->Add( m_angleLabel, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT, 5 ); - + m_angleCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); fgUpperRightGridSizer->Add( m_angleCtrl, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); - + m_angleUnits = new wxStaticText( this, wxID_ANY, _("deg"), wxDefaultPosition, wxDefaultSize, 0 ); m_angleUnits->Wrap( -1 ); fgUpperRightGridSizer->Add( m_angleUnits, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT, 5 ); - - m_thicknessLabel = new wxStaticText( this, wxID_ANY, _("Line thickness:"), wxDefaultPosition, wxDefaultSize, 0 ); + + m_filledCtrl = new wxCheckBox( this, wxID_ANY, _("Filled shape"), wxDefaultPosition, wxDefaultSize, 0 ); + fgUpperRightGridSizer->Add( m_filledCtrl, 0, wxTOP|wxLEFT, 5 ); + + + fgUpperRightGridSizer->Add( 0, 0, 1, wxEXPAND, 5 ); + + + fgUpperRightGridSizer->Add( 0, 0, 1, wxEXPAND, 5 ); + + m_thicknessLabel = new wxStaticText( this, wxID_ANY, _("Line width:"), wxDefaultPosition, wxDefaultSize, 0 ); m_thicknessLabel->Wrap( -1 ); fgUpperRightGridSizer->Add( m_thicknessLabel, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT, 5 ); - + m_thicknessCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); fgUpperRightGridSizer->Add( m_thicknessCtrl, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); - + m_thicknessUnits = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 ); m_thicknessUnits->Wrap( -1 ); fgUpperRightGridSizer->Add( m_thicknessUnits, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT, 5 ); - + m_LayerLabel = new wxStaticText( this, wxID_ANY, _("Layer:"), wxDefaultPosition, wxDefaultSize, 0 ); m_LayerLabel->Wrap( -1 ); fgUpperRightGridSizer->Add( m_LayerLabel, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 ); - - m_LayerSelectionCtrl = new PCB_LAYER_BOX_SELECTOR( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 ); + + m_LayerSelectionCtrl = new PCB_LAYER_BOX_SELECTOR( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 ); fgUpperRightGridSizer->Add( m_LayerSelectionCtrl, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 ); - - + + fgUpperRightGridSizer->Add( 0, 0, 1, wxEXPAND, 5 ); - - + + bUpperRightSizer->Add( fgUpperRightGridSizer, 0, wxEXPAND, 5 ); - - + + bUpperSizer->Add( bUpperRightSizer, 0, wxEXPAND, 5 ); - - + + bMainSizer->Add( bUpperSizer, 1, wxEXPAND|wxALL, 5 ); - + m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); bMainSizer->Add( m_staticline1, 0, wxEXPAND|wxRIGHT|wxLEFT, 10 ); - + m_StandardButtonsSizer = new wxStdDialogButtonSizer(); m_StandardButtonsSizerOK = new wxButton( this, wxID_OK ); m_StandardButtonsSizer->AddButton( m_StandardButtonsSizerOK ); m_StandardButtonsSizerCancel = new wxButton( this, wxID_CANCEL ); m_StandardButtonsSizer->AddButton( m_StandardButtonsSizerCancel ); m_StandardButtonsSizer->Realize(); - + bMainSizer->Add( m_StandardButtonsSizer, 0, wxALIGN_RIGHT|wxALL, 5 ); - - + + this->SetSizer( bMainSizer ); this->Layout(); bMainSizer->Fit( this ); - + this->Centre( wxBOTH ); - + // Connect Events this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE::OnClose ) ); this->Connect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE::OnInitDlg ) ); @@ -212,5 +221,5 @@ DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE::~DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE() // Disconnect Events this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE::OnClose ) ); this->Disconnect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE::OnInitDlg ) ); - + } diff --git a/pcbnew/dialogs/dialog_graphic_item_properties_base.fbp b/pcbnew/dialogs/dialog_graphic_item_properties_base.fbp index 41835be2c0..a0a3290ed7 100644 --- a/pcbnew/dialogs/dialog_graphic_item_properties_base.fbp +++ b/pcbnew/dialogs/dialog_graphic_item_properties_base.fbp @@ -2,7 +2,7 @@ - + C++ 1 source_name @@ -14,11 +14,12 @@ dialog_graphic_item_properties_base 1000 none + 1 DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE - + . - + 1 1 1 @@ -29,67 +30,33 @@ 0 wxAUI_MGR_DEFAULT - + wxBOTH - + 1 1 impl_virtual - - - + + + 0 wxID_ANY - + -1,-1 DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE - + -1,-1 wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxSYSTEM_MENU DIALOG_SHIM; dialog_shim.h Graphic Item Properties - - - - - - - - - - - - - + + + + OnClose - - - - - OnInitDlg - - - - - - - - - - - - - - - - - - - - - + bMainSizer wxVERTICAL none @@ -98,7 +65,7 @@ wxEXPAND|wxALL 1 - + bUpperSizer wxVERTICAL none @@ -109,10 +76,10 @@ 5,5 wxBOTH - - + + 5 - + m_sizerLeft wxFLEX_GROWMODE_SPECIFIED protected @@ -129,78 +96,56 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY Start Point - + 0 + 0 - - + + 0 - + 1 m_startPointLabel 1 - - + + protected 1 - + Resizable 1 - - + + ; forward_declare 0 - - - - + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - @@ -215,78 +160,56 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 0 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY X: - + 0 + 0 - - + + 0 - + 1 m_startXLabel 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - - - + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - @@ -301,86 +224,59 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY - + 0 - + 0 - + 0 - + 1 m_startXCtrl 1 - - + + protected 1 - + Resizable 1 - - + + ; ; forward_declare 0 - - + + wxFILTER_NONE wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + @@ -395,78 +291,56 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY unit - + 0 + 0 - - + + 0 - + 1 m_startXUnits 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - - - + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - @@ -481,78 +355,56 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 0 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY Y: - + 0 + 0 - - + + 0 - + 1 m_startYLabel 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - - - + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - @@ -567,86 +419,59 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY - + 0 - + 0 - + 0 - + 1 m_startYCtrl 1 - - + + protected 1 - + Resizable 1 - - + + ; ; forward_declare 0 - - + + wxFILTER_NONE wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + @@ -661,78 +486,56 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY unit - + 0 + 0 - - + + 0 - + 1 m_startYUnits 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - - - + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - @@ -747,78 +550,56 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY End Point - + 0 + 0 - - + + 0 - + 1 m_endPointLabel 1 - - + + protected 1 - + Resizable 1 - - + + ; forward_declare 0 - - - - + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - @@ -833,78 +614,56 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 0 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY X: - + 0 + 0 - - + + 0 - + 1 m_endXLabel 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - - - + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - @@ -919,86 +678,59 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY - + 0 - + 0 - + 0 - + 1 m_endXCtrl 1 - - + + protected 1 - + Resizable 1 - - + + ; ; forward_declare 0 - - + + wxFILTER_NONE wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + @@ -1013,78 +745,56 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY unit - + 0 + 0 - - + + 0 - + 1 m_endXUnits 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - - - + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - @@ -1099,78 +809,56 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 0 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY Y: - + 0 + 0 - - + + 0 - + 1 m_endYLabel 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - - - + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - @@ -1185,86 +873,59 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY - + 0 - + 0 - + 0 - + 1 m_endYCtrl 1 - - + + protected 1 - + Resizable 1 - - + + ; ; forward_declare 0 - - + + wxFILTER_NONE wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + @@ -1279,78 +940,56 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY unit - + 0 + 0 - - + + 0 - + 1 m_endYUnits 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - - - + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - @@ -1365,78 +1004,56 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY Bezier Control Pt - + 0 + 0 - - + + 0 - + 1 m_bezierCtrlPt1Label 1 - - + + protected 1 - + Resizable 1 - - + + ; forward_declare 0 - - - - + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - @@ -1451,78 +1068,56 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY X: - + 0 + 0 - - + + 0 - + 1 m_BezierPointC1XLabel 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - - - + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - @@ -1537,86 +1132,59 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY - + 0 - + 0 - + 0 - + 1 m_BezierC1X_Ctrl 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - + + wxFILTER_NONE wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + @@ -1631,78 +1199,56 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY unit - + 0 + 0 - - + + 0 - + 1 m_BezierPointC1XUnit 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - - - + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - @@ -1717,78 +1263,56 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY Y: - + 0 + 0 - - + + 0 - + 1 m_BezierPointC1YLabel 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - - - + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - @@ -1803,86 +1327,59 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY - + 0 - + 0 - + 0 - + 1 m_BezierC1Y_Ctrl 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - + + wxFILTER_NONE wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + @@ -1897,78 +1394,56 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY unit - + 0 + 0 - - + + 0 - + 1 m_BezierPointC1YUnit 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - - - + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - @@ -1983,78 +1458,56 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY Bezier Control Pt - + 0 + 0 - - + + 0 - + 1 m_bezierCtrlPt2Label 1 - - + + protected 1 - + Resizable 1 - - + + ; forward_declare 0 - - - - + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - @@ -2069,78 +1522,56 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY X: - + 0 + 0 - - + + 0 - + 1 m_BezierPointC2XLabel 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - - - + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - @@ -2155,86 +1586,59 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY - + 0 - + 0 - + 0 - + 1 m_BezierC2X_Ctrl 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - + + wxFILTER_NONE wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + @@ -2249,78 +1653,56 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY unit - + 0 + 0 - - + + 0 - + 1 m_BezierPointC2XUnit 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - - - + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - @@ -2335,78 +1717,56 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY Y: - + 0 + 0 - - + + 0 - + 1 m_BezierPointC2YLabel 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - - - + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - @@ -2421,86 +1781,59 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY - + 0 - + 0 - + 0 - + 1 m_BezierC2Y_Ctrl 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - + + wxFILTER_NONE wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + @@ -2515,78 +1848,56 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY unit - + 0 + 0 - - + + 0 - + 1 m_BezierPointC2YUnit 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - - - + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - @@ -2596,7 +1907,7 @@ wxEXPAND 0 - + bUpperRightSizer wxVERTICAL none @@ -2608,14 +1919,14 @@ 3 wxBOTH 1 - + 0 - + fgUpperRightGridSizer wxFLEX_GROWMODE_SPECIFIED none 0 - 5 + 3 5 wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT @@ -2625,78 +1936,56 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY Arc angle: - + 0 + 0 - - + + 0 - + 1 m_angleLabel 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - - - + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - @@ -2708,86 +1997,59 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY - + 0 - + 0 - + 0 - + 1 m_angleCtrl 1 - - + + protected 1 - + Resizable 1 - - + + ; ; forward_declare 0 - - + + wxFILTER_NONE wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + @@ -2799,78 +2061,140 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY deg - + 0 + 0 - - + + 0 - + 1 m_angleUnits 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - - - + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - + + + + 5 + wxTOP|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Filled shape + + 0 + + + 0 + + 1 + m_filledCtrl + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + 5 + wxEXPAND + 1 + + 0 + protected + 0 @@ -2882,78 +2206,56 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 0 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY - Line thickness: - + Line width: + 0 + 0 - - + + 0 - + 1 m_thicknessLabel 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - - - + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - @@ -2965,86 +2267,59 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY - + 0 - + 0 - + 0 - + 1 m_thicknessCtrl 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - + + wxFILTER_NONE wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + @@ -3056,78 +2331,56 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY unit - + 0 + 0 - - + + 0 - + 1 m_thicknessUnits 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - - - + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - @@ -3139,78 +2392,56 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 0 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY Layer: - + 0 + 0 - - + + 0 - + 1 m_LayerLabel 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - - - + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - @@ -3222,86 +2453,60 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 - + 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY - + 0 - - + + 0 - + 1 m_LayerSelectionCtrl 1 - - + + protected 1 - + Resizable -1 1 - - + + PCB_LAYER_BOX_SELECTOR; pcb_layer_box_selector.h 0 - - + + wxFILTER_NONE wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + @@ -3329,76 +2534,53 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY - + 0 - - + + 0 - + 1 m_staticline1 1 - - + + protected 1 - + Resizable 1 - + wxLI_HORIZONTAL - + 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + @@ -3414,17 +2596,9 @@ 1 0 0 - + m_StandardButtonsSizer protected - - - - - - - - diff --git a/pcbnew/dialogs/dialog_graphic_item_properties_base.h b/pcbnew/dialogs/dialog_graphic_item_properties_base.h index 1ab91dede3..c4ec67543f 100644 --- a/pcbnew/dialogs/dialog_graphic_item_properties_base.h +++ b/pcbnew/dialogs/dialog_graphic_item_properties_base.h @@ -1,12 +1,11 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Dec 30 2017) +// C++ code generated with wxFormBuilder (version Oct 26 2018) // http://www.wxformbuilder.org/ // // PLEASE DO *NOT* EDIT THIS FILE! /////////////////////////////////////////////////////////////////////////// -#ifndef __DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE_H__ -#define __DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE_H__ +#pragma once #include #include @@ -22,6 +21,7 @@ class PCB_LAYER_BOX_SELECTOR; #include #include #include +#include #include #include #include @@ -37,7 +37,7 @@ class PCB_LAYER_BOX_SELECTOR; class DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE : public DIALOG_SHIM { private: - + protected: wxGridBagSizer* m_sizerLeft; wxStaticText* m_startPointLabel; @@ -71,6 +71,7 @@ class DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE : public DIALOG_SHIM wxStaticText* m_angleLabel; wxTextCtrl* m_angleCtrl; wxStaticText* m_angleUnits; + wxCheckBox* m_filledCtrl; wxStaticText* m_thicknessLabel; wxTextCtrl* m_thicknessCtrl; wxStaticText* m_thicknessUnits; @@ -80,17 +81,16 @@ class DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE : public DIALOG_SHIM wxStdDialogButtonSizer* m_StandardButtonsSizer; wxButton* m_StandardButtonsSizerOK; wxButton* m_StandardButtonsSizerCancel; - + // Virtual event handlers, overide them in your derived class virtual void OnClose( wxCloseEvent& event ) { event.Skip(); } virtual void OnInitDlg( wxInitDialogEvent& event ) { event.Skip(); } - - + + public: - - DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Graphic Item Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxSYSTEM_MENU ); + + DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Graphic Item Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxSYSTEM_MENU ); ~DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE(); - + }; -#endif //__DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE_H__ diff --git a/pcbnew/dialogs/dialog_pad_basicshapes_properties.cpp b/pcbnew/dialogs/dialog_pad_basicshapes_properties.cpp index ca0c86c255..c7b61460a8 100644 --- a/pcbnew/dialogs/dialog_pad_basicshapes_properties.cpp +++ b/pcbnew/dialogs/dialog_pad_basicshapes_properties.cpp @@ -70,11 +70,8 @@ bool DIALOG_PAD_PRIMITIVES_PROPERTIES::TransferDataToWindow() if( m_shape == NULL ) return false; - // Shows the text info about circle or ring only for S_CIRCLE shape - if( m_shape->GetShape() != S_CIRCLE ) - m_staticTextInfo->Show( false ); - m_thickness.SetValue( m_shape->GetWidth() ); + m_filledCtrl->SetValue( m_shape->IsFilled() ); switch( m_shape->GetShape() ) { @@ -93,6 +90,7 @@ bool DIALOG_PAD_PRIMITIVES_PROPERTIES::TransferDataToWindow() m_staticTextPosCtrl2->Show( false ); m_staticTextPosCtrl2->SetSize( 0, 0 ); m_radius.Show( false ); + m_filledCtrl->Show( false ); break; case S_CURVE: // Bezier line @@ -106,6 +104,7 @@ bool DIALOG_PAD_PRIMITIVES_PROPERTIES::TransferDataToWindow() m_ctrl2X.SetValue( m_shape->GetBezControl2().x ); m_ctrl2Y.SetValue( m_shape->GetBezControl2().y ); m_radius.Show( false ); + m_filledCtrl->Show( false ); break; case S_ARC: // Arc with rounded ends @@ -126,6 +125,7 @@ bool DIALOG_PAD_PRIMITIVES_PROPERTIES::TransferDataToWindow() m_staticTextPosCtrl1->SetSize( 0, 0 ); m_staticTextPosCtrl2->Show( false ); m_staticTextPosCtrl2->SetSize( 0, 0 ); + m_filledCtrl->Show( false ); break; case S_CIRCLE: // ring or circle @@ -152,6 +152,7 @@ bool DIALOG_PAD_PRIMITIVES_PROPERTIES::TransferDataToWindow() m_staticTextPosCtrl1->SetSize( 0, 0 ); m_staticTextPosCtrl2->Show( false ); m_staticTextPosCtrl2->SetSize( 0, 0 ); + m_filledCtrl->Show( true ); break; case S_POLYGON: // polygon @@ -168,8 +169,16 @@ bool DIALOG_PAD_PRIMITIVES_PROPERTIES::TransferDataToWindow() bool DIALOG_PAD_PRIMITIVES_PROPERTIES::TransferDataFromWindow() { + if( m_thickness.GetValue() == 0 && !m_filledCtrl->GetValue() ) + { + DisplayError( this, _( "Line width may not be 0 for unfilled shapes." ) ); + m_thicknessCtrl->SetFocus(); + return false; + } + // Transfer data out of the GUI. m_shape->SetWidth( m_thickness.GetValue() ); + m_shape->SetFilled( m_filledCtrl->GetValue() ); switch( m_shape->GetShape() ) { @@ -257,6 +266,7 @@ bool DIALOG_PAD_PRIMITIVE_POLY_PROPS::TransferDataToWindow() return false; m_thickness.SetValue( m_shape->GetWidth() ); + m_filledCtrl->SetValue( m_shape->IsFilled() ); // Populates the list of corners int extra_rows = m_currPoints.size() - m_gridCornersList->GetNumberRows(); @@ -296,6 +306,7 @@ bool DIALOG_PAD_PRIMITIVE_POLY_PROPS::TransferDataFromWindow() m_shape->SetPolyPoints( m_currPoints ); m_shape->SetWidth( m_thickness.GetValue() ); + m_shape->SetFilled( m_filledCtrl->GetValue() ); return true; } diff --git a/pcbnew/dialogs/dialog_pad_properties.cpp b/pcbnew/dialogs/dialog_pad_properties.cpp index 584c04c047..bb36ef7aab 100644 --- a/pcbnew/dialogs/dialog_pad_properties.cpp +++ b/pcbnew/dialogs/dialog_pad_properties.cpp @@ -2104,8 +2104,13 @@ void DIALOG_PAD_PROPERTIES::onDeletePrimitive( wxCommandEvent& event ) void DIALOG_PAD_PROPERTIES::onAddPrimitive( wxCommandEvent& event ) { // Ask user for shape type - wxString shapelist[] = { _( "Segment" ), _( "Arc" ), _( "Bezier" ), - _( "Ring/Circle" ), _( "Polygon" ) }; + wxString shapelist[] = { + _( "Segment" ), + _( "Arc" ), + _( "Bezier" ), + _( "Ring/Circle" ), + _( "Polygon" ) + }; int type = wxGetSingleChoiceIndex( _( "Shape type:" ), _( "Add Primitive" ), arrayDim( shapelist ), shapelist, 0, this ); @@ -2119,6 +2124,7 @@ void DIALOG_PAD_PROPERTIES::onAddPrimitive( wxCommandEvent& event ) PCB_SHAPE* primitive = new PCB_SHAPE(); primitive->SetShape( listtype[type] ); primitive->SetWidth( m_board->GetDesignSettings().GetLineThickness( F_Cu ) ); + primitive->SetFilled( true ); if( listtype[type] == S_POLYGON ) { diff --git a/pcbnew/dialogs/dialog_pad_properties_base.cpp b/pcbnew/dialogs/dialog_pad_properties_base.cpp index 2197d195f9..36a9f098fb 100644 --- a/pcbnew/dialogs/dialog_pad_properties_base.cpp +++ b/pcbnew/dialogs/dialog_pad_properties_base.cpp @@ -1259,7 +1259,7 @@ DIALOG_PAD_PRIMITIVES_PROPERTIES_BASE::DIALOG_PAD_PRIMITIVES_PROPERTIES_BASE( wx fgSizerShapeProperties->Add( 0, 0, 1, wxEXPAND, 5 ); - m_thicknessLabel = new wxStaticText( this, wxID_ANY, _("Thickness:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_thicknessLabel = new wxStaticText( this, wxID_ANY, _("Line width:"), wxDefaultPosition, wxDefaultSize, 0 ); m_thicknessLabel->Wrap( -1 ); fgSizerShapeProperties->Add( m_thicknessLabel, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT, 5 ); @@ -1276,15 +1276,12 @@ DIALOG_PAD_PRIMITIVES_PROPERTIES_BASE::DIALOG_PAD_PRIMITIVES_PROPERTIES_BASE( wx fgSizerShapeProperties->Add( 0, 0, 1, wxEXPAND, 5 ); + m_filledCtrl = new wxCheckBox( this, wxID_ANY, _("Filled shape"), wxDefaultPosition, wxDefaultSize, 0 ); + fgSizerShapeProperties->Add( m_filledCtrl, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 ); + bSizermain->Add( fgSizerShapeProperties, 1, wxEXPAND|wxALL, 10 ); - m_staticTextInfo = new wxStaticText( this, wxID_ANY, _("Set thickness to 0 for a filled circle."), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticTextInfo->Wrap( -1 ); - m_staticTextInfo->SetFont( wxFont( 11, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxEmptyString ) ); - - bSizermain->Add( m_staticTextInfo, 0, wxRIGHT|wxLEFT, 15 ); - m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); bSizermain->Add( m_staticline1, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 10 ); @@ -1457,8 +1454,8 @@ DIALOG_PAD_PRIMITIVE_POLY_PROPS_BASE::DIALOG_PAD_PRIMITIVE_POLY_PROPS_BASE( wxWi m_gridCornersList->SetMargins( 0, 0 ); // Columns - m_gridCornersList->SetColSize( 0, 100 ); - m_gridCornersList->SetColSize( 1, 100 ); + m_gridCornersList->SetColSize( 0, 124 ); + m_gridCornersList->SetColSize( 1, 124 ); m_gridCornersList->EnableDragColMove( false ); m_gridCornersList->EnableDragColSize( true ); m_gridCornersList->SetColLabelSize( 22 ); @@ -1498,22 +1495,25 @@ DIALOG_PAD_PRIMITIVE_POLY_PROPS_BASE::DIALOG_PAD_PRIMITIVE_POLY_PROPS_BASE( wxWi bLeftSizer->Add( bSizerRightButts, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxRIGHT|wxLEFT, 5 ); wxFlexGridSizer* fgSizerThickness; - fgSizerThickness = new wxFlexGridSizer( 0, 5, 0, 0 ); + fgSizerThickness = new wxFlexGridSizer( 0, 4, 0, 0 ); fgSizerThickness->AddGrowableCol( 1 ); fgSizerThickness->SetFlexibleDirection( wxBOTH ); fgSizerThickness->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); - m_thicknessLabel = new wxStaticText( this, wxID_ANY, _("Outline thickness:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_thicknessLabel = new wxStaticText( this, wxID_ANY, _("Line width:"), wxDefaultPosition, wxDefaultSize, 0 ); m_thicknessLabel->Wrap( -1 ); fgSizerThickness->Add( m_thicknessLabel, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxRIGHT, 5 ); m_thicknessCtrl = new TEXT_CTRL_EVAL( this, wxID_ANY, _("0"), wxDefaultPosition, wxDefaultSize, 0 ); - fgSizerThickness->Add( m_thicknessCtrl, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + fgSizerThickness->Add( m_thicknessCtrl, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxRIGHT, 5 ); m_thicknessUnits = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 ); m_thicknessUnits->Wrap( -1 ); fgSizerThickness->Add( m_thicknessUnits, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxRIGHT, 5 ); + m_filledCtrl = new wxCheckBox( this, wxID_ANY, _("Filled shape"), wxDefaultPosition, wxDefaultSize, 0 ); + fgSizerThickness->Add( m_filledCtrl, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 20 ); + bLeftSizer->Add( fgSizerThickness, 0, wxALL|wxEXPAND, 10 ); @@ -1559,26 +1559,11 @@ DIALOG_PAD_PRIMITIVE_POLY_PROPS_BASE::DIALOG_PAD_PRIMITIVE_POLY_PROPS_BASE( wxWi wxBoxSizer* bSizer24; bSizer24 = new wxBoxSizer( wxHORIZONTAL ); - wxBoxSizer* bSizer25; - bSizer25 = new wxBoxSizer( wxVERTICAL ); - - - bSizer25->Add( 0, 0, 0, wxEXPAND|wxTOP|wxBOTTOM, 4 ); - m_statusLine1 = new wxStaticText( this, wxID_ANY, _("Coordinates are relative to anchor pad, rotated 0.0 deg."), wxDefaultPosition, wxDefaultSize, 0 ); m_statusLine1->Wrap( -1 ); m_statusLine1->SetFont( wxFont( 11, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxEmptyString ) ); - bSizer25->Add( m_statusLine1, 0, 0, 5 ); - - m_statusLine2 = new wxStaticText( this, wxID_ANY, _("Set thickness to 0 for a filled polygon."), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - m_statusLine2->Wrap( -1 ); - m_statusLine2->SetFont( wxFont( 11, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxEmptyString ) ); - - bSizer25->Add( m_statusLine2, 0, wxTOP, 2 ); - - - bSizer24->Add( bSizer25, 1, wxEXPAND|wxLEFT, 10 ); + bSizer24->Add( m_statusLine1, 1, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 10 ); m_sdbSizer = new wxStdDialogButtonSizer(); m_sdbSizerOK = new wxButton( this, wxID_OK ); diff --git a/pcbnew/dialogs/dialog_pad_properties_base.fbp b/pcbnew/dialogs/dialog_pad_properties_base.fbp index 64d32b4940..f6877baecf 100644 --- a/pcbnew/dialogs/dialog_pad_properties_base.fbp +++ b/pcbnew/dialogs/dialog_pad_properties_base.fbp @@ -10857,16 +10857,16 @@ - + bSizermain wxVERTICAL none - + 10 wxEXPAND|wxALL 1 - + 7 wxBOTH 2,4 @@ -12868,7 +12868,7 @@ 0 0 wxID_ANY - Thickness: + Line width: 0 0 @@ -13042,67 +13042,70 @@ 0 - - - - 15 - wxRIGHT|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - ,90,90,11,70,0 - 0 - 0 - wxID_ANY - Set thickness to 0 for a filled circle. - 0 - - 0 - - - 0 - - 1 - m_staticTextInfo - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - - - -1 + + 5 + wxBOTTOM|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Filled shape + + 0 + + + 0 + + 1 + m_filledCtrl + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + @@ -14313,25 +14316,25 @@ - + bSizerMain wxVERTICAL none - + 5 wxEXPAND 1 - + bSizerUpper wxHORIZONTAL none - + 5 wxEXPAND 1 - + bLeftSizer wxVERTICAL @@ -14367,7 +14370,7 @@ "Pos X" "Pos Y" wxALIGN_CENTER 2 - 100,100 + 124,124 1 0 @@ -14593,12 +14596,12 @@ - + 10 wxALL|wxEXPAND 0 - - 5 + + 4 wxBOTH 1 @@ -14641,7 +14644,7 @@ 0 0 wxID_ANY - Outline thickness: + Line width: 0 0 @@ -14672,7 +14675,7 @@ 5 - wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxRIGHT 0 1 @@ -14795,6 +14798,70 @@ -1 + + 20 + wxALIGN_CENTER_VERTICAL|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Filled shape + + 0 + + + 0 + + 1 + m_filledCtrl + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + @@ -15069,156 +15136,74 @@ - + 5 wxEXPAND 0 - + bSizer24 wxHORIZONTAL none 10 - wxEXPAND|wxLEFT + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT 1 - + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + ,90,90,11,70,0 + 0 + 0 + wxID_ANY + Coordinates are relative to anchor pad, rotated 0.0 deg. + 0 + + 0 + + + 0 - bSizer25 - wxVERTICAL - none - - 4 - wxEXPAND|wxTOP|wxBOTTOM - 0 - - 0 - protected - 0 - - - - 5 - - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - ,90,90,11,70,0 - 0 - 0 - wxID_ANY - Coordinates are relative to anchor pad, rotated 0.0 deg. - 0 - - 0 - - - 0 - - 1 - m_statusLine1 - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - - - -1 - - - - 2 - wxTOP - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - ,90,90,11,70,0 - 0 - 0 - wxID_ANY - Set thickness to 0 for a filled polygon. - 0 - - 0 - - - 0 - - 1 - m_statusLine2 - 1 - - - protected - 1 - - Resizable - 1 - -1,-1 - - ; forward_declare - 0 - - - - - -1 - - + 1 + m_statusLine1 + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 diff --git a/pcbnew/dialogs/dialog_pad_properties_base.h b/pcbnew/dialogs/dialog_pad_properties_base.h index a1615d39ff..db38f7ef02 100644 --- a/pcbnew/dialogs/dialog_pad_properties_base.h +++ b/pcbnew/dialogs/dialog_pad_properties_base.h @@ -308,7 +308,7 @@ class DIALOG_PAD_PRIMITIVES_PROPERTIES_BASE : public DIALOG_SHIM wxStaticText* m_thicknessLabel; wxTextCtrl* m_thicknessCtrl; wxStaticText* m_thicknessUnits; - wxStaticText* m_staticTextInfo; + wxCheckBox* m_filledCtrl; wxStaticLine* m_staticline1; wxStdDialogButtonSizer* m_sdbSizer; wxButton* m_sdbSizerOK; @@ -369,12 +369,12 @@ class DIALOG_PAD_PRIMITIVE_POLY_PROPS_BASE : public DIALOG_SHIM wxStaticText* m_thicknessLabel; TEXT_CTRL_EVAL* m_thicknessCtrl; wxStaticText* m_thicknessUnits; + wxCheckBox* m_filledCtrl; wxPanel* m_panelPoly; wxStaticBitmap* m_warningIcon; wxStaticText* m_warningText; wxStaticLine* m_staticline3; wxStaticText* m_statusLine1; - wxStaticText* m_statusLine2; wxStdDialogButtonSizer* m_sdbSizer; wxButton* m_sdbSizerOK; wxButton* m_sdbSizerCancel; diff --git a/pcbnew/exporters/export_gencad.cpp b/pcbnew/exporters/export_gencad.cpp index f9449df47d..320844da51 100644 --- a/pcbnew/exporters/export_gencad.cpp +++ b/pcbnew/exporters/export_gencad.cpp @@ -671,10 +671,10 @@ static size_t hashFootprint( const FOOTPRINT* aFootprint ) | HASH_FLAGS::HASH_ROT | HASH_FLAGS::HASH_LAYER; for( BOARD_ITEM* i : aFootprint->GraphicalItems() ) - ret += hash_eda( i, flags ); + ret += hash_fp_item( i, flags ); for( PAD* i : aFootprint->Pads() ) - ret += hash_eda( i, flags ); + ret += hash_fp_item( i, flags ); return ret; } diff --git a/pcbnew/files.cpp b/pcbnew/files.cpp index c08afa51d0..6833f59cfb 100644 --- a/pcbnew/files.cpp +++ b/pcbnew/files.cpp @@ -474,48 +474,6 @@ IO_MGR::PCB_FILE_T plugin_type( const wxString& aFileName, int aCtl ) } -int PCB_EDIT_FRAME::inferLegacyEdgeClearance( BOARD* aBoard ) -{ - PCB_LAYER_COLLECTOR collector; - - collector.SetLayerId( Edge_Cuts ); - collector.Collect( aBoard, GENERAL_COLLECTOR::AllBoardItems ); - - int edgeWidth = -1; - bool mixed = false; - - for( int i = 0; i < collector.GetCount(); i++ ) - { - if( collector[i]->Type() == PCB_SHAPE_T ) - { - int itemWidth = static_cast( collector[i] )->GetWidth(); - - if( edgeWidth != -1 && edgeWidth != itemWidth ) - { - mixed = true; - edgeWidth = std::max( edgeWidth, itemWidth ); - } - else - { - edgeWidth = itemWidth; - } - } - } - - if( mixed ) - { - // If they had different widths then we can't ensure that fills will be the same. - wxMessageBox( _( "If the zones on this board are refilled the Copper Edge Clearance\n" - "setting will be used (see Board Setup > Design Rules). This may\n" - "result in different fills from previous Kicad versions which used\n" - "the line thickness of the board boundary on the Edge Cuts layer." ), - _( "Edge Clearance Warning" ), wxOK|wxICON_WARNING, this ); - } - - return std::max( 0, edgeWidth / 2 ); -} - - bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector& aFileSet, int aCtl ) { // This is for python: diff --git a/pcbnew/graphics_cleaner.cpp b/pcbnew/graphics_cleaner.cpp index ac0487f610..d34683c9c8 100644 --- a/pcbnew/graphics_cleaner.cpp +++ b/pcbnew/graphics_cleaner.cpp @@ -307,6 +307,7 @@ void GRAPHICS_CLEANER::mergeRects() rect = new PCB_SHAPE(); rect->SetShape( S_RECT ); + rect->SetFilled( false ); rect->SetStart( top->start ); rect->SetEnd( bottom->end ); rect->SetLayer( top->shape->GetLayer() ); diff --git a/pcbnew/import_gfx/graphics_importer_pcbnew.cpp b/pcbnew/import_gfx/graphics_importer_pcbnew.cpp index dfa44fce11..b9a10683c3 100644 --- a/pcbnew/import_gfx/graphics_importer_pcbnew.cpp +++ b/pcbnew/import_gfx/graphics_importer_pcbnew.cpp @@ -79,6 +79,7 @@ void GRAPHICS_IMPORTER_PCBNEW::AddCircle( const VECTOR2D& aCenter, double aRadiu { std::unique_ptr circle( createDrawing() ); circle->SetShape( S_CIRCLE ); + circle->SetFilled( GetLayer() != Edge_Cuts ); circle->SetLayer( GetLayer() ); circle->SetWidth( MapLineWidth( aWidth ) ); circle->SetCenter( MapCoordinate( aCenter ) ); @@ -119,6 +120,7 @@ void GRAPHICS_IMPORTER_PCBNEW::AddPolygon( const std::vector< VECTOR2D >& aVerti std::unique_ptr polygon( createDrawing() ); polygon->SetShape( S_POLYGON ); + polygon->SetFilled( GetLayer() != Edge_Cuts ); polygon->SetLayer( GetLayer() ); polygon->SetPolyPoints( convertedPoints ); diff --git a/pcbnew/microwave/microwave_footprint.cpp b/pcbnew/microwave/microwave_footprint.cpp index 8006b6cdf4..65adc59136 100644 --- a/pcbnew/microwave/microwave_footprint.cpp +++ b/pcbnew/microwave/microwave_footprint.cpp @@ -166,7 +166,7 @@ FOOTPRINT* MICROWAVE_TOOL::createFootprint( MICROWAVE_FOOTPRINT_SHAPE aFootprint // Close the polygon: polyPoints.push_back( polyPoints[0] ); - pad->AddPrimitivePoly( polyPoints, 0 ); // add a polygonal basic shape + pad->AddPrimitivePoly( polyPoints, 0, true ); // add a polygonal basic shape } break; diff --git a/pcbnew/microwave/microwave_polygon.cpp b/pcbnew/microwave/microwave_polygon.cpp index 7bafd04693..169f6ea0c4 100644 --- a/pcbnew/microwave/microwave_polygon.cpp +++ b/pcbnew/microwave/microwave_polygon.cpp @@ -299,6 +299,7 @@ FOOTPRINT* MICROWAVE_TOOL::createPolygonShape() // Add a polygonal edge (corners will be added later) on copper layer shape = new FP_SHAPE( footprint ); shape->SetShape( S_POLYGON ); + shape->SetFilled( true ); shape->SetLayer( F_Cu ); footprint->Add( shape, ADD_MODE::INSERT ); diff --git a/pcbnew/pad.h b/pcbnew/pad.h index be392f0370..8ad15d0bdc 100644 --- a/pcbnew/pad.h +++ b/pcbnew/pad.h @@ -255,11 +255,12 @@ public: * a arc * a bezier curve */ - void AddPrimitivePoly( const SHAPE_POLY_SET& aPoly, int aThickness ); - void AddPrimitivePoly( const std::vector& aPoly, int aThickness ); + void AddPrimitivePoly( const SHAPE_POLY_SET& aPoly, int aThickness, bool aFilled ); + void AddPrimitivePoly( const std::vector& aPoly, int aThickness, bool aFilled ); void AddPrimitiveSegment( const wxPoint& aStart, const wxPoint& aEnd, int aThickness ); - void AddPrimitiveCircle( const wxPoint& aCenter, int aRadius, int aThickness ); - void AddPrimitiveRect( const wxPoint& aStart, const wxPoint& aEnd, int aThickness ); + void AddPrimitiveCircle( const wxPoint& aCenter, int aRadius, int aThickness, bool aFilled ); + void AddPrimitiveRect( const wxPoint& aStart, const wxPoint& aEnd, int aThickness, + bool aFilled ); void AddPrimitiveArc( const wxPoint& aCenter, const wxPoint& aStart, int aArcAngle, int aThickness ); void AddPrimitiveCurve( const wxPoint& aStart, const wxPoint& aEnd, const wxPoint& aCtrl1, diff --git a/pcbnew/pad_custom_shape_functions.cpp b/pcbnew/pad_custom_shape_functions.cpp index de00a21914..cec120bff7 100644 --- a/pcbnew/pad_custom_shape_functions.cpp +++ b/pcbnew/pad_custom_shape_functions.cpp @@ -36,7 +36,7 @@ * the shape is a polygon (can be with thick outline), segment, circle or arc */ -void PAD::AddPrimitivePoly( const SHAPE_POLY_SET& aPoly, int aThickness ) +void PAD::AddPrimitivePoly( const SHAPE_POLY_SET& aPoly, int aThickness, bool aFilled ) { std::vector points; @@ -48,14 +48,15 @@ void PAD::AddPrimitivePoly( const SHAPE_POLY_SET& aPoly, int aThickness ) for( auto iter = poly_no_hole.CIterate(); iter; iter++ ) points.emplace_back( iter->x, iter->y ); - AddPrimitivePoly( points, aThickness ); + AddPrimitivePoly( points, aThickness, aFilled ); } -void PAD::AddPrimitivePoly( const std::vector& aPoly, int aThickness ) +void PAD::AddPrimitivePoly( const std::vector& aPoly, int aThickness, bool aFilled ) { PCB_SHAPE* item = new PCB_SHAPE(); item->SetShape( S_POLYGON ); + item->SetFilled( aFilled ); item->SetPolyPoints( aPoly ); item->SetWidth( aThickness ); m_editPrimitives.emplace_back( item ); @@ -66,6 +67,8 @@ void PAD::AddPrimitivePoly( const std::vector& aPoly, int aThickness ) void PAD::AddPrimitiveSegment( const wxPoint& aStart, const wxPoint& aEnd, int aThickness ) { PCB_SHAPE* item = new PCB_SHAPE(); + item->SetShape( S_SEGMENT ); + item->SetFilled( false ); item->SetStart( aStart ); item->SetEnd( aEnd ); item->SetWidth( aThickness ); @@ -79,6 +82,7 @@ void PAD::AddPrimitiveArc( const wxPoint& aCenter, const wxPoint& aStart, int aA { PCB_SHAPE* item = new PCB_SHAPE(); item->SetShape( S_ARC ); + item->SetFilled( false ); item->SetCenter( aCenter ); item->SetArcStart( aStart ); item->SetAngle( aArcAngle ); @@ -93,6 +97,7 @@ void PAD::AddPrimitiveCurve( const wxPoint& aStart, const wxPoint& aEnd, const w { PCB_SHAPE* item = new PCB_SHAPE(); item->SetShape( S_CURVE ); + item->SetFilled( false ); item->SetStart( aStart ); item->SetEnd( aEnd ); item->SetBezControl1( aCtrl1 ); @@ -103,10 +108,11 @@ void PAD::AddPrimitiveCurve( const wxPoint& aStart, const wxPoint& aEnd, const w } -void PAD::AddPrimitiveCircle( const wxPoint& aCenter, int aRadius, int aThickness ) +void PAD::AddPrimitiveCircle( const wxPoint& aCenter, int aRadius, int aThickness, bool aFilled ) { PCB_SHAPE* item = new PCB_SHAPE(); item->SetShape( S_CIRCLE ); + item->SetFilled( aFilled ); item->SetStart( aCenter ); item->SetEnd( wxPoint( aCenter.x + aRadius, aCenter.y ) ); item->SetWidth( aThickness ); @@ -115,10 +121,12 @@ void PAD::AddPrimitiveCircle( const wxPoint& aCenter, int aRadius, int aThicknes } -void PAD::AddPrimitiveRect( const wxPoint& aStart, const wxPoint& aEnd, int aThickness ) +void PAD::AddPrimitiveRect( const wxPoint& aStart, const wxPoint& aEnd, int aThickness, + bool aFilled) { PCB_SHAPE* item = new PCB_SHAPE(); item->SetShape( S_RECT ); + item->SetFilled( aFilled ); item->SetStart( aStart ); item->SetEnd( aEnd ); item->SetWidth( aThickness ); diff --git a/pcbnew/pcb_edit_frame.h b/pcbnew/pcb_edit_frame.h index 3fecded846..177071b1ee 100644 --- a/pcbnew/pcb_edit_frame.h +++ b/pcbnew/pcb_edit_frame.h @@ -212,11 +212,6 @@ protected: */ bool importFile( const wxString& aFileName, int aFileType ); - /** - * Use the existing edge_cut line thicknesses to infer the edge clearace. - */ - int inferLegacyEdgeClearance( BOARD* aBoard ); - /** * Rematch orphaned zones and vias to schematic nets. */ diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp index fb4757093d..85f8d02d59 100644 --- a/pcbnew/pcb_painter.cpp +++ b/pcbnew/pcb_painter.cpp @@ -1114,52 +1114,93 @@ void PCB_PAINTER::draw( const PAD* aPad, int aLayer ) void PCB_PAINTER::draw( const PCB_SHAPE* aShape, int aLayer ) { const COLOR4D& color = m_pcbSettings.GetColor( aShape, aShape->GetLayer() ); - bool sketch = m_pcbSettings.m_sketchGraphics; - int thickness = getLineThickness( aShape->GetWidth() ); - VECTOR2D start( aShape->GetStart() ); - VECTOR2D end( aShape->GetEnd() ); + bool sketch = m_pcbSettings.m_sketchGraphics; + int thickness = getLineThickness( aShape->GetWidth() ); + VECTOR2D start( aShape->GetStart() ); + VECTOR2D end( aShape->GetEnd() ); + + if( sketch ) + { + m_gal->SetIsFill( false ); + m_gal->SetIsStroke( true ); + m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth ); + } - m_gal->SetIsFill( !sketch ); - m_gal->SetIsStroke( sketch ); m_gal->SetFillColor( color ); m_gal->SetStrokeColor( color ); - m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth ); switch( aShape->GetShape() ) { case S_SEGMENT: - m_gal->DrawSegment( start, end, thickness ); + if( sketch ) + { + m_gal->DrawSegment( start, end, thickness ); + } + else + { + m_gal->SetIsFill( true ); + m_gal->SetIsStroke( false ); + + m_gal->DrawSegment( start, end, thickness ); + } break; case S_RECT: { std::vector pts = aShape->GetRectCorners(); - if( aShape->GetWidth() > 0 ) + if( sketch ) { - m_gal->DrawSegment( pts[0], pts[1], thickness ); - m_gal->DrawSegment( pts[1], pts[2], thickness ); - m_gal->DrawSegment( pts[2], pts[3], thickness ); - m_gal->DrawSegment( pts[3], pts[0], thickness ); + m_gal->DrawSegment( pts[0], pts[1], thickness ); + m_gal->DrawSegment( pts[1], pts[2], thickness ); + m_gal->DrawSegment( pts[2], pts[3], thickness ); + m_gal->DrawSegment( pts[3], pts[0], thickness ); } else { - SHAPE_POLY_SET poly; - poly.NewOutline(); + m_gal->SetIsFill( true ); + m_gal->SetIsStroke( false ); - for( const wxPoint& pt : pts ) - poly.Append( pt ); + if( thickness > 0 ) + { + m_gal->DrawSegment( pts[0], pts[1], thickness ); + m_gal->DrawSegment( pts[1], pts[2], thickness ); + m_gal->DrawSegment( pts[2], pts[3], thickness ); + m_gal->DrawSegment( pts[3], pts[0], thickness ); + } - m_gal->DrawPolygon( poly ); + if( aShape->IsFilled() ) + { + SHAPE_POLY_SET poly; + poly.NewOutline(); + + for( const wxPoint& pt : pts ) + poly.Append( pt ); + + m_gal->DrawPolygon( poly ); + } } } break; case S_ARC: - m_gal->DrawArcSegment( start, aShape->GetRadius(), - DECIDEG2RAD( aShape->GetArcAngleStart() ), - DECIDEG2RAD( aShape->GetArcAngleStart() + aShape->GetAngle() ), // Change this - thickness ); + if( sketch ) + { + m_gal->DrawArcSegment( start, aShape->GetRadius(), + DECIDEG2RAD( aShape->GetArcAngleStart() ), + DECIDEG2RAD( aShape->GetArcAngleStart() + aShape->GetAngle() ), // Change this + thickness ); + } + else + { + m_gal->SetIsFill( true ); + m_gal->SetIsStroke( false ); + + m_gal->DrawArcSegment( start, aShape->GetRadius(), + DECIDEG2RAD( aShape->GetArcAngleStart() ), + DECIDEG2RAD( aShape->GetArcAngleStart() + aShape->GetAngle() ), // Change this + thickness ); + } break; case S_CIRCLE: @@ -1170,9 +1211,10 @@ void PCB_PAINTER::draw( const PCB_SHAPE* aShape, int aLayer ) } else { + m_gal->SetIsFill( aShape->IsFilled() ); + m_gal->SetIsStroke( thickness > 0 ); m_gal->SetLineWidth( thickness ); - m_gal->SetIsFill( aShape->GetWidth() == 0 ); - m_gal->SetIsStroke( aShape->GetWidth() > 0 ); + m_gal->DrawCircle( start, aShape->GetRadius() ); } break; @@ -1184,47 +1226,76 @@ void PCB_PAINTER::draw( const PCB_SHAPE* aShape, int aLayer ) if( shape.OutlineCount() == 0 ) break; - // On Opengl, a not convex filled polygon is usually drawn by using triangles as primitives. - // CacheTriangulation() can create basic triangle primitives to draw the polygon solid shape - // on Opengl. - // GLU tesselation is much slower, so currently we are using our tesselation. - if( m_gal->IsOpenGlEngine() && !shape.IsTriangulationUpToDate() ) - { - shape.CacheTriangulation(); - } - - m_gal->Save(); - - if( FOOTPRINT* parentFootprint = aShape->GetParentFootprint() ) - { - m_gal->Translate( parentFootprint->GetPosition() ); - m_gal->Rotate( -parentFootprint->GetOrientationRadians() ); - } - - m_gal->SetLineWidth( thickness ); - if( sketch ) - m_gal->SetIsFill( false ); + { + for( int ii = 0; ii < shape.Outline( 0 ).SegmentCount(); ++ii ) + { + SEG seg = shape.Outline( 0 ).Segment( ii ); + m_gal->DrawSegment( seg.A, seg.B, thickness ); + } + } else - m_gal->SetIsFill( aShape->IsPolygonFilled() ); + { + m_gal->SetIsFill( true ); + m_gal->SetIsStroke( false ); - m_gal->SetIsStroke( true ); - m_gal->DrawPolygon( shape ); + if( thickness > 0 ) + { + for( int ii = 0; ii < shape.Outline( 0 ).SegmentCount(); ++ii ) + { + SEG seg = shape.Outline( 0 ).Segment( ii ); + m_gal->DrawSegment( seg.A, seg.B, thickness ); + } + } + + if( aShape->IsFilled() ) + { + // On Opengl, a not convex filled polygon is usually drawn by using triangles + // as primitives. CacheTriangulation() can create basic triangle primitives to + // draw the polygon solid shape on Opengl. GLU tesselation is much slower, so + // currently we are using our tesselation. + if( m_gal->IsOpenGlEngine() && !shape.IsTriangulationUpToDate() ) + shape.CacheTriangulation(); + + m_gal->Save(); + + if( FOOTPRINT* parentFootprint = aShape->GetParentFootprint() ) + { + m_gal->Translate( parentFootprint->GetPosition() ); + m_gal->Rotate( -parentFootprint->GetOrientationRadians() ); + } + + m_gal->DrawPolygon( shape ); + m_gal->Restore(); + } + } - m_gal->Restore(); break; } case S_CURVE: - m_gal->SetIsFill( false ); - m_gal->SetIsStroke( true ); - m_gal->SetLineWidth( thickness ); - // Use thickness as filter value to convert the curve to polyline - // when the curve is not supported - m_gal->DrawCurve( VECTOR2D( aShape->GetStart() ), - VECTOR2D( aShape->GetBezControl1() ), - VECTOR2D( aShape->GetBezControl2() ), - VECTOR2D( aShape->GetEnd() ), thickness ); + if( sketch ) + { + // Use thickness as filter value to convert the curve to polyline when the curve + // is not supported + m_gal->DrawCurve( VECTOR2D( aShape->GetStart() ), + VECTOR2D( aShape->GetBezControl1() ), + VECTOR2D( aShape->GetBezControl2() ), + VECTOR2D( aShape->GetEnd() ), thickness ); + } + else + { + m_gal->SetIsFill( aShape->IsFilled() ); + m_gal->SetIsStroke( thickness > 0 ); + m_gal->SetLineWidth( thickness ); + + // Use thickness as filter value to convert the curve to polyline when the curve + // is not supported + m_gal->DrawCurve( VECTOR2D( aShape->GetStart() ), + VECTOR2D( aShape->GetBezControl1() ), + VECTOR2D( aShape->GetBezControl2() ), + VECTOR2D( aShape->GetEnd() ), thickness ); + } break; case S_LAST: diff --git a/pcbnew/pcb_shape.cpp b/pcbnew/pcb_shape.cpp index 891814a995..52d188e536 100644 --- a/pcbnew/pcb_shape.cpp +++ b/pcbnew/pcb_shape.cpp @@ -46,6 +46,7 @@ PCB_SHAPE::PCB_SHAPE( BOARD_ITEM* aParent, KICAD_T idtype ) : BOARD_ITEM( aParent, idtype ) { m_angle = 0; + m_filled = false; m_Flags = 0; m_shape = S_SEGMENT; m_width = Millimeter2iu( DEFAULT_LINE_WIDTH ); @@ -609,7 +610,7 @@ const EDA_RECT PCB_SHAPE::GetBoundingBox() const break; } - bbox.Inflate((( m_width + 1) / 2) + 1 ); + bbox.Inflate( m_width / 2 ); bbox.Normalize(); return bbox; @@ -627,7 +628,7 @@ bool PCB_SHAPE::HitTest( const wxPoint& aPosition, int aAccuracy ) const int radius = GetRadius(); int dist = KiROUND( EuclideanNorm( aPosition - GetCenter() ) ); - if( m_width == 0 ) // Filled circle hit-test + if( IsFilled() ) // Filled circle hit-test { if( dist <= radius + maxdist ) return true; @@ -681,25 +682,27 @@ bool PCB_SHAPE::HitTest( const wxPoint& aPosition, int aAccuracy ) const break; case S_CURVE: - ( (PCB_SHAPE*) this)->RebuildBezierToSegmentsPointsList( m_width ); + const_cast( this )->RebuildBezierToSegmentsPointsList( m_width ); for( unsigned int i= 1; i < m_bezierPoints.size(); i++) { if( TestSegmentHit( aPosition, m_bezierPoints[ i - 1], m_bezierPoints[i], maxdist ) ) return true; } + break; case S_SEGMENT: if( TestSegmentHit( aPosition, m_start, m_end, maxdist ) ) return true; + break; case S_RECT: { std::vector pts = GetRectCorners(); - if( m_width == 0 ) // Filled rect hit-test + if( IsFilled() ) // Filled rect hit-test { SHAPE_POLY_SET poly; poly.NewOutline(); @@ -724,15 +727,16 @@ bool PCB_SHAPE::HitTest( const wxPoint& aPosition, int aAccuracy ) const break; case S_POLYGON: + if( IsFilled() ) { - if( !IsPolygonFilled() ) - { - SHAPE_POLY_SET::VERTEX_INDEX dummy; - return m_poly.CollideEdge( VECTOR2I( aPosition ), dummy, maxdist ); - } - else - return m_poly.Collide( VECTOR2I( aPosition ), maxdist ); + return m_poly.Collide( VECTOR2I( aPosition ), maxdist ); } + else + { + SHAPE_POLY_SET::VERTEX_INDEX dummy; + return m_poly.CollideEdge( VECTOR2I( aPosition ), dummy, maxdist ); + } + break; default: @@ -1077,11 +1081,12 @@ std::vector PCB_SHAPE::MakeEffectiveShapes() const { std::vector pts = GetRectCorners(); - if( m_width == 0 ) + if( IsFilled() ) { effectiveShapes.emplace_back( new SHAPE_SIMPLE( pts ) ); } - else + + if( m_width > 0 || !IsFilled() ) { effectiveShapes.emplace_back( new SHAPE_SEGMENT( pts[0], pts[1], m_width ) ); effectiveShapes.emplace_back( new SHAPE_SEGMENT( pts[1], pts[2], m_width ) ); @@ -1093,11 +1098,12 @@ std::vector PCB_SHAPE::MakeEffectiveShapes() const case S_CIRCLE: { - if( m_width == 0 ) + if( IsFilled() ) { effectiveShapes.emplace_back( new SHAPE_CIRCLE( GetCenter(), GetRadius() ) ); } - else + + if( m_width > 0 || !IsFilled() ) { // SHAPE_CIRCLE has no ConvertToPolyline() method, so use a 360.0 SHAPE_ARC SHAPE_ARC circle( GetCenter(), GetEnd(), 360.0 ); @@ -1132,12 +1138,12 @@ std::vector PCB_SHAPE::MakeEffectiveShapes() const { SHAPE_LINE_CHAIN l = GetPolyShape().COutline( 0 ); - if( IsPolygonFilled() ) + if( IsFilled() ) { effectiveShapes.emplace_back( new SHAPE_SIMPLE( l ) ); } - if( !IsPolygonFilled() || m_width > 0 ) + if( m_width > 0 || !IsFilled() ) { for( int i = 0; i < l.SegmentCount(); i++ ) effectiveShapes.emplace_back( new SHAPE_SEGMENT( l.Segment( i ), m_width ) ); diff --git a/pcbnew/pcb_shape.h b/pcbnew/pcb_shape.h index 231fc5e33a..b1769ccc42 100644 --- a/pcbnew/pcb_shape.h +++ b/pcbnew/pcb_shape.h @@ -44,6 +44,7 @@ class PCB_SHAPE : public BOARD_ITEM { protected: int m_width; // thickness of lines ... + bool m_filled; // Pretty much what it says on the tin... wxPoint m_start; // Line start point or Circle and Arc center wxPoint m_end; // Line end point or circle and arc start point wxPoint m_thirdPoint; // Used only for Arcs: arc end point @@ -90,13 +91,27 @@ public: return false; } - /** Polygonal shape is not always filled. - * For now it is filled on all layers but Edge_Cut layer - */ - bool IsPolygonFilled() const { return m_Layer != Edge_Cuts; } + void SetFilled( bool aFlag ) { m_filled = aFlag; } - void SetWidth( int aWidth ) { m_width = aWidth; } - int GetWidth() const { return m_width; } + bool IsFilled() const + { + switch( m_shape ) + { + case S_RECT: + case S_CIRCLE: + case S_POLYGON: + return m_filled; + + case S_SEGMENT: + case S_ARC: + case S_CURVE: + case S_LAST: + return false; + } + } + + void SetWidth( int aWidth ) { m_width = aWidth; } + int GetWidth() const { return m_width; } /** * Function SetAngle diff --git a/pcbnew/plot_board_layers.cpp b/pcbnew/plot_board_layers.cpp index d3d19ebdd7..df75c0fbad 100644 --- a/pcbnew/plot_board_layers.cpp +++ b/pcbnew/plot_board_layers.cpp @@ -344,7 +344,7 @@ void PlotStandardLayer( BOARD *aBoard, PLOTTER* aPlotter, LSET aLayerMask, int numSegs = GetArcToSegmentCount( margin.x, maxError, 360.0 ); shape.InflateWithLinkedHoles( margin.x, numSegs, SHAPE_POLY_SET::PM_FAST ); dummy.DeletePrimitivesList(); - dummy.AddPrimitivePoly( shape, 0 ); + dummy.AddPrimitivePoly( shape, 0, true ); // Be sure the anchor pad is not bigger than the deflated shape because this // anchor will be added to the pad shape when plotting the pad. So now the diff --git a/pcbnew/plot_brditems_plotter.cpp b/pcbnew/plot_brditems_plotter.cpp index 9a08d03026..556711f6dd 100644 --- a/pcbnew/plot_brditems_plotter.cpp +++ b/pcbnew/plot_brditems_plotter.cpp @@ -446,6 +446,7 @@ void BRDITEMS_PLOTTER::PlotDimension( DIMENSION_BASE* aDim ) int radius = static_cast( shape.get() )->GetRadius(); draw.SetShape( S_CIRCLE ); + draw.SetFilled( false ); draw.SetStart( start ); draw.SetEnd( wxPoint( start.x + radius, start.y ) ); @@ -472,6 +473,7 @@ void BRDITEMS_PLOTTER::PlotPcbTarget( PCB_TARGET* aMire ) PCB_SHAPE draw; draw.SetShape( S_CIRCLE ); + draw.SetFilled( false ); draw.SetWidth( aMire->GetWidth() ); draw.SetLayer( aMire->GetLayer() ); draw.SetStart( aMire->GetPosition() ); @@ -534,6 +536,7 @@ void BRDITEMS_PLOTTER::PlotFootprintGraphicItem( FP_SHAPE* aShape ) m_plotter->SetColor( getColor( aShape->GetLayer() ) ); + bool sketch = GetPlotMode() == SKETCH; int thickness = aShape->GetWidth(); wxPoint pos( aShape->GetStart() ); wxPoint end( aShape->GetEnd() ); @@ -567,14 +570,15 @@ void BRDITEMS_PLOTTER::PlotFootprintGraphicItem( FP_SHAPE* aShape ) { std::vector pts = aShape->GetRectCorners(); - if( aShape->GetWidth() > 0 ) + if( sketch || thickness > 0 ) { m_plotter->ThickSegment( pts[0], pts[1], thickness, GetPlotMode(), &gbr_metadata ); m_plotter->ThickSegment( pts[1], pts[2], thickness, GetPlotMode(), &gbr_metadata ); m_plotter->ThickSegment( pts[2], pts[3], thickness, GetPlotMode(), &gbr_metadata ); m_plotter->ThickSegment( pts[3], pts[0], thickness, GetPlotMode(), &gbr_metadata ); } - else + + if( !sketch && aShape->IsFilled() ) { SHAPE_LINE_CHAIN poly; @@ -589,10 +593,10 @@ void BRDITEMS_PLOTTER::PlotFootprintGraphicItem( FP_SHAPE* aShape ) case S_CIRCLE: radius = KiROUND( GetLineLength( end, pos ) ); - if( aShape->GetWidth() > 0 ) - m_plotter->ThickCircle( pos, radius * 2, thickness, GetPlotMode(), &gbr_metadata ); + if( aShape->IsFilled() ) + m_plotter->FilledCircle( pos, radius * 2 + thickness, GetPlotMode(), &gbr_metadata ); else - m_plotter->FilledCircle( pos, radius * 2, GetPlotMode(), &gbr_metadata ); + m_plotter->ThickCircle( pos, radius * 2, thickness, GetPlotMode(), &gbr_metadata ); break; @@ -639,7 +643,7 @@ void BRDITEMS_PLOTTER::PlotFootprintGraphicItem( FP_SHAPE* aShape ) cornerList.push_back( corner ); } - if( !aShape->IsPolygonFilled() ) + if( sketch || thickness > 0 ) { for( size_t i = 1; i < cornerList.size(); i++ ) { @@ -651,7 +655,8 @@ void BRDITEMS_PLOTTER::PlotFootprintGraphicItem( FP_SHAPE* aShape ) GetPlotMode(), &gbr_metadata ); } - else + + if( !sketch && aShape->IsFilled() ) { // This must be simplified and fractured to prevent overlapping polygons // from generating invalid Gerber files @@ -674,8 +679,7 @@ void BRDITEMS_PLOTTER::PlotFootprintGraphicItem( FP_SHAPE* aShape ) case S_CURVE: m_plotter->BezierCurve( aShape->GetStart(), aShape->GetBezControl1(), - aShape->GetBezControl2(), aShape->GetEnd(), - 0, thickness ); + aShape->GetBezControl2(), aShape->GetEnd(), 0, thickness ); break; default: @@ -852,6 +856,7 @@ void BRDITEMS_PLOTTER::PlotPcbShape( PCB_SHAPE* aShape ) int radius = 0; double StAngle = 0, EndAngle = 0; + bool sketch = GetPlotMode() == SKETCH; int thickness = aShape->GetWidth(); m_plotter->SetColor( getColor( aShape->GetLayer() ) ); @@ -879,10 +884,11 @@ void BRDITEMS_PLOTTER::PlotPcbShape( PCB_SHAPE* aShape ) case S_CIRCLE: radius = KiROUND( GetLineLength( end, start ) ); - if( thickness > 0 ) - m_plotter->ThickCircle( start, radius * 2, thickness, GetPlotMode(), &gbr_metadata ); + if( aShape->IsFilled() ) + m_plotter->FilledCircle( start, radius * 2 + thickness, GetPlotMode(), &gbr_metadata ); else - m_plotter->FilledCircle( start, radius * 2, GetPlotMode(), &gbr_metadata ); + m_plotter->ThickCircle( start, radius * 2, thickness, GetPlotMode(), &gbr_metadata ); + break; case S_ARC: @@ -892,19 +898,25 @@ void BRDITEMS_PLOTTER::PlotPcbShape( PCB_SHAPE* aShape ) // when startAngle == endAngle ThickArc() doesn't know whether it's 0 deg and 360 deg if( std::abs( aShape->GetAngle() ) == 3600.0 ) + { m_plotter->ThickCircle( start, radius * 2, thickness, GetPlotMode(), &gbr_metadata ); + } else - m_plotter->ThickArc( start, -EndAngle, -StAngle, radius, thickness, GetPlotMode(), &gbr_metadata ); + { + m_plotter->ThickArc( start, -EndAngle, -StAngle, radius, thickness, GetPlotMode(), + &gbr_metadata ); + } break; case S_CURVE: - m_plotter->BezierCurve( aShape->GetStart(), aShape->GetBezControl1(), aShape->GetBezControl2(), - aShape->GetEnd(), 0, thickness ); + m_plotter->BezierCurve( aShape->GetStart(), aShape->GetBezControl1(), + aShape->GetBezControl2(), aShape->GetEnd(), 0, thickness ); break; case S_POLYGON: + if( aShape->IsPolyShapeValid() ) { - if( !aShape->IsPolygonFilled() ) + if( sketch || thickness > 0 ) { for( auto it = aShape->GetPolyShape().CIterateSegments( 0 ); it; it++ ) { @@ -913,7 +925,8 @@ void BRDITEMS_PLOTTER::PlotPcbShape( PCB_SHAPE* aShape ) thickness, GetPlotMode(), &gbr_metadata ); } } - else + + if( !sketch && aShape->IsFilled() ) { m_plotter->SetCurrentLineWidth( thickness, &gbr_metadata ); // Draw the polygon: only one polygon is expected @@ -937,14 +950,15 @@ void BRDITEMS_PLOTTER::PlotPcbShape( PCB_SHAPE* aShape ) { std::vector pts = aShape->GetRectCorners(); - if( aShape->GetWidth() > 0 ) + if( sketch || thickness > 0 ) { m_plotter->ThickSegment( pts[0], pts[1], thickness, GetPlotMode(), &gbr_metadata ); m_plotter->ThickSegment( pts[1], pts[2], thickness, GetPlotMode(), &gbr_metadata ); m_plotter->ThickSegment( pts[2], pts[3], thickness, GetPlotMode(), &gbr_metadata ); m_plotter->ThickSegment( pts[3], pts[0], thickness, GetPlotMode(), &gbr_metadata ); } - else + + if( !sketch && aShape->IsFilled() ) { SHAPE_LINE_CHAIN poly; diff --git a/pcbnew/plugins/altium/altium_pcb.cpp b/pcbnew/plugins/altium/altium_pcb.cpp index a57ce4b314..727f2659fc 100644 --- a/pcbnew/plugins/altium/altium_pcb.cpp +++ b/pcbnew/plugins/altium/altium_pcb.cpp @@ -1455,6 +1455,7 @@ void ALTIUM_PCB::ParseShapeBasedRegions6Data( const CFB::CompoundFileReader& aRe PCB_SHAPE* shape = new PCB_SHAPE( m_board ); m_board->Add( shape, ADD_MODE::APPEND ); shape->SetShape( S_POLYGON ); + shape->SetFilled( true ); shape->SetLayer( klayer ); shape->SetWidth( 0 ); @@ -1893,29 +1894,31 @@ void ALTIUM_PCB::HelperParsePad6NonCopper( const APAD6& aElem ) if( klayer == UNDEFINED_LAYER ) { - wxLogWarning( wxString::Format( - _( "Non-Copper Pad on Altium layer %d has no KiCad equivalent. Put it on Eco1_User instead" ), - aElem.layer ) ); + wxLogWarning( wxString::Format( _( "Non-Copper Pad on Altium layer %d has no KiCad " + "equivalent. Put it on Eco1_User instead" ), + aElem.layer ) ); klayer = Eco1_User; } if( aElem.net != ALTIUM_NET_UNCONNECTED ) { - wxLogError( wxString::Format( - "Non-Copper Pad '%s' is connected to a net. This is not supported", aElem.name ) ); + wxLogError( wxString::Format( "Non-Copper Pad '%s' is connected to a net. This is not " + "supported", + aElem.name ) ); } if( aElem.holesize != 0 ) { - wxLogError( wxString::Format( - "Non-Copper Pad '%s' has a hole. This should not happen", aElem.name ) ); + wxLogError( wxString::Format( _( "Non-Copper Pad '%s' has a hole. This should not happen" ), + aElem.name ) ); } if( aElem.padmode != ALTIUM_PAD_MODE::SIMPLE ) { - wxLogWarning( wxString::Format( - _( "Non-Copper Pad '%s' uses a complex pad stack (kind %d). This should not happen" ), - aElem.name, aElem.padmode ) ); + wxLogWarning( wxString::Format( _( "Non-Copper Pad '%s' uses a complex pad stack (kind %d). " + "This should not happen" ), + aElem.name, + aElem.padmode ) ); } switch( aElem.topshape ) @@ -1925,6 +1928,7 @@ void ALTIUM_PCB::HelperParsePad6NonCopper( const APAD6& aElem ) // filled rect PCB_SHAPE* shape = HelperCreateAndAddDrawsegment( aElem.component ); shape->SetShape( S_POLYGON ); + shape->SetFilled( true ); shape->SetLayer( klayer ); shape->SetWidth( 0 ); @@ -1969,6 +1973,7 @@ void ALTIUM_PCB::HelperParsePad6NonCopper( const APAD6& aElem ) { // circle shape->SetShape( S_CIRCLE ); + shape->SetFilled( true ); shape->SetCenter( aElem.position ); shape->SetWidth( aElem.topsize.x / 2 ); shape->SetArcStart( aElem.position - wxPoint( 0, aElem.topsize.x / 4 ) ); @@ -2000,6 +2005,7 @@ void ALTIUM_PCB::HelperParsePad6NonCopper( const APAD6& aElem ) // filled circle PCB_SHAPE* shape = HelperCreateAndAddDrawsegment( aElem.component ); shape->SetShape( S_CIRCLE ); + shape->SetFilled( true ); shape->SetLayer( klayer ); shape->SetCenter( aElem.position ); shape->SetWidth( aElem.topsize.x / 2 ); @@ -2039,6 +2045,7 @@ void ALTIUM_PCB::HelperParsePad6NonCopper( const APAD6& aElem ) // filled octagon PCB_SHAPE* shape = HelperCreateAndAddDrawsegment( aElem.component ); shape->SetShape( S_POLYGON ); + shape->SetFilled( true ); shape->SetLayer( klayer ); shape->SetWidth( 0 ); @@ -2407,8 +2414,8 @@ void ALTIUM_PCB::ParseTexts6Data( const CFB::CompoundFileReader& aReader, } } -void ALTIUM_PCB::ParseFills6Data( - const CFB::CompoundFileReader& aReader, const CFB::COMPOUND_FILE_ENTRY* aEntry ) +void ALTIUM_PCB::ParseFills6Data( const CFB::CompoundFileReader& aReader, + const CFB::COMPOUND_FILE_ENTRY* aEntry ) { ALTIUM_PARSER reader( aReader, aEntry ); @@ -2426,9 +2433,9 @@ void ALTIUM_PCB::ParseFills6Data( PCB_LAYER_ID klayer = GetKicadLayer( elem.layer ); if( klayer == UNDEFINED_LAYER ) { - wxLogWarning( wxString::Format( - _( "Fill on Altium layer %d has no KiCad equivalent. Put it on Eco1_User instead" ), - elem.layer ) ); + wxLogWarning( wxString::Format( _( "Fill on Altium layer %d has no KiCad equivalent. " + "Put it on Eco1_User instead" ), + elem.layer ) ); klayer = Eco1_User; } @@ -2474,6 +2481,7 @@ void ALTIUM_PCB::ParseFills6Data( m_board->Add( shape, ADD_MODE::APPEND ); shape->SetShape( S_POLYGON ); + shape->SetFilled( true ); shape->SetLayer( klayer ); shape->SetWidth( 0 ); diff --git a/pcbnew/plugins/cadstar/cadstar_pcb_archive_loader.cpp b/pcbnew/plugins/cadstar/cadstar_pcb_archive_loader.cpp index 83d4c37018..57ff96a93e 100644 --- a/pcbnew/plugins/cadstar/cadstar_pcb_archive_loader.cpp +++ b/pcbnew/plugins/cadstar/cadstar_pcb_archive_loader.cpp @@ -902,7 +902,8 @@ PAD* CADSTAR_PCB_ARCHIVE_LOADER::getKiCadPad( const COMPONENT_PAD& aCadstarPad, ERROR_LOC::ERROR_INSIDE ); PCB_SHAPE* padShape = new PCB_SHAPE; - padShape->SetShape( PCB_SHAPE_TYPE_T::S_POLYGON ); + padShape->SetShape( S_POLYGON ); + padShape->SetFilled( true ); padShape->SetPolyShape( padOutline ); padShape->SetWidth( 0 ); padShape->Move( padOffset - drillOffset ); @@ -1911,6 +1912,7 @@ void CADSTAR_PCB_ARCHIVE_LOADER::drawCadstarShape( const SHAPE& aCadstarShape, { shape = new PCB_SHAPE( aContainer ); shape->SetShape( S_POLYGON ); + shape->SetFilled( true ); } shape->SetPolyShape( getPolySetFromCadstarShape( aCadstarShape, -1, aContainer, aMoveVector, diff --git a/pcbnew/plugins/eagle/eagle_plugin.cpp b/pcbnew/plugins/eagle/eagle_plugin.cpp index 1f20e5d144..f1b1fff219 100644 --- a/pcbnew/plugins/eagle/eagle_plugin.cpp +++ b/pcbnew/plugins/eagle/eagle_plugin.cpp @@ -775,14 +775,8 @@ void EAGLE_PLUGIN::loadPlain( wxXmlNode* aGraphics ) PCB_SHAPE* shape = new PCB_SHAPE( m_board ); m_board->Add( shape, ADD_MODE::APPEND ); - // with == 0 means filled circle - if( width <= 0 ) - { - width = radius; - radius = radius / 2; - } - shape->SetShape( S_CIRCLE ); + shape->SetFilled( false ); shape->SetLayer( layer ); shape->SetStart( wxPoint( kicad_x( c.x ), kicad_y( c.y ) ) ); shape->SetEnd( wxPoint( kicad_x( c.x ) + radius, kicad_y( c.y ) ) ); diff --git a/pcbnew/plugins/kicad/kicad_plugin.cpp b/pcbnew/plugins/kicad/kicad_plugin.cpp index 50dd6e1ed6..3dc0b804d1 100644 --- a/pcbnew/plugins/kicad/kicad_plugin.cpp +++ b/pcbnew/plugins/kicad/kicad_plugin.cpp @@ -843,6 +843,9 @@ void PCB_IO::format( PCB_SHAPE* aShape, int aNestLevel ) const m_out->Print( 0, " (width %s)", FormatInternalUnits( aShape->GetWidth() ).c_str() ); + if( aShape->IsFilled() ) + m_out->Print( 0, " (fill yes)" ); + m_out->Print( 0, " (tstamp %s)", TO_UTF8( aShape->m_Uuid.AsString() ) ); m_out->Print( 0, ")\n" ); @@ -928,6 +931,9 @@ void PCB_IO::format( FP_SHAPE* aFPShape, int aNestLevel ) const m_out->Print( 0, " (width %s)", FormatInternalUnits( aFPShape->GetWidth() ).c_str() ); + if( aFPShape->IsFilled() ) + m_out->Print( 0, " (fill yes)" ); + m_out->Print( 0, " (tstamp %s)", TO_UTF8( aFPShape->m_Uuid.AsString() ) ); m_out->Print( 0, ")\n" ); @@ -1453,48 +1459,43 @@ void PCB_IO::format( PAD* aPad, int aNestLevel ) const switch( primitive->GetShape() ) { case S_SEGMENT: // usual segment : line with rounded ends - m_out->Print( nested_level, "(gr_line (start %s) (end %s) (width %s))", + m_out->Print( nested_level, "(gr_line (start %s) (end %s)", FormatInternalUnits( primitive->GetStart() ).c_str(), - FormatInternalUnits( primitive->GetEnd() ).c_str(), - FormatInternalUnits( primitive->GetWidth() ).c_str() ); + FormatInternalUnits( primitive->GetEnd() ).c_str() ); break; case S_RECT: - m_out->Print( nested_level, "(gr_rect (start %s) (end %s) (width %s))", + m_out->Print( nested_level, "(gr_rect (start %s) (end %s)", FormatInternalUnits( primitive->GetStart() ).c_str(), - FormatInternalUnits( primitive->GetEnd() ).c_str(), - FormatInternalUnits( primitive->GetWidth() ).c_str() ); + FormatInternalUnits( primitive->GetEnd() ).c_str() ); break; case S_ARC: // Arc with rounded ends - m_out->Print( nested_level, "(gr_arc (start %s) (end %s) (angle %s) (width %s))", + m_out->Print( nested_level, "(gr_arc (start %s) (end %s) (angle %s)", FormatInternalUnits( primitive->GetStart() ).c_str(), FormatInternalUnits( primitive->GetEnd() ).c_str(), - FormatAngle( primitive->GetAngle() ).c_str(), - FormatInternalUnits( primitive->GetWidth() ).c_str() ); + FormatAngle( primitive->GetAngle() ).c_str() ); break; case S_CIRCLE: // ring or circle (circle if width == 0 - m_out->Print( nested_level, "(gr_circle (center %s) (end %s) (width %s))", + m_out->Print( nested_level, "(gr_circle (center %s) (end %s)", FormatInternalUnits( primitive->GetStart() ).c_str(), - FormatInternalUnits( primitive->GetEnd() ).c_str(), - FormatInternalUnits( primitive->GetWidth() ).c_str() ); + FormatInternalUnits( primitive->GetEnd() ).c_str() ); break; case S_CURVE: // Bezier Curve - m_out->Print( aNestLevel, "(gr_curve (pts (xy %s) (xy %s) (xy %s) (xy %s)) (width %s))", + m_out->Print( nested_level, "(gr_curve (pts (xy %s) (xy %s) (xy %s) (xy %s))", FormatInternalUnits( primitive->GetStart() ).c_str(), FormatInternalUnits( primitive->GetBezControl1() ).c_str(), FormatInternalUnits( primitive->GetBezControl2() ).c_str(), - FormatInternalUnits( primitive->GetEnd() ).c_str(), - FormatInternalUnits( primitive->GetWidth() ).c_str() ); + FormatInternalUnits( primitive->GetEnd() ).c_str() ); break; case S_POLYGON: // polygon if( primitive->GetPolyShape().COutline( 0 ).CPoints().size() < 2 ) break; // Malformed polygon. - { + { m_out->Print( nested_level, "(gr_poly (pts\n"); // Write the polygon corners coordinates: @@ -1516,14 +1517,21 @@ void PCB_IO::format( PAD* aPad, int aNestLevel ) const } } - m_out->Print( newLine ? 0 : nested_level, ") (width %s))", - FormatInternalUnits( primitive->GetWidth() ).c_str() ); - } + m_out->Print( newLine ? 0 : nested_level, ")" ); + } break; default: break; } + + m_out->Print( nested_level, " (width %s)", + FormatInternalUnits( primitive->GetWidth() ).c_str() ); + + if( primitive->IsFilled() ) + m_out->Print( nested_level, " (fill yes)" ); + + m_out->Print( nested_level, ")" ); } m_out->Print( 0, "\n"); diff --git a/pcbnew/plugins/kicad/kicad_plugin.h b/pcbnew/plugins/kicad/kicad_plugin.h index 0e6befa205..6192371d08 100644 --- a/pcbnew/plugins/kicad/kicad_plugin.h +++ b/pcbnew/plugins/kicad/kicad_plugin.h @@ -88,7 +88,8 @@ class PCB_TEXT; //#define SEXPR_BOARD_FILE_VERSION 20200916 // Add center dimension //#define SEXPR_BOARD_FILE_VERSION 20200921 // Add orthogonal dimension //#define SEXPR_BOARD_FILE_VERSION 20200922 // Add user name to layer definition. -#define SEXPR_BOARD_FILE_VERSION 20201002 // Add groups in footprints (for footprint editor). +//#define SEXPR_BOARD_FILE_VERSION 20201002 // Add groups in footprints (for footprint editor). +#define SEXPR_BOARD_FILE_VERSION 20201114 // Add first-class support for filled shapes. #define BOARD_FILE_HOST_VERSION 20200825 ///< Earlier files than this include the host tag diff --git a/pcbnew/plugins/kicad/pcb_parser.cpp b/pcbnew/plugins/kicad/pcb_parser.cpp index 5160f6483b..888c412356 100644 --- a/pcbnew/plugins/kicad/pcb_parser.cpp +++ b/pcbnew/plugins/kicad/pcb_parser.cpp @@ -603,7 +603,7 @@ BOARD* PCB_PARSER::parseBOARD_unchecked() case T_gr_circle: case T_gr_rect: // these filled shapes are allowed and are filled if the line width = 0 - m_board->Add( parsePCB_SHAPE( true ), ADD_MODE::APPEND ); + m_board->Add( parsePCB_SHAPE(), ADD_MODE::APPEND ); break; case T_gr_text: @@ -2071,7 +2071,8 @@ void PCB_PARSER::parseNETCLASS() break; default: - Expecting( "clearance, trace_width, via_dia, via_drill, uvia_dia, uvia_drill, diff_pair_width, diff_pair_gap or add_net" ); + Expecting( "clearance, trace_width, via_dia, via_drill, uvia_dia, uvia_drill, " + "diff_pair_width, diff_pair_gap or add_net" ); } NeedRIGHT(); @@ -2092,7 +2093,7 @@ void PCB_PARSER::parseNETCLASS() } -PCB_SHAPE* PCB_PARSER::parsePCB_SHAPE( bool aAllowZeroWidth ) +PCB_SHAPE* PCB_PARSER::parsePCB_SHAPE() { wxCHECK_MSG( CurTok() == T_gr_arc || CurTok() == T_gr_circle || CurTok() == T_gr_curve || CurTok() == T_gr_rect || CurTok() == T_gr_line || CurTok() == T_gr_poly, NULL, @@ -2252,37 +2253,69 @@ PCB_SHAPE* PCB_PARSER::parsePCB_SHAPE( bool aAllowZeroWidth ) { case T_angle: shape->SetAngle( parseDouble( "segment angle" ) * 10.0 ); + NeedRIGHT(); break; case T_layer: shape->SetLayer( parseBoardItemLayer() ); + NeedRIGHT(); break; case T_width: shape->SetWidth( parseBoardUnits( T_width ) ); + NeedRIGHT(); break; case T_tstamp: NextTok(); const_cast( shape->m_Uuid ) = CurStrToKIID(); + NeedRIGHT(); + break; + + case T_fill: + for( token = NextTok(); token != T_RIGHT; token = NextTok() ) + { + if( token == T_LEFT ) + token = NextTok(); + + switch( token ) + { + case T_yes: + shape->SetFilled( true ); + break; + + default: + Expecting( "yes" ); + } + } break; /// We continue to parse the status field but it is no longer written case T_status: shape->SetStatus( static_cast( parseHex() ) ); + NeedRIGHT(); break; default: - Expecting( "layer, width, tstamp, or status" ); + Expecting( "layer, width, fill, tstamp, or status" ); } - - NeedRIGHT(); } - // Only filled polygons, circles and rect may have a zero-line width - // This is not permitted in KiCad for other shapes but some external tools can - // generate invalid files. - if( shape->GetWidth() < 0 || ( shape->GetWidth() == 0 && !aAllowZeroWidth ) ) + // Legacy versions didn't have a filled flag but allowed some shapes to indicate they + // should be filled by specifying a 0 stroke-width. + if( m_requiredVersion <= 20201002 ) + { + if( shape->GetWidth() == 0 && ( shape->GetShape() == S_RECT + || shape->GetShape() == S_CIRCLE + || shape->GetShape() == S_POLYGON ) ) + { + shape->SetFilled( true ); + } + } + + // Only filled shapes may have a zero line-width. This is not permitted in KiCad but some + // external tools can generate invalid files. + if( shape->GetWidth() <= 0 && !shape->IsFilled() ) { shape->SetWidth( Millimeter2iu( DEFAULT_LINE_WIDTH ) ); } @@ -3375,35 +3408,64 @@ FP_SHAPE* PCB_PARSER::parseFP_SHAPE() { case T_layer: shape->SetLayer( parseBoardItemLayer() ); + NeedRIGHT(); break; case T_width: shape->SetWidth( parseBoardUnits( T_width ) ); + NeedRIGHT(); break; case T_tstamp: NextTok(); const_cast( shape->m_Uuid ) = CurStrToKIID(); + NeedRIGHT(); + break; + + case T_fill: + for( token = NextTok(); token != T_RIGHT; token = NextTok() ) + { + if( token == T_LEFT ) + token = NextTok(); + + switch( token ) + { + case T_yes: + shape->SetFilled( true ); + break; + + default: + Expecting( "yes" ); + } + } break; /// We continue to parse the status field but it is no longer written case T_status: shape->SetStatus( static_cast( parseHex() ) ); + NeedRIGHT(); break; default: - Expecting( "layer, width or tstamp" ); + Expecting( "layer, width, fill, tstamp, or status" ); } - - NeedRIGHT(); } - // Only filled shapes may have a zero-line width. While not permitted in KiCad, some - // external tools generate invalid files. - if( shape->GetShape() != S_RECT - && shape->GetShape() != S_CIRCLE - && shape->GetShape() != S_POLYGON - && shape->GetWidth() == 0 ) + // Legacy versions didn't have a filled flag but allowed some shapes to indicate they + // should be filled by specifying a 0 stroke-width. + if( m_requiredVersion <= 20201002 ) + { + if( shape->GetWidth() == 0 && ( shape->GetShape() == S_RECT + || shape->GetShape() == S_CIRCLE + || shape->GetShape() == S_POLYGON ) ) + { + shape->SetFilled( true ); + } + } + + // Only filled shapes may have a zero line-width. This is not permitted in KiCad but some + // external tools can generate invalid files. + if( shape->GetWidth() <= 0 && !shape->IsFilled() ) { shape->SetWidth( Millimeter2iu( DEFAULT_LINE_WIDTH ) ); } @@ -3817,32 +3879,29 @@ PAD* PCB_PARSER::parsePAD( FOOTPRINT* aParent ) break; case T_gr_circle: - dummysegm = parsePCB_SHAPE( true ); // Circles with 0 thickness are allowed - // ( filled circles ) + dummysegm = parsePCB_SHAPE(); pad->AddPrimitiveCircle( dummysegm->GetCenter(), dummysegm->GetRadius(), - dummysegm->GetWidth() ); + dummysegm->GetWidth(), dummysegm->IsFilled() ); break; case T_gr_rect: - dummysegm = parsePCB_SHAPE( true ); // rect with 0 thickness are allowed - // ( filled rects ) + dummysegm = parsePCB_SHAPE(); pad->AddPrimitiveRect( dummysegm->GetStart(), dummysegm->GetEnd(), - dummysegm->GetWidth() ); + dummysegm->GetWidth(), dummysegm->IsFilled() ); break; case T_gr_poly: - dummysegm = parsePCB_SHAPE( true ); - pad->AddPrimitivePoly( dummysegm->BuildPolyPointsList(), - dummysegm->GetWidth() ); + dummysegm = parsePCB_SHAPE(); + pad->AddPrimitivePoly( dummysegm->BuildPolyPointsList(), dummysegm->GetWidth(), + dummysegm->IsFilled() ); break; case T_gr_curve: dummysegm = parsePCB_SHAPE(); pad->AddPrimitiveCurve( dummysegm->GetStart(), dummysegm->GetEnd(), dummysegm->GetBezControl1(), - dummysegm->GetBezControl2(), - dummysegm->GetWidth() ); + dummysegm->GetBezControl2(), dummysegm->GetWidth() ); break; default: diff --git a/pcbnew/plugins/kicad/pcb_parser.h b/pcbnew/plugins/kicad/pcb_parser.h index 710ad450ea..59e5c62082 100644 --- a/pcbnew/plugins/kicad/pcb_parser.h +++ b/pcbnew/plugins/kicad/pcb_parser.h @@ -157,12 +157,7 @@ class PCB_PARSER : public PCB_LEXER void parseNETINFO_ITEM(); void parseNETCLASS(); - /** Read a PCB_SHAPE description. - * @param aAllowZeroWidth = true to allow items with line width = 0 - * (in this case, the are filled shapes) - * Mainly used in custom pad shapes for filled circles. - */ - PCB_SHAPE* parsePCB_SHAPE( bool aAllowZeroWidth = false ); + PCB_SHAPE* parsePCB_SHAPE(); PCB_TEXT* parsePCB_TEXT(); DIMENSION_BASE* parseDIMENSION(); diff --git a/pcbnew/plugins/legacy/legacy_plugin.cpp b/pcbnew/plugins/legacy/legacy_plugin.cpp index dc6dc7b38d..a8225df4ae 100644 --- a/pcbnew/plugins/legacy/legacy_plugin.cpp +++ b/pcbnew/plugins/legacy/legacy_plugin.cpp @@ -1933,6 +1933,7 @@ void LEGACY_PLUGIN::loadPCB_LINE() width = 0; dseg->SetShape( PCB_SHAPE_TYPE_T( shape ) ); + dseg->SetFilled( false ); dseg->SetWidth( width ); dseg->SetStart( wxPoint( start_x, start_y ) ); dseg->SetEnd( wxPoint( end_x, end_y ) ); diff --git a/pcbnew/plugins/pcad/pcb_arc.cpp b/pcbnew/plugins/pcad/pcb_arc.cpp index 564eff3df1..9cfa6f88c8 100644 --- a/pcbnew/plugins/pcad/pcb_arc.cpp +++ b/pcbnew/plugins/pcad/pcb_arc.cpp @@ -185,6 +185,7 @@ void PCB_ARC::AddToBoard() m_board->Add( arc, ADD_MODE::APPEND ); arc->SetShape( IsCircle() ? S_CIRCLE : S_ARC ); + arc->SetFilled( false ); arc->SetLayer( m_KiCadLayer ); arc->SetStart( wxPoint( m_positionX, m_positionY ) ); arc->SetEnd( wxPoint( m_StartX, m_StartY ) ); diff --git a/pcbnew/router/pns_kicad_iface.cpp b/pcbnew/router/pns_kicad_iface.cpp index f489be2f32..6161c75578 100644 --- a/pcbnew/router/pns_kicad_iface.cpp +++ b/pcbnew/router/pns_kicad_iface.cpp @@ -1045,7 +1045,7 @@ bool PNS_KICAD_IFACE_BASE::syncGraphicalItem( PNS::NODE* aWorld, PCB_SHAPE* aIte return false; // TODO: where do we handle filled polygons on copper layers? - if( aItem->GetShape() == S_POLYGON && aItem->IsPolygonFilled() ) + if( aItem->GetShape() == S_POLYGON && aItem->IsFilled() ) return false; for( SHAPE* shape : aItem->MakeEffectiveShapes() ) diff --git a/pcbnew/tools/convert_tool.cpp b/pcbnew/tools/convert_tool.cpp index cf1adb3529..87de9f349d 100644 --- a/pcbnew/tools/convert_tool.cpp +++ b/pcbnew/tools/convert_tool.cpp @@ -191,6 +191,7 @@ int CONVERT_TOOL::LinesToPoly( const TOOL_EVENT& aEvent ) PCB_SHAPE* graphic = isFootprint ? new FP_SHAPE( parentFootprint ) : new PCB_SHAPE; graphic->SetShape( S_POLYGON ); + graphic->SetFilled( destLayer != Edge_Cuts ); graphic->SetLayer( destLayer ); graphic->SetPolyShape( poly ); @@ -616,6 +617,7 @@ int CONVERT_TOOL::SegmentToArc( const TOOL_EVENT& aEvent ) VECTOR2I center = GetArcCenter( start, mid, end ); arc->SetShape( S_ARC ); + arc->SetFilled( false ); arc->SetLayer( layer ); arc->SetWidth( line->GetWidth() ); diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index a98d08380e..1b42e8f380 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -288,6 +288,7 @@ int DRAWING_TOOL::DrawRectangle( const TOOL_EVENT& aEvent ) OPT startingPoint = boost::make_optional( false, VECTOR2D( 0, 0 ) ); rect->SetShape( S_RECT ); + rect->SetFilled( false ); rect->SetFlags(IS_NEW ); if( aEvent.HasPosition() ) @@ -312,6 +313,7 @@ int DRAWING_TOOL::DrawRectangle( const TOOL_EVENT& aEvent ) rect = m_isFootprintEditor ? new FP_SHAPE( parentFootprint ) : new PCB_SHAPE; rect->SetShape( S_RECT ); + rect->SetFilled( false ); rect->SetFlags(IS_NEW ); startingPoint = NULLOPT; } @@ -332,6 +334,7 @@ int DRAWING_TOOL::DrawCircle( const TOOL_EVENT& aEvent ) OPT startingPoint = boost::make_optional( false, VECTOR2D( 0, 0 ) ); circle->SetShape( S_CIRCLE ); + circle->SetFilled( false ); circle->SetFlags( IS_NEW ); if( aEvent.HasPosition() ) @@ -356,6 +359,7 @@ int DRAWING_TOOL::DrawCircle( const TOOL_EVENT& aEvent ) circle = m_isFootprintEditor ? new FP_SHAPE( parentFootprint ) : new PCB_SHAPE; circle->SetShape( S_CIRCLE ); + circle->SetFilled( false ); circle->SetFlags( IS_NEW ); startingPoint = NULLOPT; } @@ -1398,6 +1402,7 @@ bool DRAWING_TOOL::drawSegment( const std::string& aTool, PCB_SHAPE** aGraphic, // Init the new item attributes graphic->SetShape( (PCB_SHAPE_TYPE_T) shape ); + graphic->SetFilled( false ); graphic->SetWidth( m_lineWidth ); graphic->SetLayer( m_frame->GetActiveLayer() ); grid.SetSkipPoint( cursorPos ); diff --git a/pcbnew/tools/pad_tool.cpp b/pcbnew/tools/pad_tool.cpp index bc3485d887..c2c00c37fe 100644 --- a/pcbnew/tools/pad_tool.cpp +++ b/pcbnew/tools/pad_tool.cpp @@ -585,6 +585,7 @@ PCB_LAYER_ID PAD_TOOL::explodePad( PAD* aPad ) FP_SHAPE* shape = new FP_SHAPE( board()->GetFirstFootprint() ); shape->SetShape( primitive->GetShape() ); + shape->SetFilled( primitive->IsFilled() ); shape->SetWidth( primitive->GetWidth() ); shape->SetStart( primitive->GetStart() ); shape->SetEnd( primitive->GetEnd() ); @@ -680,6 +681,7 @@ void PAD_TOOL::recombinePad( PAD* aPad ) PCB_SHAPE* shape = new PCB_SHAPE; shape->SetShape( S_POLYGON ); + shape->SetFilled( true ); shape->SetPolyShape( existingOutline ); shape->Move( - aPad->GetPosition() ); shape->Rotate( wxPoint( 0, 0 ), - aPad->GetOrientation() ); @@ -694,6 +696,7 @@ void PAD_TOOL::recombinePad( PAD* aPad ) PCB_SHAPE* pcbShape = new PCB_SHAPE; pcbShape->SetShape( fpShape->GetShape() ); + pcbShape->SetFilled( fpShape->IsFilled() ); pcbShape->SetWidth( fpShape->GetWidth() ); pcbShape->SetStart( fpShape->GetStart() ); pcbShape->SetEnd( fpShape->GetEnd() ); diff --git a/pcbnew/tools/zone_create_helper.cpp b/pcbnew/tools/zone_create_helper.cpp index 04c59753c8..8c45e5b1ca 100644 --- a/pcbnew/tools/zone_create_helper.cpp +++ b/pcbnew/tools/zone_create_helper.cpp @@ -236,7 +236,8 @@ void ZONE_CREATE_HELPER::commitZone( std::unique_ptr aZone ) { auto poly = m_tool.m_isFootprintEditor ? new FP_SHAPE( (FOOTPRINT *) parent ) : new PCB_SHAPE(); - poly->SetShape ( S_POLYGON ); + poly->SetShape( S_POLYGON ); + poly->SetFilled( m_params.m_layer != Edge_Cuts ); poly->SetLayer( m_params.m_layer ); poly->SetPolyShape ( *aZone->Outline() ); bCommit.Add( poly );