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.
This commit is contained in:
jean-pierre charras 2018-11-05 17:04:05 +01:00
parent 430c61822d
commit cc0aa8b928
25 changed files with 3430 additions and 2683 deletions

View File

@ -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

View File

@ -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;

View File

@ -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;

File diff suppressed because it is too large Load Diff

View File

@ -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 <kiface_i.h>
#include <convert_to_biu.h>
#include <confirm.h>
#include <pcb_layer_box_selector.h>
#include <wildcards_and_files_ext.h>
#include <pcb_base_frame.h>
#include <class_board.h>
#include <class_module.h>
#include <class_edge_mod.h>
#include <class_text_mod.h>
#include <class_pcb_text.h>
#include <pcb_layer_box_selector.h>
#include <import_gfx/graphics_importer_pcbnew.h>
#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<BOARD_ITEM*>( 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<BOARD_ITEM*>( 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<BOARD_ITEM*>( 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<BOARD_ITEM*>( 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;
}

View File

@ -22,47 +22,68 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <pcb_edit_frame.h>
#include "dialog_import_gfx_base.h"
#include <import_gfx/graphics_importer_pcbnew.h>
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<std::unique_ptr<EDA_ITEM>>& 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<GRAPHICS_IMPORTER_PCBNEW> 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();
};

View File

@ -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 );
}

File diff suppressed because it is too large Load Diff

View File

@ -26,16 +26,15 @@ class PCB_LAYER_BOX_SELECTOR;
#include <wx/icon.h>
#include <wx/button.h>
#include <wx/sizer.h>
#include <wx/choice.h>
#include <wx/radiobox.h>
#include <wx/valtext.h>
#include <wx/bmpcbox.h>
#include <wx/statline.h>
#include <wx/radiobut.h>
#include <wx/valtext.h>
#include <wx/choice.h>
#include <wx/bmpcbox.h>
#include <wx/dialog.h>
///////////////////////////////////////////////////////////////////////////
#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();
};

View File

@ -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 <class_text_mod.h>
#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<int>::max();
m_maxX = std::numeric_limits<int>::min();
m_minY = std::numeric_limits<int>::max();
m_maxY = std::numeric_limits<int>::min();
m_minX = m_minY = std::numeric_limits<double>::max();
m_maxX = m_maxY = std::numeric_limits<double>::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 );

View File

@ -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<SPLINE_CTRL_POINT> m_SplineControlPointList;
// fit points list, code 11, 21 & 31 (only X and Y cood)
std::vector<wxRealPoint> m_SplineFitPointList;
std::vector<VECTOR2D> 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<BOARD_ITEM*> 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<BOARD_ITEM*>& 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 );

View File

@ -38,7 +38,8 @@ class GRAPHICS_IMPORT_MGR
{
public:
///> List of handled file types.
enum GFX_FILE_T {
enum GFX_FILE_T
{
DXF,
SVG
};

View File

@ -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:

View File

@ -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();
}

View File

@ -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<GRAPHICS_IMPORT_PLUGIN> 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 */

View File

@ -32,28 +32,28 @@ static std::unique_ptr<T> make_shape( const Args&... aArguments )
return std::unique_ptr<T>( 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 ) );
}

View File

@ -3,6 +3,7 @@
*
* Copyright (C) 2017 CERN
* @author Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
* 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,

View File

@ -3,13 +3,14 @@
*
* Copyright (C) 2016 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
* 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 <class_text_mod.h>
#include <tuple>
using namespace std;
static std::vector<wxPoint> convertPoints( const std::vector<VECTOR2D>& 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<DRAWSEGMENT> 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<EDGE_MODULE*>( 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<DRAWSEGMENT> 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<EDGE_MODULE*>( 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<DRAWSEGMENT> 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<EDGE_MODULE*>( 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<DRAWSEGMENT> polygon( createDrawing() );
polygon->SetShape( S_POLYGON );
polygon->SetLayer( GetLayer() );
polygon->SetPolyPoints( convertedVertices );
polygon->SetPolyPoints( convertedPoints );
if( polygon->Type() == PCB_MODULE_EDGE_T )
static_cast<EDGE_MODULE*>( 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<TEXTE_MODULE*>( 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<DRAWSEGMENT> 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<EDGE_MODULE*>( spline.get() )->SetLocalCoord();
addItem( std::move( spline ) );
}
@ -133,7 +178,7 @@ unique_ptr<DRAWSEGMENT> GRAPHICS_IMPORTER_BOARD::createDrawing()
}
pair<unique_ptr<BOARD_ITEM>, EDA_TEXT*> GRAPHICS_IMPORTER_BOARD::createText()
std::pair<unique_ptr<BOARD_ITEM>, EDA_TEXT*> GRAPHICS_IMPORTER_BOARD::createText()
{
TEXTE_PCB* text = new TEXTE_PCB( m_board );
return make_pair( unique_ptr<BOARD_ITEM>( text ), static_cast<EDA_TEXT*>( text ) );
@ -146,26 +191,8 @@ unique_ptr<DRAWSEGMENT> GRAPHICS_IMPORTER_MODULE::createDrawing()
}
pair<unique_ptr<BOARD_ITEM>, EDA_TEXT*> GRAPHICS_IMPORTER_MODULE::createText()
std::pair<unique_ptr<BOARD_ITEM>, EDA_TEXT*> GRAPHICS_IMPORTER_MODULE::createText()
{
TEXTE_MODULE* text = new TEXTE_MODULE( m_module );
return make_pair( unique_ptr<BOARD_ITEM>( text ), static_cast<EDA_TEXT*>( text ) );
}
static std::vector< wxPoint > convertPoints( const std::vector<VECTOR2D>& aPoints,
double aScaleFactor )
{
std::vector<wxPoint> 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;
}

View File

@ -3,6 +3,7 @@
*
* Copyright (C) 2016 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
* 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<DRAWSEGMENT> createDrawing() = 0;

View File

@ -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.

View File

@ -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 )
{

View File

@ -3,6 +3,7 @@
*
* Copyright (C) 2016 CERN
* @author Janito V. Ferreira Filho <janito.vff@gmail.com>
* 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 <math/vector2d.h>
@ -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 */

View File

@ -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

View File

@ -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,

View File

@ -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<BOARD_ITEM*>*/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<BOARD_ITEM*>( 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<TEXTE_PCB*>( 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<DRAWSEGMENT*>( 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<BOARD_ITEM*>( item )->GetLayer() );
delete item;
item = converted;
}
if( item )
commit.Add( item );
}
commit.Add( item );
commit.Push( _( "Place a DXF_SVG drawing" ) );
break;