From cc0aa8b92877ba73a1d42a6183526c881deff304 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Mon, 5 Nov 2018 17:04:05 +0100 Subject: [PATCH] Gfx import: fix many issues, and add many enhancements. * Do not compile dxf old files. * import gfx, gal mode: make absolute placement working. * Import gfx in legacy canvas: use it and make interactive placement working * Take imported line width in account. Ensure DXF line thickness is OK. * handling empty files in legacy mode. --- pcbnew/CMakeLists.txt | 9 - pcbnew/edit.cpp | 2 +- pcbnew/footprint_editor_utils.cpp | 2 +- pcbnew/import_dxf/dialog_dxf_import_base.fbp | 1914 +++++++------- pcbnew/import_gfx/dialog_import_gfx.cpp | 435 +++- pcbnew/import_gfx/dialog_import_gfx.h | 57 +- pcbnew/import_gfx/dialog_import_gfx_base.cpp | 240 +- pcbnew/import_gfx/dialog_import_gfx_base.fbp | 2265 +++++++++++------ pcbnew/import_gfx/dialog_import_gfx_base.h | 53 +- pcbnew/import_gfx/dxf_import_plugin.cpp | 466 +--- pcbnew/import_gfx/dxf_import_plugin.h | 49 +- pcbnew/import_gfx/graphics_import_mgr.h | 3 +- pcbnew/import_gfx/graphics_import_plugin.h | 17 +- pcbnew/import_gfx/graphics_importer.cpp | 14 +- pcbnew/import_gfx/graphics_importer.h | 130 +- .../import_gfx/graphics_importer_buffer.cpp | 16 +- pcbnew/import_gfx/graphics_importer_buffer.h | 37 +- .../import_gfx/graphics_importer_pcbnew.cpp | 131 +- pcbnew/import_gfx/graphics_importer_pcbnew.h | 27 +- pcbnew/import_gfx/nanosvg.h | 4 +- pcbnew/import_gfx/svg_import_plugin.cpp | 60 +- pcbnew/import_gfx/svg_import_plugin.h | 48 +- pcbnew/invoke_pcb_dialog.h | 10 +- pcbnew/menubar_pcb_editor.cpp | 4 +- pcbnew/tools/drawing_tool.cpp | 120 +- 25 files changed, 3430 insertions(+), 2683 deletions(-) diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index bc56606b16..6c1eb44fd5 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -181,14 +181,6 @@ if( KICAD_SCRIPTING AND KICAD_SCRIPTING_ACTION_MENU ) ) endif() -if( 1) -set( PCBNEW_IMPORT_DXF - import_dxf/dialog_dxf_import.cpp - import_dxf/dialog_dxf_import_base.cpp - import_dxf/dxf2brd_items.cpp - ) -endif() - set( PCBNEW_IMPORT_GFX import_gfx/dialog_import_gfx_base.cpp import_gfx/dialog_import_gfx.cpp @@ -222,7 +214,6 @@ set( PCBNEW_MICROWAVE_SRCS set( PCBNEW_CLASS_SRCS ${PCBNEW_DIALOGS} ${PCBNEW_EXPORTERS} - ${PCBNEW_IMPORT_DXF} ${PCBNEW_IMPORT_GFX} autorouter/rect_placement/rect_placement.cpp diff --git a/pcbnew/edit.cpp b/pcbnew/edit.cpp index 15b02de45c..6e46584a9d 100644 --- a/pcbnew/edit.cpp +++ b/pcbnew/edit.cpp @@ -1243,7 +1243,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) break; case ID_GEN_IMPORT_GRAPHICS_FILE: - InvokeDXFDialogBoardImport( this ); + InvokeDialogImportGfxBoard( this ); m_canvas->Refresh(); break; diff --git a/pcbnew/footprint_editor_utils.cpp b/pcbnew/footprint_editor_utils.cpp index ccd491f147..b3c8731151 100644 --- a/pcbnew/footprint_editor_utils.cpp +++ b/pcbnew/footprint_editor_utils.cpp @@ -799,7 +799,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) case ID_GEN_IMPORT_GRAPHICS_FILE: if( GetBoard()->m_Modules ) { - InvokeDXFDialogModuleImport( this, GetBoard()->m_Modules ); + InvokeDialogImportGfxModule( this, GetBoard()->m_Modules ); m_canvas->Refresh(); } break; diff --git a/pcbnew/import_dxf/dialog_dxf_import_base.fbp b/pcbnew/import_dxf/dialog_dxf_import_base.fbp index 38a8a9f8b8..d018906032 100644 --- a/pcbnew/import_dxf/dialog_dxf_import_base.fbp +++ b/pcbnew/import_dxf/dialog_dxf_import_base.fbp @@ -1,8 +1,8 @@ - + - + C++ 1 source_name @@ -16,9 +16,9 @@ none 1 dialog_dxf_import - + . - + 1 1 1 @@ -29,67 +29,67 @@ 0 wxAUI_MGR_DEFAULT - + wxBOTH - + 1 1 impl_virtual - - - + + + 0 wxID_ANY - - + + DIALOG_DXF_IMPORT_BASE - + -1,-1 wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER DIALOG_SHIM; dialog_shim.h Import DXF File - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + bSizerMain wxVERTICAL none @@ -98,7 +98,7 @@ wxALL|wxEXPAND 0 - + bSizerFile wxHORIZONTAL none @@ -111,78 +111,78 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY File: - + 0 - - + + 0 - + 1 m_staticTextFile 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - - - + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + @@ -194,86 +194,86 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY - + 0 - - - + + + 0 300,-1 1 m_textCtrlFileName 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - + + wxFILTER_NONE wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -285,17 +285,17 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 0 @@ -303,65 +303,65 @@ 0 Left 1 - + 1 - + 0 0 wxID_ANY Browse - + 0 - - + + 0 - + 1 m_buttonBrowse 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - + + wxFILTER_NONE wxDefaultValidator - - - - + + + + OnBrowseDxfFiles - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + @@ -371,7 +371,7 @@ wxALL|wxEXPAND 0 - + bSizerMiddle wxHORIZONTAL none @@ -384,93 +384,93 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 "Center of page" "Upper left corner of page" "Center left side of page" "Lower left corner of page" "User defined position" 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ORIGIN_SELECT Place DXF Origin (0,0) Point: 1 - + 0 - - + + 0 - + 1 m_rbOffsetOption 1 - - + + protected 1 - + Resizable 0 1 - + wxRA_SPECIFY_COLS - + 0 - - + + wxFILTER_NONE wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + OriginOptionOnUpdateUI 5 - + 1 - + bSizerUserPos wxVERTICAL none @@ -479,7 +479,7 @@ wxEXPAND|wxTOP|wxBOTTOM 1 - + bSizerPosSettings wxVERTICAL none @@ -492,78 +492,78 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY User defined position: - + 0 - - + + 0 - + 1 m_staticText6 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - - - + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + @@ -574,9 +574,9 @@ 3 wxBOTH 2 - + 0 - + fgSizerUserPosition wxFLEX_GROWMODE_SPECIFIED none @@ -601,78 +601,78 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY X: - + 0 - - + + 0 - + 1 m_staticTextXpos 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - - - + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + @@ -684,86 +684,86 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY - + 0 - + 10 - + 0 - + 1 m_DxfPcbXCoord 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 DXF origin on PCB Grid, X Coordinate - + wxFILTER_NUMERIC wxTextValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -785,78 +785,78 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY Y: - + 0 - - + + 0 - + 1 m_staticTextYpos 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - - - + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + @@ -868,86 +868,86 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY - + 0 - + 10 - + 0 - + 1 m_DxfPcbYCoord 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 DXF origin on PCB Grid, Y Coordinate - + wxFILTER_NUMERIC wxTextValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -969,78 +969,78 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY Units: - + 0 - - + + 0 - + 1 m_staticTextUnits 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - - - + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + @@ -1052,83 +1052,83 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 "mm" "inch" 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY - + 0 - - + + 0 - + 1 m_DxfPcbPositionUnits 1 - - + + protected 1 - + Resizable 0 1 - - - + + + 0 Select PCB grid units - + wxFILTER_NONE wxDefaultValidator - - - - - + + + + + onUnitPositionSelection - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + @@ -1144,7 +1144,7 @@ wxALL|wxEXPAND 0 - + bSizerLayer wxVERTICAL none @@ -1157,78 +1157,78 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY Import parameters: - + 0 - - + + 0 - + 1 m_staticTextPrms 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - - - + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + @@ -1236,7 +1236,7 @@ wxEXPAND 1 - + bSizer7 wxHORIZONTAL none @@ -1258,9 +1258,9 @@ 3 wxBOTH 1 - + 0 - + fgSizerImportSettings wxFLEX_GROWMODE_SPECIFIED none @@ -1275,78 +1275,78 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY Default line width: - + 0 - - + + 0 - + 1 m_staticTextLineWidth 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - - - + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + @@ -1358,86 +1358,86 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY - + 0 - - - + + + 0 - + 1 m_textCtrlLineWidth 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - + + wxFILTER_NONE wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1449,83 +1449,83 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 "mm" "mils" "inches" 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY - + 0 - - + + 0 - + 1 m_choiceUnitLineWidth 1 - - + + protected 1 - + Resizable 0 1 - - - + + + 0 - - + + wxFILTER_NONE wxDefaultValidator - - - - - + + + + + onUnitWidthSelection - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + @@ -1537,78 +1537,78 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY Graphic layer: - + 0 - - + + 0 - + 1 m_staticTextBrdlayer 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - - - + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + @@ -1620,86 +1620,86 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 - + 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY - + 0 - - + + 0 - + 1 m_SelLayerBox 1 - - + + protected 1 - + Resizable -1 1 - - + + PCB_LAYER_BOX_SELECTOR; pcb_layer_box_selector.h 0 - - + + wxFILTER_NONE wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1717,76 +1717,76 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY - + 0 - - + + 0 - + 1 m_staticline 1 - - + + protected 1 - + Resizable 1 - + wxLI_HORIZONTAL - + 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1802,17 +1802,17 @@ 1 0 0 - + m_sdbSizer protected - - - - - - - - + + + + + + + + diff --git a/pcbnew/import_gfx/dialog_import_gfx.cpp b/pcbnew/import_gfx/dialog_import_gfx.cpp index 061c00550d..6860c6429d 100644 --- a/pcbnew/import_gfx/dialog_import_gfx.cpp +++ b/pcbnew/import_gfx/dialog_import_gfx.cpp @@ -6,7 +6,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr + * Copyright (C) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 1992-2018 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or @@ -27,71 +27,76 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "dialog_import_gfx.h" #include #include -#include +#include +#include -#include #include #include #include #include #include -#include - -#include +#include "dialog_import_gfx.h" // Keys to store setup in config -#define IMPORT_GFX_LAYER_OPTION_KEY "GfxImportBrdLayer" -#define IMPORT_GFX_COORD_ORIGIN_KEY "GfxImportCoordOrigin" -#define IMPORT_GFX_LAST_FILE_KEY "GfxImportLastFile" -#define IMPORT_GFX_GRID_UNITS_KEY "GfxImportGridUnits" -#define IMPORT_GFX_GRID_OFFSET_X_KEY "GfxImportGridOffsetX" -#define IMPORT_GFX_GRID_OFFSET_Y_KEY "GfxImportGridOffsetY" +#define IMPORT_GFX_LAYER_OPTION_KEY "GfxImportBrdLayer" +#define IMPORT_GFX_PLACEMENT_INTERACTIVE_KEY "GfxImportPlacementInteractive" +#define IMPORT_GFX_LAST_FILE_KEY "GfxImportLastFile" +#define IMPORT_GFX_POSITION_UNITS_KEY "GfxImportPositionUnits" +#define IMPORT_GFX_POSITION_X_KEY "GfxImportPositionX" +#define IMPORT_GFX_POSITION_Y_KEY "GfxImportPositionY" +#define IMPORT_GFX_LINEWIDTH_UNITS_KEY "GfxImportLineWidthUnits" +#define IMPORT_GFX_LINEWIDTH_KEY "GfxImportLineWidth" -// Static members of DIALOG_IMPORT_GFX, to remember the user's choices during the session +// Static members of DIALOG_IMPORT_GFX, to remember +// the user's choices during the session wxString DIALOG_IMPORT_GFX::m_filename; -int DIALOG_IMPORT_GFX::m_offsetSelection = 0; +bool DIALOG_IMPORT_GFX::m_placementInteractive = true; LAYER_NUM DIALOG_IMPORT_GFX::m_layer = Dwgs_User; +double DIALOG_IMPORT_GFX::m_scaleImport = 1.0; // Do not change the imported items siaz -DIALOG_IMPORT_GFX::DIALOG_IMPORT_GFX( PCB_BASE_FRAME* aParent, bool aUseModuleItems ) +DIALOG_IMPORT_GFX::DIALOG_IMPORT_GFX( PCB_BASE_FRAME* aParent, bool aImportAsFootprintGraphic ) : DIALOG_IMPORT_GFX_BASE( aParent ) { m_parent = aParent; - if( aUseModuleItems ) + if( aImportAsFootprintGraphic ) m_importer.reset( new GRAPHICS_IMPORTER_MODULE( m_parent->GetBoard()->m_Modules ) ); else m_importer.reset( new GRAPHICS_IMPORTER_BOARD( m_parent->GetBoard() ) ); m_config = Kiface().KifaceSettings(); - m_gridUnits = 0; - m_gridOffsetX = 0.0; - m_gridOffsetY = 0.0; + m_originImportUnits = 0; + m_importOrigin.x = 0.0; // always in mm + m_importOrigin.y = 0.0; // always in mm + m_default_lineWidth = 0.2; // always in mm + m_lineWidthImportUnits = 0; if( m_config ) { m_layer = m_config->Read( IMPORT_GFX_LAYER_OPTION_KEY, (long)Dwgs_User ); - m_offsetSelection = m_config->Read( IMPORT_GFX_COORD_ORIGIN_KEY, (long)0 ); + m_placementInteractive = m_config->Read( IMPORT_GFX_PLACEMENT_INTERACTIVE_KEY, true ); m_filename = m_config->Read( IMPORT_GFX_LAST_FILE_KEY, wxEmptyString ); - m_config->Read( IMPORT_GFX_GRID_UNITS_KEY, &m_gridUnits, 0 ); - m_config->Read( IMPORT_GFX_GRID_OFFSET_X_KEY, &m_gridOffsetX, 0.0 ); - m_config->Read( IMPORT_GFX_GRID_OFFSET_Y_KEY, &m_gridOffsetY, 0.0 ); + m_config->Read( IMPORT_GFX_LINEWIDTH_KEY, &m_default_lineWidth, 0.2 ); + m_config->Read( IMPORT_GFX_POSITION_UNITS_KEY, &m_originImportUnits, 0 ); + m_config->Read( IMPORT_GFX_POSITION_X_KEY, &m_importOrigin.x, 0.0 ); + m_config->Read( IMPORT_GFX_POSITION_Y_KEY, &m_importOrigin.y, 0.0 ); } - m_PCBGridUnits->SetSelection( m_gridUnits ); - wxString tmpStr; - tmpStr << m_gridOffsetX; - m_PCBXCoord->SetValue( tmpStr ); - tmpStr = ""; - tmpStr << m_gridOffsetY; - m_PCBYCoord->SetValue( tmpStr ); + m_choiceUnitLineWidth->SetSelection( m_lineWidthImportUnits ); + showPCBdefaultLineWidth(); + + m_DxfPcbPositionUnits->SetSelection( m_originImportUnits ); + showPcbImportOffsets(); m_textCtrlFileName->SetValue( m_filename ); - m_rbOffsetOption->SetSelection( m_offsetSelection ); + m_rbInteractivePlacement->SetValue( m_placementInteractive ); + m_rbAbsolutePlacement->SetValue( not m_placementInteractive ); + + m_textCtrlImportScale->SetValue( wxString::Format( "%f", m_scaleImport ) ); // Configure the layers list selector m_SelLayerBox->SetLayersHotkeys( false ); // Do not display hotkeys @@ -114,23 +119,108 @@ DIALOG_IMPORT_GFX::DIALOG_IMPORT_GFX( PCB_BASE_FRAME* aParent, bool aUseModuleIt DIALOG_IMPORT_GFX::~DIALOG_IMPORT_GFX() { - m_offsetSelection = m_rbOffsetOption->GetSelection(); + updatePcbImportOffsets_mm(); m_layer = m_SelLayerBox->GetLayerSelection(); if( m_config ) { m_config->Write( IMPORT_GFX_LAYER_OPTION_KEY, (long)m_layer ); - m_config->Write( IMPORT_GFX_COORD_ORIGIN_KEY, m_offsetSelection ); + m_config->Write( IMPORT_GFX_PLACEMENT_INTERACTIVE_KEY, m_placementInteractive ); m_config->Write( IMPORT_GFX_LAST_FILE_KEY, m_filename ); - m_config->Write( IMPORT_GFX_GRID_UNITS_KEY, GetPCBGridUnits() ); - m_config->Write( IMPORT_GFX_GRID_OFFSET_X_KEY, m_PCBXCoord->GetValue() ); - m_config->Write( IMPORT_GFX_GRID_OFFSET_Y_KEY, m_PCBYCoord->GetValue() ); + m_config->Write( IMPORT_GFX_POSITION_UNITS_KEY, m_originImportUnits ); + m_config->Write( IMPORT_GFX_POSITION_X_KEY, m_importOrigin.x ); + m_config->Write( IMPORT_GFX_POSITION_Y_KEY, m_importOrigin.y ); + + m_lineWidthImportUnits = getPCBdefaultLineWidthMM(); + m_config->Write( IMPORT_GFX_LINEWIDTH_KEY, m_default_lineWidth ); + m_config->Write( IMPORT_GFX_LINEWIDTH_UNITS_KEY, m_lineWidthImportUnits ); } } -void DIALOG_IMPORT_GFX::OnBrowseFiles( wxCommandEvent& event ) +void DIALOG_IMPORT_GFX::DIALOG_IMPORT_GFX::onUnitPositionSelection( wxCommandEvent& event ) +{ + // Collect last entered values: + updatePcbImportOffsets_mm(); + + m_originImportUnits = m_DxfPcbPositionUnits->GetSelection();; + showPcbImportOffsets(); +} + + +double DIALOG_IMPORT_GFX::getPCBdefaultLineWidthMM() +{ + double value = DoubleValueFromString( UNSCALED_UNITS, m_textCtrlLineWidth->GetValue() ); + + switch( m_lineWidthImportUnits ) + { + default: + case 0: // display units = mm + break; + + case 1: // display units = mil + value *= 25.4 / 1000; + break; + + case 2: // display units = inch + value *= 25.4; + break; + } + + return value; // value is in mm +} + + +void DIALOG_IMPORT_GFX::onUnitWidthSelection( wxCommandEvent& event ) +{ + m_default_lineWidth = getPCBdefaultLineWidthMM(); + + // Switch to new units + m_lineWidthImportUnits = m_choiceUnitLineWidth->GetSelection(); + showPCBdefaultLineWidth(); +} + + +void DIALOG_IMPORT_GFX::showPcbImportOffsets() +{ + // Display m_importOrigin value according to the unit selection: + VECTOR2D offset = m_importOrigin; + + if( m_originImportUnits ) // Units are inches + offset = m_importOrigin / 25.4; + + m_DxfPcbXCoord->SetValue( wxString::Format( "%f", offset.x ) ); + m_DxfPcbYCoord->SetValue( wxString::Format( "%f", offset.y ) ); + +} + + +void DIALOG_IMPORT_GFX::showPCBdefaultLineWidth() +{ + double value; + + switch( m_lineWidthImportUnits ) + { + default: + case 0: // display units = mm + value = m_default_lineWidth; + break; + + case 1: // display units = mil + value = m_default_lineWidth / 25.4 * 1000; + break; + + case 2: // display units = inch + value = m_default_lineWidth / 25.4; + break; + } + + m_textCtrlLineWidth->SetValue( wxString::Format( "%f", value ) ); +} + + +void DIALOG_IMPORT_GFX::onBrowseFiles( wxCommandEvent& event ) { wxString path; wxString filename; @@ -173,155 +263,226 @@ void DIALOG_IMPORT_GFX::OnBrowseFiles( wxCommandEvent& event ) } -void DIALOG_IMPORT_GFX::OnOKClick( wxCommandEvent& event ) +void DIALOG_IMPORT_GFX::onOKClick( wxCommandEvent& event ) { m_filename = m_textCtrlFileName->GetValue(); if( m_filename.IsEmpty() ) - return; - - double offsetX = 0; - double offsetY = 0; - - m_offsetSelection = m_rbOffsetOption->GetSelection(); - - switch( m_offsetSelection ) { - case 0: - offsetX = m_parent->GetPageSizeIU().x * MM_PER_IU / 2; - offsetY = m_parent->GetPageSizeIU().y * MM_PER_IU / 2; - break; - - case 1: - break; - - case 2: - offsetY = m_parent->GetPageSizeIU().y * MM_PER_IU / 2; - break; - - case 3: - offsetY = m_parent->GetPageSizeIU().y * MM_PER_IU; - break; - - case 4: - GetPCBGridOffsets( offsetX, offsetY ); - - if( GetPCBGridUnits() ) - { - offsetX *= 25.4; - offsetY *= 25.4; - } - break; + wxMessageBox( _( "Error: No DXF filename!" ) ); + return; } - // Set coordinates offset for import (offset is given in mm) - //m_importer.SetOffset( offsetX, offsetY ); + updatePcbImportOffsets_mm(); // Update m_importOriginX and m_importOriginY; + m_layer = m_SelLayerBox->GetLayerSelection(); + + if( m_layer < 0 ) + { + wxMessageBox( _( "Please, select a valid layer " ) ); + return; + } + + m_default_lineWidth = getPCBdefaultLineWidthMM(); + m_importer->SetLayer( PCB_LAYER_ID( m_layer ) ); auto plugin = GRAPHICS_IMPORT_MGR::GetPluginByExt( wxFileName( m_filename ).GetExt() ); if( plugin ) { - m_importer->SetScale( 1.0 /*1e6*/ ); // mm -> IU @todo: add a setting in the dialog and apply it here - m_importer->SetLineWidth( 0.1 * 1e6 ); // @todo add a setting in the dialog and apply it here + // Set coordinates offset for import (offset is given in mm) + m_importer->SetImportOffsetMM( m_importOrigin ); + m_scaleImport = DoubleValueFromString( UNSCALED_UNITS, m_textCtrlImportScale->GetValue() ); + + m_importer->SetLineWidthMM( m_default_lineWidth ); m_importer->SetPlugin( std::move( plugin ) ); - if( m_importer->Load( m_filename ) ) - m_importer->Import( 1.0, 1.0 ); // @todo + LOCALE_IO dummy; // Ensure floats can be read. - EndModal( wxID_OK ); + if( m_importer->Load( m_filename ) ) + m_importer->Import( m_scaleImport ); + + // Get warning messages: + const std::string& warnings = m_importer->GetMessages(); + + if( !warnings.empty() ) + wxMessageBox( warnings.c_str(), _( "Not Handled Items" ) ); + + event.Skip(); } else { - DisplayError( this, _( "There is no plugin to handle this file type" ) ); + wxMessageBox( _( "There is no plugin to handle this file type" ) ); } } -void DIALOG_IMPORT_GFX::onChangeHeight( wxUpdateUIEvent &event) -{ - // @todo: implement scaling of Y -#if 0 - double heightInput = DoubleValueFromString(UNSCALED_UNITS,m_tcHeight->GetValue()); - if(m_cbKeepAspectRatio->GetValue()) - { - } -#endif -} - -#if 0 - // Must be reworked (perhaps removed) because this is not used in GAL canvases - // only in legacy canvas. +// Used only in legacy canvas by the board editor. bool InvokeDialogImportGfxBoard( PCB_BASE_FRAME* aCaller ) { DIALOG_IMPORT_GFX dlg( aCaller ); - bool success = ( dlg.ShowModal() == wxID_OK ); - if( success ) + if( dlg.ShowModal() != wxID_OK ) + return false; + + auto& list = dlg.GetImportedItems(); + + // Ensure the list is not empty: + if( list.empty() ) { - PICKED_ITEMS_LIST picklist; - BOARD* board = aCaller->GetBoard(); - auto& items = dlg.GetImportedItems(); - - for( auto it = items.begin(); it != items.end(); ++it ) - { - BOARD_ITEM* item = static_cast( it->release() ); - board->Add( item ); - - ITEM_PICKER itemWrapper( item, UR_NEW ); - picklist.PushItem( itemWrapper ); - } - - aCaller->SaveCopyInUndoList( picklist, UR_NEW, wxPoint( 0, 0 ) ); - aCaller->OnModify(); + wxMessageBox( _( "No graphic items found in file to import") ); + return false; } - return success; + PICKED_ITEMS_LIST picklist; // the pick list for undo command + ITEM_PICKER item_picker( nullptr, UR_NEW ); + BOARD* board = aCaller->GetBoard(); + + // Now prepare a block move command to place the new items, if interactive placement, + // and prepare the undo command. + EDA_RECT bbox; // the new items bounding box, for block move if interactive placement. + bool bboxInit = true; // true until the bounding box is initialized + BLOCK_SELECTOR& blockmove = aCaller->GetScreen()->m_BlockLocate; + + if( dlg.IsPlacementInteractive() ) + aCaller->HandleBlockBegin( NULL, BLOCK_PRESELECT_MOVE, wxPoint( 0, 0) ); + + PICKED_ITEMS_LIST& blockitemsList = blockmove.GetItems(); + + for( auto it = list.begin(); it != list.end(); ++it ) + { + BOARD_ITEM* item = static_cast( it->release() ); + + if( dlg.IsPlacementInteractive() ) + item->SetFlags( IS_MOVED ); + + board->Add( item ); + + item_picker.SetItem( item ); + picklist.PushItem( item_picker ); + + if( dlg.IsPlacementInteractive() ) + { + blockitemsList.PushItem( item_picker ); + + if( bboxInit ) + bbox = item->GetBoundingBox(); + else + bbox.Merge( item->GetBoundingBox() ); + + bboxInit = false; + } + } + + aCaller->SaveCopyInUndoList( picklist, UR_NEW, wxPoint( 0, 0 ) ); + aCaller->OnModify(); + + if( dlg.IsPlacementInteractive() ) + { + // Finish block move command: + wxPoint cpos = aCaller->GetNearestGridPosition( bbox.Centre() ); + blockmove.SetOrigin( bbox.GetOrigin() ); + blockmove.SetSize( bbox.GetSize() ); + blockmove.SetLastCursorPosition( cpos ); + aCaller->HandleBlockEnd( NULL ); + } + + return true; } +// Used only in legacy canvas by the footprint editor. bool InvokeDialogImportGfxModule( PCB_BASE_FRAME* aCaller, MODULE* aModule ) { - wxASSERT( aModule ); + if( !aModule ) + return false; DIALOG_IMPORT_GFX dlg( aCaller, true ); - bool success = ( dlg.ShowModal() == wxID_OK ); - if( success ) + if( dlg.ShowModal() != wxID_OK ) + return false; + + auto& list = dlg.GetImportedItems(); + + // Ensure the list is not empty: + if( list.empty() ) { - aCaller->SaveCopyInUndoList( aModule, UR_CHANGED ); - aCaller->OnModify(); - auto& list = dlg.GetImportedItems(); - - for( auto it = list.begin(); it != list.end(); ++it ) - { - aModule->Add( static_cast( it->release() ) ); - } + wxMessageBox( _( "No graphic items found in file to import") ); + return false; } - return success; -} -#endif + aCaller->SaveCopyInUndoList( aModule, UR_CHANGED ); -void DIALOG_IMPORT_GFX::OriginOptionOnUpdateUI( wxUpdateUIEvent& event ) -{ - bool enable = m_rbOffsetOption->GetSelection() == 4; + PICKED_ITEMS_LIST picklist; // the pick list for undo command + ITEM_PICKER item_picker( nullptr, UR_NEW ); - m_PCBGridUnits->Enable( enable ); - m_PCBXCoord->Enable( enable ); - m_PCBYCoord->Enable( enable ); + // Now prepare a block move command to place the new items, if interactive placement, + // and prepare the undo command. + EDA_RECT bbox; // the new items bounding box, for block move if interactive placement. + bool bboxInit = true; // true until the bounding box is initialized + BLOCK_SELECTOR& blockmove = aCaller->GetScreen()->m_BlockLocate; + + if( dlg.IsPlacementInteractive() ) + aCaller->HandleBlockBegin( nullptr, BLOCK_PRESELECT_MOVE, wxPoint( 0, 0) ); + + PICKED_ITEMS_LIST& blockitemsList = blockmove.GetItems(); + + for( auto it = list.begin(); it != list.end(); ++it ) + { + BOARD_ITEM* item = static_cast( it->release() ); + aModule->Add( item ); + + if( dlg.IsPlacementInteractive() ) + { + item->SetFlags( IS_MOVED ); + item_picker.SetItem( item ); + blockitemsList.PushItem( item_picker ); + + if( bboxInit ) + bbox = item->GetBoundingBox(); + else + bbox.Merge( item->GetBoundingBox() ); + + bboxInit = false; + } + } + + aCaller->OnModify(); + + if( dlg.IsPlacementInteractive() ) + { + // Finish block move command: + wxPoint cpos = aCaller->GetNearestGridPosition( bbox.Centre() ); + blockmove.SetOrigin( bbox.GetOrigin() ); + blockmove.SetSize( bbox.GetSize() ); + blockmove.SetLastCursorPosition( cpos ); + aCaller->HandleBlockEnd( NULL ); + } + + return true; } -int DIALOG_IMPORT_GFX::GetPCBGridUnits( void ) +void DIALOG_IMPORT_GFX::originOptionOnUpdateUI( wxUpdateUIEvent& event ) { - return m_PCBGridUnits->GetSelection(); + m_rbInteractivePlacement->SetValue( m_placementInteractive ); + m_rbAbsolutePlacement->SetValue( not m_placementInteractive ); + + m_DxfPcbPositionUnits->Enable( not m_placementInteractive ); + m_DxfPcbXCoord->Enable( not m_placementInteractive ); + m_DxfPcbYCoord->Enable( not m_placementInteractive ); } -void DIALOG_IMPORT_GFX::GetPCBGridOffsets( double &aXOffset, double &aYOffset ) +void DIALOG_IMPORT_GFX::updatePcbImportOffsets_mm() { - aXOffset = DoubleValueFromString( UNSCALED_UNITS, m_PCBXCoord->GetValue() ); - aYOffset = DoubleValueFromString( UNSCALED_UNITS, m_PCBYCoord->GetValue() ); + m_importOrigin.x = DoubleValueFromString( UNSCALED_UNITS, m_DxfPcbXCoord->GetValue() ); + m_importOrigin.y = DoubleValueFromString( UNSCALED_UNITS, m_DxfPcbYCoord->GetValue() ); + + if( m_originImportUnits ) // Units are inches + { + m_importOrigin = m_importOrigin * 25.4; + } + return; } diff --git a/pcbnew/import_gfx/dialog_import_gfx.h b/pcbnew/import_gfx/dialog_import_gfx.h index 1b70b04d6d..77bc3f4248 100644 --- a/pcbnew/import_gfx/dialog_import_gfx.h +++ b/pcbnew/import_gfx/dialog_import_gfx.h @@ -22,47 +22,68 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +#include #include "dialog_import_gfx_base.h" #include -class PCB_BASE_FRAME; - class DIALOG_IMPORT_GFX : public DIALOG_IMPORT_GFX_BASE { public: DIALOG_IMPORT_GFX( PCB_BASE_FRAME* aParent, bool aUseModuleItems = false ); ~DIALOG_IMPORT_GFX(); + /** * Function GetImportedItems() - * - * Returns a list of items imported from a vector graphics file. + * @return a list of items imported from a vector graphics file. */ std::list>& GetImportedItems() { return m_importer->GetItems(); } + /** @return true if the placement is interactive, i.e. all imported + * items must be moved by the mouse cursor to the final position + * false means the imported items are placed to the final position after import. + */ + bool IsPlacementInteractive() + { + return m_placementInteractive; + } + private: PCB_BASE_FRAME* m_parent; - wxConfigBase* m_config; // Current config + wxConfigBase* m_config; // Current config std::unique_ptr m_importer; - int m_gridUnits; - double m_gridOffsetX; - double m_gridOffsetY; - double m_newHeight; - double m_newWidth; + int m_originImportUnits; + VECTOR2D m_importOrigin; // This is the offset to add to imported coordinates + // Always in mm static wxString m_filename; - static int m_offsetSelection; + static bool m_placementInteractive; static LAYER_NUM m_layer; + double m_default_lineWidth; // always in mm: line width when a line width is not specified + int m_lineWidthImportUnits; + static double m_scaleImport; // a scale factor to change the size of imported items + // m_scaleImport =1.0 means keep original size // Virtual event handlers - void OnCancelClick( wxCommandEvent& event ) override { event.Skip(); } - void OnOKClick( wxCommandEvent& event ) override; - void OnBrowseFiles( wxCommandEvent& event ) override; - void OriginOptionOnUpdateUI( wxUpdateUIEvent& event ) override; - void onChangeHeight( wxUpdateUIEvent& event ) override; - int GetPCBGridUnits( void ); - void GetPCBGridOffsets( double &aXOffset, double &aYOffset ); + void onOKClick( wxCommandEvent& event ) override; + void onUnitPositionSelection( wxCommandEvent& event ) override; + void onUnitWidthSelection( wxCommandEvent& event ) override; + void onBrowseFiles( wxCommandEvent& event ) override; + void originOptionOnUpdateUI( wxUpdateUIEvent& event ) override; + void onInteractivePlacement( wxCommandEvent& event ) override + { + m_placementInteractive = true; + } + void onAbsolutePlacement( wxCommandEvent& event ) override + { + m_placementInteractive = false; + } + + void updatePcbImportOffsets_mm(); + double getPCBdefaultLineWidthMM(); + void showPCBdefaultLineWidth(); + void showPcbImportOffsets(); }; diff --git a/pcbnew/import_gfx/dialog_import_gfx_base.cpp b/pcbnew/import_gfx/dialog_import_gfx_base.cpp index 20c3b15131..d818fdc5b2 100644 --- a/pcbnew/import_gfx/dialog_import_gfx_base.cpp +++ b/pcbnew/import_gfx/dialog_import_gfx_base.cpp @@ -21,9 +21,9 @@ DIALOG_IMPORT_GFX_BASE::DIALOG_IMPORT_GFX_BASE( wxWindow* parent, wxWindowID id, wxBoxSizer* bSizerFile; bSizerFile = new wxBoxSizer( wxHORIZONTAL ); - m_staticText37 = new wxStaticText( this, wxID_ANY, _("File:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText37->Wrap( -1 ); - bSizerFile->Add( m_staticText37, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + m_staticTextFile = new wxStaticText( this, wxID_ANY, _("File:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextFile->Wrap( -1 ); + bSizerFile->Add( m_staticTextFile, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); m_textCtrlFileName = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); m_textCtrlFileName->SetMinSize( wxSize( 300,-1 ) ); @@ -36,122 +36,163 @@ DIALOG_IMPORT_GFX_BASE::DIALOG_IMPORT_GFX_BASE( wxWindow* parent, wxWindowID id, bSizerMain->Add( bSizerFile, 0, wxALL|wxEXPAND, 5 ); - wxBoxSizer* bSizer10; - bSizer10 = new wxBoxSizer( wxVERTICAL ); + m_staticline2 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); + bSizerMain->Add( m_staticline2, 0, wxEXPAND | wxALL, 5 ); - wxBoxSizer* bSizer5; - bSizer5 = new wxBoxSizer( wxHORIZONTAL ); + wxBoxSizer* bSizerPlacement; + bSizerPlacement = new wxBoxSizer( wxVERTICAL ); - m_staticText3 = new wxStaticText( this, wxID_ANY, _("Units:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText3->Wrap( -1 ); - bSizer5->Add( m_staticText3, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + m_staticTextPlacement = new wxStaticText( this, wxID_ANY, _("Placement:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextPlacement->Wrap( -1 ); + m_staticTextPlacement->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false, wxEmptyString ) ); - wxString m_PCBGridUnitsChoices[] = { _("mm"), _("inch") }; - int m_PCBGridUnitsNChoices = sizeof( m_PCBGridUnitsChoices ) / sizeof( wxString ); - m_PCBGridUnits = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_PCBGridUnitsNChoices, m_PCBGridUnitsChoices, 0 ); - m_PCBGridUnits->SetSelection( 0 ); - m_PCBGridUnits->SetToolTip( _("Select PCB grid units") ); + bSizerPlacement->Add( m_staticTextPlacement, 0, wxALL, 5 ); - bSizer5->Add( m_PCBGridUnits, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + wxBoxSizer* bSizerOptions; + bSizerOptions = new wxBoxSizer( wxVERTICAL ); + m_rbInteractivePlacement = new wxRadioButton( this, wxID_ANY, _("Interactive placement"), wxDefaultPosition, wxDefaultSize, wxRB_SINGLE ); + m_rbInteractivePlacement->SetValue( true ); + bSizerOptions->Add( m_rbInteractivePlacement, 0, wxALL, 5 ); - bSizer10->Add( bSizer5, 0, wxALL|wxEXPAND, 5 ); + wxBoxSizer* bSizerUserPos; + bSizerUserPos = new wxBoxSizer( wxHORIZONTAL ); - wxBoxSizer* bSizer3; - bSizer3 = new wxBoxSizer( wxHORIZONTAL ); + m_rbAbsolutePlacement = new wxRadioButton( this, wxID_ANY, _("At"), wxDefaultPosition, wxDefaultSize, wxRB_SINGLE ); + bSizerUserPos->Add( m_rbAbsolutePlacement, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - wxString m_rbOffsetOptionChoices[] = { _("Center of page"), _("Upper left corner of page"), _("Center left side of page"), _("Lower left corner of page"), _("User defined position") }; - int m_rbOffsetOptionNChoices = sizeof( m_rbOffsetOptionChoices ) / sizeof( wxString ); - m_rbOffsetOption = new wxRadioBox( this, wxID_ORIGIN_SELECT, _("Place origin (0,0) point:"), wxDefaultPosition, wxDefaultSize, m_rbOffsetOptionNChoices, m_rbOffsetOptionChoices, 1, wxRA_SPECIFY_COLS ); - m_rbOffsetOption->SetSelection( 0 ); - bSizer3->Add( m_rbOffsetOption, 0, wxALL|wxEXPAND, 5 ); + wxBoxSizer* bSizerPosSettings; + bSizerPosSettings = new wxBoxSizer( wxHORIZONTAL ); - wxBoxSizer* bSizer4; - bSizer4 = new wxBoxSizer( wxVERTICAL ); + m_staticTextXpos = new wxStaticText( this, wxID_ANY, _("X:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextXpos->Wrap( -1 ); + bSizerPosSettings->Add( m_staticTextXpos, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 ); - wxBoxSizer* bSizer6; - bSizer6 = new wxBoxSizer( wxHORIZONTAL ); - - m_staticText4 = new wxStaticText( this, wxID_ANY, _("X Position:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText4->Wrap( -1 ); - bSizer6->Add( m_staticText4, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); - - m_PCBXCoord = new wxTextCtrl( this, wxID_ANY, _("0.0"), wxDefaultPosition, wxDefaultSize, 0 ); + m_DxfPcbXCoord = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); #ifdef __WXGTK__ - if ( !m_PCBXCoord->HasFlag( wxTE_MULTILINE ) ) + if ( !m_DxfPcbXCoord->HasFlag( wxTE_MULTILINE ) ) { - m_PCBXCoord->SetMaxLength( 10 ); + m_DxfPcbXCoord->SetMaxLength( 10 ); } #else - m_PCBXCoord->SetMaxLength( 10 ); + m_DxfPcbXCoord->SetMaxLength( 10 ); #endif - m_PCBXCoord->SetToolTip( _("DXF origin on PCB Grid, X Coordinate") ); + m_DxfPcbXCoord->SetToolTip( _("DXF origin on PCB Grid, X Coordinate") ); - bSizer6->Add( m_PCBXCoord, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + bSizerPosSettings->Add( m_DxfPcbXCoord, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + m_staticTextYpos = new wxStaticText( this, wxID_ANY, _("Y:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextYpos->Wrap( -1 ); + bSizerPosSettings->Add( m_staticTextYpos, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT, 5 ); + + m_DxfPcbYCoord = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + #ifdef __WXGTK__ + if ( !m_DxfPcbYCoord->HasFlag( wxTE_MULTILINE ) ) + { + m_DxfPcbYCoord->SetMaxLength( 10 ); + } + #else + m_DxfPcbYCoord->SetMaxLength( 10 ); + #endif + m_DxfPcbYCoord->SetToolTip( _("DXF origin on PCB Grid, Y Coordinate") ); + + bSizerPosSettings->Add( m_DxfPcbYCoord, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + m_staticTextUnits = new wxStaticText( this, wxID_ANY, _("Units:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextUnits->Wrap( -1 ); + bSizerPosSettings->Add( m_staticTextUnits, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxString m_DxfPcbPositionUnitsChoices[] = { _("mm"), _("inch") }; + int m_DxfPcbPositionUnitsNChoices = sizeof( m_DxfPcbPositionUnitsChoices ) / sizeof( wxString ); + m_DxfPcbPositionUnits = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_DxfPcbPositionUnitsNChoices, m_DxfPcbPositionUnitsChoices, 0 ); + m_DxfPcbPositionUnits->SetSelection( 0 ); + m_DxfPcbPositionUnits->SetToolTip( _("Select PCB grid units") ); + + bSizerPosSettings->Add( m_DxfPcbPositionUnits, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxRIGHT, 5 ); - bSizer4->Add( bSizer6, 1, wxEXPAND, 5 ); + bSizerUserPos->Add( bSizerPosSettings, 1, wxEXPAND|wxTOP|wxBOTTOM, 5 ); + + + bSizerOptions->Add( bSizerUserPos, 0, wxEXPAND, 5 ); + + + bSizerPlacement->Add( bSizerOptions, 1, wxEXPAND|wxLEFT, 20 ); + + + bSizerMain->Add( bSizerPlacement, 1, wxEXPAND, 5 ); + + m_staticline3 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); + bSizerMain->Add( m_staticline3, 0, wxEXPAND | wxALL, 5 ); + + wxBoxSizer* bSizerLayer; + bSizerLayer = new wxBoxSizer( wxVERTICAL ); + + m_staticTextPrms = new wxStaticText( this, wxID_ANY, _("Import parameters:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextPrms->Wrap( -1 ); + m_staticTextPrms->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false, wxEmptyString ) ); + + bSizerLayer->Add( m_staticTextPrms, 0, wxALL, 5 ); wxBoxSizer* bSizer7; bSizer7 = new wxBoxSizer( wxHORIZONTAL ); - m_staticText5 = new wxStaticText( this, wxID_ANY, _("Y Position:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText5->Wrap( -1 ); - bSizer7->Add( m_staticText5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); - m_PCBYCoord = new wxTextCtrl( this, wxID_ANY, _("0.0"), wxDefaultPosition, wxDefaultSize, 0 ); - #ifdef __WXGTK__ - if ( !m_PCBYCoord->HasFlag( wxTE_MULTILINE ) ) - { - m_PCBYCoord->SetMaxLength( 10 ); - } - #else - m_PCBYCoord->SetMaxLength( 10 ); - #endif - m_PCBYCoord->SetToolTip( _("DXF origin on PCB Grid, Y Coordinate") ); + bSizer7->Add( 0, 0, 0, wxRIGHT|wxLEFT, 10 ); - bSizer7->Add( m_PCBYCoord, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + wxFlexGridSizer* fgSizerImportSettings; + fgSizerImportSettings = new wxFlexGridSizer( 0, 3, 0, 0 ); + fgSizerImportSettings->AddGrowableCol( 1 ); + fgSizerImportSettings->SetFlexibleDirection( wxBOTH ); + fgSizerImportSettings->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + m_staticTextLineWidth = new wxStaticText( this, wxID_ANY, _("Line width (DXF import):"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextLineWidth->Wrap( -1 ); + fgSizerImportSettings->Add( m_staticTextLineWidth, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - bSizer4->Add( bSizer7, 1, wxEXPAND, 5 ); + m_textCtrlLineWidth = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + fgSizerImportSettings->Add( m_textCtrlLineWidth, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - wxBoxSizer* bSizer11; - bSizer11 = new wxBoxSizer( wxHORIZONTAL ); + wxString m_choiceUnitLineWidthChoices[] = { _("mm"), _("mils"), _("inches") }; + int m_choiceUnitLineWidthNChoices = sizeof( m_choiceUnitLineWidthChoices ) / sizeof( wxString ); + m_choiceUnitLineWidth = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceUnitLineWidthNChoices, m_choiceUnitLineWidthChoices, 0 ); + m_choiceUnitLineWidth->SetSelection( 0 ); + fgSizerImportSettings->Add( m_choiceUnitLineWidth, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - m_staticTextScale = new wxStaticText( this, wxID_ANY, _("Scale:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticTextScale->Wrap( -1 ); - bSizer11->Add( m_staticTextScale, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); - - m_tcScale = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - bSizer11->Add( m_tcScale, 0, wxALIGN_CENTER_VERTICAL, 5 ); - - - bSizer4->Add( bSizer11, 0, wxALL|wxEXPAND, 5 ); - - - bSizer3->Add( bSizer4, 1, wxALIGN_CENTER_VERTICAL, 5 ); - - - bSizer10->Add( bSizer3, 0, wxALL|wxEXPAND, 5 ); - - - bSizerMain->Add( bSizer10, 1, wxALL|wxEXPAND, 5 ); - - wxBoxSizer* bSizer8; - bSizer8 = new wxBoxSizer( wxHORIZONTAL ); - - m_staticTextBrdlayer = new wxStaticText( this, wxID_ANY, _("Layer:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextBrdlayer = new wxStaticText( this, wxID_ANY, _("Graphic layer:"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTextBrdlayer->Wrap( -1 ); - bSizer8->Add( m_staticTextBrdlayer, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxTOP, 5 ); + fgSizerImportSettings->Add( m_staticTextBrdlayer, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxTOP, 5 ); m_SelLayerBox = new PCB_LAYER_BOX_SELECTOR( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 ); - bSizer8->Add( m_SelLayerBox, 1, wxALL|wxEXPAND, 5 ); + fgSizerImportSettings->Add( m_SelLayerBox, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5 ); - bSizerMain->Add( bSizer8, 0, wxALL|wxEXPAND, 5 ); + fgSizerImportSettings->Add( 0, 0, 0, 0, 5 ); - m_staticline8 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); - bSizerMain->Add( m_staticline8, 0, wxALL|wxEXPAND, 5 ); + m_staticTextscale = new wxStaticText( this, wxID_ANY, _("Import scale:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextscale->Wrap( -1 ); + fgSizerImportSettings->Add( m_staticTextscale, 0, wxALL, 5 ); + + m_textCtrlImportScale = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + fgSizerImportSettings->Add( m_textCtrlImportScale, 0, wxALL|wxEXPAND, 5 ); + + + fgSizerImportSettings->Add( 0, 0, 0, 0, 5 ); + + + bSizer7->Add( fgSizerImportSettings, 1, wxEXPAND, 5 ); + + + bSizerLayer->Add( bSizer7, 1, wxEXPAND, 5 ); + + + bSizerMain->Add( bSizerLayer, 0, wxALL|wxEXPAND, 5 ); + + + bSizerMain->Add( 0, 0, 1, wxEXPAND, 5 ); + + m_staticline = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); + bSizerMain->Add( m_staticline, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 ); m_sdbSizer = new wxStdDialogButtonSizer(); m_sdbSizerOK = new wxButton( this, wxID_OK ); @@ -160,30 +201,35 @@ DIALOG_IMPORT_GFX_BASE::DIALOG_IMPORT_GFX_BASE( wxWindow* parent, wxWindowID id, m_sdbSizer->AddButton( m_sdbSizerCancel ); m_sdbSizer->Realize(); - bSizerMain->Add( m_sdbSizer, 0, wxALIGN_RIGHT|wxBOTTOM|wxLEFT|wxRIGHT, 5 ); + bSizerMain->Add( m_sdbSizer, 0, wxEXPAND|wxALL, 5 ); this->SetSizer( bSizerMain ); this->Layout(); - bSizerMain->Fit( this ); this->Centre( wxBOTH ); // Connect Events - m_buttonBrowse->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_IMPORT_GFX_BASE::OnBrowseFiles ), NULL, this ); - m_rbOffsetOption->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_IMPORT_GFX_BASE::OriginOptionOnUpdateUI ), NULL, this ); - m_tcScale->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_IMPORT_GFX_BASE::onChangeHeight ), NULL, this ); - m_sdbSizerCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_IMPORT_GFX_BASE::OnCancelClick ), NULL, this ); - m_sdbSizerOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_IMPORT_GFX_BASE::OnOKClick ), NULL, this ); + m_buttonBrowse->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_IMPORT_GFX_BASE::onBrowseFiles ), NULL, this ); + m_rbInteractivePlacement->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_IMPORT_GFX_BASE::onInteractivePlacement ), NULL, this ); + m_rbInteractivePlacement->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_IMPORT_GFX_BASE::originOptionOnUpdateUI ), NULL, this ); + m_rbAbsolutePlacement->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_IMPORT_GFX_BASE::onAbsolutePlacement ), NULL, this ); + m_rbAbsolutePlacement->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_IMPORT_GFX_BASE::originOptionOnUpdateUI ), NULL, this ); + m_DxfPcbPositionUnits->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_IMPORT_GFX_BASE::onUnitPositionSelection ), NULL, this ); + m_choiceUnitLineWidth->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_IMPORT_GFX_BASE::onUnitWidthSelection ), NULL, this ); + m_sdbSizerOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_IMPORT_GFX_BASE::onOKClick ), NULL, this ); } DIALOG_IMPORT_GFX_BASE::~DIALOG_IMPORT_GFX_BASE() { // Disconnect Events - m_buttonBrowse->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_IMPORT_GFX_BASE::OnBrowseFiles ), NULL, this ); - m_rbOffsetOption->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_IMPORT_GFX_BASE::OriginOptionOnUpdateUI ), NULL, this ); - m_tcScale->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_IMPORT_GFX_BASE::onChangeHeight ), NULL, this ); - m_sdbSizerCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_IMPORT_GFX_BASE::OnCancelClick ), NULL, this ); - m_sdbSizerOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_IMPORT_GFX_BASE::OnOKClick ), NULL, this ); + m_buttonBrowse->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_IMPORT_GFX_BASE::onBrowseFiles ), NULL, this ); + m_rbInteractivePlacement->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_IMPORT_GFX_BASE::onInteractivePlacement ), NULL, this ); + m_rbInteractivePlacement->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_IMPORT_GFX_BASE::originOptionOnUpdateUI ), NULL, this ); + m_rbAbsolutePlacement->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_IMPORT_GFX_BASE::onAbsolutePlacement ), NULL, this ); + m_rbAbsolutePlacement->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_IMPORT_GFX_BASE::originOptionOnUpdateUI ), NULL, this ); + m_DxfPcbPositionUnits->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_IMPORT_GFX_BASE::onUnitPositionSelection ), NULL, this ); + m_choiceUnitLineWidth->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_IMPORT_GFX_BASE::onUnitWidthSelection ), NULL, this ); + m_sdbSizerOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_IMPORT_GFX_BASE::onOKClick ), NULL, this ); } diff --git a/pcbnew/import_gfx/dialog_import_gfx_base.fbp b/pcbnew/import_gfx/dialog_import_gfx_base.fbp index 4c9a366e34..9b4c4fe943 100644 --- a/pcbnew/import_gfx/dialog_import_gfx_base.fbp +++ b/pcbnew/import_gfx/dialog_import_gfx_base.fbp @@ -16,7 +16,7 @@ none 1 - dialog_import_gfx + dialog_dxf_import . @@ -45,7 +45,7 @@ DIALOG_IMPORT_GFX_BASE - -1,-1 + 476,373 wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER DIALOG_SHIM; dialog_shim.h Import vector graphics file @@ -111,16 +111,16 @@ 5 wxALL|wxEXPAND 0 - + bSizerFile wxHORIZONTAL none - + 5 wxALIGN_CENTER_VERTICAL|wxALL 0 - + 1 1 1 @@ -157,7 +157,7 @@ 0 1 - m_staticText37 + m_staticTextFile 1 @@ -207,11 +207,11 @@ - + 5 wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxTOP 1 - + 1 1 1 @@ -305,11 +305,11 @@ - + 5 wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxTOP 0 - + 1 1 1 @@ -381,7 +381,7 @@ - OnBrowseFiles + onBrowseFiles @@ -412,224 +412,206 @@ 5 - wxALL|wxEXPAND + wxEXPAND | wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_staticline2 + 1 + + + protected + 1 + + Resizable + 1 + + wxLI_HORIZONTAL + ; forward_declare + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND 1 - bSizer10 + bSizerPlacement wxVERTICAL none 5 - wxALL|wxEXPAND + wxALL 0 - + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + ,90,92,-1,70,0 + 0 + 0 + wxID_ANY + Placement: + 0 + + 0 + + + 0 - bSizer5 - wxHORIZONTAL - none - - 5 - wxALIGN_CENTER_VERTICAL|wxALL - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Units: - 0 - - 0 - - - 0 - - 1 - m_staticText3 - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxALL - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - "mm" "inch" - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - - 0 - - 1 - m_PCBGridUnits - 1 - - - protected - 1 - - Resizable - 0 - 1 - - - - 0 - Select PCB grid units - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + 1 + m_staticTextPlacement + 1 + + + protected + 1 + + Resizable + 1 + + + ; forward_declare + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - 5 - wxALL|wxEXPAND - 0 + 20 + wxEXPAND|wxLEFT + 1 - bSizer3 - wxHORIZONTAL + bSizerOptions + wxVERTICAL none - + 5 - wxALL|wxEXPAND + wxALL 0 - + 1 1 1 @@ -643,7 +625,6 @@ 1 0 - "Center of page" "Upper left corner of page" "Center left side of page" "Lower left corner of page" "User defined position" 1 1 @@ -657,9 +638,8 @@ 0 0 - wxID_ORIGIN_SELECT - Place origin (0,0) point: - 1 + wxID_ANY + Interactive placement 0 @@ -667,7 +647,7 @@ 0 1 - m_rbOffsetOption + m_rbInteractivePlacement 1 @@ -675,17 +655,17 @@ 1 Resizable - 0 1 - wxRA_SPECIFY_COLS - + wxRB_SINGLE + ; forward_declare 0 wxFILTER_NONE wxDefaultValidator + 1 @@ -713,36 +693,131 @@ - + onInteractivePlacement - OriginOptionOnUpdateUI + originOptionOnUpdateUI 5 - wxALIGN_CENTER_VERTICAL - 1 + wxEXPAND + 0 - bSizer4 - wxVERTICAL + bSizerUserPos + wxHORIZONTAL none - + 5 - wxEXPAND - 1 - + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + At + + 0 + + + 0 - bSizer6 + 1 + m_rbAbsolutePlacement + 1 + + + protected + 1 + + Resizable + 1 + + wxRB_SINGLE + ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + onAbsolutePlacement + + + + + + originOptionOnUpdateUI + + + + 5 + wxEXPAND|wxTOP|wxBOTTOM + 1 + + + bSizerPosSettings wxHORIZONTAL none 5 - wxALIGN_CENTER_VERTICAL|wxALL + wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT 0 1 @@ -772,7 +847,7 @@ 0 0 wxID_ANY - X Position: + X: 0 0 @@ -781,7 +856,7 @@ 0 1 - m_staticText4 + m_staticTextXpos 1 @@ -834,7 +909,7 @@ 5 wxALIGN_CENTER_VERTICAL|wxALL - 0 + 1 1 1 @@ -871,7 +946,7 @@ 0 1 - m_PCBXCoord + m_DxfPcbXCoord 1 @@ -889,406 +964,6 @@ wxFILTER_NUMERIC wxTextValidator - 0.0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxEXPAND - 1 - - - bSizer7 - wxHORIZONTAL - none - - 5 - wxALIGN_CENTER_VERTICAL|wxALL - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Y Position: - 0 - - 0 - - - 0 - - 1 - m_staticText5 - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxALL - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - 10 - - 0 - - 1 - m_PCBYCoord - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - DXF origin on PCB Grid, Y Coordinate - - wxFILTER_NUMERIC - wxTextValidator - - 0.0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND - 0 - - - bSizer11 - wxHORIZONTAL - none - - 5 - wxALIGN_CENTER_VERTICAL|wxALL - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Scale: - 0 - - 0 - - - 0 - - 1 - m_staticTextScale - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL - 0 - - 1 - 1 - 1 - 1 - - - - - - - Set imported image height in PCB - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - - - 0 - - 1 - m_tcScale - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - wxFILTER_NUMERIC - wxTextValidator - @@ -1326,7 +1001,382 @@ - onChangeHeight + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Y: + 0 + + 0 + + + 0 + + 1 + m_staticTextYpos + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + 10 + + 0 + + 1 + m_DxfPcbYCoord + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + DXF origin on PCB Grid, Y Coordinate + + wxFILTER_NUMERIC + wxTextValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Units: + 0 + + 0 + + + 0 + + 1 + m_staticTextUnits + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxRIGHT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + "mm" "inch" + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_DxfPcbPositionUnits + 1 + + + protected + 1 + + Resizable + 0 + 1 + + + + 0 + Select PCB grid units + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + onUnitPositionSelection + + + + + + + + + + + + + + + + + + + + + + @@ -1337,20 +1387,108 @@ + + 5 + wxEXPAND | wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_staticline3 + 1 + + + protected + 1 + + Resizable + 1 + + wxLI_HORIZONTAL + ; forward_declare + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 wxALL|wxEXPAND 0 - bSizer8 - wxHORIZONTAL + bSizerLayer + wxVERTICAL none - + 5 - wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxTOP + wxALL 0 - + 1 1 1 @@ -1374,11 +1512,11 @@ 1 1 - + ,90,92,-1,70,0 0 0 wxID_ANY - Layer: + Import parameters: 0 0 @@ -1387,7 +1525,7 @@ 0 1 - m_staticTextBrdlayer + m_staticTextPrms 1 @@ -1437,111 +1575,744 @@ - + 5 - wxALL|wxEXPAND + wxEXPAND 1 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - - 0 + - 1 - m_SelLayerBox - 1 - - - protected - 1 - - Resizable - -1 - 1 - - - PCB_LAYER_BOX_SELECTOR; pcb_layer_box_selector.h; forward_declare - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + bSizer7 + wxHORIZONTAL + none + + 10 + wxRIGHT|wxLEFT + 0 + + 0 + protected + 0 + + + + 5 + wxEXPAND + 1 + + 3 + wxBOTH + 1 + + 0 + + fgSizerImportSettings + wxFLEX_GROWMODE_SPECIFIED + none + 0 + 0 + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Line width (DXF import): + 0 + + 0 + + + 0 + + 1 + m_staticTextLineWidth + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + + 0 + + 1 + m_textCtrlLineWidth + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + "mm" "mils" "inches" + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_choiceUnitLineWidth + 1 + + + protected + 1 + + Resizable + 0 + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + onUnitWidthSelection + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxTOP + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Graphic layer: + 0 + + 0 + + + 0 + + 1 + m_staticTextBrdlayer + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_SelLayerBox + 1 + + + protected + 1 + + Resizable + -1 + 1 + + + PCB_LAYER_BOX_SELECTOR; pcb_layer_box_selector.h + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + + 0 + + 0 + protected + 0 + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Import scale: + 0 + + 0 + + + 0 + + 1 + m_staticTextscale + 1 + + + protected + 1 + + Resizable + 1 + + + ; forward_declare + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + + 0 + + 1 + m_textCtrlImportScale + 1 + + + protected + 1 + + Resizable + 1 + + + ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + + 0 + + 0 + protected + 0 + + + + - + 5 - wxALL|wxEXPAND + wxEXPAND + 1 + + 0 + protected + 0 + + + + 5 + wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT 0 - + 1 1 1 @@ -1576,7 +2347,7 @@ 0 1 - m_staticline8 + m_staticline 1 @@ -1625,11 +2396,11 @@ - + 5 - wxALIGN_RIGHT|wxBOTTOM|wxLEFT|wxRIGHT + wxEXPAND|wxALL 0 - + 0 1 0 @@ -1642,11 +2413,11 @@ m_sdbSizer protected - OnCancelClick + - OnOKClick + onOKClick diff --git a/pcbnew/import_gfx/dialog_import_gfx_base.h b/pcbnew/import_gfx/dialog_import_gfx_base.h index 9a35fe33df..27a98bba9f 100644 --- a/pcbnew/import_gfx/dialog_import_gfx_base.h +++ b/pcbnew/import_gfx/dialog_import_gfx_base.h @@ -26,16 +26,15 @@ class PCB_LAYER_BOX_SELECTOR; #include #include #include -#include -#include -#include -#include #include +#include +#include +#include +#include #include /////////////////////////////////////////////////////////////////////////// -#define wxID_ORIGIN_SELECT 1000 /////////////////////////////////////////////////////////////////////////////// /// Class DIALOG_IMPORT_GFX_BASE @@ -45,36 +44,46 @@ class DIALOG_IMPORT_GFX_BASE : public DIALOG_SHIM private: protected: - wxStaticText* m_staticText37; + wxStaticText* m_staticTextFile; wxTextCtrl* m_textCtrlFileName; wxButton* m_buttonBrowse; - wxStaticText* m_staticText3; - wxChoice* m_PCBGridUnits; - wxRadioBox* m_rbOffsetOption; - wxStaticText* m_staticText4; - wxTextCtrl* m_PCBXCoord; - wxStaticText* m_staticText5; - wxTextCtrl* m_PCBYCoord; - wxStaticText* m_staticTextScale; - wxTextCtrl* m_tcScale; + wxStaticLine* m_staticline2; + wxStaticText* m_staticTextPlacement; + wxRadioButton* m_rbInteractivePlacement; + wxRadioButton* m_rbAbsolutePlacement; + wxStaticText* m_staticTextXpos; + wxTextCtrl* m_DxfPcbXCoord; + wxStaticText* m_staticTextYpos; + wxTextCtrl* m_DxfPcbYCoord; + wxStaticText* m_staticTextUnits; + wxChoice* m_DxfPcbPositionUnits; + wxStaticLine* m_staticline3; + wxStaticText* m_staticTextPrms; + wxStaticText* m_staticTextLineWidth; + wxTextCtrl* m_textCtrlLineWidth; + wxChoice* m_choiceUnitLineWidth; wxStaticText* m_staticTextBrdlayer; PCB_LAYER_BOX_SELECTOR* m_SelLayerBox; - wxStaticLine* m_staticline8; + wxStaticText* m_staticTextscale; + wxTextCtrl* m_textCtrlImportScale; + wxStaticLine* m_staticline; wxStdDialogButtonSizer* m_sdbSizer; wxButton* m_sdbSizerOK; wxButton* m_sdbSizerCancel; // Virtual event handlers, overide them in your derived class - virtual void OnBrowseFiles( wxCommandEvent& event ) { event.Skip(); } - virtual void OriginOptionOnUpdateUI( wxUpdateUIEvent& event ) { event.Skip(); } - virtual void onChangeHeight( wxUpdateUIEvent& event ) { event.Skip(); } - virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); } - virtual void OnOKClick( wxCommandEvent& event ) { event.Skip(); } + virtual void onBrowseFiles( wxCommandEvent& event ) { event.Skip(); } + virtual void onInteractivePlacement( wxCommandEvent& event ) { event.Skip(); } + virtual void originOptionOnUpdateUI( wxUpdateUIEvent& event ) { event.Skip(); } + virtual void onAbsolutePlacement( wxCommandEvent& event ) { event.Skip(); } + virtual void onUnitPositionSelection( wxCommandEvent& event ) { event.Skip(); } + virtual void onUnitWidthSelection( wxCommandEvent& event ) { event.Skip(); } + virtual void onOKClick( wxCommandEvent& event ) { event.Skip(); } public: - DIALOG_IMPORT_GFX_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Import vector graphics file"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + DIALOG_IMPORT_GFX_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Import vector graphics file"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 476,373 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); ~DIALOG_IMPORT_GFX_BASE(); }; diff --git a/pcbnew/import_gfx/dxf_import_plugin.cpp b/pcbnew/import_gfx/dxf_import_plugin.cpp index 83962815f5..3badead7ac 100644 --- a/pcbnew/import_gfx/dxf_import_plugin.cpp +++ b/pcbnew/import_gfx/dxf_import_plugin.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr - * Copyright (C) 1992-2018 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2018 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 @@ -42,10 +42,20 @@ #include #include "common.h" + +/* + * Important note: all DXF coordinates and sizes are converted to mm. + * they will be converted to internal units later. + */ + + // minimum bulge value before resorting to a line segment; // the value 0.0218 is equivalent to about 5 degrees arc, #define MIN_BULGE 0.0218 +//#define SCALE_FACTOR(x) millimeter2iu(x) /* no longer used */ +#define SCALE_FACTOR(x) (x) + DXF_IMPORT_PLUGIN::DXF_IMPORT_PLUGIN() : DL_CreationAdapter() { m_xOffset = 0.0; // X coord offset for conversion (in mm) @@ -55,10 +65,8 @@ DXF_IMPORT_PLUGIN::DXF_IMPORT_PLUGIN() : DL_CreationAdapter() m_defaultThickness = 0.2; // default thickness (in mm) m_brdLayer = Dwgs_User; // The default import layer m_importAsfootprintGraphicItems = true; - m_minX = std::numeric_limits::max(); - m_maxX = std::numeric_limits::min(); - m_minY = std::numeric_limits::max(); - m_maxY = std::numeric_limits::min(); + m_minX = m_minY = std::numeric_limits::max(); + m_maxX = m_maxY = std::numeric_limits::min(); } @@ -73,7 +81,7 @@ bool DXF_IMPORT_PLUGIN::Load( const wxString& aFileName ) } -bool DXF_IMPORT_PLUGIN::Import( float aXScale, float aYScale ) +bool DXF_IMPORT_PLUGIN::Import() { wxCHECK( m_importer, false ); m_internalImporter.ImportTo( *m_importer ); @@ -82,43 +90,45 @@ bool DXF_IMPORT_PLUGIN::Import( float aXScale, float aYScale ) } -unsigned int DXF_IMPORT_PLUGIN::GetImageWidth() const { +double DXF_IMPORT_PLUGIN::GetImageWidth() const +{ return m_maxX - m_minX; } -unsigned int DXF_IMPORT_PLUGIN::GetImageHeight() const { +double DXF_IMPORT_PLUGIN::GetImageHeight() const +{ return m_maxY - m_minY; } // coordinate conversions from dxf to internal units -int DXF_IMPORT_PLUGIN::mapX( double aDxfCoordX ) +double DXF_IMPORT_PLUGIN::mapX( double aDxfCoordX ) { - return Millimeter2iu( m_xOffset + ( aDxfCoordX * m_DXF2mm ) ); + return SCALE_FACTOR( m_xOffset + ( aDxfCoordX * m_DXF2mm ) ); } -int DXF_IMPORT_PLUGIN::mapY( double aDxfCoordY ) +double DXF_IMPORT_PLUGIN::mapY( double aDxfCoordY ) { - return Millimeter2iu( m_yOffset - ( aDxfCoordY * m_DXF2mm ) ); + return SCALE_FACTOR( m_yOffset - ( aDxfCoordY * m_DXF2mm ) ); } -int DXF_IMPORT_PLUGIN::mapDim( double aDxfValue ) +double DXF_IMPORT_PLUGIN::mapDim( double aDxfValue ) { - return Millimeter2iu( aDxfValue * m_DXF2mm ); + return SCALE_FACTOR( aDxfValue * m_DXF2mm ); } -int DXF_IMPORT_PLUGIN::mapWidth( double aDxfWidth ) +double DXF_IMPORT_PLUGIN::mapWidth( double aDxfWidth ) { // Always return the default line width #if 0 // mapWidth returns the aDxfValue if aDxfWidth > 0 m_defaultThickness if( aDxfWidth > 0.0 ) - return Millimeter2iu( aDxfWidth * m_DXF2mm ); + return SCALE_FACTOR( aDxfWidth * m_DXF2mm ); #endif - return Millimeter2iu( m_defaultThickness ); + return SCALE_FACTOR( m_defaultThickness ); } bool DXF_IMPORT_PLUGIN::ImportDxfFile( const wxString& aFile ) @@ -171,8 +181,8 @@ void DXF_IMPORT_PLUGIN::addControlPoint( const DL_ControlPointData& aData ) void DXF_IMPORT_PLUGIN::addFitPoint( const DL_FitPointData& aData ) { // Called for every spline fit point, when reading a spline entity - // we store only the X,Y coord values in a wxRealPoint - m_curr_entity.m_SplineFitPointList.push_back( wxRealPoint( aData.x, aData.y ) ); + // we store only the X,Y coord values in a VECTOR2D + m_curr_entity.m_SplineFitPointList.push_back( VECTOR2D( aData.x, aData.y ) ); } @@ -195,23 +205,14 @@ void DXF_IMPORT_PLUGIN::addLayer( const DL_LayerData& aData ) void DXF_IMPORT_PLUGIN::addLine( const DL_LineData& aData ) { -/* DRAWSEGMENT* segm = ( m_importAsfootprintGraphicItems ) ? - static_cast< DRAWSEGMENT* >( new EDGE_MODULE( NULL ) ) : new DRAWSEGMENT; - - segm->SetLayer( ToLAYER_ID( m_brdLayer ) ); - wxPoint start( mapX( aData.x1 ), mapY( aData.y1 ) ); - segm->SetStart( start ); - wxPoint end( mapX( aData.x2 ), mapY( aData.y2 ) ); - segm->SetEnd( end ); - segm->SetWidth( mapWidth( attributes.getWidth() ) ); - m_newItemsList.push_back( segm );*/ VECTOR2D start( mapX( aData.x1 ), mapY( aData.y1 ) ); VECTOR2D end( mapX( aData.x2 ), mapY( aData.y2 ) ); - m_internalImporter.AddLine( start, end ); + double lineWidth = mapWidth( attributes.getWidth() ); + + m_internalImporter.AddLine( start, end, lineWidth ); updateImageLimits( start ); updateImageLimits( end ); - } @@ -223,7 +224,6 @@ void DXF_IMPORT_PLUGIN::addPolyline(const DL_PolylineData& aData ) // to import correctly is a 2D Polyline in X and Y, which is what // we assume of all Polylines. The width used is the width of the Polyline. // per-vertex line widths, if present, are ignored. - m_curr_entity.Clear(); m_curr_entity.m_EntityParseStatus = 1; m_curr_entity.m_EntityFlag = aData.flags; @@ -236,7 +236,7 @@ void DXF_IMPORT_PLUGIN::addVertex( const DL_VertexData& aData ) if( m_curr_entity.m_EntityParseStatus == 0 ) return; // Error - int lineWidth = mapWidth( attributes.getWidth() ); + double lineWidth = mapWidth( attributes.getWidth() ); const DL_VertexData* vertex = &aData; @@ -250,8 +250,7 @@ void DXF_IMPORT_PLUGIN::addVertex( const DL_VertexData& aData ) return; } - - wxRealPoint seg_end( m_xOffset + vertex->x * m_DXF2mm, + VECTOR2D seg_end( m_xOffset + vertex->x * m_DXF2mm, m_yOffset - vertex->y * m_DXF2mm ); if( std::abs( m_curr_entity.m_BulgeVertex ) < MIN_BULGE ) @@ -272,7 +271,7 @@ void DXF_IMPORT_PLUGIN::endEntity() // Polyline flags bit 0 indicates closed (1) or open (0) polyline if( m_curr_entity.m_EntityFlag & 1 ) { - int lineWidth = mapWidth( attributes.getWidth() ); + double lineWidth = mapWidth( attributes.getWidth() ); if( std::abs( m_curr_entity.m_BulgeVertex ) < MIN_BULGE ) insertLine( m_curr_entity.m_LastCoordinate, m_curr_entity.m_PolylineStart, lineWidth ); @@ -284,7 +283,7 @@ void DXF_IMPORT_PLUGIN::endEntity() if( m_curr_entity.m_EntityType == DL_ENTITY_SPLINE ) { - int lineWidth = mapWidth( attributes.getWidth() ); + double lineWidth = mapWidth( attributes.getWidth() ); insertSpline( lineWidth ); } @@ -294,20 +293,9 @@ void DXF_IMPORT_PLUGIN::endEntity() void DXF_IMPORT_PLUGIN::addCircle( const DL_CircleData& aData ) { -/* DRAWSEGMENT* segm = ( m_importAsfootprintGraphicItems ) ? - static_cast< DRAWSEGMENT* >( new EDGE_MODULE( NULL ) ) : new DRAWSEGMENT; - - segm->SetLayer( ToLAYER_ID( m_brdLayer ) ); - segm->SetShape( S_CIRCLE ); - wxPoint center( mapX( aData.cx ), mapY( aData.cy ) ); - segm->SetCenter( center ); - wxPoint circle_start( mapX( aData.cx + aData.radius ), mapY( aData.cy ) ); - segm->SetArcStart( circle_start ); - segm->SetWidth( mapWidth( attributes.getWidth() ) ); - m_newItemsList.push_back( segm ); -*/ VECTOR2D center( mapX( aData.cx ), mapY( aData.cy ) ); - m_internalImporter.AddCircle( center, mapDim( aData.radius ) ); + double lineWidth = mapWidth( attributes.getWidth() ); + m_internalImporter.AddCircle( center, mapDim( aData.radius ), lineWidth ); VECTOR2D radiusDelta( mapDim( aData.radius ), mapDim( aData.radius ) ); @@ -321,43 +309,6 @@ void DXF_IMPORT_PLUGIN::addCircle( const DL_CircleData& aData ) */ void DXF_IMPORT_PLUGIN::addArc( const DL_ArcData& aData ) { -/* - DRAWSEGMENT* segm = ( m_importAsfootprintGraphicItems ) ? - static_cast< DRAWSEGMENT* >( new EDGE_MODULE( NULL ) ) : new DRAWSEGMENT; - - segm->SetLayer( ToLAYER_ID( m_brdLayer ) ); - segm->SetShape( S_ARC ); - - // Init arc centre: - wxPoint center( mapX( aData.cx ), mapY( aData.cy ) ); - segm->SetCenter( center ); - - // Init arc start point - double arcStartx = aData.radius; - double arcStarty = 0; - - // aData.anglex is in degrees. Our internal units are 0.1 degree - // so convert DXF angles to our units - #define DXF2ANGLEUI 10 - double startangle = aData.angle1 * DXF2ANGLEUI; - double endangle = aData.angle2 * DXF2ANGLEUI; - - RotatePoint( &arcStartx, &arcStarty, -startangle ); - wxPoint arcStart( mapX( arcStartx + aData.cx ), - mapY( arcStarty + aData.cy ) ); - segm->SetArcStart( arcStart ); - - // calculate arc angle (arcs are CCW, and should be < 0 in Pcbnew) - double angle = -( endangle - startangle ); - - if( angle > 0.0 ) - angle -= 3600.0; - - segm->SetAngle( angle ); - - segm->SetWidth( mapWidth( attributes.getWidth() ) ); - m_newItemsList.push_back( segm ); -*/ // Init arc centre: VECTOR2D center( mapX( aData.cx ), mapY( aData.cy ) ); @@ -372,7 +323,7 @@ void DXF_IMPORT_PLUGIN::addArc( const DL_ArcData& aData ) double endangle = aData.angle2 * DXF2ANGLEUI; RotatePoint( &arcStartx, &arcStarty, -RAD2DECIDEG( startangle ) ); - wxPoint arcStart( mapX( arcStartx + aData.cx ), mapY( arcStarty + aData.cy ) ); + VECTOR2D arcStart( mapX( arcStartx + aData.cx ), mapY( arcStarty + aData.cy ) ); // calculate arc angle (arcs are CCW, and should be < 0 in Pcbnew) double angle = -( endangle - startangle ); @@ -380,7 +331,8 @@ void DXF_IMPORT_PLUGIN::addArc( const DL_ArcData& aData ) if( angle > 0.0 ) angle -= 3600.0; - m_internalImporter.AddArc( center, arcStart, angle ); + double lineWidth = mapWidth( attributes.getWidth() ); + m_internalImporter.AddArc( center, arcStart, angle, lineWidth ); VECTOR2D radiusDelta( mapDim( aData.radius ), mapDim( aData.radius ) ); @@ -391,123 +343,14 @@ void DXF_IMPORT_PLUGIN::addArc( const DL_ArcData& aData ) void DXF_IMPORT_PLUGIN::addText( const DL_TextData& aData ) { -#if 0 - BOARD_ITEM* brdItem; - EDA_TEXT* textItem; - - if( m_importAsfootprintGraphicItems ) - { - TEXTE_MODULE* modText = new TEXTE_MODULE( NULL ); - brdItem = static_cast< BOARD_ITEM* >( modText ); - textItem = static_cast< EDA_TEXT* >( modText ); - } - else - { - TEXTE_PCB* pcbText = new TEXTE_PCB( NULL ); - brdItem = static_cast< BOARD_ITEM* >( pcbText ); - textItem = static_cast< EDA_TEXT* >( pcbText ); - } - - brdItem->SetLayer( ToLAYER_ID( m_brdLayer ) ); - - wxPoint refPoint( mapX( aData.ipx ), mapY( aData.ipy ) ); - wxPoint secPoint( mapX( aData.apx ), mapY( aData.apy ) ); + VECTOR2D refPoint( mapX( aData.ipx ), mapY( aData.ipy ) ); + VECTOR2D secPoint( mapX( aData.apx ), mapY( aData.apy ) ); if( aData.vJustification != 0 || aData.hJustification != 0 || aData.hJustification == 4 ) { if( aData.hJustification != 3 && aData.hJustification != 5 ) { - wxPoint tmp = secPoint; - secPoint = refPoint; - refPoint = tmp; - } - } - - switch( aData.vJustification ) - { - case 0: //DRW_Text::VBaseLine: - textItem->SetVertJustify( GR_TEXT_VJUSTIFY_BOTTOM ); - break; - - case 1: //DRW_Text::VBottom: - textItem->SetVertJustify( GR_TEXT_VJUSTIFY_BOTTOM ); - break; - - case 2: //DRW_Text::VMiddle: - textItem->SetVertJustify( GR_TEXT_VJUSTIFY_CENTER ); - break; - - case 3: //DRW_Text::VTop: - textItem->SetVertJustify( GR_TEXT_VJUSTIFY_TOP ); - break; - } - - switch( aData.hJustification ) - { - case 0: //DRW_Text::HLeft: - textItem->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT ); - break; - - case 1: //DRW_Text::HCenter: - textItem->SetHorizJustify( GR_TEXT_HJUSTIFY_CENTER ); - break; - - case 2: //DRW_Text::HRight: - textItem->SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT ); - break; - - case 3: //DRW_Text::HAligned: - // no equivalent options in text pcb. - textItem->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT ); - break; - - case 4: //DRW_Text::HMiddle: - // no equivalent options in text pcb. - textItem->SetHorizJustify( GR_TEXT_HJUSTIFY_CENTER ); - break; - - case 5: //DRW_Text::HFit: - // no equivalent options in text pcb. - textItem->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT ); - break; - } - -#if 0 - wxString sty = wxString::FromUTF8( aData.style.c_str() ); - sty = sty.ToLower(); - - if( aData.textgen == 2 ) - { - // Text dir = left to right; - } else if( aData.textgen == 4 ) - { - // Text dir = top to bottom; - } else - { - } -#endif - - wxString text = toNativeString( wxString::FromUTF8( aData.text.c_str() ) ); - - textItem->SetTextPos( refPoint ); - textItem->SetTextAngle( aData.angle * 10 ); - - // The 0.9 factor gives a better height/width ratio with our font - textItem->SetTextWidth( mapDim( aData.height * 0.9 ) ); - textItem->SetTextHeight( mapDim( aData.height ) ); - textItem->SetThickness( mapWidth( aData.height * DEFAULT_TEXT_WIDTH ) ); // Gives a reasonable text thickness - textItem->SetText( text ); - - m_newItemsList.push_back( static_cast< BOARD_ITEM* >( brdItem ) ); -#endif - wxPoint refPoint( mapX( aData.ipx ), mapY( aData.ipy ) ); - wxPoint secPoint( mapX( aData.apx ), mapY( aData.apy ) ); - - if( aData.vJustification != 0 || aData.hJustification != 0 || aData.hJustification == 4 ) - { - if( aData.hJustification != 3 && aData.hJustification != 5 ) - { - wxPoint tmp = secPoint; + VECTOR2D tmp = secPoint; secPoint = refPoint; refPoint = tmp; } @@ -635,116 +478,6 @@ void DXF_IMPORT_PLUGIN::addText( const DL_TextData& aData ) void DXF_IMPORT_PLUGIN::addMText( const DL_MTextData& aData ) { -#if 0 - wxString text = toNativeString( wxString::FromUTF8( aData.text.c_str() ) ); - wxString attrib, tmp; - - /* Some texts start by '\' and have formating chars (font name, font option...) - * ending with ';' - * Here are some mtext formatting codes: - * Format code Purpose - * \0...\o Turns overline on and off - * \L...\l Turns underline on and off - * \~ Inserts a nonbreaking space - \\ Inserts a backslash - \\\{...\} Inserts an opening and closing brace - \\ \File name; Changes to the specified font file - \\ \Hvalue; Changes to the text height specified in drawing units - \\ \Hvaluex; Changes the text height to a multiple of the current text height - \\ \S...^...; Stacks the subsequent text at the \, #, or ^ symbol - \\ \Tvalue; Adjusts the space between characters, from.75 to 4 times - \\ \Qangle; Changes obliquing angle - \\ \Wvalue; Changes width factor to produce wide text - \\ \A Sets the alignment value; valid values: 0, 1, 2 (bottom, center, top) while( text.StartsWith( wxT("\\") ) ) - */ - while( text.StartsWith( wxT( "\\" ) ) ) - { - attrib << text.BeforeFirst( ';' ); - tmp = text.AfterFirst( ';' ); - text = tmp; - } - - BOARD_ITEM* brdItem; - EDA_TEXT* textItem; - - if( m_importAsfootprintGraphicItems ) - { - TEXTE_MODULE* modText = new TEXTE_MODULE( NULL ); - brdItem = static_cast< BOARD_ITEM* >( modText ); - textItem = static_cast< EDA_TEXT* >( modText ); - } - else - { - TEXTE_PCB* pcbText = new TEXTE_PCB( NULL ); - brdItem = static_cast< BOARD_ITEM* >( pcbText ); - textItem = static_cast< EDA_TEXT* >( pcbText ); - } - - brdItem->SetLayer( ToLAYER_ID( m_brdLayer ) ); - wxPoint textpos( mapX( aData.ipx ), mapY( aData.ipy ) ); - - textItem->SetTextPos( textpos ); - textItem->SetTextAngle( aData.angle * 10 ); - - // The 0.9 factor gives a better height/width ratio with our font - textItem->SetTextWidth( mapDim( aData.height * 0.9 ) ); - textItem->SetTextHeight( mapDim( aData.height ) ); - textItem->SetThickness( mapWidth( aData.height * DEFAULT_TEXT_WIDTH ) ); // Gives a reasonable text thickness - textItem->SetText( text ); - - // Initialize text justifications: - if( aData.attachmentPoint <= 3 ) - { - textItem->SetVertJustify( GR_TEXT_VJUSTIFY_TOP ); - } - else if( aData.attachmentPoint <= 6 ) - { - textItem->SetVertJustify( GR_TEXT_VJUSTIFY_CENTER ); - } - else - { - textItem->SetVertJustify( GR_TEXT_VJUSTIFY_BOTTOM ); - } - - if( aData.attachmentPoint % 3 == 1 ) - { - textItem->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT ); - } - else if( aData.attachmentPoint % 3 == 2 ) - { - textItem->SetHorizJustify( GR_TEXT_HJUSTIFY_CENTER ); - } - else - { - textItem->SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT ); - } - -#if 0 // These setting have no meaning in Pcbnew - if( data.alignH == 1 ) - { - // Text is left to right; - } - else if( data.alignH == 3 ) - { - // Text is top to bottom; - } - else - { - // use ByStyle; - } - - if( aData.alignV == 1 ) - { - // use AtLeast; - } - else - { - // useExact; - } -#endif - - m_newItemsList.push_back( static_cast< BOARD_ITEM* >( brdItem ) ); -#endif wxString text = toNativeString( wxString::FromUTF8( aData.text.c_str() ) ); wxString attrib, tmp; @@ -753,10 +486,10 @@ void DXF_IMPORT_PLUGIN::addMText( const DL_MTextData& aData ) double charWidth = textHeight * 0.9; double textWidth = charWidth * text.length(); // Rough approximation - wxRealPoint bottomLeft(0.0, 0.0); - wxRealPoint bottomRight(0.0, 0.0); - wxRealPoint topLeft(0.0, 0.0); - wxRealPoint topRight(0.0, 0.0); + VECTOR2D bottomLeft(0.0, 0.0); + VECTOR2D bottomRight(0.0, 0.0); + VECTOR2D topLeft(0.0, 0.0); + VECTOR2D topRight(0.0, 0.0); /* Some texts start by '\' and have formating chars (font name, font option...) * ending with ';' @@ -783,7 +516,7 @@ void DXF_IMPORT_PLUGIN::addMText( const DL_MTextData& aData ) text = tmp; } - wxPoint textpos( mapX( aData.ipx ), mapY( aData.ipy ) ); + VECTOR2D textpos( mapX( aData.ipx ), mapY( aData.ipy ) ); // Initialize text justifications: EDA_TEXT_HJUSTIFY_T hJustify = GR_TEXT_HJUSTIFY_LEFT; @@ -1116,39 +849,23 @@ void DXF_IMPORT_PLUGIN::addTextStyle( const DL_StyleData& aData ) } -void DXF_IMPORT_PLUGIN::insertLine( const wxRealPoint& aSegStart, - const wxRealPoint& aSegEnd, int aWidth ) +void DXF_IMPORT_PLUGIN::insertLine( const VECTOR2D& aSegStart, + const VECTOR2D& aSegEnd, int aWidth ) { - #if 0 - DRAWSEGMENT* segm = ( m_importAsfootprintGraphicItems ) ? - static_cast< DRAWSEGMENT* >( new EDGE_MODULE( NULL ) ) : new DRAWSEGMENT; - wxPoint segment_startpoint( Millimeter2iu( aSegStart.x ), Millimeter2iu( aSegStart.y ) ); - wxPoint segment_endpoint( Millimeter2iu( aSegEnd.x ), Millimeter2iu( aSegEnd.y ) ); - - segm->SetLayer( ToLAYER_ID( m_brdLayer ) ); - segm->SetStart( segment_startpoint ); - segm->SetEnd( segment_endpoint ); - segm->SetWidth( aWidth ); - - m_newItemsList.push_back( segm ); - #endif - VECTOR2D origin( Millimeter2iu( aSegStart.x ), Millimeter2iu( aSegStart.y ) ); - VECTOR2D end( Millimeter2iu( aSegEnd.x ), Millimeter2iu( aSegEnd.y ) ); - m_internalImporter.AddLine( origin, end ); + VECTOR2D origin( SCALE_FACTOR( aSegStart.x ), SCALE_FACTOR( aSegStart.y ) ); + VECTOR2D end( SCALE_FACTOR( aSegEnd.x ), SCALE_FACTOR( aSegEnd.y ) ); + m_internalImporter.AddLine( origin, end, aWidth ); updateImageLimits( origin ); updateImageLimits( end ); } -void DXF_IMPORT_PLUGIN::insertArc( const wxRealPoint& aSegStart, const wxRealPoint& aSegEnd, +void DXF_IMPORT_PLUGIN::insertArc( const VECTOR2D& aSegStart, const VECTOR2D& aSegEnd, double aBulge, int aWidth ) { -/* DRAWSEGMENT* segm = ( m_importAsfootprintGraphicItems ) ? - static_cast< DRAWSEGMENT* >( new EDGE_MODULE( NULL ) ) : new DRAWSEGMENT; -*/ - VECTOR2D segment_startpoint( Millimeter2iu( aSegStart.x ), Millimeter2iu( aSegStart.y ) ); - VECTOR2D segment_endpoint( Millimeter2iu( aSegEnd.x ), Millimeter2iu( aSegEnd.y ) ); + VECTOR2D segment_startpoint( SCALE_FACTOR( aSegStart.x ), SCALE_FACTOR( aSegStart.y ) ); + VECTOR2D segment_endpoint( SCALE_FACTOR( aSegEnd.x ), SCALE_FACTOR( aSegEnd.y ) ); // ensure aBulge represents an angle from +/- ( 0 .. approx 359.8 deg ) if( aBulge < -2000.0 ) @@ -1198,34 +915,23 @@ void DXF_IMPORT_PLUGIN::insertArc( const wxRealPoint& aSegStart, const wxRealPoi // center point double cx = h * cos( offAng ) + xm; double cy = h * sin( offAng ) + ym; - VECTOR2D center( Millimeter2iu( cx ), Millimeter2iu( -cy ) ); + VECTOR2D center( SCALE_FACTOR( cx ), SCALE_FACTOR( -cy ) ); VECTOR2D arc_start; double angle = RAD2DECIDEG( ang ); - //segm->SetLayer( ToLAYER_ID( m_brdLayer ) ); - //segm->SetShape( S_ARC ); - //segm->SetCenter( wxPoint( Millimeter2iu( cx ), Millimeter2iu( -cy ) ) ); - if( ang < 0.0 ) { - arc_start = VECTOR2D( Millimeter2iu( ep.x ), Millimeter2iu( -ep.y ) ); - //segm->SetArcStart( wxPoint( Millimeter2iu( ep.x ), Millimeter2iu( -ep.y ) ) ); - //segm->SetAngle( RAD2DECIDEG( ang ) ); + arc_start = VECTOR2D( SCALE_FACTOR( ep.x ), SCALE_FACTOR( -ep.y ) ); } else { - arc_start = VECTOR2D( Millimeter2iu( sp.x ), Millimeter2iu( -sp.y ) ); + arc_start = VECTOR2D( SCALE_FACTOR( sp.x ), SCALE_FACTOR( -sp.y ) ); angle = -angle; - //segm->SetArcStart( wxPoint( Millimeter2iu( sp.x ), Millimeter2iu( -sp.y ) ) ); - //segm->SetAngle( RAD2DECIDEG( -ang ) ); } - //segm->SetWidth( aWidth ); - //m_newItemsList.push_back( segm ); + m_internalImporter.AddArc( center, arc_start, angle, aWidth ); - m_internalImporter.AddArc( center, arc_start, angle ); - - wxPoint radiusDelta( Millimeter2iu( radius ), Millimeter2iu( radius ) ); + VECTOR2D radiusDelta( SCALE_FACTOR( radius ), SCALE_FACTOR( radius ) ); updateImageLimits( center + radiusDelta ); updateImageLimits( center - radiusDelta ); @@ -1245,31 +951,27 @@ void DXF_IMPORT_PLUGIN::insertSpline( int aWidth ) m_curr_entity.m_SplineFitPointList.size() ); #endif - // Very basic conversion to segments unsigned imax = m_curr_entity.m_SplineControlPointList.size(); if( imax < 2 ) // malformed spline return; #if 0 // set to 1 to approximate the spline by segments between 2 control points - wxPoint startpoint( mapX( m_curr_entity.m_SplineControlPointList[0].m_x ), + VECTOR2D startpoint( mapX( m_curr_entity.m_SplineControlPointList[0].m_x ), mapY( m_curr_entity.m_SplineControlPointList[0].m_y ) ); for( unsigned int ii = 1; ii < imax; ++ii ) { - wxPoint endpoint( mapX( m_curr_entity.m_SplineControlPointList[ii].m_x ), - mapY( m_curr_entity.m_SplineControlPointList[ii].m_y ) ); + VECTOR2D endpoint( mapX( m_curr_entity.m_SplineControlPointList[ii].m_x ), + mapY( m_curr_entity.m_SplineControlPointList[ii].m_y ) ); if( startpoint != endpoint ) { - DRAWSEGMENT* segm = ( m_importAsfootprintGraphicItems ) ? - static_cast< DRAWSEGMENT* >( new EDGE_MODULE( NULL ) ) : - new DRAWSEGMENT; - segm->SetLayer( ToLAYER_ID( m_brdLayer ) ); - segm->SetStart( startpoint ); - segm->SetEnd( endpoint ); - segm->SetWidth( aWidth ); - m_newItemsList.push_back( segm ); + m_internalImporter.AddLine( startpoint, endpoint ); + + updateImageLimits( startpoint ); + updateImageLimits( endpoint ); + startpoint = endpoint; } } @@ -1294,20 +996,6 @@ void DXF_IMPORT_PLUGIN::insertSpline( int aWidth ) // So we can have more than one Bezier curve ( there are one curve each four vertices) for( unsigned ii = 0; ii < coords.size(); ii += 8 ) { - #if 0 - DRAWSEGMENT* segm = ( m_importAsfootprintGraphicItems ) ? - static_cast< DRAWSEGMENT* >( new EDGE_MODULE( NULL ) ) : - new DRAWSEGMENT; - segm->SetLayer( ToLAYER_ID( m_brdLayer ) ); - segm->SetShape( S_CURVE ); - segm->SetStart( wxPoint( mapX( coords[ii] ), mapY( coords[ii+1] ) ) ); - segm->SetBezControl1( wxPoint( mapX( coords[ii+2] ), mapY( coords[ii+3] ) ) ); - segm->SetBezControl2( wxPoint( mapX( coords[ii+4] ), mapY( coords[ii+5] ) ) ); - segm->SetEnd( wxPoint( mapX( coords[ii+6] ), mapY( coords[ii+7] ) ) ); - segm->SetWidth( aWidth ); - segm->RebuildBezierToSegmentsPointsList( aWidth ); - m_newItemsList.push_back( segm ); - #endif VECTOR2D start( mapX( coords[ii] ), mapY( coords[ii+1] ) ); VECTOR2D bezierControl1( mapX( coords[ii+2] ), mapY( coords[ii+3] ) ); VECTOR2D bezierControl2( mapX( coords[ii+4] ), mapY( coords[ii+5] ) ); @@ -1319,20 +1007,6 @@ void DXF_IMPORT_PLUGIN::insertSpline( int aWidth ) void DXF_IMPORT_PLUGIN::updateImageLimits( const VECTOR2D& aPoint ) -{ - wxPoint truncatedPoint( (int)aPoint.x, (int)aPoint.y ); - - updateImageLimits( truncatedPoint ); -} - - -void DXF_IMPORT_PLUGIN::updateImageLimits( const wxRealPoint& aPoint ) -{ - updateImageLimits( VECTOR2D( aPoint.x, aPoint.y ) ); -} - - -void DXF_IMPORT_PLUGIN::updateImageLimits( const wxPoint& aPoint ) { m_minX = std::min( aPoint.x, m_minX ); m_maxX = std::max( aPoint.x, m_maxX ); diff --git a/pcbnew/import_gfx/dxf_import_plugin.h b/pcbnew/import_gfx/dxf_import_plugin.h index 021d1cbb9d..9759d82954 100644 --- a/pcbnew/import_gfx/dxf_import_plugin.h +++ b/pcbnew/import_gfx/dxf_import_plugin.h @@ -64,8 +64,8 @@ public: // 2 = entity in progress int m_EntityFlag; // a info flag to parse entities - wxRealPoint m_LastCoordinate; // the last vertex coordinate read (unit = mm) - wxRealPoint m_PolylineStart; // The first point of the polyline entity, when reading a polyline (unit = mm) + VECTOR2D m_LastCoordinate; // the last vertex coordinate read (unit = mm) + VECTOR2D m_PolylineStart; // The first point of the polyline entity, when reading a polyline (unit = mm) double m_BulgeVertex; // the last vertex bulge value read // for spline parsing: parameters @@ -83,7 +83,7 @@ public: // control points list coordinates, code 10, 20 & 30 (only X and Y cood and Weight) std::vector m_SplineControlPointList; // fit points list, code 11, 21 & 31 (only X and Y cood) - std::vector m_SplineFitPointList; + std::vector m_SplineFitPointList; DXF2BRD_ENTITY_DATA() { Clear(); }; @@ -115,7 +115,6 @@ public: class DXF_IMPORT_PLUGIN : public GRAPHICS_IMPORT_PLUGIN, public DL_CreationAdapter { private: - std::list m_newItemsList; // The list of new items added to the board double m_xOffset; // X coord offset for conversion (in mm) double m_yOffset; // Y coord offset for conversion (in mm) double m_defaultThickness; // default line thickness for conversion (in mm) @@ -129,8 +128,8 @@ private: // Each message ends by '\n' DXF2BRD_ENTITY_DATA m_curr_entity; // the current entity parameters when parsing a DXF entity - int m_minX, m_maxX; // handles image size - int m_minY, m_maxY; // handles image size + double m_minX, m_maxX; // handles image size in mm + double m_minY, m_maxY; // handles image size in mm GRAPHICS_IMPORTER_BUFFER m_internalImporter; @@ -150,13 +149,11 @@ public: } bool Load( const wxString& aFileName ) override; - bool Import( float aXScale, float aYScale ) override; + bool Import() override; - unsigned int GetImageWidth() const override; - unsigned int GetImageHeight() const override; + double GetImageWidth() const override; + double GetImageHeight() const override; - void updateImageLimits( const wxPoint& aPoint ); - void updateImageLimits( const wxRealPoint& aPoint ); void updateImageLimits( const VECTOR2D& aPoint ); /** @@ -209,34 +206,30 @@ public: */ bool ImportDxfFile( const wxString& aFile ); - /** - * @return the list of new BOARD_ITEM - */ - const std::list& GetItemsList() const - { - return m_newItemsList; - } - /** * @return the list of messages in one string. Each message ends by '\n' */ - std::string& GetMessages() { return m_messages; } + const std::string& GetMessages() const override + { + return m_messages; + } + private: // report message to keep trace of not supported dxf entities: void reportMsg( const char* aMessage ); - // coordinate conversions from dxf to internal units - int mapX( double aDxfCoordX ); - int mapY( double aDxfCoordY ); - int mapDim( double aDxfValue ); - // mapWidth returns ( in internal units) the aDxfValue if aDxfWidth > 0 + // coordinate conversions from dxf file to mm + double mapX( double aDxfCoordX ); + double mapY( double aDxfCoordY ); + double mapDim( double aDxfValue ); + // mapWidth returns ( in mm) the aDxfValue if aDxfWidth > 0 // or m_defaultThickness - int mapWidth( double aDxfWidth ); + double mapWidth( double aDxfWidth ); // Functions to aid in the creation of a Polyline - void insertLine( const wxRealPoint& aSegStart, const wxRealPoint& aSegEnd, int aWidth ); - void insertArc( const wxRealPoint& aSegStart, const wxRealPoint& aSegEnd, + void insertLine( const VECTOR2D& aSegStart, const VECTOR2D& aSegEnd, int aWidth ); + void insertArc( const VECTOR2D& aSegStart, const VECTOR2D& aSegEnd, double aBulge, int aWidth ); // Add a dxf spline (stored in m_curr_entity) to the board, after conversion to segments void insertSpline( int aWidth ); diff --git a/pcbnew/import_gfx/graphics_import_mgr.h b/pcbnew/import_gfx/graphics_import_mgr.h index bd8a6e3cb8..e312146a03 100644 --- a/pcbnew/import_gfx/graphics_import_mgr.h +++ b/pcbnew/import_gfx/graphics_import_mgr.h @@ -38,7 +38,8 @@ class GRAPHICS_IMPORT_MGR { public: ///> List of handled file types. - enum GFX_FILE_T { + enum GFX_FILE_T + { DXF, SVG }; diff --git a/pcbnew/import_gfx/graphics_import_plugin.h b/pcbnew/import_gfx/graphics_import_plugin.h index b56163648d..529afa1039 100644 --- a/pcbnew/import_gfx/graphics_import_plugin.h +++ b/pcbnew/import_gfx/graphics_import_plugin.h @@ -91,23 +91,30 @@ public: /** * @brief Return image height from original imported file. * - * @return Original Image height in internal units. + * @return Original Image height in mm. */ - virtual unsigned int GetImageHeight() const = 0; + virtual double GetImageHeight() const = 0; /** * @brief Return image width from original imported file. * - * @return Original Image width in internal units. + * @return Original Image width in mm. */ - virtual unsigned int GetImageWidth() const = 0; + virtual double GetImageWidth() const = 0; /** * @brief Actually imports the file. * * It is necessary to have loaded the file beforehand. */ - virtual bool Import( float aXScale, float aYScale ) = 0; + virtual bool Import() = 0; + + /** + * @brief collect warning and error messages after loading/importing. + * @return the list of messages in one string. Each message ends by '\n' + */ + const virtual std::string& GetMessages() const = 0; + protected: diff --git a/pcbnew/import_gfx/graphics_importer.cpp b/pcbnew/import_gfx/graphics_importer.cpp index fe2f4b6c4d..095275a871 100644 --- a/pcbnew/import_gfx/graphics_importer.cpp +++ b/pcbnew/import_gfx/graphics_importer.cpp @@ -25,9 +25,13 @@ #include "graphics_importer.h" #include "graphics_import_plugin.h" -GRAPHICS_IMPORTER::GRAPHICS_IMPORTER() : - m_lineWidth( DEFAULT_LINE_WIDTH_DFX ), m_scale( 1.0 ) +GRAPHICS_IMPORTER::GRAPHICS_IMPORTER() { + m_millimeterToIu = 1.0; + m_lineWidth = DEFAULT_LINE_WIDTH_DFX; + m_scale = 1.0; + m_originalWidth = 0.0; + m_originalHeight = 0.0; } @@ -46,7 +50,7 @@ bool GRAPHICS_IMPORTER::Load( const wxString &aFileName ) return m_plugin->Load( aFileName ); } -bool GRAPHICS_IMPORTER::Import( float aXScale, float aYScale) +bool GRAPHICS_IMPORTER::Import( double aScale ) { if( !m_plugin ) { @@ -54,7 +58,9 @@ bool GRAPHICS_IMPORTER::Import( float aXScale, float aYScale) return false; } + SetScale( aScale ); + m_plugin->SetImporter( this ); - return m_plugin->Import( aXScale, aYScale ); + return m_plugin->Import(); } diff --git a/pcbnew/import_gfx/graphics_importer.h b/pcbnew/import_gfx/graphics_importer.h index 7e660fe095..b3e4ba6040 100644 --- a/pcbnew/import_gfx/graphics_importer.h +++ b/pcbnew/import_gfx/graphics_importer.h @@ -68,16 +68,28 @@ public: * @brief Imports shapes from loaded file. * * It is important to have the file loaded before importing. + * + * @param aScale allow import graphic items with a non 1:1 import ratio + * aScale = 1.0 to import graphics with their actual size. */ - bool Import( float aXScale, float aYScale); + bool Import( double aScale = 1.0 ); + + /** + * @brief collect warning and error messages after loading/importing. + * @return the list of messages in one string. Each message ends by '\n' + */ + const std::string& GetMessages() const + { + return m_plugin->GetMessages(); + } /** * @brief Get original image Wigth. * - * @return Width of the loaded image in internal units. + * @return Width of the loaded image in mm. */ - unsigned int GetImageWidth() const + double GetImageWidthMM() const { return m_originalWidth; } @@ -85,48 +97,77 @@ public: /** * @brief Get original image Height * - * @return Height of the loaded image in internal units. + * @return Height of the loaded image in mm. */ - unsigned int GetImageHeight() const + double GetImageHeightMM() const { return m_originalHeight; } /** - * @brief Sets the line width for the imported outlines. + * @brief Sets the line width for the imported outlines (in mm). */ - void SetLineWidth( double aWidth ) + void SetLineWidthMM( double aWidth ) { - m_lineWidth = (unsigned int)( aWidth * m_scale ); + m_lineWidth = aWidth; } /** - * @brief Returns the line width used for importing the outlines. + * @brief Returns the line width used for importing the outlines (in mm). */ - unsigned int GetLineWidth() const + double GetLineWidthMM() const { return m_lineWidth; } - - /** - * @brief Returns the scale factor affecting the imported shapes. + /** @return the scale factor affecting the imported shapes. */ double GetScale() const { return m_scale; } - /** - * @brief set the scale factor affecting the imported shapes. - * it allows conversion between imported shapes units and internal units + /** @return the offset to add to coordinates when importing graphic items. + * The offset is always in mm + */ + const VECTOR2D& GetImportOffsetMM() const + { + return m_offsetCoordmm; + } + + /** Set the offset to add to coordinates when importing graphic items. + * The offset is always in mm + */ + void SetImportOffsetMM( const VECTOR2D& aOffset ) + { + m_offsetCoordmm = aOffset; + } + + /** Set the scale factor affecting the imported shapes. + * it allows conversion between imported shapes units and mm */ void SetScale( double aScale ) { m_scale = aScale; } + /** @return the conversion factor from mm to internal unit + */ + double GetMillimeterToIuFactor() + { + return m_millimeterToIu; + } + + + /** + * @return the overall scale factor to convert the imported shapes dimension to mm. + */ + double ImportScalingFactor() const + { + return m_scale * m_millimeterToIu; + } + /** * @breif Returns the list of objects representing the imported shapes. */ @@ -135,35 +176,38 @@ public: return m_items; } - ///> Default line thickness (in internal units) + ///> Default line thickness (in mm) static constexpr unsigned int DEFAULT_LINE_WIDTH_DFX = 1; // Methods to be implemented by derived graphics importers /** * @brief Creates an object representing a line segment. - * @param aOrigin is the segment origin point expressed in internal units. - * @param aEnd is the segment end point expressed in internal units. + * @param aOrigin is the segment origin point expressed in mm. + * @param aEnd is the segment end point expressed in mm. + * @param aWidth is the segment thickness in mm. Use -1 for default line thickness */ - virtual void AddLine( const VECTOR2D& aOrigin, const VECTOR2D& aEnd ) = 0; + virtual void AddLine( const VECTOR2D& aOrigin, const VECTOR2D& aEnd, double aWidth ) = 0; /** * @brief Creates an object representing a circle. - * @param aCenter is the circle center point expressed in internal units. - * @param aRadius is the circle radius expressed in internal units. + * @param aCenter is the circle center point expressed in mm. + * @param aRadius is the circle radius expressed in mm. + * @param aWidth is the segment thickness in mm. Use -1 for default line thickness */ - virtual void AddCircle( const VECTOR2D& aCenter, double aRadius ) = 0; + virtual void AddCircle( const VECTOR2D& aCenter, double aRadius, double aWidth ) = 0; /** * @brief Creates an object representing an arc. - * @param aCenter is the arc center point expressed in internal units. - * @param aStart is the arc arm end point expressed in internal units. + * @param aCenter is the arc center point expressed in mm. + * @param aStart is the arc arm end point expressed in mm. * Its length is the arc radius. * @param aAngle is the arc angle expressed in decidegrees. + * @param aWidth is the segment thickness in mm. Use -1 for default line thickness */ - virtual void AddArc( const VECTOR2D& aCenter, const VECTOR2D& aStart, double aAngle ) = 0; + virtual void AddArc( const VECTOR2D& aCenter, const VECTOR2D& aStart, double aAngle, double aWidth ) = 0; - virtual void AddPolygon( const std::vector< VECTOR2D >& aVertices ) = 0; + virtual void AddPolygon( const std::vector< VECTOR2D >& aVertices, double aWidth ) = 0; //virtual void AddArc( const VECTOR2D& aOrigin, double aStartAngle, double aEndAngle ) = 0; // @@ -171,16 +215,25 @@ public: * @brief Creates an object representing a text. * @param aOrigin is the text position. * @param aText is the displayed text. - * @param aHeight is the text height expressed in internal units. - * @param aWidth is the text width expressed in internal units. + * @param aHeight is the text height expressed in mm. + * @param aWidth is the text width expressed in mm. * @param aOrientation is the text orientation angle expressed in decidegrees. * @param aHJustify is the text horizontal justification. * @param aVJustify is the text vertical justification. + * @param aWidth is the segment thickness in mm. Use -1 for default line thickness */ virtual void AddText( const VECTOR2D& aOrigin, const wxString& aText, - double aHeight, double, double aOrientation, + double aHeight, double aWidth, double aOrientation, EDA_TEXT_HJUSTIFY_T aHJustify, EDA_TEXT_VJUSTIFY_T aVJustify ) = 0; + /** + * @brief Creates an object representing an arc. + * @param aStart is the curve start point expressed in mm. + * @param aBezierControl1 is the first Bezier control point expressed in mm. + * @param aBezierControl2 is the second Bezier control point expressed in mm. + * @param aEnd is the curve end point expressed in mm. + * @param aWidth is the segment thickness in mm. Use -1 for default line thickness + */ virtual void AddSpline( const VECTOR2D& aStart, const VECTOR2D& aBezierControl1, const VECTOR2D& aBezierControl2, const VECTOR2D& aEnd, double aWidth ) = 0; @@ -199,17 +252,26 @@ private: std::unique_ptr m_plugin; ///> Total image width - unsigned int m_originalWidth; + double m_originalWidth; ///> Total image Height; - unsigned int m_originalHeight; + double m_originalHeight; ///> Default line thickness for the imported graphics - unsigned int m_lineWidth; + double m_lineWidth; - ///> Scale factor applied to the imported graphics + /** Scale factor applied to the imported graphics. + * 1.0 does not change the size of imported items + * scale < 1.0 reduce the size of imported items + */ double m_scale; +protected: + ///> factor to convert millimeters to Internal Units + double m_millimeterToIu; + + ///> Offset (in mm) for imported coordinates + VECTOR2D m_offsetCoordmm; }; #endif /* GRAPHICS_IMPORTER_H */ diff --git a/pcbnew/import_gfx/graphics_importer_buffer.cpp b/pcbnew/import_gfx/graphics_importer_buffer.cpp index 14709aeb0d..068681bd05 100644 --- a/pcbnew/import_gfx/graphics_importer_buffer.cpp +++ b/pcbnew/import_gfx/graphics_importer_buffer.cpp @@ -32,28 +32,28 @@ static std::unique_ptr make_shape( const Args&... aArguments ) return std::unique_ptr( new T( aArguments... ) ); } -void GRAPHICS_IMPORTER_BUFFER::AddLine( const VECTOR2D& aStart, const VECTOR2D& aEnd ) +void GRAPHICS_IMPORTER_BUFFER::AddLine( const VECTOR2D& aStart, const VECTOR2D& aEnd, double aWidth ) { - m_shapes.push_back( make_shape< IMPORTED_LINE >( aStart, aEnd ) ); + m_shapes.push_back( make_shape< IMPORTED_LINE >( aStart, aEnd, aWidth ) ); } -void GRAPHICS_IMPORTER_BUFFER::AddCircle( const VECTOR2D& aCenter, double aRadius ) +void GRAPHICS_IMPORTER_BUFFER::AddCircle( const VECTOR2D& aCenter, double aRadius, double aWidth ) { - m_shapes.push_back( make_shape< IMPORTED_CIRCLE >( aCenter, aRadius ) ); + m_shapes.push_back( make_shape< IMPORTED_CIRCLE >( aCenter, aRadius, aWidth ) ); } void GRAPHICS_IMPORTER_BUFFER::AddArc( const VECTOR2D& aCenter, const VECTOR2D& aStart, - double aAngle ) + double aAngle, double aWidth ) { - m_shapes.push_back( make_shape< IMPORTED_ARC >( aCenter, aStart, aAngle ) ); + m_shapes.push_back( make_shape< IMPORTED_ARC >( aCenter, aStart, aAngle, aWidth ) ); } -void GRAPHICS_IMPORTER_BUFFER::AddPolygon( const std::vector< VECTOR2D >& aVertices ) +void GRAPHICS_IMPORTER_BUFFER::AddPolygon( const std::vector< VECTOR2D >& aVertices, double aWidth ) { - m_shapes.push_back( make_shape< IMPORTED_POLYGON >( aVertices ) ); + m_shapes.push_back( make_shape< IMPORTED_POLYGON >( aVertices, aWidth ) ); } diff --git a/pcbnew/import_gfx/graphics_importer_buffer.h b/pcbnew/import_gfx/graphics_importer_buffer.h index ec3fb50248..abe5bc32c3 100644 --- a/pcbnew/import_gfx/graphics_importer_buffer.h +++ b/pcbnew/import_gfx/graphics_importer_buffer.h @@ -3,6 +3,7 @@ * * Copyright (C) 2017 CERN * @author Janito Vaqueiro Ferreira Filho + * Copyright (C) 2018 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 @@ -39,76 +40,80 @@ public: class IMPORTED_LINE : public IMPORTED_SHAPE { public: - IMPORTED_LINE( const VECTOR2D& aStart, const VECTOR2D& aEnd ) - : m_start( aStart ), m_end( aEnd ) + IMPORTED_LINE( const VECTOR2D& aStart, const VECTOR2D& aEnd, double aWidth ) + : m_start( aStart ), m_end( aEnd ), m_width( aWidth ) { } void ImportTo( GRAPHICS_IMPORTER& aImporter ) const override { - aImporter.AddLine( m_start, m_end ); + aImporter.AddLine( m_start, m_end, m_width ); } private: const VECTOR2D m_start; const VECTOR2D m_end; + double m_width; }; class IMPORTED_CIRCLE : public IMPORTED_SHAPE { public: - IMPORTED_CIRCLE( const VECTOR2D& aCenter, double aRadius ) - : m_center( aCenter ), m_radius( aRadius ) + IMPORTED_CIRCLE( const VECTOR2D& aCenter, double aRadius, double aWidth ) + : m_center( aCenter ), m_radius( aRadius ), m_width( aWidth ) { } void ImportTo( GRAPHICS_IMPORTER& aImporter ) const override { - aImporter.AddCircle( m_center, m_radius ); + aImporter.AddCircle( m_center, m_radius, m_width ); } private: const VECTOR2D m_center; double m_radius; + double m_width; }; class IMPORTED_ARC : public IMPORTED_SHAPE { public: - IMPORTED_ARC( const VECTOR2D& aCenter, const VECTOR2D& aStart, double aAngle ) - : m_center( aCenter ), m_start( aStart ), m_angle( aAngle ) + IMPORTED_ARC( const VECTOR2D& aCenter, const VECTOR2D& aStart, double aAngle, double aWidth ) + : m_center( aCenter ), m_start( aStart ), m_angle( aAngle ), m_width( aWidth ) { } void ImportTo( GRAPHICS_IMPORTER& aImporter ) const override { - aImporter.AddArc( m_center, m_start, m_angle ); + aImporter.AddArc( m_center, m_start, m_angle, m_width ); } private: const VECTOR2D m_center; const VECTOR2D m_start; double m_angle; + double m_width; }; class IMPORTED_POLYGON : public IMPORTED_SHAPE { public: - IMPORTED_POLYGON( const std::vector< VECTOR2D >& aVertices ) - : m_vertices( aVertices ) + IMPORTED_POLYGON( const std::vector< VECTOR2D >& aVertices, double aWidth ) + : m_vertices( aVertices ), m_width( aWidth ) { } void ImportTo( GRAPHICS_IMPORTER& aImporter ) const override { - aImporter.AddPolygon( m_vertices ); + aImporter.AddPolygon( m_vertices, m_width ); } private: const std::vector< VECTOR2D > m_vertices; + double m_width; }; @@ -169,13 +174,13 @@ private: class GRAPHICS_IMPORTER_BUFFER : public GRAPHICS_IMPORTER { public: - void AddLine( const VECTOR2D& aStart, const VECTOR2D& aEnd ) override; + void AddLine( const VECTOR2D& aStart, const VECTOR2D& aEnd, double aWidth ) override; - void AddCircle( const VECTOR2D& aCenter, double aRadius ) override; + void AddCircle( const VECTOR2D& aCenter, double aRadius, double aWidth ) override; - void AddArc( const VECTOR2D& aCenter, const VECTOR2D& aStart, double aAngle ) override; + void AddArc( const VECTOR2D& aCenter, const VECTOR2D& aStart, double aAngle, double aWidth ) override; - void AddPolygon( const std::vector< VECTOR2D >& aVertices ) override; + void AddPolygon( const std::vector< VECTOR2D >& aVertices, double aWidth ) override; void AddText( const VECTOR2D& aOrigin, const wxString& aText, double aHeight, double aWidth, double aOrientation, diff --git a/pcbnew/import_gfx/graphics_importer_pcbnew.cpp b/pcbnew/import_gfx/graphics_importer_pcbnew.cpp index df2c231406..0bd273f42e 100644 --- a/pcbnew/import_gfx/graphics_importer_pcbnew.cpp +++ b/pcbnew/import_gfx/graphics_importer_pcbnew.cpp @@ -3,13 +3,14 @@ * * Copyright (C) 2016 CERN * @author Maciej Suminski + * Copyright (C) 2018 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, + * 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. @@ -30,62 +31,99 @@ #include #include -using namespace std; - -static std::vector convertPoints( const std::vector& aPoints, - double aScaleFactor ); +#include "convert_to_biu.h" -static wxPoint Round( const VECTOR2D& aVec ) +GRAPHICS_IMPORTER_PCBNEW::GRAPHICS_IMPORTER_PCBNEW() { - return wxPoint( (int) aVec.x, (int) aVec.y ); + m_layer = Dwgs_User; + m_millimeterToIu = Millimeter2iu( 1.0 ); } -void GRAPHICS_IMPORTER_PCBNEW::AddLine( const VECTOR2D& aOrigin, const VECTOR2D& aEnd ) +wxPoint GRAPHICS_IMPORTER_PCBNEW::MapCoordinate( const VECTOR2D& aCoordinate ) +{ + VECTOR2D coord = ( aCoordinate + GetImportOffsetMM() ) * ImportScalingFactor(); + return wxPoint( (int) coord.x, (int) coord.y ); +} + + +int GRAPHICS_IMPORTER_PCBNEW::MapLineWidth( double aLineWidth ) +{ + if( aLineWidth <= 0.0 ) + return int( GetLineWidthMM() * ImportScalingFactor() ); + + // aLineWidth is in mm: + return int( aLineWidth * ImportScalingFactor() ); +} + + +void GRAPHICS_IMPORTER_PCBNEW::AddLine( const VECTOR2D& aOrigin, const VECTOR2D& aEnd, double aWidth ) { unique_ptr line( createDrawing() ); line->SetShape( S_SEGMENT ); line->SetLayer( GetLayer() ); - line->SetWidth( GetLineWidth() ); - line->SetStart( Round ( aOrigin * GetScale() ) ); - line->SetEnd( Round ( aEnd * GetScale() ) ); + line->SetWidth( MapLineWidth( aWidth ) ); + line->SetStart( MapCoordinate( aOrigin ) ); + line->SetEnd( MapCoordinate( aEnd ) ); + + if( line->Type() == PCB_MODULE_EDGE_T ) + static_cast( line.get() )->SetLocalCoord(); + addItem( std::move( line ) ); } -void GRAPHICS_IMPORTER_PCBNEW::AddCircle( const VECTOR2D& aCenter, double aRadius ) +void GRAPHICS_IMPORTER_PCBNEW::AddCircle( const VECTOR2D& aCenter, double aRadius, double aWidth ) { unique_ptr circle( createDrawing() ); circle->SetShape( S_CIRCLE ); circle->SetLayer( GetLayer() ); - circle->SetWidth( GetLineWidth() ); - circle->SetCenter( Round ( aCenter * GetScale() ) ); - circle->SetArcStart( Round ( VECTOR2D( aCenter.x + aRadius, aCenter.y ) * GetScale() ) ); + circle->SetWidth( MapLineWidth( aWidth ) ); + circle->SetCenter( MapCoordinate( aCenter ) ); + circle->SetArcStart( MapCoordinate( VECTOR2D( aCenter.x + aRadius, aCenter.y ) ) ); + + if( circle->Type() == PCB_MODULE_EDGE_T ) + static_cast( circle.get() )->SetLocalCoord(); + addItem( std::move( circle ) ); } -void GRAPHICS_IMPORTER_PCBNEW::AddArc( const VECTOR2D& aCenter, const VECTOR2D& aStart, double aAngle ) +void GRAPHICS_IMPORTER_PCBNEW::AddArc( const VECTOR2D& aCenter, const VECTOR2D& aStart, double aAngle, double aWidth ) { unique_ptr arc( createDrawing() ); arc->SetShape( S_ARC ); arc->SetLayer( GetLayer() ); - arc->SetWidth( GetLineWidth() ); - arc->SetCenter( Round ( aCenter * GetScale() ) ); - arc->SetArcStart( Round ( aStart * GetScale() ) ); + arc->SetWidth( MapLineWidth( aWidth ) ); + arc->SetCenter( MapCoordinate( aCenter) ); + arc->SetArcStart( MapCoordinate( aStart ) ); arc->SetAngle( aAngle ); + + if( arc->Type() == PCB_MODULE_EDGE_T ) + static_cast( arc.get() )->SetLocalCoord(); + addItem( std::move( arc ) ); } -void GRAPHICS_IMPORTER_PCBNEW::AddPolygon( const std::vector< VECTOR2D >& aVertices ) +void GRAPHICS_IMPORTER_PCBNEW::AddPolygon( const std::vector< VECTOR2D >& aVertices, double aWidth ) { - std::vector< wxPoint > convertedVertices = convertPoints( aVertices, GetScale() ); + std::vector< wxPoint > convertedPoints; + convertedPoints.reserve( convertedPoints.size() ); + + for( const VECTOR2D& precisePoint : aVertices ) + convertedPoints.emplace_back( MapCoordinate( precisePoint ) ); + unique_ptr polygon( createDrawing() ); polygon->SetShape( S_POLYGON ); polygon->SetLayer( GetLayer() ); - polygon->SetPolyPoints( convertedVertices ); + polygon->SetPolyPoints( convertedPoints ); + + if( polygon->Type() == PCB_MODULE_EDGE_T ) + static_cast( polygon.get() )->SetLocalCoord(); + + polygon->SetWidth( MapLineWidth( aWidth ) ); addItem( std::move( polygon ) ); } @@ -98,14 +136,18 @@ void GRAPHICS_IMPORTER_PCBNEW::AddText( const VECTOR2D& aOrigin, const wxString& EDA_TEXT* textItem; tie( boardItem, textItem ) = createText(); boardItem->SetLayer( GetLayer() ); - textItem->SetThickness( GetLineWidth() ); - textItem->SetTextPos( Round( aOrigin * GetScale() ) ); + textItem->SetThickness( MapLineWidth( aWidth ) ); + textItem->SetTextPos( MapCoordinate( aOrigin ) ); textItem->SetTextAngle( aOrientation ); - textItem->SetTextWidth( aWidth * GetScale() ); - textItem->SetTextHeight( aHeight * GetScale() ); + textItem->SetTextWidth( aWidth * ImportScalingFactor() ); + textItem->SetTextHeight( aHeight * ImportScalingFactor() ); textItem->SetVertJustify( aVJustify ); textItem->SetHorizJustify( aHJustify ); textItem->SetText( aText ); + + if( boardItem->Type() == PCB_MODULE_TEXT_T ) + static_cast( boardItem.get() )->SetLocalCoord(); + addItem( std::move( boardItem ) ); } @@ -114,15 +156,18 @@ void GRAPHICS_IMPORTER_PCBNEW::AddSpline( const VECTOR2D& aStart, const VECTOR2D const VECTOR2D& BezierControl2, const VECTOR2D& aEnd, double aWidth ) { unique_ptr spline( createDrawing() ); - aWidth = GetLineWidth(); // To do: use dxf line thickness if defined spline->SetShape( S_CURVE ); spline->SetLayer( GetLayer() ); - spline->SetWidth( aWidth ); - spline->SetStart( Round( aStart * GetScale() ) ); - spline->SetBezControl1( Round( BezierControl1 * GetScale() ) ); - spline->SetBezControl2( Round( BezierControl2 * GetScale() ) ); - spline->SetEnd( Round( aEnd * GetScale() ) ); + spline->SetWidth( MapLineWidth( aWidth ) ); + spline->SetStart( MapCoordinate( aStart ) ); + spline->SetBezControl1( MapCoordinate( BezierControl1 ) ); + spline->SetBezControl2( MapCoordinate( BezierControl2 ) ); + spline->SetEnd( MapCoordinate( aEnd ) ); spline->RebuildBezierToSegmentsPointsList( aWidth ); + + if( spline->Type() == PCB_MODULE_EDGE_T ) + static_cast( spline.get() )->SetLocalCoord(); + addItem( std::move( spline ) ); } @@ -133,7 +178,7 @@ unique_ptr GRAPHICS_IMPORTER_BOARD::createDrawing() } -pair, EDA_TEXT*> GRAPHICS_IMPORTER_BOARD::createText() +std::pair, EDA_TEXT*> GRAPHICS_IMPORTER_BOARD::createText() { TEXTE_PCB* text = new TEXTE_PCB( m_board ); return make_pair( unique_ptr( text ), static_cast( text ) ); @@ -146,26 +191,8 @@ unique_ptr GRAPHICS_IMPORTER_MODULE::createDrawing() } -pair, EDA_TEXT*> GRAPHICS_IMPORTER_MODULE::createText() +std::pair, EDA_TEXT*> GRAPHICS_IMPORTER_MODULE::createText() { TEXTE_MODULE* text = new TEXTE_MODULE( m_module ); return make_pair( unique_ptr( text ), static_cast( text ) ); } - - -static std::vector< wxPoint > convertPoints( const std::vector& aPoints, - double aScaleFactor ) -{ - std::vector convertedPoints; - convertedPoints.reserve( aPoints.size() ); - - for( const VECTOR2D& precisePoint : aPoints ) - { - auto scaledX = precisePoint.x * aScaleFactor; - auto scaledY = precisePoint.y * aScaleFactor; - - convertedPoints.emplace_back( scaledX, scaledY ); - } - - return convertedPoints; -} diff --git a/pcbnew/import_gfx/graphics_importer_pcbnew.h b/pcbnew/import_gfx/graphics_importer_pcbnew.h index be1aa68bec..bb7ff6a3f5 100644 --- a/pcbnew/import_gfx/graphics_importer_pcbnew.h +++ b/pcbnew/import_gfx/graphics_importer_pcbnew.h @@ -3,6 +3,7 @@ * * Copyright (C) 2016 CERN * @author Maciej Suminski + * Copyright (C) 2018 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 @@ -38,10 +39,7 @@ class EDA_TEXT; class GRAPHICS_IMPORTER_PCBNEW : public GRAPHICS_IMPORTER { public: - GRAPHICS_IMPORTER_PCBNEW() - : m_layer( Dwgs_User ) - { - } + GRAPHICS_IMPORTER_PCBNEW(); /** * @brief Sets the target layer for the imported shapes. @@ -60,13 +58,13 @@ public: return m_layer; } - void AddLine( const VECTOR2D& aOrigin, const VECTOR2D& aEnd ) override; + void AddLine( const VECTOR2D& aOrigin, const VECTOR2D& aEnd, double aWidth ) override; - void AddCircle( const VECTOR2D& aOrigin, double aRadius ) override; + void AddCircle( const VECTOR2D& aOrigin, double aRadius, double aWidth ) override; - void AddArc( const VECTOR2D& aCenter, const VECTOR2D& aStart, double aAngle ) override; + void AddArc( const VECTOR2D& aCenter, const VECTOR2D& aStart, double aAngle, double aWidth ) override; - void AddPolygon( const std::vector< VECTOR2D >& aVertices ) override; + void AddPolygon( const std::vector< VECTOR2D >& aVertices, double aWidth ) override; void AddText( const VECTOR2D& aOrigin, const wxString& aText, double aHeight, double aWidth, double aOrientation, @@ -75,6 +73,19 @@ public: void AddSpline( const VECTOR2D& aStart, const VECTOR2D& aBezierControl1, const VECTOR2D& aBezierControl2, const VECTOR2D& aEnd , double aWidth ) override; + /** convert a imported coordinate to a board coordinate, according to + * the internal units, the user scale and offset + * @param aCoordinate is the imported coordinate in mm + */ + wxPoint MapCoordinate( const VECTOR2D& aCoordinate ); + + /** @return a line thickness in a board Iu value, according to + * the internal units. + * if aLineWidth < 0, the default ine thickness value is returned + * @param aLineWidth is the line thickness in mm to convert + */ + int MapLineWidth( double aLineWidth ); + protected: ///> Create an object representing a graphical shape. virtual std::unique_ptr createDrawing() = 0; diff --git a/pcbnew/import_gfx/nanosvg.h b/pcbnew/import_gfx/nanosvg.h index a6c60155ea..80ce4bb96a 100644 --- a/pcbnew/import_gfx/nanosvg.h +++ b/pcbnew/import_gfx/nanosvg.h @@ -141,8 +141,8 @@ typedef struct NSVGshape float opacity; // Opacity of the shape. float strokeWidth; // Stroke width (scaled). float strokeDashOffset; // Stroke dash offset (scaled). - float strokeDashArray[8]; // Stroke dash array (scaled). - char strokeDashCount; // Number of dash values in dash array. + float strokeDashArray[8]; // Stroke dash array (scaled). + char strokeDashCount; // Number of dash values in dash array. char strokeLineJoin; // Stroke join type. char strokeLineCap; // Stroke cap type. char fillRule; // Fill rule, see NSVGfillRule. diff --git a/pcbnew/import_gfx/svg_import_plugin.cpp b/pcbnew/import_gfx/svg_import_plugin.cpp index 4281fef3a1..13d4630f61 100644 --- a/pcbnew/import_gfx/svg_import_plugin.cpp +++ b/pcbnew/import_gfx/svg_import_plugin.cpp @@ -3,6 +3,7 @@ * * Copyright (C) 2016 CERN * @author Janito V. Ferreira Filho + * Copyright (C) 1992-2018 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 @@ -49,6 +50,7 @@ static VECTOR2D getPointInLine( const VECTOR2D& aLineStart, const VECTOR2D& aLin static float distanceFromPointToLine( const VECTOR2D& aPoint, const VECTOR2D& aLineStart, const VECTOR2D& aLineEnd ); + bool SVG_IMPORT_PLUGIN::Load( const wxString& aFileName ) { wxCHECK( m_importer, false ); @@ -60,31 +62,55 @@ bool SVG_IMPORT_PLUGIN::Load( const wxString& aFileName ) return true; } -bool SVG_IMPORT_PLUGIN::Import(float aXScale, float aYScale) +bool SVG_IMPORT_PLUGIN::Import() { for( NSVGshape* shape = m_parsedImage->shapes; shape != NULL; shape = shape->next ) { - m_importer->SetLineWidth( shape->strokeWidth ); + double lineWidth = shape->strokeWidth; for( NSVGpath* path = shape->paths; path != NULL; path = path->next ) - DrawPath( path->pts, path->npts, path->closed ); + DrawPath( path->pts, path->npts, path->closed, shape->fill.type == NSVG_PAINT_COLOR, lineWidth ); } return true; } -void SVG_IMPORT_PLUGIN::DrawPath( const float* aPoints, int aNumPoints, bool aClosedPath ) +double SVG_IMPORT_PLUGIN::GetImageHeight() const +{ + if( !m_parsedImage ) + { + wxASSERT_MSG(false, "Image must have been loaded before checking height"); + return 0.0; + } + + return m_parsedImage->height; +} + + +double SVG_IMPORT_PLUGIN::GetImageWidth() const +{ + if( !m_parsedImage ) + { + wxASSERT_MSG(false, "Image must have been loaded before checking width"); + return 0.0; + } + + return m_parsedImage->width; +} + + +void SVG_IMPORT_PLUGIN::DrawPath( const float* aPoints, int aNumPoints, bool aClosedPath, bool aFilled, double aLineWidth ) { std::vector< VECTOR2D > collectedPathPoints; if( aNumPoints > 0 ) DrawCubicBezierPath( aPoints, aNumPoints, collectedPathPoints ); - if( aClosedPath ) - DrawPolygon( collectedPathPoints ); + if( aFilled && aClosedPath ) + DrawPolygon( collectedPathPoints, aLineWidth ); else - DrawLineSegments( collectedPathPoints ); + DrawLineSegments( collectedPathPoints, aLineWidth ); } @@ -109,28 +135,28 @@ void SVG_IMPORT_PLUGIN::DrawCubicBezierPath( const float* aPoints, int aNumPoint void SVG_IMPORT_PLUGIN::DrawCubicBezierCurve( const float* aPoints, std::vector< VECTOR2D >& aGeneratedPoints ) { - auto start = getBezierPoint( aPoints, 0.f ); - auto end = getBezierPoint( aPoints, 1.f ); + auto start = getBezierPoint( aPoints, 0.0f ); + auto end = getBezierPoint( aPoints, 1.0f ); auto segmentationThreshold = calculateBezierSegmentationThreshold( aPoints ); aGeneratedPoints.push_back( start ); - segmentBezierCurve( start, end, 0.f, 0.5f, aPoints, segmentationThreshold, aGeneratedPoints ); + segmentBezierCurve( start, end, 0.0f, 0.5f, aPoints, segmentationThreshold, aGeneratedPoints ); aGeneratedPoints.push_back( end ); } -void SVG_IMPORT_PLUGIN::DrawPolygon( const std::vector< VECTOR2D >& aPoints ) +void SVG_IMPORT_PLUGIN::DrawPolygon( const std::vector< VECTOR2D >& aPoints, double aWidth ) { - m_importer->AddPolygon( aPoints ); + m_importer->AddPolygon( aPoints, aWidth ); } -void SVG_IMPORT_PLUGIN::DrawLineSegments( const std::vector< VECTOR2D >& aPoints ) +void SVG_IMPORT_PLUGIN::DrawLineSegments( const std::vector< VECTOR2D >& aPoints, double aWidth ) { unsigned int numLineStartPoints = aPoints.size() - 1; for( unsigned int pointIndex = 0; pointIndex < numLineStartPoints; ++pointIndex ) - m_importer->AddLine( aPoints[ pointIndex ], aPoints[ pointIndex + 1 ] ); + m_importer->AddLine( aPoints[ pointIndex ], aPoints[ pointIndex + 1 ], aWidth ); } @@ -185,10 +211,8 @@ static float calculateBezierSegmentationThreshold( const float* aCurvePoints ) static VECTOR2D calculateBezierBoundingBoxExtremity( const float* aCurvePoints, std::function< const float&( const float&, const float& ) > comparator ) { - float x, y; - - x = aCurvePoints[0]; - y = aCurvePoints[1]; + float x = aCurvePoints[0]; + float y = aCurvePoints[1]; for( int pointIndex = 1; pointIndex < 3; ++pointIndex ) { diff --git a/pcbnew/import_gfx/svg_import_plugin.h b/pcbnew/import_gfx/svg_import_plugin.h index e43bb575e0..464c81fb3b 100644 --- a/pcbnew/import_gfx/svg_import_plugin.h +++ b/pcbnew/import_gfx/svg_import_plugin.h @@ -3,6 +3,7 @@ * * Copyright (C) 2016 CERN * @author Janito V. Ferreira Filho + * Copyright (C) 2018 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 @@ -25,11 +26,11 @@ #ifndef SVG_IMPORT_PLUGIN_H #define SVG_IMPORT_PLUGIN_H +#include "vector" + #include "nanosvg.h" #include "graphics_import_plugin.h" -//#include "drw_interface.h" -#include "convert_to_biu.h" #include @@ -46,34 +47,22 @@ public: return wxArrayString( 1, { "svg" } ); } - bool Import(float aXScale, float aYScale) override; + /** + * @return the list of messages in one string. Each message ends by '\n' + */ + const std::string& GetMessages() const override + { + return m_messages; + } + + bool Import() override; bool Load( const wxString& aFileName ) override; - virtual unsigned int GetImageHeight() const override - { - if( !m_parsedImage ) - { - wxASSERT_MSG(false, "Image must have been loaded before checking height"); - return false; - } - - return Millimeter2iu( m_parsedImage->height ); - } - - virtual unsigned int GetImageWidth() const override - { - if( !m_parsedImage ) - { - wxASSERT_MSG(false, "Image must have been loaded before checking width"); - return false; - } - - return Millimeter2iu( m_parsedImage->width ); - } - + virtual double GetImageHeight() const override; + virtual double GetImageWidth() const override; private: - void DrawPath( const float* aPoints, int aNumPoints, bool aClosedPath ); + void DrawPath( const float* aPoints, int aNumPoints, bool aClosedPath, bool aFilled, double aLineWidth ); void DrawCubicBezierPath( const float* aPoints, int aNumPoints, std::vector< VECTOR2D >& aGeneratedPoints ); @@ -81,10 +70,13 @@ private: void DrawCubicBezierCurve( const float* aPoints, std::vector< VECTOR2D >& aGeneratedPoints ); - void DrawPolygon( const std::vector< VECTOR2D >& aPoints ); - void DrawLineSegments( const std::vector< VECTOR2D >& aPoints ); + void DrawPolygon( const std::vector< VECTOR2D >& aPoints, double aWidth ); + void DrawLineSegments( const std::vector< VECTOR2D >& aPoints, double aWidth ); struct NSVGimage* m_parsedImage; + + std::string m_messages; // messages generated during svg file parsing. + // Each message ends by '\n' }; #endif /* SVG_IMPORT_PLUGIN_H */ diff --git a/pcbnew/invoke_pcb_dialog.h b/pcbnew/invoke_pcb_dialog.h index 9d178cb36b..27457ef232 100644 --- a/pcbnew/invoke_pcb_dialog.h +++ b/pcbnew/invoke_pcb_dialog.h @@ -96,23 +96,21 @@ void InvokePluginOptionsEditor( wxWindow* aCaller, const wxString& aNickname, const wxString& aPluginType, const wxString& aOptions, wxString* aResult ); /** - * Function InvokeDXFDialogBoardImport - * shows the modal DIALOG_DXF_IMPORT for importing a DXF file to a board. + * Shows the modal DIALOG_IMPORT_GFX for importing a DXF file to a board. * @param aCaller is the wxTopLevelWindow which is invoking the dialog. * @return true if the import was made. */ -bool InvokeDXFDialogBoardImport( PCB_BASE_FRAME* aCaller ); +bool InvokeDialogImportGfxBoard( PCB_BASE_FRAME* aCaller ); /** - * Function InvokeDXFDialogModuleImport - * shows the modal DIALOG_DXF_IMPORT for importing a DXF file as footprint outlines. + * shows the modal DIALOG_IMPORT_GFX for importing a DXF file as footprint outlines. * * @param aCaller is the wxTopLevelWindow which is invoking the dialog. * @param aModule is the footprint currently edited. * @return true if the import was made. */ -bool InvokeDXFDialogModuleImport( PCB_BASE_FRAME* aCaller, MODULE* aModule ); +bool InvokeDialogImportGfxModule( PCB_BASE_FRAME* aCaller, MODULE* aModule ); /** * Function InvokeExportSVG diff --git a/pcbnew/menubar_pcb_editor.cpp b/pcbnew/menubar_pcb_editor.cpp index 323ee4e2d7..b104f2517b 100644 --- a/pcbnew/menubar_pcb_editor.cpp +++ b/pcbnew/menubar_pcb_editor.cpp @@ -831,8 +831,8 @@ void prepareFilesMenu( wxMenu* aParentMenu, bool aIsOutsideProject ) KiBitmap( import_xpm ) ); AddMenuItem( submenuImport, ID_GEN_IMPORT_GRAPHICS_FILE, - _( "SVG or DXF &Graphics..." ), - _( "Import 2D Drawing DXF or SVG file to Pcbnew on Drawings layer" ), + _( "Import &Graphics..." ), + _( "Import 2D Drawing file to Pcbnew on Drawings layer" ), KiBitmap( import_xpm ) ); AddMenuItem( aParentMenu, submenuImport, diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index 6fee9c837d..bc75b704fb 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -739,33 +739,58 @@ int DRAWING_TOOL::PlaceImportedGraphics( const TOOL_EVENT& aEvent ) if( !m_frame->GetModel() ) return 0; - //DIALOG_DXF_IMPORT dlg( m_frame ); // Note: PlaceImportedGraphics() will convert PCB_LINE_T and PCB_TEXT_T to module graphic items // if needed - DIALOG_IMPORT_GFX dlg( m_frame, false );// m_editModules ); + DIALOG_IMPORT_GFX dlg( m_frame, m_editModules ); int dlgResult = dlg.ShowModal(); - /*const std::list*/auto& list = dlg.GetImportedItems(); + auto& list = dlg.GetImportedItems(); - if( dlgResult != wxID_OK || list.empty() ) + if( dlgResult != wxID_OK ) return 0; + // Ensure the list is not empty: + if( list.empty() ) + { + wxMessageBox( _( "No graphic items found in file to import") ); + return 0; + } + + + m_frame->SetNoToolSelected(); + // Add a VIEW_GROUP that serves as a preview for the new item SELECTION preview; BOARD_COMMIT commit( m_frame ); // Build the undo list & add items to the current view - //for( auto item : list ) for( auto it = list.begin(), itEnd = list.end(); it != itEnd; ++it ) { EDA_ITEM* item = it->get(); - wxASSERT( item->Type() == PCB_LINE_T || item->Type() == PCB_TEXT_T ); + if( m_editModules ) + { + wxASSERT( item->Type() == PCB_MODULE_EDGE_T || item->Type() == PCB_MODULE_TEXT_T ); + } + else + { + wxASSERT( item->Type() == PCB_LINE_T || item->Type() == PCB_TEXT_T ); + } + + if( dlg.IsPlacementInteractive() ) + preview.Add( item ); + else + commit.Add( item ); - preview.Add( item ); it->release(); } + if( !dlg.IsPlacementInteractive() ) + { + commit.Push( _( "Place a DXF_SVG drawing" ) ); + return 0; + } + BOARD_ITEM* firstItem = static_cast( preview.Front() ); m_view->Add( &preview ); @@ -836,86 +861,9 @@ int DRAWING_TOOL::PlaceImportedGraphics( const TOOL_EVENT& aEvent ) } else if( evt->IsClick( BUT_LEFT ) ) { - // Place the drawing - BOARD_ITEM_CONTAINER* parent = m_frame->GetModel(); - + // Place the imported drawings for( auto item : preview ) - { - if( m_editModules ) - { - // Modules use different types for the same things, - // so we need to convert imported items to appropriate classes. - BOARD_ITEM* converted = NULL; - - switch( item->Type() ) - { - case PCB_TEXT_T: - { - TEXTE_PCB* text = static_cast( item ); - TEXTE_MODULE* textMod = new TEXTE_MODULE( (MODULE*) parent ); - - // Assignment operator also copies the item PCB_TEXT_T type, - // so it cannot be added to a module which handles PCB_MODULE_TEXT_T - textMod->SetText( text->GetText() ); -#if 0 - textMod->SetTextSize( text->GetTextSize() ); - textMod->SetThickness( text->GetThickness() ); - textMod->SetOrientation( text->GetTextAngle() ); - textMod->SetTextPos( text->GetTextPos() ); - textMod->SetTextSize( text->GetTextSize() ); - textMod->SetVisible( text->GetVisible() ); - textMod->SetMirrored( text->IsMirrored() ); - textMod->SetItalic( text->IsItalic() ); - textMod->SetBold( text->IsBold() ); - textMod->SetHorizJustify( text->GetHorizJustify() ); - textMod->SetVertJustify( text->GetVertJustify() ); - textMod->SetMultilineAllowed( text->IsMultilineAllowed() ); -#else - textMod->EDA_TEXT::SetEffects( *text ); - textMod->SetLocalCoord(); // using changed SetTexPos() via SetEffects() -#endif - converted = textMod; - break; - } - - case PCB_LINE_T: - { - DRAWSEGMENT* seg = static_cast( item ); - EDGE_MODULE* modSeg = new EDGE_MODULE( (MODULE*) parent ); - - // Assignment operator also copies the item PCB_LINE_T type, - // so it cannot be added to a module which handles PCB_MODULE_EDGE_T - modSeg->SetWidth( seg->GetWidth() ); - modSeg->SetStart( seg->GetStart() ); - modSeg->SetEnd( seg->GetEnd() ); - modSeg->SetAngle( seg->GetAngle() ); - modSeg->SetShape( seg->GetShape() ); - modSeg->SetType( seg->GetType() ); - modSeg->SetBezControl1( seg->GetBezControl1() ); - modSeg->SetBezControl2( seg->GetBezControl2() ); - modSeg->SetBezierPoints( seg->GetBezierPoints() ); - modSeg->SetPolyShape( seg->GetPolyShape() ); - modSeg->SetLocalCoord(); - converted = modSeg; - break; - } - - default: - wxASSERT_MSG( false, - wxString::Format( "item type %d not allowed", item->Type() ) ); - break; - } - - if( converted ) - converted->SetLayer( static_cast( item )->GetLayer() ); - - delete item; - item = converted; - } - - if( item ) - commit.Add( item ); - } + commit.Add( item ); commit.Push( _( "Place a DXF_SVG drawing" ) ); break;