diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index d51c1019b1..f462c70074 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -883,6 +883,7 @@ set( PCB_COMMON_SRCS ${CMAKE_SOURCE_DIR}/pcbnew/pad.cpp ${CMAKE_SOURCE_DIR}/pcbnew/pad_utils.cpp ${CMAKE_SOURCE_DIR}/pcbnew/padstack.cpp + ${CMAKE_SOURCE_DIR}/pcbnew/pcb_point.cpp ${CMAKE_SOURCE_DIR}/pcbnew/pcb_target.cpp ${CMAKE_SOURCE_DIR}/pcbnew/pcb_reference_image.cpp ${CMAKE_SOURCE_DIR}/pcbnew/pcb_field.cpp diff --git a/common/bitmap_info.cpp b/common/bitmap_info.cpp index 01a9958c37..a1284980ed 100644 --- a/common/bitmap_info.cpp +++ b/common/bitmap_info.cpp @@ -397,6 +397,7 @@ void BuildBitmapInfo( std::unordered_map>& aBi aBitmapInfoCache[BITMAPS::add_line].emplace_back( BITMAPS::add_line, wxT( "add_line_24.png" ), 24, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::add_orthogonal_dimension].emplace_back( BITMAPS::add_orthogonal_dimension, wxT( "add_orthogonal_dimension_24.png" ), 24, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::add_pcb_target].emplace_back( BITMAPS::add_pcb_target, wxT( "add_pcb_target_24.png" ), 24, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::add_point].emplace_back( BITMAPS::add_point, wxT( "add_point_24.png" ), 24, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::add_power].emplace_back( BITMAPS::add_power, wxT( "add_power_24.png" ), 24, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::add_radial_dimension].emplace_back( BITMAPS::add_radial_dimension, wxT( "add_radial_dimension_24.png" ), 24, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::add_rectangle].emplace_back( BITMAPS::add_rectangle, wxT( "add_rectangle_24.png" ), 24, wxT( "light" ) ); @@ -836,6 +837,7 @@ void BuildBitmapInfo( std::unordered_map>& aBi aBitmapInfoCache[BITMAPS::add_line].emplace_back( BITMAPS::add_line, wxT( "add_line_dark_24.png" ), 24, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::add_orthogonal_dimension].emplace_back( BITMAPS::add_orthogonal_dimension, wxT( "add_orthogonal_dimension_dark_24.png" ), 24, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::add_pcb_target].emplace_back( BITMAPS::add_pcb_target, wxT( "add_pcb_target_dark_24.png" ), 24, wxT( "dark" ) ); + aBitmapInfoCache[BITMAPS::add_point].emplace_back( BITMAPS::add_point, wxT( "add_point_dark_24.png" ), 24, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::add_power].emplace_back( BITMAPS::add_power, wxT( "add_power_dark_24.png" ), 24, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::add_radial_dimension].emplace_back( BITMAPS::add_radial_dimension, wxT( "add_radial_dimension_dark_24.png" ), 24, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::add_rectangle].emplace_back( BITMAPS::add_rectangle, wxT( "add_rectangle_dark_24.png" ), 24, wxT( "dark" ) ); @@ -1275,6 +1277,7 @@ void BuildBitmapInfo( std::unordered_map>& aBi aBitmapInfoCache[BITMAPS::add_line].emplace_back( BITMAPS::add_line, wxT( "add_line_16.png" ), 16, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::add_orthogonal_dimension].emplace_back( BITMAPS::add_orthogonal_dimension, wxT( "add_orthogonal_dimension_16.png" ), 16, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::add_pcb_target].emplace_back( BITMAPS::add_pcb_target, wxT( "add_pcb_target_16.png" ), 16, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::add_point].emplace_back( BITMAPS::add_point, wxT( "add_point_16.png" ), 16, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::add_power].emplace_back( BITMAPS::add_power, wxT( "add_power_16.png" ), 16, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::add_radial_dimension].emplace_back( BITMAPS::add_radial_dimension, wxT( "add_radial_dimension_16.png" ), 16, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::add_rectangle].emplace_back( BITMAPS::add_rectangle, wxT( "add_rectangle_16.png" ), 16, wxT( "light" ) ); @@ -1714,6 +1717,7 @@ void BuildBitmapInfo( std::unordered_map>& aBi aBitmapInfoCache[BITMAPS::add_line].emplace_back( BITMAPS::add_line, wxT( "add_line_dark_16.png" ), 16, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::add_orthogonal_dimension].emplace_back( BITMAPS::add_orthogonal_dimension, wxT( "add_orthogonal_dimension_dark_16.png" ), 16, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::add_pcb_target].emplace_back( BITMAPS::add_pcb_target, wxT( "add_pcb_target_dark_16.png" ), 16, wxT( "dark" ) ); + aBitmapInfoCache[BITMAPS::add_point].emplace_back( BITMAPS::add_point, wxT( "add_point_dark_16.png" ), 16, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::add_power].emplace_back( BITMAPS::add_power, wxT( "add_power_dark_16.png" ), 16, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::add_radial_dimension].emplace_back( BITMAPS::add_radial_dimension, wxT( "add_radial_dimension_dark_16.png" ), 16, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::add_rectangle].emplace_back( BITMAPS::add_rectangle, wxT( "add_rectangle_dark_16.png" ), 16, wxT( "dark" ) ); @@ -2153,6 +2157,7 @@ void BuildBitmapInfo( std::unordered_map>& aBi aBitmapInfoCache[BITMAPS::add_line].emplace_back( BITMAPS::add_line, wxT( "add_line_32.png" ), 32, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::add_orthogonal_dimension].emplace_back( BITMAPS::add_orthogonal_dimension, wxT( "add_orthogonal_dimension_32.png" ), 32, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::add_pcb_target].emplace_back( BITMAPS::add_pcb_target, wxT( "add_pcb_target_32.png" ), 32, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::add_point].emplace_back( BITMAPS::add_point, wxT( "add_point_32.png" ), 32, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::add_power].emplace_back( BITMAPS::add_power, wxT( "add_power_32.png" ), 32, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::add_radial_dimension].emplace_back( BITMAPS::add_radial_dimension, wxT( "add_radial_dimension_32.png" ), 32, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::add_rectangle].emplace_back( BITMAPS::add_rectangle, wxT( "add_rectangle_32.png" ), 32, wxT( "light" ) ); @@ -2592,6 +2597,7 @@ void BuildBitmapInfo( std::unordered_map>& aBi aBitmapInfoCache[BITMAPS::add_line].emplace_back( BITMAPS::add_line, wxT( "add_line_dark_32.png" ), 32, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::add_orthogonal_dimension].emplace_back( BITMAPS::add_orthogonal_dimension, wxT( "add_orthogonal_dimension_dark_32.png" ), 32, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::add_pcb_target].emplace_back( BITMAPS::add_pcb_target, wxT( "add_pcb_target_dark_32.png" ), 32, wxT( "dark" ) ); + aBitmapInfoCache[BITMAPS::add_point].emplace_back( BITMAPS::add_point, wxT( "add_point_dark_32.png" ), 32, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::add_power].emplace_back( BITMAPS::add_power, wxT( "add_power_dark_32.png" ), 32, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::add_radial_dimension].emplace_back( BITMAPS::add_radial_dimension, wxT( "add_radial_dimension_dark_32.png" ), 32, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::add_rectangle].emplace_back( BITMAPS::add_rectangle, wxT( "add_rectangle_dark_32.png" ), 32, wxT( "dark" ) ); @@ -3031,6 +3037,7 @@ void BuildBitmapInfo( std::unordered_map>& aBi aBitmapInfoCache[BITMAPS::add_line].emplace_back( BITMAPS::add_line, wxT( "add_line_48.png" ), 48, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::add_orthogonal_dimension].emplace_back( BITMAPS::add_orthogonal_dimension, wxT( "add_orthogonal_dimension_48.png" ), 48, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::add_pcb_target].emplace_back( BITMAPS::add_pcb_target, wxT( "add_pcb_target_48.png" ), 48, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::add_point].emplace_back( BITMAPS::add_point, wxT( "add_point_48.png" ), 48, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::add_power].emplace_back( BITMAPS::add_power, wxT( "add_power_48.png" ), 48, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::add_radial_dimension].emplace_back( BITMAPS::add_radial_dimension, wxT( "add_radial_dimension_48.png" ), 48, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::add_rectangle].emplace_back( BITMAPS::add_rectangle, wxT( "add_rectangle_48.png" ), 48, wxT( "light" ) ); @@ -3470,6 +3477,7 @@ void BuildBitmapInfo( std::unordered_map>& aBi aBitmapInfoCache[BITMAPS::add_line].emplace_back( BITMAPS::add_line, wxT( "add_line_dark_48.png" ), 48, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::add_orthogonal_dimension].emplace_back( BITMAPS::add_orthogonal_dimension, wxT( "add_orthogonal_dimension_dark_48.png" ), 48, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::add_pcb_target].emplace_back( BITMAPS::add_pcb_target, wxT( "add_pcb_target_dark_48.png" ), 48, wxT( "dark" ) ); + aBitmapInfoCache[BITMAPS::add_point].emplace_back( BITMAPS::add_point, wxT( "add_point_dark_48.png" ), 48, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::add_power].emplace_back( BITMAPS::add_power, wxT( "add_power_dark_48.png" ), 48, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::add_radial_dimension].emplace_back( BITMAPS::add_radial_dimension, wxT( "add_radial_dimension_dark_48.png" ), 48, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::add_rectangle].emplace_back( BITMAPS::add_rectangle, wxT( "add_rectangle_dark_48.png" ), 48, wxT( "dark" ) ); @@ -3909,6 +3917,7 @@ void BuildBitmapInfo( std::unordered_map>& aBi aBitmapInfoCache[BITMAPS::add_line].emplace_back( BITMAPS::add_line, wxT( "add_line_64.png" ), 64, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::add_orthogonal_dimension].emplace_back( BITMAPS::add_orthogonal_dimension, wxT( "add_orthogonal_dimension_64.png" ), 64, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::add_pcb_target].emplace_back( BITMAPS::add_pcb_target, wxT( "add_pcb_target_64.png" ), 64, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::add_point].emplace_back( BITMAPS::add_point, wxT( "add_point_64.png" ), 64, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::add_power].emplace_back( BITMAPS::add_power, wxT( "add_power_64.png" ), 64, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::add_radial_dimension].emplace_back( BITMAPS::add_radial_dimension, wxT( "add_radial_dimension_64.png" ), 64, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::add_rectangle].emplace_back( BITMAPS::add_rectangle, wxT( "add_rectangle_64.png" ), 64, wxT( "light" ) ); @@ -4348,6 +4357,7 @@ void BuildBitmapInfo( std::unordered_map>& aBi aBitmapInfoCache[BITMAPS::add_line].emplace_back( BITMAPS::add_line, wxT( "add_line_dark_64.png" ), 64, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::add_orthogonal_dimension].emplace_back( BITMAPS::add_orthogonal_dimension, wxT( "add_orthogonal_dimension_dark_64.png" ), 64, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::add_pcb_target].emplace_back( BITMAPS::add_pcb_target, wxT( "add_pcb_target_dark_64.png" ), 64, wxT( "dark" ) ); + aBitmapInfoCache[BITMAPS::add_point].emplace_back( BITMAPS::add_point, wxT( "add_point_dark_64.png" ), 64, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::add_power].emplace_back( BITMAPS::add_power, wxT( "add_power_dark_64.png" ), 64, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::add_radial_dimension].emplace_back( BITMAPS::add_radial_dimension, wxT( "add_radial_dimension_dark_64.png" ), 64, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::add_rectangle].emplace_back( BITMAPS::add_rectangle, wxT( "add_rectangle_dark_64.png" ), 64, wxT( "dark" ) ); diff --git a/common/eda_item.cpp b/common/eda_item.cpp index 23392af1d2..40b8a04587 100644 --- a/common/eda_item.cpp +++ b/common/eda_item.cpp @@ -433,6 +433,7 @@ static struct EDA_ITEM_DESC .Map( PCB_DIM_RADIAL_T, _HKI( "Dimension" ) ) .Map( PCB_DIM_LEADER_T, _HKI( "Leader" ) ) .Map( PCB_TARGET_T, _HKI( "Target" ) ) + .Map( PCB_POINT_T, _HKI( "Point" ) ) .Map( PCB_ZONE_T, _HKI( "Zone" ) ) .Map( PCB_ITEM_LIST_T, _HKI( "ItemList" ) ) .Map( PCB_NETINFO_T, _HKI( "NetInfo" ) ) diff --git a/common/layer_id.cpp b/common/layer_id.cpp index e8bff96763..439a5547e3 100644 --- a/common/layer_id.cpp +++ b/common/layer_id.cpp @@ -142,6 +142,7 @@ wxString LayerName( int aLayer ) case LAYER_DRC_EXCLUSION: return _( "DRC exclusions" ); case LAYER_MARKER_SHADOWS: return _( "DRC marker shadows" ); case LAYER_ANCHOR: return _( "Anchors" ); + case LAYER_POINTS: return _( "Points" ); case LAYER_DRAWINGSHEET: return _( "Drawing sheet" ); case LAYER_PAGE_LIMITS: return _( "Page limits" ); case LAYER_CURSOR: return _( "Cursor" ); diff --git a/common/lset.cpp b/common/lset.cpp index f9108df9ea..f434f9baa9 100644 --- a/common/lset.cpp +++ b/common/lset.cpp @@ -806,7 +806,8 @@ GAL_SET GAL_SET::DefaultVisible() LAYER_FILLED_SHAPES, LAYER_LOCKED_ITEM_SHADOW, // LAYER_BOARD_OUTLINE_AREA, // currently hidden by default - LAYER_CONFLICTS_SHADOW + LAYER_CONFLICTS_SHADOW, + LAYER_POINTS }; static const GAL_SET saved( visible, arrayDim( visible ) ); diff --git a/common/pcb.keywords b/common/pcb.keywords index b9a9b6aa0e..f43de0ff54 100644 --- a/common/pcb.keywords +++ b/common/pcb.keywords @@ -280,6 +280,7 @@ pintype placed placement plus +point polygon portrait precision diff --git a/common/settings/builtin_color_themes.h b/common/settings/builtin_color_themes.h index 24d195c75f..8b6ca49660 100644 --- a/common/settings/builtin_color_themes.h +++ b/common/settings/builtin_color_themes.h @@ -175,6 +175,7 @@ static const std::map s_defaultTheme = { NETNAMES_LAYER_ID_START, CSS_COLOR( 255, 255, 255, 0.7 ) }, { LAYER_PAD_NETNAMES, CSS_COLOR( 255, 255, 255, 0.9 ) }, { LAYER_VIA_NETNAMES, CSS_COLOR( 50, 50, 50, 0.9 ) }, + { LAYER_POINTS, CSS_COLOR( 255, 38, 226, 1 ) }, { F_Cu, CSS_COLOR( 200, 52, 52, 1 ) }, { In1_Cu, CSS_COLOR( 127, 200, 127, 1 ) }, @@ -450,6 +451,7 @@ static const std::map s_classicTheme = { NETNAMES_LAYER_ID_START, CSS_COLOR( 255, 255, 255, 0.7 ) }, { LAYER_PAD_NETNAMES, CSS_COLOR( 255, 255, 255, 0.9 ) }, { LAYER_VIA_NETNAMES, CSS_COLOR( 50, 50, 50, 0.9 ) }, + { LAYER_POINTS, COLOR4D( BLUE ) }, { F_Cu, COLOR4D( RED ) }, { In1_Cu, COLOR4D( YELLOW ) }, diff --git a/common/settings/color_settings.cpp b/common/settings/color_settings.cpp index daa2359dab..c958084e95 100644 --- a/common/settings/color_settings.cpp +++ b/common/settings/color_settings.cpp @@ -142,6 +142,7 @@ COLOR_SETTINGS::COLOR_SETTINGS( const wxString& aFilename, bool aAbsolutePath ) CLR( "board.track_net_names", NETNAMES_LAYER_ID_START ); CLR( "board.pad_net_names", LAYER_PAD_NETNAMES ); CLR( "board.via_net_names", LAYER_VIA_NETNAMES ); + CLR( "board.points", LAYER_POINTS ); CLR( "board.copper.f", F_Cu ); CLR( "board.copper.in1", In1_Cu ); diff --git a/common/settings/layer_settings_utils.cpp b/common/settings/layer_settings_utils.cpp index 98460c00bb..2ac446d8c7 100644 --- a/common/settings/layer_settings_utils.cpp +++ b/common/settings/layer_settings_utils.cpp @@ -39,6 +39,7 @@ GAL_SET UserVisbilityLayers() LAYER_FP_REFERENCES, LAYER_FP_TEXT, LAYER_ANCHOR, + LAYER_POINTS, LAYER_RATSNEST, LAYER_DRC_WARNING, LAYER_DRC_ERROR, @@ -71,6 +72,7 @@ GAL_LAYER_ID RenderLayerFromVisibilityLayer( VISIBILITY_LAYER aLayer ) case VISIBILITY_LAYER::FOOTPRINT_REFERENCES: return LAYER_FP_REFERENCES; case VISIBILITY_LAYER::FOOTPRINT_TEXT: return LAYER_FP_TEXT; case VISIBILITY_LAYER::FOOTPRINT_ANCHORS: return LAYER_ANCHOR; + case VISIBILITY_LAYER::POINTS: return LAYER_POINTS; case VISIBILITY_LAYER::RATSNEST: return LAYER_RATSNEST; case VISIBILITY_LAYER::DRC_WARNINGS: return LAYER_DRC_WARNING; case VISIBILITY_LAYER::DRC_ERRORS: return LAYER_DRC_ERROR; @@ -102,6 +104,7 @@ std::optional VisibilityLayerFromRenderLayer( GAL_LAYER_ID aLa case LAYER_FP_REFERENCES: return VISIBILITY_LAYER::FOOTPRINT_REFERENCES; case LAYER_FP_TEXT: return VISIBILITY_LAYER::FOOTPRINT_TEXT; case LAYER_ANCHOR: return VISIBILITY_LAYER::FOOTPRINT_ANCHORS; + case LAYER_POINTS: return VISIBILITY_LAYER::POINTS; case LAYER_RATSNEST: return VISIBILITY_LAYER::RATSNEST; case LAYER_DRC_WARNING: return VISIBILITY_LAYER::DRC_WARNINGS; case LAYER_DRC_ERROR: return VISIBILITY_LAYER::DRC_ERRORS; diff --git a/common/view/view_group.cpp b/common/view/view_group.cpp index ba8c9fc12e..dc31f4b703 100644 --- a/common/view/view_group.cpp +++ b/common/view/view_group.cpp @@ -174,6 +174,10 @@ void VIEW_GROUP::ViewDraw( int aLayer, VIEW* aView ) const { draw = aView->IsLayerVisible( layer - LAYER_CLEARANCE_START ); } + else if( IsPointsLayer( layer ) ) + { + draw = aView->IsLayerVisible( layer - LAYER_POINT_START ); + } if( isSelection ) { diff --git a/demos/vme-wren/vme-wren.kicad_pro b/demos/vme-wren/vme-wren.kicad_pro index d65fc693da..1c35a9c064 100644 --- a/demos/vme-wren/vme-wren.kicad_pro +++ b/demos/vme-wren/vme-wren.kicad_pro @@ -108,6 +108,7 @@ "solder_mask_bridge": "warning", "starved_thermal": "warning", "text_height": "warning", + "text_on_edge_cuts": "error", "text_thickness": "warning", "through_hole_pad_without_hole": "ignore", "too_many_vias": "ignore", @@ -246,6 +247,15 @@ "viewports": [] }, "boards": [], + "component_class_settings": { + "assignments": [], + "meta": { + "version": 0 + }, + "sheet_component_classes": { + "enabled": false + } + }, "cvpcb": { "equivalence_files": [] }, diff --git a/include/bitmaps/bitmaps_list.h b/include/bitmaps/bitmaps_list.h index 1f96667b03..367ec1394e 100644 --- a/include/bitmaps/bitmaps_list.h +++ b/include/bitmaps/bitmaps_list.h @@ -69,6 +69,7 @@ enum class BITMAPS : unsigned int add_line_label, add_orthogonal_dimension, add_pcb_target, + add_point, add_power, add_radial_dimension, add_rectangle, diff --git a/include/core/typeinfo.h b/include/core/typeinfo.h index 84c5f67ade..48584ae20c 100644 --- a/include/core/typeinfo.h +++ b/include/core/typeinfo.h @@ -109,6 +109,7 @@ enum KICAD_T PCB_NETINFO_T, ///< class NETINFO_ITEM, a description of a net PCB_GROUP_T, ///< class PCB_GROUP, a set of BOARD_ITEMs PCB_BOARD_OUTLINE_T, ///< class PCB_BOARD_OUTLINE_T, a pcb board outline item + PCB_POINT_T, ///< class PCB_POINT, a 0-dimensional point // Be prudent with these types: // they should be used only to locate a specific field type among PCB_FIELD_Ts @@ -447,6 +448,7 @@ constexpr bool IsPcbnewType( const KICAD_T aType ) case PCB_DIM_RADIAL_T: case PCB_DIM_ORTHOGONAL_T: case PCB_TARGET_T: + case PCB_POINT_T: case PCB_ZONE_T: case PCB_ITEM_LIST_T: case PCB_NETINFO_T: diff --git a/include/layer_ids.h b/include/layer_ids.h index 2764a5c684..1e28b2b0aa 100644 --- a/include/layer_ids.h +++ b/include/layer_ids.h @@ -315,6 +315,10 @@ enum GAL_LAYER_ID: int LAYER_DRC_SHAPE2 = GAL_LAYER_ID_START + 43, ///< Custom shape for DRC marker. LAYER_BOARD_OUTLINE_AREA = GAL_LAYER_ID_START + 44, ///< PCB board outline + + /// PCB reference/manual snap points visibility + LAYER_POINTS = GAL_LAYER_ID_START + 45, + // Add layers below this point that do not have visibility controls, so don't need explicit // enum values @@ -344,6 +348,10 @@ enum GAL_LAYER_ID: int LAYER_BITMAP_START, LAYER_BITMAP_END = LAYER_BITMAP_START + PCB_LAYER_ID_COUNT, + /// Virtual layers for points per board layer. + LAYER_POINT_START, + LAYER_POINT_END = LAYER_POINT_START + PCB_LAYER_ID_COUNT, + // Layers for drawing on-canvas UI LAYER_UI_START, LAYER_UI_END = LAYER_UI_START + GAL_UI_LAYER_COUNT, @@ -360,6 +368,7 @@ enum GAL_LAYER_ID: int #define PAD_COPPER_LAYER_FOR( boardLayer ) ( LAYER_PAD_COPPER_START + boardLayer ) #define VIA_COPPER_LAYER_FOR( boardLayer ) ( LAYER_VIA_COPPER_START + boardLayer ) #define CLEARANCE_LAYER_FOR( boardLayer ) ( LAYER_CLEARANCE_START + boardLayer ) +#define POINT_LAYER_FOR( boardLayer ) ( LAYER_POINT_START + boardLayer ) constexpr int GAL_LAYER_ID_COUNT = GAL_LAYER_ID_END - GAL_LAYER_ID_START; @@ -883,6 +892,12 @@ inline bool IsClearanceLayer( int aLayer ) } +inline bool IsPointsLayer( int aLayer ) +{ + return aLayer >= LAYER_POINT_START && aLayer <= LAYER_POINT_END; +} + + inline bool IsDCodeLayer( int aLayer ) { return aLayer >= ( GERBVIEW_LAYER_ID_START + GERBER_DRAWLAYERS_COUNT ) diff --git a/include/settings/layer_settings_utils.h b/include/settings/layer_settings_utils.h index 758486445f..5995eb8eeb 100644 --- a/include/settings/layer_settings_utils.h +++ b/include/settings/layer_settings_utils.h @@ -43,6 +43,7 @@ enum class VISIBILITY_LAYER FOOTPRINT_REFERENCES, FOOTPRINT_TEXT, FOOTPRINT_ANCHORS, + POINTS, RATSNEST, DRC_WARNINGS, DRC_ERRORS, diff --git a/pcbnew/board.cpp b/pcbnew/board.cpp index b0e800d2e0..4b0228a0f7 100644 --- a/pcbnew/board.cpp +++ b/pcbnew/board.cpp @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -165,6 +166,7 @@ BOARD::~BOARD() m_tracks.clear(); m_drawings.clear(); m_groups.clear(); + m_points.clear(); // Generators not currently returned by GetItemSet for( PCB_GENERATOR* g : m_generators ) @@ -554,6 +556,12 @@ bool BOARD::ResolveTextVar( wxString* token, int aDepth ) const } +bool BOARD::IsEmpty() const +{ + return m_drawings.empty() && m_footprints.empty() && m_tracks.empty() && m_zones.empty() && m_points.empty(); +} + + VECTOR2I BOARD::GetPosition() const { return ZeroOffset; @@ -604,6 +612,9 @@ void BOARD::RunOnChildren( const std::function& aFunction, for( PCB_GROUP* group : m_groups ) aFunction( group ); + for( PCB_POINT* point : m_points ) + aFunction( point ); + for( FOOTPRINT* footprint : m_footprints ) { aFunction( footprint ); @@ -1262,6 +1273,11 @@ void BOARD::Add( BOARD_ITEM* aBoardItem, ADD_MODE aMode, bool aSkipConnectivity break; } + case PCB_POINT_T: + // These aren't graphics as they have no physical presence + m_points.push_back( static_cast( aBoardItem ) ); + break; + case PCB_TABLECELL_T: // Handled by parent table break; @@ -1348,6 +1364,10 @@ void BOARD::Remove( BOARD_ITEM* aBoardItem, REMOVE_MODE aRemoveMode ) std::erase( m_zones, aBoardItem ); break; + case PCB_POINT_T: + std::erase( m_points, aBoardItem ); + break; + case PCB_GENERATOR_T: std::erase( m_generators, aBoardItem ); break; @@ -1445,6 +1465,11 @@ void BOARD::RemoveAll( std::initializer_list aTypes ) m_groups.clear(); break; + case PCB_POINT_T: + std::copy( m_points.begin(), m_points.end(), std::back_inserter( removed ) ); + m_points.clear(); + break; + case PCB_ZONE_T: std::copy( m_zones.begin(), m_zones.end(), std::back_inserter( removed ) ); m_zones.clear(); @@ -1678,6 +1703,12 @@ BOARD_ITEM* BOARD::ResolveItem( const KIID& aID, bool aAllowNullptrReturn ) cons return marker; } + for( PCB_POINT* point : m_points ) + { + if( point->m_Uuid == aID ) + return point; + } + for( NETINFO_ITEM* netInfo : m_NetInfo ) { if( netInfo->m_Uuid == aID ) @@ -1729,6 +1760,9 @@ void BOARD::FillItemMap( std::map& aMap ) for( PCB_GROUP* group : m_groups ) aMap[ group->m_Uuid ] = group; + for( PCB_POINT* point : m_points ) + aMap[ point->m_Uuid ] = point; + for( PCB_GENERATOR* generator : m_generators ) aMap[ generator->m_Uuid ] = generator; } @@ -1908,6 +1942,11 @@ BOX2I BOARD::ComputeBoundingBox( bool aBoardEdgesOnly ) const if( ( aZone->GetLayerSet() & visible ).any() ) bbox.Merge( aZone->GetBoundingBox() ); } + + for( PCB_POINT* point : m_points ) + { + bbox.Merge( point->GetBoundingBox() ); + } } return bbox; @@ -2043,6 +2082,15 @@ INSPECT_RESULT BOARD::Visit( INSPECTOR inspector, void* testData, break; + case PCB_POINT_T: + for( PCB_POINT* point : m_points ) + { + if( point->Visit( inspector, testData, { scanType } ) == INSPECT_RESULT::QUIT ) + return INSPECT_RESULT::QUIT; + } + + break; + case PCB_ZONE_T: if( !footprintsScanned ) { @@ -3121,6 +3169,7 @@ const BOARD_ITEM_SET BOARD::GetItemSet() std::copy( m_drawings.begin(), m_drawings.end(), std::inserter( items, items.end() ) ); std::copy( m_markers.begin(), m_markers.end(), std::inserter( items, items.end() ) ); std::copy( m_groups.begin(), m_groups.end(), std::inserter( items, items.end() ) ); + std::copy( m_points.begin(), m_points.end(), std::inserter( items, items.end() ) ); return items; } @@ -3239,4 +3288,3 @@ int BOARD::GetPadWithCastellatedAttrCount() return count; } - diff --git a/pcbnew/board.h b/pcbnew/board.h index a43cf6aec3..c76c40e8c2 100644 --- a/pcbnew/board.h +++ b/pcbnew/board.h @@ -369,6 +369,8 @@ public: const MARKERS& Markers() const { return m_markers; } + const PCB_POINTS& Points() const { return m_points; } + // SWIG requires non-const accessors for some reason to make the custom iterators in board.i // work. It would be good to remove this if we can figure out how to fix that. #ifdef SWIG @@ -414,10 +416,7 @@ public: void SetPosition( const VECTOR2I& aPos ) override; const VECTOR2I GetFocusPosition() const override { return GetBoundingBox().GetCenter(); } - bool IsEmpty() const - { - return m_drawings.empty() && m_footprints.empty() && m_tracks.empty() && m_zones.empty(); - } + bool IsEmpty() const; void Move( const VECTOR2I& aMoveVector ) override; @@ -1423,6 +1422,7 @@ private: ZONES m_zones; GENERATORS m_generators; PCB_BOARD_OUTLINE* m_boardOutline; + PCB_POINTS m_points; // Cache for fast access to items in the containers above by KIID, including children std::unordered_map m_itemByIdCache; diff --git a/pcbnew/board_commit.cpp b/pcbnew/board_commit.cpp index 73eacfac17..23508d41d8 100644 --- a/pcbnew/board_commit.cpp +++ b/pcbnew/board_commit.cpp @@ -386,6 +386,7 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags ) case PCB_DIM_LEADER_T: case PCB_TARGET_T: case PCB_MARKER_T: + case PCB_POINT_T: case PCB_ZONE_T: case PCB_FOOTPRINT_T: case PCB_GROUP_T: diff --git a/pcbnew/collectors.cpp b/pcbnew/collectors.cpp index c0951090e3..0dc4e965b5 100644 --- a/pcbnew/collectors.cpp +++ b/pcbnew/collectors.cpp @@ -60,6 +60,7 @@ const std::vector GENERAL_COLLECTOR::AllBoardItems = { PCB_FOOTPRINT_T, // in m_footprints PCB_GROUP_T, // in m_groups PCB_ZONE_T, // in m_zones + PCB_POINT_T, // in m_points PCB_GENERATOR_T // in m_generators }; @@ -77,6 +78,7 @@ const std::vector GENERAL_COLLECTOR::BoardLevelItems = { PCB_DIM_RADIAL_T, PCB_DIM_LEADER_T, PCB_TARGET_T, + PCB_POINT_T, PCB_VIA_T, PCB_ARC_T, PCB_TRACE_T, @@ -116,6 +118,7 @@ const std::vector GENERAL_COLLECTOR::FootprintItems = { PCB_PAD_T, PCB_ZONE_T, PCB_GROUP_T, + PCB_POINT_T, PCB_REFERENCE_IMAGE_T }; @@ -240,6 +243,10 @@ INSPECT_RESULT GENERAL_COLLECTOR::Inspect( EDA_ITEM* aTestItem, void* aTestData boardItem = static_cast( aTestItem ); break; + case PCB_POINT_T: + boardItem = static_cast( aTestItem ); + break; + case PCB_FIELD_T: if( m_Guide->IgnoreNoNets() ) return INSPECT_RESULT::CONTINUE; diff --git a/pcbnew/edit.cpp b/pcbnew/edit.cpp new file mode 100644 index 0000000000..3ebe7be87b --- /dev/null +++ b/pcbnew/edit.cpp @@ -0,0 +1,177 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr + * Copyright (C) 2015 SoftPLC Corporation, Dick Hollenbeck + * Copyright (C) 2015 Wayne Stambaugh + * Copyright The KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Handles the selection of command events. +void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) +{ + switch( event.GetId() ) // Execute command + { + case ID_MENU_EXPORT_FOOTPRINTS_TO_LIBRARY: + ExportFootprintsToLibrary( false ); + break; + + case ID_MENU_EXPORT_FOOTPRINTS_TO_NEW_LIBRARY: + ExportFootprintsToLibrary( true ); + break; + + default: + break; + } +} + + +void PCB_EDIT_FRAME::SwitchLayer( PCB_LAYER_ID layer ) +{ + PCB_LAYER_ID curLayer = GetActiveLayer(); + const PCB_DISPLAY_OPTIONS& displ_opts = GetDisplayOptions(); + + // Check if the specified layer matches the present layer + if( layer == curLayer ) + return; + + // Copper layers cannot be selected unconditionally; how many of those layers are currently + // enabled needs to be checked. + if( IsCopperLayer( layer ) ) + { + if( layer > GetBoard()->GetCopperLayerStackMaxId() ) + return; + } + + // Is yet more checking required? E.g. when the layer to be selected is a non-copper layer, + // or when switching between a copper layer and a non-copper layer, or vice-versa? + + SetActiveLayer( layer ); + + if( displ_opts.m_ContrastModeDisplay != HIGH_CONTRAST_MODE::NORMAL ) + GetCanvas()->Refresh(); +} + + +void PCB_EDIT_FRAME::OnEditItemRequest( BOARD_ITEM* aItem ) +{ + switch( aItem->Type() ) + { + case PCB_REFERENCE_IMAGE_T: + ShowReferenceImagePropertiesDialog( aItem ); + break; + + case PCB_FIELD_T: + case PCB_TEXT_T: + ShowTextPropertiesDialog( static_cast( aItem ) ); + break; + + case PCB_TEXTBOX_T: + ShowTextBoxPropertiesDialog( static_cast( aItem ) ); + break; + + case PCB_TABLE_T: + { + DIALOG_TABLE_PROPERTIES dlg( this, static_cast( aItem ) ); + + //QuasiModal required for Scintilla auto-complete + dlg.ShowQuasiModal(); + break; + } + + case PCB_PAD_T: + ShowPadPropertiesDialog( static_cast( aItem ) ); + break; + + case PCB_FOOTPRINT_T: + ShowFootprintPropertiesDialog( static_cast( aItem ) ); + break; + + case PCB_TARGET_T: + ShowTargetOptionsDialog( static_cast( aItem ) ); + break; + + case PCB_DIM_ALIGNED_T: + case PCB_DIM_CENTER_T: + case PCB_DIM_RADIAL_T: + case PCB_DIM_ORTHOGONAL_T: + case PCB_DIM_LEADER_T: + { + DIALOG_DIMENSION_PROPERTIES dlg( this, static_cast( aItem ) ); + + // TODO: why is this QuasiModal? + dlg.ShowQuasiModal(); + break; + } + + case PCB_SHAPE_T: + ShowGraphicItemPropertiesDialog( static_cast( aItem ) ); + break; + + case PCB_ZONE_T: + Edit_Zone_Params( static_cast( aItem ) ); + break; + + case PCB_GROUP_T: + m_toolManager->RunAction( ACTIONS::groupProperties, + static_cast( static_cast( aItem ) ) ); + break; + + case PCB_GENERATOR_T: + static_cast( aItem )->ShowPropertiesDialog( this ); + break; + + case PCB_MARKER_T: + m_toolManager->GetTool()->CrossProbe( static_cast( aItem ) ); + break; + + case PCB_POINT_T: + break; + + default: + break; + } +} + diff --git a/pcbnew/footprint.cpp b/pcbnew/footprint.cpp index b1bbf18e05..c7d3c29b50 100644 --- a/pcbnew/footprint.cpp +++ b/pcbnew/footprint.cpp @@ -56,6 +56,7 @@ #include #include #include +#include #include #include #include @@ -225,6 +226,13 @@ FOOTPRINT::FOOTPRINT( const FOOTPRINT& aFootprint ) : Add( newGroup, ADD_MODE::APPEND ); // Append to ensure indexes are identical } + for( PCB_POINT* point : aFootprint.Points() ) + { + PCB_POINT* newPoint = static_cast( point->Clone() ); + ptrMap[ point ] = newPoint; + Add( newPoint, ADD_MODE::APPEND ); // Append to ensure indexes are identical + } + // Rebuild groups for( PCB_GROUP* group : aFootprint.Groups() ) { @@ -276,6 +284,11 @@ FOOTPRINT::~FOOTPRINT() m_groups.clear(); + for( PCB_POINT* point : m_points ) + delete point; + + m_points.clear(); + for( BOARD_ITEM* d : m_drawings ) delete d; @@ -550,6 +563,7 @@ bool FOOTPRINT::Deserialize( const google::protobuf::Any &aContainer ) Zones().clear(); Groups().clear(); Models().clear(); + Points().clear(); for( const google::protobuf::Any& itemMsg : footprint.definition().items() ) { @@ -728,10 +742,14 @@ bool FOOTPRINT::FixUuids() for( PCB_GROUP* group : m_groups ) item_list.push_back( group ); - // Probably notneeded, because old fp do not have zones. But just in case. + // Probably not needed, because old fp do not have zones. But just in case. for( ZONE* zone : m_zones ) item_list.push_back( zone ); + // Ditto + for( PCB_POINT* point : m_points ) + item_list.push_back( point ); + bool changed = false; for( BOARD_ITEM* item : item_list ) @@ -841,6 +859,17 @@ FOOTPRINT& FOOTPRINT::operator=( FOOTPRINT&& aOther ) aOther.Groups().clear(); + // Move the points + for( PCB_POINT* point : m_points ) + delete point; + + m_groups.clear(); + + for( PCB_POINT* point : aOther.Points() ) + Add( point ); + + aOther.Points().clear(); + EMBEDDED_FILES::operator=( std::move( aOther ) ); // Copy auxiliary data @@ -951,6 +980,16 @@ FOOTPRINT& FOOTPRINT::operator=( const FOOTPRINT& aOther ) Add( newGroup ); } + // Copy drawings + m_points.clear(); + + for( PCB_POINT* point : aOther.Points() ) + { + BOARD_ITEM* newItem = static_cast( point->Clone() ); + ptrMap[ point ] = newItem; + Add( newItem ); + } + // Copy auxiliary data m_3D_Drawings = aOther.m_3D_Drawings; m_libDescription = aOther.m_libDescription; @@ -1141,6 +1180,14 @@ void FOOTPRINT::Add( BOARD_ITEM* aBoardItem, ADD_MODE aMode, bool aSkipConnectiv wxFAIL_MSG( wxT( "FOOTPRINT::Add(): Nested footprints not supported" ) ); return; + case PCB_POINT_T: + if( aMode == ADD_MODE::APPEND ) + m_points.push_back( static_cast( aBoardItem ) ); + else + m_points.insert( m_points.begin(), static_cast( aBoardItem ) ); + + break; + default: wxFAIL_MSG( wxString::Format( wxT( "FOOTPRINT::Add(): BOARD_ITEM type (%d) not handled" ), aBoardItem->Type() ) ); @@ -1226,6 +1273,18 @@ void FOOTPRINT::Remove( BOARD_ITEM* aBoardItem, REMOVE_MODE aMode ) break; + case PCB_POINT_T: + for( auto it = m_points.begin(); it != m_points.end(); ++it ) + { + if( *it == static_cast( aBoardItem ) ) + { + m_points.erase( it ); + break; + } + } + + break; + default: { wxString msg; @@ -1433,6 +1492,9 @@ const BOX2I FOOTPRINT::GetBoundingBox( bool aIncludeText ) const for( ZONE* zone : m_zones ) bbox.Merge( zone->GetBoundingBox() ); + for( PCB_POINT* point : m_points ) + bbox.Merge( point->GetBoundingBox() ); + bool noDrawItems = ( m_drawings.empty() && m_pads.empty() && m_zones.empty() ); // Groups do not contribute to the rect, only their members @@ -1542,6 +1604,17 @@ const BOX2I FOOTPRINT::GetLayerBoundingBox( const LSET& aLayers ) const bbox.Merge( zone->GetBoundingBox() ); } + for( PCB_POINT* point : m_points ) + { + if( m_privateLayers.test( point->GetLayer() ) && !isFPEdit ) + continue; + + if( ( aLayers & point->GetLayerSet() ).none() ) + continue; + + bbox.Merge( point->GetBoundingBox() ); + } + return bbox; } @@ -1951,6 +2024,12 @@ bool FOOTPRINT::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) co return true; } + for( PCB_POINT* point : m_points ) + { + if( point->HitTest( arect, false, 0 ) ) + return true; + } + // PCB fields are selectable on their own, so they don't get tested for( BOARD_ITEM* item : m_drawings ) @@ -2228,6 +2307,15 @@ INSPECT_RESULT FOOTPRINT::Visit( INSPECTOR inspector, void* testData, break; + case PCB_POINT_T: + if( IterateForward( m_points, inspector, testData, { scanType } ) + == INSPECT_RESULT::QUIT ) + { + return INSPECT_RESULT::QUIT; + } + + break; + default: break; } @@ -2276,6 +2364,9 @@ void FOOTPRINT::RunOnChildren( const std::function& aFuncti for( PCB_GROUP* group : m_groups ) aFunction( group ); + for( PCB_POINT* point : m_points ) + aFunction( point ); + for( BOARD_ITEM* drawing : m_drawings ) { aFunction( drawing ); @@ -2503,6 +2594,10 @@ void FOOTPRINT::Flip( const VECTOR2I& aCentre, FLIP_DIRECTION aFlipDirection ) for( BOARD_ITEM* item : m_drawings ) item->Flip( m_pos, FLIP_DIRECTION::TOP_BOTTOM ); + // Points move but don't flip layer + for( PCB_POINT* point : m_points ) + point->Flip( m_pos, FLIP_DIRECTION::TOP_BOTTOM ); + // Now rotate 180 deg if required if( aFlipDirection == FLIP_DIRECTION::LEFT_RIGHT ) Rotate( aCentre, ANGLE_180 ); @@ -2535,6 +2630,9 @@ void FOOTPRINT::SetPosition( const VECTOR2I& aPos ) for( BOARD_ITEM* item : m_drawings ) item->Move( delta ); + for( PCB_POINT* point : m_points ) + point->Move( delta ); + m_cachedBoundingBox.Move( delta ); m_cachedTextExcludedBBox.Move( delta ); m_cachedHull.Move( delta ); @@ -2618,6 +2716,9 @@ void FOOTPRINT::SetOrientation( const EDA_ANGLE& aNewAngle ) for( BOARD_ITEM* item : m_drawings ) item->Rotate( GetPosition(), angleChange ); + for( PCB_POINT* point : m_points ) + point->Rotate( GetPosition(), angleChange ); + m_boundingBoxCacheTimeStamp = 0; m_textExcludedBBoxCacheTimeStamp = 0; m_hullCacheTimeStamp = 0; @@ -2672,6 +2773,18 @@ BOARD_ITEM* FOOTPRINT::DuplicateItem( bool addToParentGroup, BOARD_COMMIT* aComm break; } + case PCB_POINT_T: + { + PCB_POINT* new_point = new PCB_POINT( *static_cast( aItem ) ); + const_cast( new_point->m_Uuid ) = KIID(); + + if( addToFootprint ) + m_points.push_back( new_point ); + + new_item = new_point; + break; + } + case PCB_FIELD_T: case PCB_TEXT_T: { @@ -3696,6 +3809,9 @@ bool FOOTPRINT::operator==( const FOOTPRINT& aOther ) const return false; } + if( m_points.size() != aOther.m_points.size() ) + return false; + // Compare fields in ordinally-sorted order std::vector fields, otherFields; diff --git a/pcbnew/footprint.h b/pcbnew/footprint.h index 833d4be79c..0ea9a92a3e 100644 --- a/pcbnew/footprint.h +++ b/pcbnew/footprint.h @@ -55,6 +55,7 @@ class MSG_PANEL_ITEM; class SHAPE; class REPORTER; class COMPONENT_CLASS_CACHE_PROXY; +class PCB_POINT; namespace KIGFX { class VIEW; @@ -232,6 +233,9 @@ public: GROUPS& Groups() { return m_groups; } const GROUPS& Groups() const { return m_groups; } + PCB_POINTS& Points() { return m_points; } + const PCB_POINTS& Points() const { return m_points; } + bool HasThroughHolePads() const; std::vector& Models() { return m_3D_Drawings; } @@ -1098,6 +1102,7 @@ private: std::deque m_pads; // Pads, owned by pointer std::vector m_zones; // Rule area zones, owned by pointer std::deque m_groups; // Groups, owned by pointer + std::deque m_points; // Points, owned by pointer EDA_ANGLE m_orient; // Orientation VECTOR2I m_pos; // Position of footprint on the board in internal units. diff --git a/pcbnew/footprint_edit_frame.cpp b/pcbnew/footprint_edit_frame.cpp index d29ec83c39..e8631e7638 100644 --- a/pcbnew/footprint_edit_frame.cpp +++ b/pcbnew/footprint_edit_frame.cpp @@ -1467,6 +1467,7 @@ void FOOTPRINT_EDIT_FRAME::setupUIConditions() CURRENT_EDIT_TOOL( PCB_ACTIONS::drawPolygon ); CURRENT_EDIT_TOOL( PCB_ACTIONS::drawBezier ); CURRENT_EDIT_TOOL( PCB_ACTIONS::drawRuleArea ); + CURRENT_EDIT_TOOL( PCB_ACTIONS::placePoint ); CURRENT_EDIT_TOOL( PCB_ACTIONS::placeReferenceImage ); CURRENT_EDIT_TOOL( PCB_ACTIONS::placeText ); CURRENT_EDIT_TOOL( PCB_ACTIONS::drawTextBox ); diff --git a/pcbnew/footprint_editor_utils.cpp b/pcbnew/footprint_editor_utils.cpp index 1bb918e9c2..0c61af1bc7 100644 --- a/pcbnew/footprint_editor_utils.cpp +++ b/pcbnew/footprint_editor_utils.cpp @@ -256,6 +256,9 @@ void FOOTPRINT_EDIT_FRAME::OnEditItemRequest( BOARD_ITEM* aItem ) m_toolManager->GetTool()->CrossProbe( static_cast( aItem ) ); break; + case PCB_POINT_T: + break; + default: wxFAIL_MSG( wxT( "FOOTPRINT_EDIT_FRAME::OnEditItemRequest: unsupported item type " ) + aItem->GetClass() ); diff --git a/pcbnew/menubar_footprint_editor.cpp b/pcbnew/menubar_footprint_editor.cpp index 3baa4175e8..02ba8c1714 100644 --- a/pcbnew/menubar_footprint_editor.cpp +++ b/pcbnew/menubar_footprint_editor.cpp @@ -188,6 +188,7 @@ void FOOTPRINT_EDIT_FRAME::doReCreateMenuBar() placeMenu->Add( PCB_ACTIONS::placeText ); placeMenu->Add( PCB_ACTIONS::drawTextBox ); placeMenu->Add( PCB_ACTIONS::drawTable ); + placeMenu->Add( PCB_ACTIONS::placePoint ); placeMenu->AppendSeparator(); placeMenu->Add( PCB_ACTIONS::drawOrthogonalDimension ); diff --git a/pcbnew/menubar_pcb_editor.cpp b/pcbnew/menubar_pcb_editor.cpp index 3f22c8c6de..a23cab84e2 100644 --- a/pcbnew/menubar_pcb_editor.cpp +++ b/pcbnew/menubar_pcb_editor.cpp @@ -311,6 +311,7 @@ void PCB_EDIT_FRAME::doReCreateMenuBar() placeMenu->Add( PCB_ACTIONS::placeText ); placeMenu->Add( PCB_ACTIONS::drawTextBox ); placeMenu->Add( PCB_ACTIONS::drawTable ); + placeMenu->Add( PCB_ACTIONS::placePoint ); placeMenu->AppendSeparator(); ACTION_MENU* dimensionSubmenu = new ACTION_MENU( false, selTool ); diff --git a/pcbnew/pcb_draw_panel_gal.cpp b/pcbnew/pcb_draw_panel_gal.cpp index 90cff1822c..58e8edfc04 100644 --- a/pcbnew/pcb_draw_panel_gal.cpp +++ b/pcbnew/pcb_draw_panel_gal.cpp @@ -24,6 +24,7 @@ */ #include "pcb_draw_panel_gal.h" + #include #include #include @@ -34,8 +35,9 @@ #include #include #include -#include #include +#include +#include #include #include #include @@ -79,64 +81,66 @@ const int GAL_LAYER_ORDER[] = LAYER_DRC_ERROR, LAYER_DRC_WARNING, LAYER_DRC_EXCLUSION, LAYER_MARKER_SHADOWS, LAYER_DRC_SHAPE1, LAYER_DRC_SHAPE2, LAYER_PAD_NETNAMES, LAYER_VIA_NETNAMES, - Dwgs_User, ZONE_LAYER_FOR( Dwgs_User ), - Cmts_User, ZONE_LAYER_FOR( Cmts_User ), - Eco1_User, ZONE_LAYER_FOR( Eco1_User ), - Eco2_User, ZONE_LAYER_FOR( Eco2_User ), - Edge_Cuts, ZONE_LAYER_FOR( Edge_Cuts ), - Margin, ZONE_LAYER_FOR( Margin ), + Dwgs_User, ZONE_LAYER_FOR( Dwgs_User ), POINT_LAYER_FOR( Dwgs_User ), + Cmts_User, ZONE_LAYER_FOR( Cmts_User ), POINT_LAYER_FOR( Cmts_User ), + Eco1_User, ZONE_LAYER_FOR( Eco1_User ), POINT_LAYER_FOR( Eco1_User ), + Eco2_User, ZONE_LAYER_FOR( Eco2_User ), POINT_LAYER_FOR( Eco2_User ), + Edge_Cuts, ZONE_LAYER_FOR( Edge_Cuts ), POINT_LAYER_FOR( Edge_Cuts ), + Margin, ZONE_LAYER_FOR( Margin ), POINT_LAYER_FOR( Margin ), - User_1, ZONE_LAYER_FOR( User_1 ), - User_2, ZONE_LAYER_FOR( User_2 ), - User_3, ZONE_LAYER_FOR( User_3 ), - User_4, ZONE_LAYER_FOR( User_4 ), - User_5, ZONE_LAYER_FOR( User_5 ), - User_6, ZONE_LAYER_FOR( User_6 ), - User_7, ZONE_LAYER_FOR( User_7 ), - User_8, ZONE_LAYER_FOR( User_8 ), - User_9, ZONE_LAYER_FOR( User_9 ), - User_10, ZONE_LAYER_FOR( User_10 ), - User_11, ZONE_LAYER_FOR( User_11 ), - User_12, ZONE_LAYER_FOR( User_12 ), - User_13, ZONE_LAYER_FOR( User_13 ), - User_14, ZONE_LAYER_FOR( User_14 ), - User_15, ZONE_LAYER_FOR( User_15 ), - User_16, ZONE_LAYER_FOR( User_16 ), - User_17, ZONE_LAYER_FOR( User_17 ), - User_18, ZONE_LAYER_FOR( User_18 ), - User_19, ZONE_LAYER_FOR( User_19 ), - User_20, ZONE_LAYER_FOR( User_20 ), - User_21, ZONE_LAYER_FOR( User_21 ), - User_22, ZONE_LAYER_FOR( User_22 ), - User_23, ZONE_LAYER_FOR( User_23 ), - User_24, ZONE_LAYER_FOR( User_24 ), - User_25, ZONE_LAYER_FOR( User_25 ), - User_26, ZONE_LAYER_FOR( User_26 ), - User_27, ZONE_LAYER_FOR( User_27 ), - User_28, ZONE_LAYER_FOR( User_28 ), - User_29, ZONE_LAYER_FOR( User_29 ), - User_30, ZONE_LAYER_FOR( User_30 ), - User_31, ZONE_LAYER_FOR( User_31 ), - User_32, ZONE_LAYER_FOR( User_32 ), - User_33, ZONE_LAYER_FOR( User_33 ), - User_34, ZONE_LAYER_FOR( User_34 ), - User_35, ZONE_LAYER_FOR( User_35 ), - User_36, ZONE_LAYER_FOR( User_36 ), - User_37, ZONE_LAYER_FOR( User_37 ), - User_38, ZONE_LAYER_FOR( User_38 ), - User_39, ZONE_LAYER_FOR( User_39 ), - User_40, ZONE_LAYER_FOR( User_40 ), - User_41, ZONE_LAYER_FOR( User_41 ), - User_42, ZONE_LAYER_FOR( User_42 ), - User_43, ZONE_LAYER_FOR( User_43 ), - User_44, ZONE_LAYER_FOR( User_44 ), - User_45, ZONE_LAYER_FOR( User_45 ), + User_1, ZONE_LAYER_FOR( User_1 ), POINT_LAYER_FOR( User_1 ), + User_2, ZONE_LAYER_FOR( User_2 ), POINT_LAYER_FOR( User_2 ), + User_3, ZONE_LAYER_FOR( User_3 ), POINT_LAYER_FOR( User_3 ), + User_4, ZONE_LAYER_FOR( User_4 ), POINT_LAYER_FOR( User_4 ), + User_5, ZONE_LAYER_FOR( User_5 ), POINT_LAYER_FOR( User_5 ), + User_6, ZONE_LAYER_FOR( User_6 ), POINT_LAYER_FOR( User_6 ), + User_7, ZONE_LAYER_FOR( User_7 ), POINT_LAYER_FOR( User_7 ), + User_8, ZONE_LAYER_FOR( User_8 ), POINT_LAYER_FOR( User_8 ), + User_9, ZONE_LAYER_FOR( User_9 ), POINT_LAYER_FOR( User_9 ), + User_10, ZONE_LAYER_FOR( User_10 ), POINT_LAYER_FOR( User_10 ), + User_11, ZONE_LAYER_FOR( User_11 ), POINT_LAYER_FOR( User_11 ), + User_12, ZONE_LAYER_FOR( User_12 ), POINT_LAYER_FOR( User_12 ), + User_13, ZONE_LAYER_FOR( User_13 ), POINT_LAYER_FOR( User_13 ), + User_14, ZONE_LAYER_FOR( User_14 ), POINT_LAYER_FOR( User_14 ), + User_15, ZONE_LAYER_FOR( User_15 ), POINT_LAYER_FOR( User_15 ), + User_16, ZONE_LAYER_FOR( User_16 ), POINT_LAYER_FOR( User_16 ), + User_17, ZONE_LAYER_FOR( User_17 ), POINT_LAYER_FOR( User_17 ), + User_18, ZONE_LAYER_FOR( User_18 ), POINT_LAYER_FOR( User_18 ), + User_19, ZONE_LAYER_FOR( User_19 ), POINT_LAYER_FOR( User_19 ), + User_20, ZONE_LAYER_FOR( User_20 ), POINT_LAYER_FOR( User_20 ), + User_21, ZONE_LAYER_FOR( User_21 ), POINT_LAYER_FOR( User_21 ), + User_22, ZONE_LAYER_FOR( User_22 ), POINT_LAYER_FOR( User_22 ), + User_23, ZONE_LAYER_FOR( User_23 ), POINT_LAYER_FOR( User_23 ), + User_24, ZONE_LAYER_FOR( User_24 ), POINT_LAYER_FOR( User_24 ), + User_25, ZONE_LAYER_FOR( User_25 ), POINT_LAYER_FOR( User_25 ), + User_26, ZONE_LAYER_FOR( User_26 ), POINT_LAYER_FOR( User_26 ), + User_27, ZONE_LAYER_FOR( User_27 ), POINT_LAYER_FOR( User_27 ), + User_28, ZONE_LAYER_FOR( User_28 ), POINT_LAYER_FOR( User_28 ), + User_29, ZONE_LAYER_FOR( User_29 ), POINT_LAYER_FOR( User_29 ), + User_30, ZONE_LAYER_FOR( User_30 ), POINT_LAYER_FOR( User_30 ), + User_31, ZONE_LAYER_FOR( User_31 ), POINT_LAYER_FOR( User_31 ), + User_32, ZONE_LAYER_FOR( User_32 ), POINT_LAYER_FOR( User_32 ), + User_33, ZONE_LAYER_FOR( User_33 ), POINT_LAYER_FOR( User_33 ), + User_34, ZONE_LAYER_FOR( User_34 ), POINT_LAYER_FOR( User_34 ), + User_35, ZONE_LAYER_FOR( User_35 ), POINT_LAYER_FOR( User_35 ), + User_36, ZONE_LAYER_FOR( User_36 ), POINT_LAYER_FOR( User_36 ), + User_37, ZONE_LAYER_FOR( User_37 ), POINT_LAYER_FOR( User_37 ), + User_38, ZONE_LAYER_FOR( User_38 ), POINT_LAYER_FOR( User_38 ), + User_39, ZONE_LAYER_FOR( User_39 ), POINT_LAYER_FOR( User_39 ), + User_40, ZONE_LAYER_FOR( User_40 ), POINT_LAYER_FOR( User_40 ), + User_41, ZONE_LAYER_FOR( User_41 ), POINT_LAYER_FOR( User_41 ), + User_42, ZONE_LAYER_FOR( User_42 ), POINT_LAYER_FOR( User_42 ), + User_43, ZONE_LAYER_FOR( User_43 ), POINT_LAYER_FOR( User_43 ), + User_44, ZONE_LAYER_FOR( User_44 ), POINT_LAYER_FOR( User_44 ), + User_45, ZONE_LAYER_FOR( User_45 ), POINT_LAYER_FOR( User_45 ), + POINT_LAYER_FOR( F_Cu ), LAYER_FP_TEXT, LAYER_FP_REFERENCES, LAYER_FP_VALUES, LAYER_RATSNEST, LAYER_ANCHOR, + LAYER_POINTS, LAYER_LOCKED_ITEM_SHADOW, LAYER_VIA_HOLES, LAYER_VIA_HOLEWALLS, LAYER_PAD_PLATEDHOLES, LAYER_PAD_HOLEWALLS, LAYER_NON_PLATEDHOLES, @@ -147,6 +151,7 @@ const int GAL_LAYER_ORDER[] = PAD_COPPER_LAYER_FOR( F_Cu ), VIA_COPPER_LAYER_FOR( F_Cu ), CLEARANCE_LAYER_FOR( F_Cu ), + // POINT_LAYER_FOR( F_Cu ), F_Cu, ZONE_LAYER_FOR( F_Cu ), F_Mask, ZONE_LAYER_FOR( F_Mask ), F_SilkS, ZONE_LAYER_FOR( F_SilkS ), @@ -157,93 +162,123 @@ const int GAL_LAYER_ORDER[] = NETNAMES_LAYER_INDEX( In1_Cu ), PAD_COPPER_LAYER_FOR( In1_Cu ), VIA_COPPER_LAYER_FOR( In1_Cu ), CLEARANCE_LAYER_FOR( In1_Cu ), + POINT_LAYER_FOR( In1_Cu ), In1_Cu, ZONE_LAYER_FOR( In1_Cu ), NETNAMES_LAYER_INDEX( In2_Cu ), PAD_COPPER_LAYER_FOR( In2_Cu ), VIA_COPPER_LAYER_FOR( In2_Cu ), CLEARANCE_LAYER_FOR( In2_Cu ), + POINT_LAYER_FOR( In2_Cu ), In2_Cu, ZONE_LAYER_FOR( In2_Cu ), NETNAMES_LAYER_INDEX( In3_Cu ), PAD_COPPER_LAYER_FOR( In3_Cu ), VIA_COPPER_LAYER_FOR( In3_Cu ), CLEARANCE_LAYER_FOR( In3_Cu ), + POINT_LAYER_FOR( In3_Cu ), In3_Cu, ZONE_LAYER_FOR( In3_Cu ), NETNAMES_LAYER_INDEX( In4_Cu ), PAD_COPPER_LAYER_FOR( In4_Cu ), VIA_COPPER_LAYER_FOR( In4_Cu ), CLEARANCE_LAYER_FOR( In4_Cu ), + POINT_LAYER_FOR( In4_Cu ), In4_Cu, ZONE_LAYER_FOR( In4_Cu ), NETNAMES_LAYER_INDEX( In5_Cu ), PAD_COPPER_LAYER_FOR( In5_Cu ), VIA_COPPER_LAYER_FOR( In5_Cu ), CLEARANCE_LAYER_FOR( In5_Cu ), + POINT_LAYER_FOR( In5_Cu ), In5_Cu, ZONE_LAYER_FOR( In5_Cu ), NETNAMES_LAYER_INDEX( In6_Cu ), PAD_COPPER_LAYER_FOR( In6_Cu ), VIA_COPPER_LAYER_FOR( In6_Cu ), CLEARANCE_LAYER_FOR( In6_Cu ), + POINT_LAYER_FOR( In6_Cu ), In6_Cu, ZONE_LAYER_FOR( In6_Cu ), NETNAMES_LAYER_INDEX( In7_Cu ), PAD_COPPER_LAYER_FOR( In7_Cu ), VIA_COPPER_LAYER_FOR( In7_Cu ), CLEARANCE_LAYER_FOR( In7_Cu ), + POINT_LAYER_FOR( In7_Cu ), In7_Cu, ZONE_LAYER_FOR( In7_Cu ), NETNAMES_LAYER_INDEX( In8_Cu ), PAD_COPPER_LAYER_FOR( In8_Cu ), VIA_COPPER_LAYER_FOR( In8_Cu ), CLEARANCE_LAYER_FOR( In8_Cu ), + POINT_LAYER_FOR( In8_Cu ), In8_Cu, ZONE_LAYER_FOR( In8_Cu ), NETNAMES_LAYER_INDEX( In9_Cu ), PAD_COPPER_LAYER_FOR( In9_Cu ), VIA_COPPER_LAYER_FOR( In9_Cu ), CLEARANCE_LAYER_FOR( In9_Cu ), + POINT_LAYER_FOR( In9_Cu ), In9_Cu, ZONE_LAYER_FOR( In9_Cu ), NETNAMES_LAYER_INDEX( In10_Cu ), PAD_COPPER_LAYER_FOR( In10_Cu ), VIA_COPPER_LAYER_FOR( In10_Cu ), CLEARANCE_LAYER_FOR( In10_Cu ), + POINT_LAYER_FOR( In10_Cu ), In10_Cu, ZONE_LAYER_FOR( In10_Cu ), NETNAMES_LAYER_INDEX( In11_Cu ), PAD_COPPER_LAYER_FOR( In11_Cu ), VIA_COPPER_LAYER_FOR( In11_Cu ), CLEARANCE_LAYER_FOR( In11_Cu ), + POINT_LAYER_FOR( In11_Cu ), In11_Cu, ZONE_LAYER_FOR( In11_Cu ), NETNAMES_LAYER_INDEX( In12_Cu ), PAD_COPPER_LAYER_FOR( In12_Cu ), VIA_COPPER_LAYER_FOR( In12_Cu ), CLEARANCE_LAYER_FOR( In12_Cu ), + POINT_LAYER_FOR( In12_Cu ), In12_Cu, ZONE_LAYER_FOR( In12_Cu ), NETNAMES_LAYER_INDEX( In13_Cu ), PAD_COPPER_LAYER_FOR( In13_Cu ), VIA_COPPER_LAYER_FOR( In13_Cu ), CLEARANCE_LAYER_FOR( In13_Cu ), + POINT_LAYER_FOR( In13_Cu ), In13_Cu, ZONE_LAYER_FOR( In13_Cu ), NETNAMES_LAYER_INDEX( In14_Cu ), PAD_COPPER_LAYER_FOR( In14_Cu ), VIA_COPPER_LAYER_FOR( In14_Cu ), CLEARANCE_LAYER_FOR( In14_Cu ), + POINT_LAYER_FOR( In14_Cu ), In14_Cu, ZONE_LAYER_FOR( In14_Cu ), NETNAMES_LAYER_INDEX( In15_Cu ), PAD_COPPER_LAYER_FOR( In15_Cu ), VIA_COPPER_LAYER_FOR( In15_Cu ), CLEARANCE_LAYER_FOR( In15_Cu ), + POINT_LAYER_FOR( In15_Cu ), In15_Cu, ZONE_LAYER_FOR( In15_Cu ), NETNAMES_LAYER_INDEX( In16_Cu ), PAD_COPPER_LAYER_FOR( In16_Cu ), VIA_COPPER_LAYER_FOR( In16_Cu ), CLEARANCE_LAYER_FOR( In16_Cu ), + POINT_LAYER_FOR( In16_Cu ), In16_Cu, ZONE_LAYER_FOR( In16_Cu ), NETNAMES_LAYER_INDEX( In17_Cu ), PAD_COPPER_LAYER_FOR( In17_Cu ), VIA_COPPER_LAYER_FOR( In17_Cu ), CLEARANCE_LAYER_FOR( In17_Cu ), + POINT_LAYER_FOR( In17_Cu ), In17_Cu, ZONE_LAYER_FOR( In17_Cu ), NETNAMES_LAYER_INDEX( In18_Cu ), PAD_COPPER_LAYER_FOR( In18_Cu ), VIA_COPPER_LAYER_FOR( In18_Cu ), CLEARANCE_LAYER_FOR( In18_Cu ), + POINT_LAYER_FOR( In18_Cu ), In18_Cu, ZONE_LAYER_FOR( In18_Cu ), NETNAMES_LAYER_INDEX( In19_Cu ), PAD_COPPER_LAYER_FOR( In19_Cu ), VIA_COPPER_LAYER_FOR( In19_Cu ), CLEARANCE_LAYER_FOR( In19_Cu ), + POINT_LAYER_FOR( In19_Cu ), In19_Cu, ZONE_LAYER_FOR( In19_Cu ), NETNAMES_LAYER_INDEX( In20_Cu ), PAD_COPPER_LAYER_FOR( In20_Cu ), VIA_COPPER_LAYER_FOR( In20_Cu ), CLEARANCE_LAYER_FOR( In20_Cu ), + POINT_LAYER_FOR( In20_Cu ), In20_Cu, ZONE_LAYER_FOR( In20_Cu ), NETNAMES_LAYER_INDEX( In21_Cu ), PAD_COPPER_LAYER_FOR( In21_Cu ), VIA_COPPER_LAYER_FOR( In21_Cu ), CLEARANCE_LAYER_FOR( In21_Cu ), + POINT_LAYER_FOR( In21_Cu ), In21_Cu, ZONE_LAYER_FOR( In21_Cu ), NETNAMES_LAYER_INDEX( In22_Cu ), PAD_COPPER_LAYER_FOR( In22_Cu ), VIA_COPPER_LAYER_FOR( In22_Cu ), CLEARANCE_LAYER_FOR( In22_Cu ), + POINT_LAYER_FOR( In22_Cu ), In22_Cu, ZONE_LAYER_FOR( In22_Cu ), NETNAMES_LAYER_INDEX( In23_Cu ), PAD_COPPER_LAYER_FOR( In23_Cu ), VIA_COPPER_LAYER_FOR( In23_Cu ), CLEARANCE_LAYER_FOR( In23_Cu ), + POINT_LAYER_FOR( In23_Cu ), In23_Cu, ZONE_LAYER_FOR( In23_Cu ), NETNAMES_LAYER_INDEX( In24_Cu ), PAD_COPPER_LAYER_FOR( In24_Cu ), VIA_COPPER_LAYER_FOR( In24_Cu ), CLEARANCE_LAYER_FOR( In24_Cu ), + POINT_LAYER_FOR( In24_Cu ), In24_Cu, ZONE_LAYER_FOR( In24_Cu ), NETNAMES_LAYER_INDEX( In25_Cu ), PAD_COPPER_LAYER_FOR( In25_Cu ), VIA_COPPER_LAYER_FOR( In25_Cu ), CLEARANCE_LAYER_FOR( In25_Cu ), + POINT_LAYER_FOR( In25_Cu ), In25_Cu, ZONE_LAYER_FOR( In25_Cu ), NETNAMES_LAYER_INDEX( In26_Cu ), PAD_COPPER_LAYER_FOR( In26_Cu ), VIA_COPPER_LAYER_FOR( In26_Cu ), CLEARANCE_LAYER_FOR( In26_Cu ), + POINT_LAYER_FOR( In26_Cu ), In26_Cu, ZONE_LAYER_FOR( In26_Cu ), NETNAMES_LAYER_INDEX( In27_Cu ), PAD_COPPER_LAYER_FOR( In27_Cu ), VIA_COPPER_LAYER_FOR( In27_Cu ), CLEARANCE_LAYER_FOR( In27_Cu ), + POINT_LAYER_FOR( In27_Cu ), In27_Cu, ZONE_LAYER_FOR( In27_Cu ), NETNAMES_LAYER_INDEX( In28_Cu ), PAD_COPPER_LAYER_FOR( In28_Cu ), VIA_COPPER_LAYER_FOR( In28_Cu ), CLEARANCE_LAYER_FOR( In28_Cu ), + POINT_LAYER_FOR( In28_Cu ), In28_Cu, ZONE_LAYER_FOR( In28_Cu ), NETNAMES_LAYER_INDEX( In29_Cu ), PAD_COPPER_LAYER_FOR( In29_Cu ), VIA_COPPER_LAYER_FOR( In29_Cu ), CLEARANCE_LAYER_FOR( In29_Cu ), + POINT_LAYER_FOR( In29_Cu ), In29_Cu, ZONE_LAYER_FOR( In29_Cu ), NETNAMES_LAYER_INDEX( In30_Cu ), PAD_COPPER_LAYER_FOR( In30_Cu ), VIA_COPPER_LAYER_FOR( In30_Cu ), CLEARANCE_LAYER_FOR( In30_Cu ), + POINT_LAYER_FOR( In30_Cu ), In30_Cu, ZONE_LAYER_FOR( In30_Cu ), LAYER_PAD_BK_NETNAMES, @@ -251,6 +286,7 @@ const int GAL_LAYER_ORDER[] = PAD_COPPER_LAYER_FOR( B_Cu ), VIA_COPPER_LAYER_FOR( B_Cu ), CLEARANCE_LAYER_FOR( B_Cu ), + POINT_LAYER_FOR( B_Cu ), B_Cu, ZONE_LAYER_FOR( B_Cu ), B_Mask, ZONE_LAYER_FOR( B_Mask ), B_SilkS, ZONE_LAYER_FOR( B_SilkS ), @@ -433,6 +469,10 @@ void PCB_DRAW_PANEL_GAL::DisplayBoard( BOARD* aBoard, PROGRESS_REPORTER* aReport for( PCB_MARKER* marker : aBoard->Markers() ) m_view->Add( marker ); + // Load points + for( PCB_POINT* point : aBoard->Points() ) + m_view->Add( point ); + // Load zones for( ZONE* zone : aBoard->Zones() ) m_view->Add( zone ); @@ -505,13 +545,16 @@ void PCB_DRAW_PANEL_GAL::SetHighContrastLayer( PCB_LAYER_ID aLayer ) VIA_COPPER_LAYER_FOR( aLayer ), ZONE_LAYER_FOR( aLayer ), BITMAP_LAYER_FOR( aLayer ), + POINT_LAYER_FOR( aLayer ), LAYER_PAD_PLATEDHOLES, LAYER_PAD_HOLEWALLS, LAYER_NON_PLATEDHOLES, LAYER_VIA_THROUGH, LAYER_VIA_BBLIND, LAYER_VIA_MICROVIA, LAYER_VIA_HOLES, LAYER_VIA_HOLEWALLS, LAYER_DRC_ERROR, LAYER_DRC_WARNING, LAYER_DRC_EXCLUSION, LAYER_MARKER_SHADOWS, LAYER_DRC_SHAPE1, LAYER_DRC_SHAPE2, LAYER_SELECT_OVERLAY, LAYER_GP_OVERLAY, - LAYER_RATSNEST, LAYER_CURSOR, LAYER_ANCHOR, LAYER_LOCKED_ITEM_SHADOW + LAYER_RATSNEST, LAYER_CURSOR, + LAYER_ANCHOR, + LAYER_LOCKED_ITEM_SHADOW }; for( int i : layers ) @@ -591,7 +634,8 @@ void PCB_DRAW_PANEL_GAL::SetTopLayer( PCB_LAYER_ID aLayer ) m_view->SetTopLayer( PAD_COPPER_LAYER_FOR( layer ) ); m_view->SetTopLayer( VIA_COPPER_LAYER_FOR( layer ) ); m_view->SetTopLayer( CLEARANCE_LAYER_FOR( layer ) ); - } + m_view->SetTopLayer( POINT_LAYER_FOR( layer ) ); + } } // Move the active layer to the top of the stack but below all the overlay layers @@ -600,13 +644,15 @@ void PCB_DRAW_PANEL_GAL::SetTopLayer( PCB_LAYER_ID aLayer ) m_view->SetLayerOrder( aLayer, m_view->GetLayerOrder( LAYER_MARKER_SHADOWS ) + 1 ); m_view->SetLayerOrder( ZONE_LAYER_FOR( aLayer ), m_view->GetLayerOrder( LAYER_MARKER_SHADOWS ) + 2 ); + m_view->SetLayerOrder( POINT_LAYER_FOR( aLayer ), + m_view->GetLayerOrder( LAYER_MARKER_SHADOWS ) + 3 ); // Fix up pad and via netnames to be below. This is hacky, we need a rethink // of layer ordering... m_view->SetLayerOrder( LAYER_PAD_NETNAMES, - m_view->GetLayerOrder( LAYER_MARKER_SHADOWS ) + 3 ); - m_view->SetLayerOrder( LAYER_VIA_NETNAMES, m_view->GetLayerOrder( LAYER_MARKER_SHADOWS ) + 4 ); + m_view->SetLayerOrder( LAYER_VIA_NETNAMES, + m_view->GetLayerOrder( LAYER_MARKER_SHADOWS ) + 5 ); } } @@ -621,6 +667,7 @@ void PCB_DRAW_PANEL_GAL::SetTopLayer( PCB_LAYER_ID aLayer ) m_view->SetTopLayer( GetNetnameLayer( aLayer ) ); } + m_view->SetTopLayer( POINT_LAYER_FOR( aLayer ) ); m_view->SetTopLayer( BITMAP_LAYER_FOR( aLayer ) ); m_view->EnableTopLayer( true ); m_view->UpdateAllLayersOrder(); @@ -657,6 +704,9 @@ void PCB_DRAW_PANEL_GAL::SyncLayersVisibility( const BOARD* aBoard ) for( int i = LAYER_CLEARANCE_START; i < LAYER_CLEARANCE_END; i++ ) m_view->SetLayerVisible( i, false ); + for( int i = LAYER_POINT_START; i < LAYER_POINT_END; i++ ) + m_view->SetLayerVisible( i, true ); + for( int i = LAYER_BITMAP_START; i < LAYER_BITMAP_END; i++ ) m_view->SetLayerVisible( i, true ); @@ -819,6 +869,7 @@ void PCB_DRAW_PANEL_GAL::setDefaultLayerDeps() m_view->SetRequired( PAD_COPPER_LAYER_FOR( layer ), layer ); m_view->SetRequired( VIA_COPPER_LAYER_FOR( layer ), layer ); m_view->SetRequired( CLEARANCE_LAYER_FOR( layer ), layer ); + m_view->SetRequired( POINT_LAYER_FOR( layer ), layer ); m_view->SetRequired( BITMAP_LAYER_FOR( layer ), layer ); m_view->SetLayerTarget( BITMAP_LAYER_FOR( layer ), KIGFX::TARGET_NONCACHED ); @@ -826,6 +877,7 @@ void PCB_DRAW_PANEL_GAL::setDefaultLayerDeps() } else if( IsNonCopperLayer( layer ) ) { + m_view->SetRequired( POINT_LAYER_FOR( layer ), layer ); m_view->SetRequired( ZONE_LAYER_FOR( layer ), layer ); m_view->SetLayerTarget( BITMAP_LAYER_FOR( layer ), KIGFX::TARGET_NONCACHED ); m_view->SetRequired( BITMAP_LAYER_FOR( layer ), layer ); diff --git a/pcbnew/pcb_edit_frame.cpp b/pcbnew/pcb_edit_frame.cpp index 91a4c1d778..ae3b55562d 100644 --- a/pcbnew/pcb_edit_frame.cpp +++ b/pcbnew/pcb_edit_frame.cpp @@ -1117,6 +1117,7 @@ void PCB_EDIT_FRAME::setupUIConditions() CURRENT_EDIT_TOOL( PCB_ACTIONS::drawArc ); CURRENT_EDIT_TOOL( PCB_ACTIONS::drawPolygon ); CURRENT_EDIT_TOOL( PCB_ACTIONS::drawBezier ); + CURRENT_EDIT_TOOL( PCB_ACTIONS::placePoint ); CURRENT_EDIT_TOOL( PCB_ACTIONS::placeReferenceImage ); CURRENT_EDIT_TOOL( PCB_ACTIONS::placeText ); CURRENT_EDIT_TOOL( PCB_ACTIONS::drawTextBox ); @@ -2886,8 +2887,10 @@ void PCB_EDIT_FRAME::OnEditItemRequest( BOARD_ITEM* aItem ) m_toolManager->GetTool()->CrossProbe( static_cast( aItem ) ); break; + case PCB_POINT_T: + break; + default: break; } } - diff --git a/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.cpp b/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.cpp index 6535b6cdbc..8fae01805b 100644 --- a/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.cpp +++ b/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.cpp @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -373,6 +374,10 @@ void PCB_IO_KICAD_SEXPR::Format( const BOARD_ITEM* aItem ) const format( static_cast( aItem ) ); break; + case PCB_POINT_T: + format( static_cast( aItem ) ); + break; + case PCB_TARGET_T: format( static_cast( aItem ) ); break; @@ -769,6 +774,8 @@ void PCB_IO_KICAD_SEXPR::format( const BOARD* aBoard ) const aBoard->Drawings().end() ); std::set sorted_tracks( aBoard->Tracks().begin(), aBoard->Tracks().end() ); + std::set sorted_points( aBoard->Points().begin(), + aBoard->Points().end() ); std::set sorted_zones( aBoard->Zones().begin(), aBoard->Zones().end() ); std::set sorted_groups( aBoard->Groups().begin(), @@ -785,6 +792,10 @@ void PCB_IO_KICAD_SEXPR::format( const BOARD* aBoard ) const for( BOARD_ITEM* item : sorted_drawings ) Format( item ); + // Save the points + for( PCB_POINT* point : sorted_points ) + Format( point ); + // Do not save PCB_MARKERs, they can be regenerated easily. // Save the tracks and vias. @@ -1101,6 +1112,20 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_REFERENCE_IMAGE* aBitmap ) const } +void PCB_IO_KICAD_SEXPR::format( const PCB_POINT* aPoint ) const +{ + m_out->Print( "(point (at %s) (size %s)", + formatInternalUnits( aPoint->GetPosition() ).c_str(), + formatInternalUnits( aPoint->GetSize() ).c_str() + ); + + formatLayer( aPoint->GetLayer() ); + + KICAD_FORMAT::FormatUuid( m_out, aPoint->m_Uuid ); + m_out->Print( ")" ); +} + + void PCB_IO_KICAD_SEXPR::format( const PCB_TARGET* aTarget ) const { m_out->Print( "(target %s (at %s) (size %s)", @@ -1345,6 +1370,9 @@ void PCB_IO_KICAD_SEXPR::format( const FOOTPRINT* aFootprint ) const std::set sorted_drawings( aFootprint->GraphicalItems().begin(), aFootprint->GraphicalItems().end() ); + std::set sorted_points( + aFootprint->Points().begin(), + aFootprint->Points().end() ); std::set sorted_zones( aFootprint->Zones().begin(), aFootprint->Zones().end() ); std::set sorted_groups( aFootprint->Groups().begin(), @@ -1355,6 +1383,9 @@ void PCB_IO_KICAD_SEXPR::format( const FOOTPRINT* aFootprint ) const for( BOARD_ITEM* gr : sorted_drawings ) Format( gr ); + for( PCB_POINT* point : sorted_points ) + Format( point ); + // Save pads. for( PAD* pad : sorted_pads ) Format( pad ); diff --git a/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.h b/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.h index 5927f7f159..7b782d91b5 100644 --- a/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.h +++ b/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.h @@ -47,8 +47,9 @@ class PCB_IO_KICAD_SEXPR_PARSER; class NETINFO_MAPPING; class BOARD_DESIGN_SETTINGS; class PCB_DIMENSION_BASE; -class PCB_SHAPE; +class PCB_POINT; class PCB_REFERENCE_IMAGE; +class PCB_SHAPE; class PCB_TARGET; class PAD; class PADSTACK; @@ -64,6 +65,7 @@ class SHAPE_LINE_CHAIN; class TEARDROP_PARAMETERS; class PCB_IO_KICAD_SEXPR; // forward decl +// clang-format off /// Current s-expression file format version. 2 was the last legacy format version. //#define SEXPR_BOARD_FILE_VERSION 3 // first s-expression format, used legacy cu stack @@ -187,14 +189,15 @@ class PCB_IO_KICAD_SEXPR; // forward decl //#define SEXPR_BOARD_FILE_VERSION 20250801 // (island) -> (island yes/no) //#define SEXPR_BOARD_FILE_VERSION 20250811 // press-fit pad fabr prop support //#define SEXPR_BOARD_FILE_VERSION 20250818 // Support for custom layer counts in footprints -#define SEXPR_BOARD_FILE_VERSION 20250829 // Support Rounded Rectangles +//#define SEXPR_BOARD_FILE_VERSION 20250829 // Support Rounded Rectangles +#define SEXPR_BOARD_FILE_VERSION 20250901 // PCB points #define BOARD_FILE_HOST_VERSION 20200825 ///< Earlier files than this include the host tag #define LEGACY_ARC_FORMATTING 20210925 ///< These were the last to use old arc formatting #define LEGACY_NET_TIES 20220815 ///< These were the last to use the keywords field ///< to indicate a net-tie. #define FIRST_NORMALIZED_VERISON 20230924 ///< Earlier files did not have normalized bools - +// clang-format on // common combinations of the above: @@ -446,6 +449,7 @@ private: void format( const PCB_SHAPE* aSegment ) const; void format( const PCB_TARGET* aTarget ) const; + void format( const PCB_POINT* aPoint ) const; void format( const FOOTPRINT* aFootprint ) const; diff --git a/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr_parser.cpp b/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr_parser.cpp index 8ccbb7f9bb..2a47f4e80d 100644 --- a/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr_parser.cpp +++ b/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr_parser.cpp @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -1091,6 +1092,12 @@ BOARD* PCB_IO_KICAD_SEXPR_PARSER::parseBOARD_unchecked() bulkAddedItems.push_back( item ); break; + case T_point: + item = parsePCB_POINT(); + m_board->Add( item, ADD_MODE::BULK_APPEND, true ); + bulkAddedItems.push_back( item ); + break; + case T_embedded_fonts: { m_board->GetEmbeddedFiles()->SetAreFontsEmbedded( parseBool() ); @@ -5020,6 +5027,12 @@ FOOTPRINT* PCB_IO_KICAD_SEXPR_PARSER::parseFOOTPRINT_unchecked( wxArrayString* a parseGROUP( footprint.get() ); break; + case T_point: + { + PCB_POINT* point = parsePCB_POINT(); + footprint->Add( point, ADD_MODE::APPEND, true ); + break; + } case T_embedded_fonts: { footprint->GetEmbeddedFiles()->SetAreFontsEmbedded( parseBool() ); @@ -7740,6 +7753,56 @@ ZONE* PCB_IO_KICAD_SEXPR_PARSER::parseZONE( BOARD_ITEM_CONTAINER* aParent ) } +PCB_POINT* PCB_IO_KICAD_SEXPR_PARSER::parsePCB_POINT() +{ + wxCHECK_MSG( CurTok() == T_point, nullptr, + wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as PCB_POINT." ) ); + + std::unique_ptr point = std::make_unique( nullptr ); + + for( T token = NextTok(); token != T_RIGHT; token = NextTok() ) + { + if( token == T_LEFT ) + token = NextTok(); + + switch( token ) + { + case T_at: + { + VECTOR2I pt; + pt.x = parseBoardUnits( "point x position" ); + pt.y = parseBoardUnits( "point y position" ); + point->SetPosition( pt ); + NeedRIGHT(); + break; + } + case T_size: + { + point->SetSize( parseBoardUnits( "point size" ) ); + NeedRIGHT(); + break; + } + case T_layer: + { + point->SetLayer( parseBoardItemLayer() ); + NeedRIGHT(); + break; + } + case T_uuid: + { + NextTok(); + const_cast( point->m_Uuid ) = CurStrToKIID(); + NeedRIGHT(); + break; + } + default: Expecting( "at, size, layer or uuid" ); + } + } + + return point.release(); +} + + PCB_TARGET* PCB_IO_KICAD_SEXPR_PARSER::parsePCB_TARGET() { wxCHECK_MSG( CurTok() == T_target, nullptr, diff --git a/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr_parser.h b/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr_parser.h index 674b6a90cc..1fce404b4b 100644 --- a/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr_parser.h +++ b/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr_parser.h @@ -60,6 +60,7 @@ class PCB_TABLE; class PCB_TABLECELL; class FOOTPRINT; class PCB_GROUP; +class PCB_POINT; class PCB_TARGET; class PCB_VIA; class ZONE; @@ -243,6 +244,7 @@ private: void parseViastack( PCB_VIA* aVia ); ZONE* parseZONE( BOARD_ITEM_CONTAINER* aParent ); PCB_TARGET* parsePCB_TARGET(); + PCB_POINT* parsePCB_POINT(); BOARD* parseBOARD(); void parseGROUP_members( GROUP_INFO& aGroupInfo ); void parseGROUP( BOARD_ITEM* aParent ); diff --git a/pcbnew/pcb_item_containers.h b/pcbnew/pcb_item_containers.h index 690a95d6ce..fe3ea5b770 100644 --- a/pcbnew/pcb_item_containers.h +++ b/pcbnew/pcb_item_containers.h @@ -31,6 +31,7 @@ class FOOTPRINT; class PCB_TRACK; class PCB_GROUP; class PCB_GENERATOR; +class PCB_POINT; class PCB_MARKER; class ZONE; @@ -41,6 +42,7 @@ DECL_DEQ_FOR_SWIG( FOOTPRINTS, FOOTPRINT* ) // Dequeue rather than Vector just so we can use moveUnflaggedItems in pcbnew_control.cpp DECL_DEQ_FOR_SWIG( GROUPS, PCB_GROUP* ) DECL_DEQ_FOR_SWIG( GENERATORS, PCB_GENERATOR* ) +DECL_DEQ_FOR_SWIG( PCB_POINTS, PCB_POINT* ) // Shared with board and footprint diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp index 6209f8443e..0c59ddbc05 100644 --- a/pcbnew/pcb_painter.cpp +++ b/pcbnew/pcb_painter.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -733,6 +734,10 @@ bool PCB_PAINTER::Draw( const VIEW_ITEM* aItem, int aLayer ) draw( static_cast( item ) ); break; + case PCB_POINT_T: + draw( static_cast( item ), aLayer ); + break; + case PCB_MARKER_T: draw( static_cast( item ), aLayer ); break; @@ -2962,7 +2967,7 @@ void PCB_PAINTER::draw( const PCB_DIMENSION_BASE* aDimension, int aLayer ) void PCB_PAINTER::draw( const PCB_TARGET* aTarget ) { - const COLOR4D& strokeColor = m_pcbSettings.GetColor( aTarget, aTarget->GetLayer() ); + const COLOR4D strokeColor = m_pcbSettings.GetColor( aTarget, aTarget->GetLayer() ); VECTOR2D position( aTarget->GetPosition() ); double size, radius; @@ -2996,6 +3001,53 @@ void PCB_PAINTER::draw( const PCB_TARGET* aTarget ) } +void PCB_PAINTER::draw( const PCB_POINT* aPoint, int aLayer ) +{ + // aLayer will be the virtual zone layer (LAYER_ZONE_START, ... in GAL_LAYER_ID) + // This is used for draw ordering in the GAL. + // The color for the point comes from the associated copper layer ( aLayer - LAYER_POINT_START ) + // and the visibility comes from the combination of that copper layer and LAYER_POINT + + double size = aPoint->GetSize() / 2; + + // Keep the width constant, not related to the scale because the anchor + // is just a marker on screen, just draw in pixels + double thickness = m_pcbSettings.m_outlineWidth; + + // The general "points" colour + COLOR4D crossColor = m_pcbSettings.GetColor( aPoint, LAYER_POINTS ); + // The colour for the ring around the point follows the "real" layer of the point + COLOR4D ringColor = m_pcbSettings.GetColor( aPoint, aPoint->GetLayer() ); + + if( aLayer == LAYER_LOCKED_ITEM_SHADOW ) + { + thickness += m_lockedShadowMargin; + crossColor = m_pcbSettings.GetColor( aPoint, aLayer ); + ringColor = m_pcbSettings.GetColor( aPoint, aLayer ); + } + + VECTOR2D position( aPoint->GetPosition() ); + + m_gal->SetLineWidth( thickness ); + m_gal->SetStrokeColor( crossColor ); + m_gal->SetIsFill( false ); + m_gal->SetIsStroke( true ); + + m_gal->Save(); + m_gal->Translate( position ); + + // Draw as X to make it clearer when overlaid on cursor or axes + m_gal->DrawLine( VECTOR2D( -size, -size ), VECTOR2D( size, size ) ); + m_gal->DrawLine( VECTOR2D( size, -size ), VECTOR2D( -size, size ) ); + + // Draw the circle in the layer colour + m_gal->SetStrokeColor( ringColor ); + m_gal->DrawCircle( VECTOR2D( 0.0, 0.0 ), size / 2 ); + + m_gal->Restore(); +} + + void PCB_PAINTER::draw( const PCB_MARKER* aMarker, int aLayer ) { switch( aLayer ) diff --git a/pcbnew/pcb_painter.h b/pcbnew/pcb_painter.h index 664a2f9129..200ec39b96 100644 --- a/pcbnew/pcb_painter.h +++ b/pcbnew/pcb_painter.h @@ -57,6 +57,7 @@ class PCB_TEXTBOX; class PCB_TABLE; class PCB_DIMENSION_BASE; class PCB_TARGET; +class PCB_POINT; class PCB_MARKER; class NET_SETTINGS; class NETINFO_LIST; @@ -210,6 +211,7 @@ protected: void draw( const PCB_GROUP* aGroup, int aLayer ); void draw( const ZONE* aZone, int aLayer ); void draw( const PCB_DIMENSION_BASE* aDimension, int aLayer ); + void draw( const PCB_POINT* aPoint, int aLayer ); void draw( const PCB_TARGET* aTarget ); void draw( const PCB_MARKER* aMarker, int aLayer ); void draw( const PCB_BOARD_OUTLINE* aBoardOutline, int aLayer ); diff --git a/pcbnew/pcb_point.cpp b/pcbnew/pcb_point.cpp new file mode 100644 index 0000000000..4dcfb31103 --- /dev/null +++ b/pcbnew/pcb_point.cpp @@ -0,0 +1,235 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2012 Jean-Pierre Charras, jp.charras at wanadoo.fr + * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck + * Copyright (C) 2012 Wayne Stambaugh + * Copyright The KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ +#include "pcb_point.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static const double DEFAULT_PT_SIZE_MM = 1.0; + + +PCB_POINT::PCB_POINT( BOARD_ITEM* aParent ) : + BOARD_ITEM( aParent, PCB_POINT_T ), + m_pos( 0, 0 ), + m_size( pcbIUScale.mmToIU( DEFAULT_PT_SIZE_MM ) ) +{ +} + + +PCB_POINT::PCB_POINT( BOARD_ITEM* aParent, const VECTOR2I& aPos, int aSize ) : + BOARD_ITEM( aParent, PCB_POINT_T ), + m_pos( aPos ), + m_size( aSize ) +{ +} + + +bool PCB_POINT::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const +{ + // Compute the hit on the bars of the X + const int size = GetSize() / 2; + const SEG loc = SEG( aPosition, aPosition ); + + const SEG seg1 = SEG( m_pos - VECTOR2I{ size, size }, m_pos + VECTOR2I{ size, size } ); + const SEG seg2 = SEG( m_pos - VECTOR2I{ size, -size }, m_pos + VECTOR2I{ size, -size } ); + const SHAPE_CIRCLE circle( m_pos, size / 2 ); + + bool hit = seg1.Collide( loc, aAccuracy ) || seg2.Collide( loc, aAccuracy ) || circle.Collide( loc, aAccuracy ); + + return hit; +} + + +bool PCB_POINT::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const +{ + return KIGEOM::BoxHitTest( aRect, GetBoundingBox(), aContained, aAccuracy ); +} + + +std::vector PCB_POINT::ViewGetLayers() const +{ + const PCB_LAYER_ID layer = GetLayer(); + + std::vector layers = { + POINT_LAYER_FOR( layer ), + }; + + if( IsLocked() ) + layers.push_back( LAYER_LOCKED_ITEM_SHADOW ); + + return layers; +} + + +double PCB_POINT::ViewGetLOD( int aLayer, const KIGFX::VIEW* aView ) const +{ + // All points hidden + if( !aView->IsLayerVisible( LAYER_POINTS ) ) + return LOD_HIDE; + + // Hide if the "main" layer is not shown + if( !aView->IsLayerVisible( m_layer ) ) + return LOD_HIDE; + + return LOD_SHOW; +} + + +void PCB_POINT::Rotate( const VECTOR2I& aRotCentre, const EDA_ANGLE& aAngle ) +{ + RotatePoint( m_pos, aRotCentre, aAngle ); +} + + +void PCB_POINT::Flip( const VECTOR2I& aCentre, FLIP_DIRECTION aFlipDirection ) +{ + MIRROR(m_pos, aCentre, aFlipDirection); + + SetLayer( GetBoard()->FlipLayer( GetLayer() ) ); +} + + +const BOX2I PCB_POINT::GetBoundingBox() const +{ + BOX2I bbox = BOX2I::ByCenter( m_pos, VECTOR2I{ m_size, m_size } ); + return bbox; +} + + +std::shared_ptr PCB_POINT::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING aFlash ) const +{ + return std::make_shared( GetBoundingBox() ); +} + + +wxString PCB_POINT::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const +{ + return _( "Point" ); +} + + +BITMAPS PCB_POINT::GetMenuImage() const +{ + return BITMAPS::add_point; +} + + +EDA_ITEM* PCB_POINT::Clone() const +{ + return new PCB_POINT( *this ); +} + + +void PCB_POINT::swapData( BOARD_ITEM* aOther ) +{ + assert( aOther->Type() == PCB_POINT_T ); + + std::swap( *((PCB_POINT*) this), *((PCB_POINT*) aOther) ); +} + + +void PCB_POINT::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector& aList ) +{ + aList.emplace_back( _( "PCB Point" ), wxEmptyString ); + + aList.emplace_back( _( "Position X" ), aFrame->MessageTextFromValue( GetPosition().x ) ); + aList.emplace_back( _( "Position Y" ), aFrame->MessageTextFromValue( GetPosition().y ) ); + aList.emplace_back( _( "Size" ), aFrame->MessageTextFromValue( GetSize() ) ); + aList.emplace_back( _( "Layer" ), GetLayerName() ); +} + + +void PCB_POINT::TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer, + int aClearance, int aError, ERROR_LOC aErrorLoc, + bool ignoreLineWidth ) const +{ +} + + +bool PCB_POINT::operator==( const BOARD_ITEM& aBoardItem ) const +{ + if( aBoardItem.Type() != Type() ) + return false; + + const PCB_POINT& other = static_cast( aBoardItem ); + + return *this == other; +} + + +bool PCB_POINT::operator==( const PCB_POINT& aOther ) const +{ + return m_pos == aOther.m_pos && m_size == aOther.m_size; +} + + +double PCB_POINT::Similarity( const BOARD_ITEM& aOther ) const +{ + if( aOther.Type() != Type() ) + return 0.0; + + const PCB_POINT& other = static_cast( aOther ); + + double similarity = 1.0; + + if( m_pos == other.m_pos ) + similarity *= 0.9; + + if( m_size != other.m_size ) + similarity *= 0.9; + + if( GetLayer() != other.GetLayer() ) + similarity *= 0.9; + + return similarity; +} + +static struct PCB_POINT_DESC +{ + // clang-format off + PCB_POINT_DESC() + { + PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance(); + // PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance(); + REGISTER_TYPE( PCB_POINT ); + propMgr.InheritsAfter( TYPE_HASH( PCB_POINT ), TYPE_HASH( BOARD_ITEM ) ); + + propMgr.AddProperty( new PROPERTY( _HKI( "Size" ), + &PCB_POINT::SetSize, &PCB_POINT::GetSize, + PROPERTY_DISPLAY::PT_SIZE ) ); + } + // clang-format on +} _PCB_POINT_DESC; diff --git a/pcbnew/pcb_point.h b/pcbnew/pcb_point.h new file mode 100644 index 0000000000..8e1c22787d --- /dev/null +++ b/pcbnew/pcb_point.h @@ -0,0 +1,131 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2004 Jean-Pierre Charras, jp.charras at wanadoo.fr + * Copyright The KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#pragma once + +#include + + +/** + * A PCB_POINT is a 0-dimensional point that is used to mark a position on a PCB, + * or more usually a footprint for some purpose. This can be, for example: + * + * * As a defined snap anchor for component alignment + * * As a routing snap point in a custom pad + * + * For now, the point has only location, and a size. The size is the size of + * the displayed point in board space. Having the points a constant size in screen + * space regardless of zoom seems plasible, but it means at low zoom, the board will + * be full of "huge" markers. So allow users to set how big they are as needed. + */ +class PCB_POINT : public BOARD_ITEM +{ +public: + + PCB_POINT( BOARD_ITEM* aParent ); + + /** + * Construct a point at the given location. + */ + PCB_POINT( BOARD_ITEM* aParent, const VECTOR2I& aPos, const int aSize); + + static inline bool ClassOf( const EDA_ITEM* aItem ) + { + return aItem && PCB_POINT_T == aItem->Type(); + } + + void SetPosition( const VECTOR2I& aPos ) override { m_pos = aPos; } + VECTOR2I GetPosition() const override { return m_pos; } + + void SetSize( const int aSize ) { m_size = aSize; } + int GetSize() const { return m_size; } + + void Move( const VECTOR2I& aMoveVector ) override + { + m_pos += aMoveVector; + } + + double ViewGetLOD( int aLayer, const KIGFX::VIEW* aView ) const override; + std::vector ViewGetLayers() const override; + + void Rotate( const VECTOR2I& aRotCentre, const EDA_ANGLE& aAngle ) override; + + void Flip( const VECTOR2I& aCentre, FLIP_DIRECTION aFlipDirection ) override; + + wxString GetClass() const override + { + return wxT( "PCB_POINT" ); + } + + bool HitTest( const VECTOR2I& aPosition, int aAccuracy = 0 ) const override; + bool HitTest( const BOX2I& aRect, bool aContained, int aAccuracy = 0 ) const override; + + // Virtual function + const BOX2I GetBoundingBox() const override; + + std::shared_ptr + GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING aFlash = FLASHING::DEFAULT ) const override; + + wxString GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const override; + + BITMAPS GetMenuImage() const override; + + EDA_ITEM* Clone() const override; + + void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector& aList ) override; + + /** + * Convert the shape to a closed polygon. + * + * Used in filling zones calculations. Circles and arcs are approximated by segments. + * + * @param aBuffer is a buffer to store the polygon. + * @param aClearance is the clearance around the pad. + * @param aError is the maximum deviation from a true arc. + * @param aErrorLoc whether any approximation error should be placed inside or outside + * @param ignoreLineWidth is used for edge cut items where the line width is only for + * visualization + */ + void TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer, int aClearance, + int aError, ERROR_LOC aErrorLoc, + bool ignoreLineWidth = false ) const override; + + double Similarity( const BOARD_ITEM& aBoardItem ) const override; + + bool operator==( const PCB_POINT& aOther ) const; + bool operator==( const BOARD_ITEM& aBoardItem ) const override; + +#if defined( DEBUG ) + void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); } +#endif + +protected: + virtual void swapData( BOARD_ITEM* aImage ) override; + +private: + // Center of the point + VECTOR2I m_pos; + // Visual size of the point in board space + int m_size; +}; diff --git a/pcbnew/pcb_target.cpp b/pcbnew/pcb_target.cpp index dff7e39769..0618c324a6 100644 --- a/pcbnew/pcb_target.cpp +++ b/pcbnew/pcb_target.cpp @@ -23,11 +23,11 @@ * or you may write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "pcb_target.h" #include #include #include -#include #include #include #include @@ -37,6 +37,7 @@ #include #include + PCB_TARGET::PCB_TARGET( BOARD_ITEM* aParent ) : BOARD_ITEM( aParent, PCB_TARGET_T ) { diff --git a/pcbnew/toolbars_footprint_editor.cpp b/pcbnew/toolbars_footprint_editor.cpp index 5289bd65e6..fa8b19a81d 100644 --- a/pcbnew/toolbars_footprint_editor.cpp +++ b/pcbnew/toolbars_footprint_editor.cpp @@ -114,6 +114,7 @@ std::optional FOOTPRINT_EDIT_TOOLBAR_SETTINGS::DefaultToo .AppendAction( ACTIONS::deleteTool ); config.AppendSeparator() + .AppendAction( PCB_ACTIONS::placePoint ) .AppendAction( PCB_ACTIONS::setAnchor ) .AppendAction( ACTIONS::gridSetOrigin ) .AppendAction( ACTIONS::measureTool ); diff --git a/pcbnew/toolbars_pcb_editor.cpp b/pcbnew/toolbars_pcb_editor.cpp index 8eb35561b3..e99ca635ee 100644 --- a/pcbnew/toolbars_pcb_editor.cpp +++ b/pcbnew/toolbars_pcb_editor.cpp @@ -227,9 +227,10 @@ std::optional PCB_EDIT_TOOLBAR_SETTINGS::DefaultToolbarCo .AppendAction( ACTIONS::deleteTool ); config.AppendSeparator() - .AppendGroup( TOOLBAR_GROUP_CONFIG( _( "PCB origins" ) ) + .AppendGroup( TOOLBAR_GROUP_CONFIG( _( "PCB origins and points" ) ) .AddAction( ACTIONS::gridSetOrigin ) .AddAction( PCB_ACTIONS::drillOrigin ) ) + .AppendAction( PCB_ACTIONS::placePoint ) .AppendAction( ACTIONS::measureTool ); /* TODO (ISM): Support context menus diff --git a/pcbnew/tools/array_tool.cpp b/pcbnew/tools/array_tool.cpp index bf0b4374cc..2533528551 100644 --- a/pcbnew/tools/array_tool.cpp +++ b/pcbnew/tools/array_tool.cpp @@ -298,6 +298,7 @@ void ARRAY_TOOL::onDialogClosed( wxCloseEvent& aEvent ) case PCB_DIM_RADIAL_T: case PCB_DIM_ORTHOGONAL_T: case PCB_DIM_LEADER_T: + case PCB_POINT_T: case PCB_TARGET_T: case PCB_ZONE_T: this_item = item->Duplicate( true, &commit ); diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index 6c49f1ef47..57e857ef11 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -67,6 +67,7 @@ #include #include #include +#include #include #include #include @@ -856,6 +857,61 @@ int DRAWING_TOOL::PlaceReferenceImage( const TOOL_EVENT& aEvent ) return 0; } +struct POINT_PLACER : public INTERACTIVE_PLACER_BASE +{ + POINT_PLACER( DRAWING_TOOL& aDrawingTool, PCB_BASE_EDIT_FRAME& aFrame ) : + m_drawingTool( aDrawingTool ), + m_frame( aFrame ), + m_gridHelper( aDrawingTool.GetManager(), aFrame.GetMagneticItemsSettings() ) + { + } + + std::unique_ptr CreateItem() override + { + std::unique_ptr new_point = std::make_unique( m_frame.GetModel() ); + + PCB_LAYER_ID layer = m_frame.GetActiveLayer(); + new_point->SetLayer( layer ); + + return new_point; + } + + void SnapItem( BOARD_ITEM* aItem ) override + { + m_gridHelper.SetSnap( !( m_modifiers & MD_SHIFT ) ); + m_gridHelper.SetUseGrid( !( m_modifiers & MD_CTRL ) ); + + KIGFX::VIEW_CONTROLS& viewControls = *m_drawingTool.GetManager()->GetViewControls(); + const VECTOR2I position = viewControls.GetMousePosition(); + + VECTOR2I cursorPos = m_gridHelper.BestSnapAnchor( position, aItem->GetLayerSet() ); + viewControls.ForceCursorPosition( true, cursorPos ); + aItem->SetPosition( cursorPos ); + } + + DRAWING_TOOL& m_drawingTool; + PCB_BASE_EDIT_FRAME& m_frame; + PCB_GRID_HELPER m_gridHelper; +}; + + +int DRAWING_TOOL::PlacePoint( const TOOL_EVENT& aEvent ) +{ + if( m_isFootprintEditor && !m_frame->GetModel() ) + return 0; + + if( m_inDrawingTool ) + return 0; + + REENTRANCY_GUARD guard( &m_inDrawingTool ); + + POINT_PLACER placer( *this, *frame() ); + + doInteractiveItemPlacement( aEvent, &placer, _( "Place point" ), IPO_REPEAT | IPO_SINGLE_CLICK ); + + return 0; +} + int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent ) { @@ -4154,6 +4210,7 @@ void DRAWING_TOOL::setTransitions() Go( &DRAWING_TOOL::DrawZone, PCB_ACTIONS::drawZoneCutout.MakeEvent() ); Go( &DRAWING_TOOL::DrawZone, PCB_ACTIONS::drawSimilarZone.MakeEvent() ); Go( &DRAWING_TOOL::DrawVia, PCB_ACTIONS::drawVia.MakeEvent() ); + Go( &DRAWING_TOOL::PlacePoint, PCB_ACTIONS::placePoint.MakeEvent() ); Go( &DRAWING_TOOL::PlaceReferenceImage, PCB_ACTIONS::placeReferenceImage.MakeEvent() ); Go( &DRAWING_TOOL::PlaceText, PCB_ACTIONS::placeText.MakeEvent() ); Go( &DRAWING_TOOL::DrawTable, PCB_ACTIONS::drawTable.MakeEvent() ); diff --git a/pcbnew/tools/drawing_tool.h b/pcbnew/tools/drawing_tool.h index 12388a37db..df06e534be 100644 --- a/pcbnew/tools/drawing_tool.h +++ b/pcbnew/tools/drawing_tool.h @@ -75,6 +75,7 @@ public: IMAGE, TEXT, ANCHOR, + POINT, DXF, DIMENSION, KEEPOUT, @@ -150,6 +151,11 @@ public: */ int PlaceReferenceImage( const TOOL_EVENT& aEvent ); + /** + * Place a reference 0D point + */ + int PlacePoint( const TOOL_EVENT& aEvent ); + /** * Display a dialog that allows one to input text and its settings and then lets the user * decide where to place the text in editor. diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 150e135538..20146ad459 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -2268,6 +2269,7 @@ const std::vector EDIT_TOOL::MirrorableItems = { PCB_VIA_T, PCB_GROUP_T, PCB_GENERATOR_T, + PCB_POINT_T, }; @@ -2352,6 +2354,10 @@ int EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent ) static_cast( item )->Mirror( mirrorPoint, flipDirection ); break; + case PCB_POINT_T: + static_cast( item )->Mirror( mirrorPoint, flipDirection ); + break; + default: // it's likely the commit object is wrong if you get here UNIMPLEMENTED_FOR( item->GetClass() ); @@ -2598,6 +2604,7 @@ void EDIT_TOOL::DeleteItems( const PCB_SELECTION& aItems, bool aIsCut ) case PCB_DIM_CENTER_T: case PCB_DIM_RADIAL_T: case PCB_DIM_ORTHOGONAL_T: + case PCB_POINT_T: commit.Remove( board_item ); itemsDeleted++; break; @@ -2949,6 +2956,7 @@ int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent ) case PCB_VIA_T: case PCB_ZONE_T: case PCB_TARGET_T: + case PCB_POINT_T: case PCB_DIM_ALIGNED_T: case PCB_DIM_CENTER_T: case PCB_DIM_RADIAL_T: diff --git a/pcbnew/tools/pcb_actions.cpp b/pcbnew/tools/pcb_actions.cpp index 6c76941d24..bda9a80327 100644 --- a/pcbnew/tools/pcb_actions.cpp +++ b/pcbnew/tools/pcb_actions.cpp @@ -177,6 +177,15 @@ TOOL_ACTION PCB_ACTIONS::placeStackup( TOOL_ACTION_ARGS() .ToolbarState( TOOLBAR_STATE::TOGGLE ) .Flags( AF_ACTIVATE ) ); +TOOL_ACTION PCB_ACTIONS::placePoint( TOOL_ACTION_ARGS() + .Name( "pcbnew.InteractiveDrawing.placePoint" ) + .Scope( AS_GLOBAL ) + .FriendlyName( _( "Place Point" ) ) + .Tooltip( _( "Add reference/snap points" ) ) + .ToolbarState( TOOLBAR_STATE::TOGGLE ) + .Icon( BITMAPS::add_point ) + .Flags( AF_ACTIVATE ) ); + TOOL_ACTION PCB_ACTIONS::placeReferenceImage( TOOL_ACTION_ARGS() .Name( "pcbnew.InteractiveDrawing.placeReferenceImage" ) .Scope( AS_GLOBAL ) diff --git a/pcbnew/tools/pcb_actions.h b/pcbnew/tools/pcb_actions.h index 46eb6d25ac..b79601efaf 100644 --- a/pcbnew/tools/pcb_actions.h +++ b/pcbnew/tools/pcb_actions.h @@ -192,6 +192,7 @@ public: static TOOL_ACTION drawCircle; static TOOL_ACTION drawArc; static TOOL_ACTION drawBezier; + static TOOL_ACTION placePoint; static TOOL_ACTION placeReferenceImage; static TOOL_ACTION placeText; static TOOL_ACTION drawTextBox; diff --git a/pcbnew/tools/pcb_grid_helper.cpp b/pcbnew/tools/pcb_grid_helper.cpp index 4214a25fd3..e25d4b3cfc 100644 --- a/pcbnew/tools/pcb_grid_helper.cpp +++ b/pcbnew/tools/pcb_grid_helper.cpp @@ -1561,6 +1561,7 @@ void PCB_GRID_HELPER::computeAnchors( BOARD_ITEM* aItem, const VECTOR2I& aRefPos case PCB_MARKER_T: case PCB_TARGET_T: + case PCB_POINT_T: addAnchor( aItem->GetPosition(), ORIGIN | CORNER | SNAPPABLE, aItem, POINT_TYPE::PT_CENTER ); break; diff --git a/pcbnew/tools/pcb_selection_tool.cpp b/pcbnew/tools/pcb_selection_tool.cpp index 42e0e085e2..b61b17988c 100644 --- a/pcbnew/tools/pcb_selection_tool.cpp +++ b/pcbnew/tools/pcb_selection_tool.cpp @@ -34,6 +34,7 @@ using namespace std::placeholders; #include #include #include +#include #include #include #include @@ -3129,6 +3130,12 @@ bool PCB_SELECTION_TOOL::Selectable( const BOARD_ITEM* aItem, bool checkVisibili return true; } + for( const PCB_POINT* point: footprint->Points() ) + { + if( Selectable( point, true ) ) + return true; + } + return false; } else if( aItem->Type() == PCB_GROUP_T ) @@ -3323,6 +3330,15 @@ bool PCB_SELECTION_TOOL::Selectable( const BOARD_ITEM* aItem, bool checkVisibili break; + case PCB_POINT_T: + if( !layerVisible( aItem->GetLayer() ) ) + return false; + + if( !board()->IsElementVisible( LAYER_POINTS ) ) + return false; + + break; + // These are not selectable case PCB_NETINFO_T: case NOT_USED: diff --git a/pcbnew/tools/pcb_tool_base.cpp b/pcbnew/tools/pcb_tool_base.cpp index dd981ce364..3b35871ce5 100644 --- a/pcbnew/tools/pcb_tool_base.cpp +++ b/pcbnew/tools/pcb_tool_base.cpp @@ -358,4 +358,3 @@ bool INTERACTIVE_PLACER_BASE::PlaceItem( BOARD_ITEM *aItem, BOARD_COMMIT& aCommi aCommit.Add( aItem ); return true; } - diff --git a/pcbnew/undo_redo.cpp b/pcbnew/undo_redo.cpp index f7627082d5..a6e7f19e4a 100644 --- a/pcbnew/undo_redo.cpp +++ b/pcbnew/undo_redo.cpp @@ -33,7 +33,6 @@ using namespace std::placeholders; #include #include #include -#include #include #include #include diff --git a/pcbnew/widgets/appearance_controls.cpp b/pcbnew/widgets/appearance_controls.cpp index 6dd9707598..8be5a33918 100644 --- a/pcbnew/widgets/appearance_controls.cpp +++ b/pcbnew/widgets/appearance_controls.cpp @@ -348,6 +348,7 @@ const APPEARANCE_CONTROLS::APPEARANCE_SETTING APPEARANCE_CONTROLS::s_objectSetti RR( _HKI( "DRC Errors" ), LAYER_DRC_ERROR, _HKI( "DRC violations with an Error severity" ) ), RR( _HKI( "DRC Exclusions" ), LAYER_DRC_EXCLUSION, _HKI( "DRC violations which have been individually excluded" ) ), RR( _HKI( "Anchors" ), LAYER_ANCHOR, _HKI( "Show footprint and text origins as a cross" ) ), + RR( _HKI( "Points" ), LAYER_POINTS, _HKI( "Show explicit snap points as crosses" ) ), RR( _HKI( "Locked Item Shadow" ), LAYER_LOCKED_ITEM_SHADOW, _HKI( "Show a shadow on locked items" ) ), RR( _HKI( "Colliding Courtyards" ), LAYER_CONFLICTS_SHADOW, _HKI( "Show colliding footprint courtyards" ) ), RR( _HKI( "Board Area Shadow" ), LAYER_BOARD_OUTLINE_AREA, _HKI( "Show board area shadow" ) ), @@ -368,7 +369,8 @@ static std::set s_allowedInFpEditor = LAYER_FP_REFERENCES, LAYER_FP_TEXT, LAYER_DRAW_BITMAPS, - LAYER_GRID + LAYER_GRID, + LAYER_POINTS, }; // These are the built-in layer presets that cannot be deleted @@ -2230,7 +2232,7 @@ void APPEARANCE_CONTROLS::rebuildObjects() COLOR4D color = theme->GetColor( layer ); COLOR4D defColor = theme->GetDefaultColor( layer ); - if( color != COLOR4D::UNSPECIFIED ) + if( color != COLOR4D::UNSPECIFIED || defColor != COLOR4D::UNSPECIFIED ) { COLOR_SWATCH* swatch = new COLOR_SWATCH( m_windowObjects, color, layer, bgColor, defColor, SWATCH_SMALL ); diff --git a/qa/tests/pcbnew/test_board_item.cpp b/qa/tests/pcbnew/test_board_item.cpp index ffc3f32829..7fe9fc074d 100644 --- a/qa/tests/pcbnew/test_board_item.cpp +++ b/qa/tests/pcbnew/test_board_item.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -111,6 +112,7 @@ public: case PCB_DIM_RADIAL_T: return new PCB_DIM_RADIAL( &m_board ); case PCB_DIM_ORTHOGONAL_T: return new PCB_DIM_ORTHOGONAL( &m_board ); case PCB_TARGET_T: return new PCB_TARGET( &m_board ); + case PCB_POINT_T: return new PCB_POINT( &m_board ); case PCB_ZONE_T: { diff --git a/resources/bitmaps_png/CMakeLists.txt b/resources/bitmaps_png/CMakeLists.txt index 8d7492c00d..ebff26ffe5 100644 --- a/resources/bitmaps_png/CMakeLists.txt +++ b/resources/bitmaps_png/CMakeLists.txt @@ -188,6 +188,7 @@ set( BMAPS_MID add_line add_orthogonal_dimension add_pcb_target + add_point add_power add_radial_dimension add_rectangle diff --git a/resources/bitmaps_png/png/add_point_16.png b/resources/bitmaps_png/png/add_point_16.png new file mode 100644 index 0000000000..ef4847ea1e Binary files /dev/null and b/resources/bitmaps_png/png/add_point_16.png differ diff --git a/resources/bitmaps_png/png/add_point_24.png b/resources/bitmaps_png/png/add_point_24.png new file mode 100644 index 0000000000..d90bc04ab2 Binary files /dev/null and b/resources/bitmaps_png/png/add_point_24.png differ diff --git a/resources/bitmaps_png/png/add_point_32.png b/resources/bitmaps_png/png/add_point_32.png new file mode 100644 index 0000000000..7c7de62f83 Binary files /dev/null and b/resources/bitmaps_png/png/add_point_32.png differ diff --git a/resources/bitmaps_png/png/add_point_48.png b/resources/bitmaps_png/png/add_point_48.png new file mode 100644 index 0000000000..832f40de0e Binary files /dev/null and b/resources/bitmaps_png/png/add_point_48.png differ diff --git a/resources/bitmaps_png/png/add_point_64.png b/resources/bitmaps_png/png/add_point_64.png new file mode 100644 index 0000000000..8bd4c16403 Binary files /dev/null and b/resources/bitmaps_png/png/add_point_64.png differ diff --git a/resources/bitmaps_png/png/add_point_dark_16.png b/resources/bitmaps_png/png/add_point_dark_16.png new file mode 100644 index 0000000000..d9a105fa06 Binary files /dev/null and b/resources/bitmaps_png/png/add_point_dark_16.png differ diff --git a/resources/bitmaps_png/png/add_point_dark_24.png b/resources/bitmaps_png/png/add_point_dark_24.png new file mode 100644 index 0000000000..1f25fc3b02 Binary files /dev/null and b/resources/bitmaps_png/png/add_point_dark_24.png differ diff --git a/resources/bitmaps_png/png/add_point_dark_32.png b/resources/bitmaps_png/png/add_point_dark_32.png new file mode 100644 index 0000000000..2604e1f874 Binary files /dev/null and b/resources/bitmaps_png/png/add_point_dark_32.png differ diff --git a/resources/bitmaps_png/png/add_point_dark_48.png b/resources/bitmaps_png/png/add_point_dark_48.png new file mode 100644 index 0000000000..ba790b83fd Binary files /dev/null and b/resources/bitmaps_png/png/add_point_dark_48.png differ diff --git a/resources/bitmaps_png/png/add_point_dark_64.png b/resources/bitmaps_png/png/add_point_dark_64.png new file mode 100644 index 0000000000..e367043ddb Binary files /dev/null and b/resources/bitmaps_png/png/add_point_dark_64.png differ diff --git a/resources/bitmaps_png/sources/dark/add_point.svg b/resources/bitmaps_png/sources/dark/add_point.svg new file mode 100644 index 0000000000..015a883a7f --- /dev/null +++ b/resources/bitmaps_png/sources/dark/add_point.svg @@ -0,0 +1,106 @@ + + + + + + + + + + + image/svg+xml + + add_point + + + + + + + + + + + + + + + add_point + + + diff --git a/resources/bitmaps_png/sources/light/add_point.svg b/resources/bitmaps_png/sources/light/add_point.svg new file mode 100644 index 0000000000..6b985d55e4 --- /dev/null +++ b/resources/bitmaps_png/sources/light/add_point.svg @@ -0,0 +1,106 @@ + + + + + + + + + + + image/svg+xml + + add_point + + + + + + + + + + + + + + + add_point + + +