Remove pcbnew/import_dxf because all the useful code was moved/merged to import_gfx
This commit is contained in:
parent
3b54a44540
commit
4493af9f4d
|
@ -1,399 +0,0 @@
|
||||||
/**
|
|
||||||
* @file dialog_dxf_import.cpp
|
|
||||||
* @brief Dialog to import a dxf file on a given board layer.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors.
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2
|
|
||||||
* of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, you may find one here:
|
|
||||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|
||||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
|
||||||
* or you may write to the Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <dialog_dxf_import.h>
|
|
||||||
#include <kiface_i.h>
|
|
||||||
#include <convert_to_biu.h>
|
|
||||||
#include <pcb_layer_box_selector.h>
|
|
||||||
#include <wildcards_and_files_ext.h>
|
|
||||||
|
|
||||||
#include <class_board.h>
|
|
||||||
#include <class_module.h>
|
|
||||||
#include <class_edge_mod.h>
|
|
||||||
#include <class_text_mod.h>
|
|
||||||
#include <class_pcb_text.h>
|
|
||||||
|
|
||||||
// Keys to store setup in config
|
|
||||||
#define DXF_IMPORT_LAYER_OPTION_KEY "DxfImportBrdLayer"
|
|
||||||
#define DXF_IMPORT_COORD_ORIGIN_KEY "DxfImportCoordOrigin"
|
|
||||||
#define DXF_IMPORT_LAST_FILE_KEY "DxfImportLastFile"
|
|
||||||
#define DXF_IMPORT_IMPORT_UNITS_KEY "DxfImportOffsetUnits"
|
|
||||||
#define DXF_IMPORT_IMPORT_OFFSET_X_KEY "DxfImportOffsetX"
|
|
||||||
#define DXF_IMPORT_IMPORT_OFFSET_Y_KEY "DxfImportOffsetY"
|
|
||||||
#define DXF_IMPORT_LINEWIDTH_UNITS_KEY "DxfImportLineWidthUnits"
|
|
||||||
#define DXF_IMPORT_LINEWIDTH_KEY "DxfImportLineWidth"
|
|
||||||
|
|
||||||
|
|
||||||
// Static members of DIALOG_DXF_IMPORT, to remember
|
|
||||||
// the user's choices during the session
|
|
||||||
wxString DIALOG_DXF_IMPORT::m_dxfFilename;
|
|
||||||
int DIALOG_DXF_IMPORT::m_offsetSelection = 0;
|
|
||||||
LAYER_NUM DIALOG_DXF_IMPORT::m_layer = Dwgs_User;
|
|
||||||
|
|
||||||
|
|
||||||
DIALOG_DXF_IMPORT::DIALOG_DXF_IMPORT( PCB_BASE_FRAME* aParent, bool aImportAsFootprintGraphic )
|
|
||||||
: DIALOG_DXF_IMPORT_BASE( aParent )
|
|
||||||
{
|
|
||||||
m_parent = aParent;
|
|
||||||
m_dxfImporter.ImportAsFootprintGraphic( aImportAsFootprintGraphic );
|
|
||||||
m_config = Kiface().KifaceSettings();
|
|
||||||
m_PcbImportUnits = 0;
|
|
||||||
m_PcbImportOffsetX = 0.0; // always in mm
|
|
||||||
m_PcbImportOffsetY = 0.0; // always in mm
|
|
||||||
m_PCBdefaultLineWidth = 0.2; // in mm
|
|
||||||
m_PCBLineWidthUnits = 0;
|
|
||||||
|
|
||||||
if( m_config )
|
|
||||||
{
|
|
||||||
m_layer = m_config->Read( DXF_IMPORT_LAYER_OPTION_KEY, (long)Dwgs_User );
|
|
||||||
m_offsetSelection = m_config->Read( DXF_IMPORT_COORD_ORIGIN_KEY, (long)0 );
|
|
||||||
m_dxfFilename = m_config->Read( DXF_IMPORT_LAST_FILE_KEY, wxEmptyString );
|
|
||||||
m_config->Read( DXF_IMPORT_IMPORT_UNITS_KEY, &m_PcbImportUnits, 0 );
|
|
||||||
m_config->Read( DXF_IMPORT_IMPORT_OFFSET_X_KEY, &m_PcbImportOffsetX, 0.0 );
|
|
||||||
m_config->Read( DXF_IMPORT_IMPORT_OFFSET_Y_KEY, &m_PcbImportOffsetY, 0.0 );
|
|
||||||
m_config->Read( DXF_IMPORT_LINEWIDTH_UNITS_KEY, &m_PCBLineWidthUnits, 0 );
|
|
||||||
m_config->Read( DXF_IMPORT_LINEWIDTH_KEY, &m_PCBdefaultLineWidth, 0.2 );
|
|
||||||
}
|
|
||||||
|
|
||||||
m_choiceUnitLineWidth->SetSelection( m_PCBLineWidthUnits );
|
|
||||||
showPCBdefaultLineWidth();
|
|
||||||
m_dxfImporter.SetDefaultLineWidthMM( m_PCBdefaultLineWidth );
|
|
||||||
|
|
||||||
m_DxfPcbPositionUnits->SetSelection( m_PcbImportUnits );
|
|
||||||
showPcbImportOffsets();
|
|
||||||
|
|
||||||
m_textCtrlFileName->SetValue( m_dxfFilename );
|
|
||||||
m_rbOffsetOption->SetSelection( m_offsetSelection );
|
|
||||||
|
|
||||||
// Configure the layers list selector
|
|
||||||
m_SelLayerBox->SetLayersHotkeys( false ); // Do not display hotkeys
|
|
||||||
m_SelLayerBox->SetNotAllowedLayerSet( LSET::AllCuMask() ); // Do not use copper layers
|
|
||||||
m_SelLayerBox->SetBoardFrame( m_parent );
|
|
||||||
m_SelLayerBox->Resync();
|
|
||||||
|
|
||||||
if( m_SelLayerBox->SetLayerSelection( m_layer ) < 0 )
|
|
||||||
{
|
|
||||||
m_layer = Dwgs_User;
|
|
||||||
m_SelLayerBox->SetLayerSelection( m_layer );
|
|
||||||
}
|
|
||||||
|
|
||||||
m_sdbSizerOK->SetDefault();
|
|
||||||
GetSizer()->Fit( this );
|
|
||||||
GetSizer()->SetSizeHints( this );
|
|
||||||
Centre();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DIALOG_DXF_IMPORT::~DIALOG_DXF_IMPORT()
|
|
||||||
{
|
|
||||||
m_offsetSelection = m_rbOffsetOption->GetSelection();
|
|
||||||
getPcbImportOffsets();
|
|
||||||
m_layer = m_SelLayerBox->GetLayerSelection();
|
|
||||||
|
|
||||||
if( m_config )
|
|
||||||
{
|
|
||||||
m_config->Write( DXF_IMPORT_LAYER_OPTION_KEY, (long)m_layer );
|
|
||||||
m_config->Write( DXF_IMPORT_COORD_ORIGIN_KEY, m_offsetSelection );
|
|
||||||
m_config->Write( DXF_IMPORT_LAST_FILE_KEY, m_dxfFilename );
|
|
||||||
|
|
||||||
m_config->Write( DXF_IMPORT_IMPORT_UNITS_KEY, m_PcbImportUnits );
|
|
||||||
m_config->Write( DXF_IMPORT_IMPORT_OFFSET_X_KEY, m_PcbImportOffsetX );
|
|
||||||
m_config->Write( DXF_IMPORT_IMPORT_OFFSET_Y_KEY, m_PcbImportOffsetY );
|
|
||||||
|
|
||||||
m_config->Write( DXF_IMPORT_LINEWIDTH_UNITS_KEY, m_PCBLineWidthUnits );
|
|
||||||
m_PCBLineWidthUnits = getPCBdefaultLineWidthMM();
|
|
||||||
m_config->Write( DXF_IMPORT_LINEWIDTH_KEY, m_PCBdefaultLineWidth );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DIALOG_DXF_IMPORT::DIALOG_DXF_IMPORT::onUnitPositionSelection( wxCommandEvent& event )
|
|
||||||
{
|
|
||||||
// Collect last entered values:
|
|
||||||
getPcbImportOffsets();
|
|
||||||
|
|
||||||
m_PcbImportUnits = m_DxfPcbPositionUnits->GetSelection();;
|
|
||||||
showPcbImportOffsets();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
double DIALOG_DXF_IMPORT::getPCBdefaultLineWidthMM()
|
|
||||||
{
|
|
||||||
double value = DoubleValueFromString( UNSCALED_UNITS, m_textCtrlLineWidth->GetValue() );
|
|
||||||
|
|
||||||
switch( m_PCBLineWidthUnits )
|
|
||||||
{
|
|
||||||
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_DXF_IMPORT::onUnitWidthSelection( wxCommandEvent& event )
|
|
||||||
{
|
|
||||||
m_PCBdefaultLineWidth = getPCBdefaultLineWidthMM();
|
|
||||||
|
|
||||||
// Switch to new units
|
|
||||||
m_PCBLineWidthUnits = m_choiceUnitLineWidth->GetSelection();
|
|
||||||
showPCBdefaultLineWidth();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DIALOG_DXF_IMPORT::showPcbImportOffsets()
|
|
||||||
{
|
|
||||||
// Display m_PcbImportOffsetX and m_PcbImportOffsetY values according to
|
|
||||||
// the unit selection:
|
|
||||||
double xoffset = m_PcbImportOffsetX;
|
|
||||||
double yoffset = m_PcbImportOffsetY;
|
|
||||||
|
|
||||||
if( m_PcbImportUnits ) // Units are inches
|
|
||||||
{
|
|
||||||
xoffset /= 25.4;
|
|
||||||
yoffset /= 25.4;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_DxfPcbXCoord->SetValue( wxString::Format( "%f", xoffset ) );
|
|
||||||
m_DxfPcbYCoord->SetValue( wxString::Format( "%f", yoffset ) );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DIALOG_DXF_IMPORT::showPCBdefaultLineWidth()
|
|
||||||
{
|
|
||||||
double value;
|
|
||||||
|
|
||||||
switch( m_PCBLineWidthUnits )
|
|
||||||
{
|
|
||||||
default:
|
|
||||||
case 0: // display units = mm
|
|
||||||
value = m_PCBdefaultLineWidth;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1: // display units = mil
|
|
||||||
value = m_PCBdefaultLineWidth / 25.4 * 1000;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2: // display units = inch
|
|
||||||
value = m_PCBdefaultLineWidth / 25.4;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_textCtrlLineWidth->SetValue( wxString::Format( "%f", value ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DIALOG_DXF_IMPORT::OnBrowseDxfFiles( wxCommandEvent& event )
|
|
||||||
{
|
|
||||||
wxString path;
|
|
||||||
wxString filename;
|
|
||||||
|
|
||||||
if( !m_dxfFilename.IsEmpty() )
|
|
||||||
{
|
|
||||||
wxFileName fn( m_dxfFilename );
|
|
||||||
path = fn.GetPath();
|
|
||||||
filename = fn.GetFullName();
|
|
||||||
}
|
|
||||||
|
|
||||||
wxFileDialog dlg( m_parent,
|
|
||||||
_( "Open File" ),
|
|
||||||
path, filename,
|
|
||||||
DxfFileWildcard(),
|
|
||||||
wxFD_OPEN|wxFD_FILE_MUST_EXIST );
|
|
||||||
|
|
||||||
if( dlg.ShowModal() != wxID_OK )
|
|
||||||
return;
|
|
||||||
|
|
||||||
wxString fileName = dlg.GetPath();
|
|
||||||
|
|
||||||
if( fileName.IsEmpty() )
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_dxfFilename = fileName;
|
|
||||||
m_textCtrlFileName->SetValue( fileName );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool DIALOG_DXF_IMPORT::TransferDataFromWindow()
|
|
||||||
{
|
|
||||||
m_dxfFilename = m_textCtrlFileName->GetValue();
|
|
||||||
|
|
||||||
if( m_dxfFilename.IsEmpty() )
|
|
||||||
{
|
|
||||||
wxMessageBox( _( "Error: No DXF filename!" ) );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
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:
|
|
||||||
getPcbImportOffsets();
|
|
||||||
offsetX = m_PcbImportOffsetX;
|
|
||||||
offsetY = m_PcbImportOffsetY;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set coordinates offset for import (offset is given in mm)
|
|
||||||
m_dxfImporter.SetOffset( offsetX, offsetY );
|
|
||||||
m_layer = m_SelLayerBox->GetLayerSelection();
|
|
||||||
|
|
||||||
if( m_layer < 0 )
|
|
||||||
{
|
|
||||||
wxMessageBox( _( "Please, select a valid layer " ) );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_dxfImporter.SetBrdLayer( m_layer );
|
|
||||||
m_PCBdefaultLineWidth = getPCBdefaultLineWidthMM();
|
|
||||||
m_dxfImporter.SetDefaultLineWidthMM( m_PCBdefaultLineWidth );
|
|
||||||
|
|
||||||
// Read dxf file:
|
|
||||||
m_dxfImporter.ImportDxfFile( m_dxfFilename );
|
|
||||||
|
|
||||||
// Get messages:
|
|
||||||
std::string& messages = m_dxfImporter.GetMessages();
|
|
||||||
|
|
||||||
if( messages.empty() )
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// Show messages (list of net handled dxf items
|
|
||||||
wxMessageBox( messages.c_str(), _( "Not Handled DXF Items" ) );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool InvokeDXFDialogBoardImport( PCB_BASE_FRAME* aCaller )
|
|
||||||
{
|
|
||||||
DIALOG_DXF_IMPORT dlg( aCaller );
|
|
||||||
bool success = ( dlg.ShowModal() == wxID_OK );
|
|
||||||
|
|
||||||
if( success )
|
|
||||||
{
|
|
||||||
const std::list<BOARD_ITEM*>& list = dlg.GetImportedItems();
|
|
||||||
PICKED_ITEMS_LIST picklist;
|
|
||||||
BOARD* board = aCaller->GetBoard();
|
|
||||||
|
|
||||||
std::list<BOARD_ITEM*>::const_iterator it, itEnd;
|
|
||||||
for( it = list.begin(), itEnd = list.end(); it != itEnd; ++it )
|
|
||||||
{
|
|
||||||
BOARD_ITEM* item = *it;
|
|
||||||
board->Add( item );
|
|
||||||
|
|
||||||
ITEM_PICKER itemWrapper( item, UR_NEW );
|
|
||||||
picklist.PushItem( itemWrapper );
|
|
||||||
}
|
|
||||||
|
|
||||||
aCaller->SaveCopyInUndoList( picklist, UR_NEW, wxPoint( 0, 0 ) );
|
|
||||||
aCaller->OnModify();
|
|
||||||
}
|
|
||||||
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool InvokeDXFDialogModuleImport( PCB_BASE_FRAME* aCaller, MODULE* aModule )
|
|
||||||
{
|
|
||||||
wxASSERT( aModule );
|
|
||||||
|
|
||||||
DIALOG_DXF_IMPORT dlg( aCaller, true );
|
|
||||||
bool success = ( dlg.ShowModal() == wxID_OK );
|
|
||||||
|
|
||||||
if( success )
|
|
||||||
{
|
|
||||||
const std::list<BOARD_ITEM*>& list = dlg.GetImportedItems();
|
|
||||||
|
|
||||||
aCaller->SaveCopyInUndoList( aModule, UR_CHANGED );
|
|
||||||
aCaller->OnModify();
|
|
||||||
|
|
||||||
std::list<BOARD_ITEM*>::const_iterator it, itEnd;
|
|
||||||
|
|
||||||
for( it = list.begin(), itEnd = list.end(); it != itEnd; ++it )
|
|
||||||
{
|
|
||||||
aModule->Add( *it );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DIALOG_DXF_IMPORT::OriginOptionOnUpdateUI( wxUpdateUIEvent& event )
|
|
||||||
{
|
|
||||||
bool enable = m_rbOffsetOption->GetSelection() == 4;
|
|
||||||
|
|
||||||
m_DxfPcbPositionUnits->Enable( enable );
|
|
||||||
m_DxfPcbXCoord->Enable( enable );
|
|
||||||
m_DxfPcbYCoord->Enable( enable );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DIALOG_DXF_IMPORT::getPcbImportOffsets()
|
|
||||||
{
|
|
||||||
m_PcbImportOffsetX = DoubleValueFromString( UNSCALED_UNITS, m_DxfPcbXCoord->GetValue() );
|
|
||||||
m_PcbImportOffsetY = DoubleValueFromString( UNSCALED_UNITS, m_DxfPcbYCoord->GetValue() );
|
|
||||||
|
|
||||||
if( m_PcbImportUnits ) // Units are inches
|
|
||||||
{
|
|
||||||
m_PcbImportOffsetX *= 25.4;
|
|
||||||
m_PcbImportOffsetY *= 25.4;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
|
@ -1,72 +0,0 @@
|
||||||
/*
|
|
||||||
* 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) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2
|
|
||||||
* of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, you may find one here:
|
|
||||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|
||||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
|
||||||
* or you may write to the Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <dialog_dxf_import_base.h>
|
|
||||||
#include <pcb_edit_frame.h>
|
|
||||||
#include <dxf2brd_items.h>
|
|
||||||
|
|
||||||
class DIALOG_DXF_IMPORT : public DIALOG_DXF_IMPORT_BASE
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
DIALOG_DXF_IMPORT( PCB_BASE_FRAME* aParent, bool aUseModuleItems = false );
|
|
||||||
~DIALOG_DXF_IMPORT();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function GetImportedItems()
|
|
||||||
*
|
|
||||||
* Returns a list of items imported from a DXF file.
|
|
||||||
*/
|
|
||||||
const std::list<BOARD_ITEM*>& GetImportedItems() const
|
|
||||||
{
|
|
||||||
return m_dxfImporter.GetItemsList();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
PCB_BASE_FRAME* m_parent;
|
|
||||||
wxConfigBase* m_config; // Current config
|
|
||||||
DXF2BRD_CONVERTER m_dxfImporter;
|
|
||||||
int m_PcbImportUnits;
|
|
||||||
double m_PcbImportOffsetX; // Always in mm
|
|
||||||
double m_PcbImportOffsetY; // Always in mm
|
|
||||||
|
|
||||||
static wxString m_dxfFilename;
|
|
||||||
static int m_offsetSelection;
|
|
||||||
static LAYER_NUM m_layer;
|
|
||||||
double m_PCBdefaultLineWidth; // in mm
|
|
||||||
int m_PCBLineWidthUnits;
|
|
||||||
|
|
||||||
// Virtual event handlers
|
|
||||||
void onUnitPositionSelection( wxCommandEvent& event ) override;
|
|
||||||
void onUnitWidthSelection( wxCommandEvent& event ) override;
|
|
||||||
void OnBrowseDxfFiles( wxCommandEvent& event ) override;
|
|
||||||
void OriginOptionOnUpdateUI( wxUpdateUIEvent& event ) override;
|
|
||||||
|
|
||||||
void getPcbImportOffsets();
|
|
||||||
double getPCBdefaultLineWidthMM();
|
|
||||||
void showPCBdefaultLineWidth();
|
|
||||||
void showPcbImportOffsets();
|
|
||||||
|
|
||||||
// Automatically called by OK button:
|
|
||||||
bool TransferDataFromWindow() override;
|
|
||||||
};
|
|
|
@ -1,213 +0,0 @@
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
// C++ code generated with wxFormBuilder (version Aug 4 2017)
|
|
||||||
// http://www.wxformbuilder.org/
|
|
||||||
//
|
|
||||||
// PLEASE DO "NOT" EDIT THIS FILE!
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "pcb_layer_box_selector.h"
|
|
||||||
|
|
||||||
#include "dialog_dxf_import_base.h"
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
DIALOG_DXF_IMPORT_BASE::DIALOG_DXF_IMPORT_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
|
|
||||||
{
|
|
||||||
this->SetSizeHints( wxDefaultSize, wxDefaultSize );
|
|
||||||
|
|
||||||
wxBoxSizer* bSizerMain;
|
|
||||||
bSizerMain = new wxBoxSizer( wxVERTICAL );
|
|
||||||
|
|
||||||
wxBoxSizer* bSizerFile;
|
|
||||||
bSizerFile = new wxBoxSizer( wxHORIZONTAL );
|
|
||||||
|
|
||||||
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 ) );
|
|
||||||
|
|
||||||
bSizerFile->Add( m_textCtrlFileName, 1, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxTOP, 5 );
|
|
||||||
|
|
||||||
m_buttonBrowse = new wxButton( this, wxID_ANY, _("Browse"), wxDefaultPosition, wxDefaultSize, 0 );
|
|
||||||
bSizerFile->Add( m_buttonBrowse, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxTOP, 5 );
|
|
||||||
|
|
||||||
|
|
||||||
bSizerMain->Add( bSizerFile, 0, wxALL|wxEXPAND, 5 );
|
|
||||||
|
|
||||||
wxBoxSizer* bSizerMiddle;
|
|
||||||
bSizerMiddle = new wxBoxSizer( wxHORIZONTAL );
|
|
||||||
|
|
||||||
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 DXF Origin (0,0) Point:"), wxDefaultPosition, wxDefaultSize, m_rbOffsetOptionNChoices, m_rbOffsetOptionChoices, 1, wxRA_SPECIFY_COLS );
|
|
||||||
m_rbOffsetOption->SetSelection( 0 );
|
|
||||||
bSizerMiddle->Add( m_rbOffsetOption, 1, wxALL, 5 );
|
|
||||||
|
|
||||||
wxBoxSizer* bSizerUserPos;
|
|
||||||
bSizerUserPos = new wxBoxSizer( wxVERTICAL );
|
|
||||||
|
|
||||||
wxBoxSizer* bSizerPosSettings;
|
|
||||||
bSizerPosSettings = new wxBoxSizer( wxVERTICAL );
|
|
||||||
|
|
||||||
m_staticText6 = new wxStaticText( this, wxID_ANY, _("User defined position:"), wxDefaultPosition, wxDefaultSize, 0 );
|
|
||||||
m_staticText6->Wrap( -1 );
|
|
||||||
bSizerPosSettings->Add( m_staticText6, 0, wxALL, 5 );
|
|
||||||
|
|
||||||
wxFlexGridSizer* fgSizerUserPosition;
|
|
||||||
fgSizerUserPosition = new wxFlexGridSizer( 0, 3, 0, 0 );
|
|
||||||
fgSizerUserPosition->AddGrowableCol( 2 );
|
|
||||||
fgSizerUserPosition->SetFlexibleDirection( wxBOTH );
|
|
||||||
fgSizerUserPosition->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
|
|
||||||
|
|
||||||
|
|
||||||
fgSizerUserPosition->Add( 0, 0, 0, wxRIGHT|wxLEFT, 5 );
|
|
||||||
|
|
||||||
m_staticTextXpos = new wxStaticText( this, wxID_ANY, _("X:"), wxDefaultPosition, wxDefaultSize, 0 );
|
|
||||||
m_staticTextXpos->Wrap( -1 );
|
|
||||||
fgSizerUserPosition->Add( m_staticTextXpos, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
|
||||||
|
|
||||||
m_DxfPcbXCoord = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
|
||||||
#ifdef __WXGTK__
|
|
||||||
if ( !m_DxfPcbXCoord->HasFlag( wxTE_MULTILINE ) )
|
|
||||||
{
|
|
||||||
m_DxfPcbXCoord->SetMaxLength( 10 );
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
m_DxfPcbXCoord->SetMaxLength( 10 );
|
|
||||||
#endif
|
|
||||||
m_DxfPcbXCoord->SetToolTip( _("DXF origin on PCB Grid, X Coordinate") );
|
|
||||||
|
|
||||||
fgSizerUserPosition->Add( m_DxfPcbXCoord, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5 );
|
|
||||||
|
|
||||||
|
|
||||||
fgSizerUserPosition->Add( 0, 0, 0, wxRIGHT|wxLEFT, 5 );
|
|
||||||
|
|
||||||
m_staticTextYpos = new wxStaticText( this, wxID_ANY, _("Y:"), wxDefaultPosition, wxDefaultSize, 0 );
|
|
||||||
m_staticTextYpos->Wrap( -1 );
|
|
||||||
fgSizerUserPosition->Add( m_staticTextYpos, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT, 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") );
|
|
||||||
|
|
||||||
fgSizerUserPosition->Add( m_DxfPcbYCoord, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
|
|
||||||
|
|
||||||
|
|
||||||
fgSizerUserPosition->Add( 0, 0, 0, wxRIGHT|wxLEFT, 5 );
|
|
||||||
|
|
||||||
m_staticTextUnits = new wxStaticText( this, wxID_ANY, _("Units:"), wxDefaultPosition, wxDefaultSize, 0 );
|
|
||||||
m_staticTextUnits->Wrap( -1 );
|
|
||||||
fgSizerUserPosition->Add( m_staticTextUnits, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT, 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") );
|
|
||||||
|
|
||||||
fgSizerUserPosition->Add( m_DxfPcbPositionUnits, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
|
|
||||||
|
|
||||||
|
|
||||||
bSizerPosSettings->Add( fgSizerUserPosition, 1, wxEXPAND, 5 );
|
|
||||||
|
|
||||||
|
|
||||||
bSizerUserPos->Add( bSizerPosSettings, 1, wxEXPAND|wxTOP|wxBOTTOM, 5 );
|
|
||||||
|
|
||||||
|
|
||||||
bSizerMiddle->Add( bSizerUserPos, 1, 0, 5 );
|
|
||||||
|
|
||||||
|
|
||||||
bSizerMain->Add( bSizerMiddle, 0, wxALL|wxEXPAND, 5 );
|
|
||||||
|
|
||||||
wxBoxSizer* bSizerLayer;
|
|
||||||
bSizerLayer = new wxBoxSizer( wxVERTICAL );
|
|
||||||
|
|
||||||
m_staticTextPrms = new wxStaticText( this, wxID_ANY, _("Import parameters:"), wxDefaultPosition, wxDefaultSize, 0 );
|
|
||||||
m_staticTextPrms->Wrap( -1 );
|
|
||||||
bSizerLayer->Add( m_staticTextPrms, 0, wxALL, 5 );
|
|
||||||
|
|
||||||
wxBoxSizer* bSizer7;
|
|
||||||
bSizer7 = new wxBoxSizer( wxHORIZONTAL );
|
|
||||||
|
|
||||||
|
|
||||||
bSizer7->Add( 0, 0, 0, wxRIGHT|wxLEFT, 10 );
|
|
||||||
|
|
||||||
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, _("Default line width:"), wxDefaultPosition, wxDefaultSize, 0 );
|
|
||||||
m_staticTextLineWidth->Wrap( -1 );
|
|
||||||
fgSizerImportSettings->Add( m_staticTextLineWidth, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
|
|
||||||
|
|
||||||
m_textCtrlLineWidth = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
|
||||||
fgSizerImportSettings->Add( m_textCtrlLineWidth, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 );
|
|
||||||
|
|
||||||
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_staticTextBrdlayer = new wxStaticText( this, wxID_ANY, _("Graphic layer:"), wxDefaultPosition, wxDefaultSize, 0 );
|
|
||||||
m_staticTextBrdlayer->Wrap( -1 );
|
|
||||||
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 );
|
|
||||||
fgSizerImportSettings->Add( m_SelLayerBox, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5 );
|
|
||||||
|
|
||||||
|
|
||||||
bSizer7->Add( fgSizerImportSettings, 1, wxEXPAND, 5 );
|
|
||||||
|
|
||||||
|
|
||||||
bSizerLayer->Add( bSizer7, 1, wxEXPAND, 5 );
|
|
||||||
|
|
||||||
|
|
||||||
bSizerMain->Add( bSizerLayer, 0, wxALL|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 );
|
|
||||||
m_sdbSizer->AddButton( m_sdbSizerOK );
|
|
||||||
m_sdbSizerCancel = new wxButton( this, wxID_CANCEL );
|
|
||||||
m_sdbSizer->AddButton( m_sdbSizerCancel );
|
|
||||||
m_sdbSizer->Realize();
|
|
||||||
|
|
||||||
bSizerMain->Add( m_sdbSizer, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
|
|
||||||
|
|
||||||
|
|
||||||
this->SetSizer( bSizerMain );
|
|
||||||
this->Layout();
|
|
||||||
bSizerMain->Fit( this );
|
|
||||||
|
|
||||||
this->Centre( wxBOTH );
|
|
||||||
|
|
||||||
// Connect Events
|
|
||||||
m_buttonBrowse->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DXF_IMPORT_BASE::OnBrowseDxfFiles ), NULL, this );
|
|
||||||
m_rbOffsetOption->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_DXF_IMPORT_BASE::OriginOptionOnUpdateUI ), NULL, this );
|
|
||||||
m_DxfPcbPositionUnits->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_DXF_IMPORT_BASE::onUnitPositionSelection ), NULL, this );
|
|
||||||
m_choiceUnitLineWidth->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_DXF_IMPORT_BASE::onUnitWidthSelection ), NULL, this );
|
|
||||||
}
|
|
||||||
|
|
||||||
DIALOG_DXF_IMPORT_BASE::~DIALOG_DXF_IMPORT_BASE()
|
|
||||||
{
|
|
||||||
// Disconnect Events
|
|
||||||
m_buttonBrowse->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DXF_IMPORT_BASE::OnBrowseDxfFiles ), NULL, this );
|
|
||||||
m_rbOffsetOption->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_DXF_IMPORT_BASE::OriginOptionOnUpdateUI ), NULL, this );
|
|
||||||
m_DxfPcbPositionUnits->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_DXF_IMPORT_BASE::onUnitPositionSelection ), NULL, this );
|
|
||||||
m_choiceUnitLineWidth->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_DXF_IMPORT_BASE::onUnitWidthSelection ), NULL, this );
|
|
||||||
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,82 +0,0 @@
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
// C++ code generated with wxFormBuilder (version Aug 4 2017)
|
|
||||||
// http://www.wxformbuilder.org/
|
|
||||||
//
|
|
||||||
// PLEASE DO "NOT" EDIT THIS FILE!
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef __DIALOG_DXF_IMPORT_BASE_H__
|
|
||||||
#define __DIALOG_DXF_IMPORT_BASE_H__
|
|
||||||
|
|
||||||
#include <wx/artprov.h>
|
|
||||||
#include <wx/xrc/xmlres.h>
|
|
||||||
#include <wx/intl.h>
|
|
||||||
class DIALOG_SHIM;
|
|
||||||
class PCB_LAYER_BOX_SELECTOR;
|
|
||||||
|
|
||||||
#include "dialog_shim.h"
|
|
||||||
#include <wx/string.h>
|
|
||||||
#include <wx/stattext.h>
|
|
||||||
#include <wx/gdicmn.h>
|
|
||||||
#include <wx/font.h>
|
|
||||||
#include <wx/colour.h>
|
|
||||||
#include <wx/settings.h>
|
|
||||||
#include <wx/textctrl.h>
|
|
||||||
#include <wx/button.h>
|
|
||||||
#include <wx/sizer.h>
|
|
||||||
#include <wx/radiobox.h>
|
|
||||||
#include <wx/valtext.h>
|
|
||||||
#include <wx/choice.h>
|
|
||||||
#include <wx/bmpcbox.h>
|
|
||||||
#include <wx/statline.h>
|
|
||||||
#include <wx/dialog.h>
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#define wxID_ORIGIN_SELECT 1000
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// Class DIALOG_DXF_IMPORT_BASE
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
class DIALOG_DXF_IMPORT_BASE : public DIALOG_SHIM
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
|
|
||||||
protected:
|
|
||||||
wxStaticText* m_staticTextFile;
|
|
||||||
wxTextCtrl* m_textCtrlFileName;
|
|
||||||
wxButton* m_buttonBrowse;
|
|
||||||
wxRadioBox* m_rbOffsetOption;
|
|
||||||
wxStaticText* m_staticText6;
|
|
||||||
wxStaticText* m_staticTextXpos;
|
|
||||||
wxTextCtrl* m_DxfPcbXCoord;
|
|
||||||
wxStaticText* m_staticTextYpos;
|
|
||||||
wxTextCtrl* m_DxfPcbYCoord;
|
|
||||||
wxStaticText* m_staticTextUnits;
|
|
||||||
wxChoice* m_DxfPcbPositionUnits;
|
|
||||||
wxStaticText* m_staticTextPrms;
|
|
||||||
wxStaticText* m_staticTextLineWidth;
|
|
||||||
wxTextCtrl* m_textCtrlLineWidth;
|
|
||||||
wxChoice* m_choiceUnitLineWidth;
|
|
||||||
wxStaticText* m_staticTextBrdlayer;
|
|
||||||
PCB_LAYER_BOX_SELECTOR* m_SelLayerBox;
|
|
||||||
wxStaticLine* m_staticline;
|
|
||||||
wxStdDialogButtonSizer* m_sdbSizer;
|
|
||||||
wxButton* m_sdbSizerOK;
|
|
||||||
wxButton* m_sdbSizerCancel;
|
|
||||||
|
|
||||||
// Virtual event handlers, overide them in your derived class
|
|
||||||
virtual void OnBrowseDxfFiles( wxCommandEvent& event ) { event.Skip(); }
|
|
||||||
virtual void OriginOptionOnUpdateUI( wxUpdateUIEvent& event ) { event.Skip(); }
|
|
||||||
virtual void onUnitPositionSelection( wxCommandEvent& event ) { event.Skip(); }
|
|
||||||
virtual void onUnitWidthSelection( wxCommandEvent& event ) { event.Skip(); }
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
DIALOG_DXF_IMPORT_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Import DXF File"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
|
|
||||||
~DIALOG_DXF_IMPORT_BASE();
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif //__DIALOG_DXF_IMPORT_BASE_H__
|
|
|
@ -1,946 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2
|
|
||||||
* of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, you may find one here:
|
|
||||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|
||||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
|
||||||
* or you may write to the Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
// The DXF reader lib (libdxfrw) comes from LibreCAD project, a 2D CAD program
|
|
||||||
// libdxfrw can be found on http://sourceforge.net/projects/libdxfrw/
|
|
||||||
// or (latest sources) on
|
|
||||||
// https://github.com/LibreCAD/LibreCAD/tree/master/libraries/libdxfrw/src
|
|
||||||
//
|
|
||||||
// There is no doc to use it, but have a look to
|
|
||||||
// https://github.com/LibreCAD/LibreCAD/blob/master/librecad/src/lib/filters/rs_filterdxf.cpp
|
|
||||||
// and https://github.com/LibreCAD/LibreCAD/blob/master/librecad/src/lib/filters/rs_filterdxf.h
|
|
||||||
// Each time a dxf entity is read, a "call back" fuction is called
|
|
||||||
// like void DXF2BRD_CONVERTER::addLine( const DRW_Line& data ) when a line is read.
|
|
||||||
// this function just add the BOARD entity from dxf parameters (start and end point ...)
|
|
||||||
|
|
||||||
|
|
||||||
#include "dxf2brd_items.h"
|
|
||||||
#include <wx/arrstr.h>
|
|
||||||
#include <wx/regex.h>
|
|
||||||
|
|
||||||
#include <trigo.h>
|
|
||||||
#include <macros.h>
|
|
||||||
#include <class_board.h>
|
|
||||||
#include <class_drawsegment.h>
|
|
||||||
#include <class_edge_mod.h>
|
|
||||||
#include <class_pcb_text.h>
|
|
||||||
#include <class_text_mod.h>
|
|
||||||
#include "common.h"
|
|
||||||
|
|
||||||
// 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
|
|
||||||
|
|
||||||
DXF2BRD_CONVERTER::DXF2BRD_CONVERTER() : DL_CreationAdapter()
|
|
||||||
{
|
|
||||||
m_xOffset = 0.0; // X coord offset for conversion (in mm)
|
|
||||||
m_yOffset = 0.0; // Y coord offset for conversion (in mm)
|
|
||||||
m_DXF2mm = 1.0; // The scale factor to convert DXF units to mm
|
|
||||||
m_version = 0; // the dxf version, not yet used
|
|
||||||
m_defaultThickness = 0.2; // default thickness (in mm)
|
|
||||||
m_brdLayer = Dwgs_User; // The default import layer
|
|
||||||
m_importAsfootprintGraphicItems = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DXF2BRD_CONVERTER::~DXF2BRD_CONVERTER()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// coordinate conversions from dxf to internal units
|
|
||||||
int DXF2BRD_CONVERTER::mapX( double aDxfCoordX )
|
|
||||||
{
|
|
||||||
return Millimeter2iu( m_xOffset + ( aDxfCoordX * m_DXF2mm ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int DXF2BRD_CONVERTER::mapY( double aDxfCoordY )
|
|
||||||
{
|
|
||||||
return Millimeter2iu( m_yOffset - ( aDxfCoordY * m_DXF2mm ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int DXF2BRD_CONVERTER::mapDim( double aDxfValue )
|
|
||||||
{
|
|
||||||
return Millimeter2iu( aDxfValue * m_DXF2mm );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int DXF2BRD_CONVERTER::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 );
|
|
||||||
#endif
|
|
||||||
return Millimeter2iu( m_defaultThickness );
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DXF2BRD_CONVERTER::ImportDxfFile( const wxString& aFile )
|
|
||||||
{
|
|
||||||
LOCALE_IO locale;
|
|
||||||
|
|
||||||
DL_Dxf dxf_reader;
|
|
||||||
std::string filename = TO_UTF8( aFile );
|
|
||||||
bool success = true;
|
|
||||||
|
|
||||||
if( !dxf_reader.in( filename, this ) ) // if file open failed
|
|
||||||
success = false;
|
|
||||||
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DXF2BRD_CONVERTER::reportMsg( const char* aMessage )
|
|
||||||
{
|
|
||||||
// Add message to keep trace of not handled dxf entities
|
|
||||||
m_messages += aMessage;
|
|
||||||
m_messages += '\n';
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DXF2BRD_CONVERTER::addSpline( const DL_SplineData& aData )
|
|
||||||
{
|
|
||||||
// Called when starting reading a spline
|
|
||||||
m_curr_entity.Clear();
|
|
||||||
m_curr_entity.m_EntityParseStatus = 1;
|
|
||||||
m_curr_entity.m_EntityFlag = aData.flags;
|
|
||||||
m_curr_entity.m_EntityType = DL_ENTITY_SPLINE;
|
|
||||||
m_curr_entity.m_SplineDegree = aData.degree;
|
|
||||||
m_curr_entity.m_SplineTangentStartX = aData.tangentStartX;
|
|
||||||
m_curr_entity.m_SplineTangentStartY = aData.tangentStartY;
|
|
||||||
m_curr_entity.m_SplineTangentEndX = aData.tangentEndX;
|
|
||||||
m_curr_entity.m_SplineTangentEndY = aData.tangentEndY;
|
|
||||||
m_curr_entity.m_SplineKnotsCount = aData.nKnots;
|
|
||||||
m_curr_entity.m_SplineControlCount = aData.nControl;
|
|
||||||
m_curr_entity.m_SplineFitCount = aData.nFit;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DXF2BRD_CONVERTER::addControlPoint( const DL_ControlPointData& aData )
|
|
||||||
{
|
|
||||||
// Called for every spline control point, when reading a spline entity
|
|
||||||
m_curr_entity.m_SplineControlPointList.push_back( SPLINE_CTRL_POINT( aData.x , aData.y, aData.w ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
void DXF2BRD_CONVERTER::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 ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DXF2BRD_CONVERTER::addKnot( const DL_KnotData& aData)
|
|
||||||
{
|
|
||||||
// Called for every spline knot value, when reading a spline entity
|
|
||||||
m_curr_entity.m_SplineKnotsList.push_back( aData.k );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DXF2BRD_CONVERTER::addLayer( const DL_LayerData& aData )
|
|
||||||
{
|
|
||||||
// Not yet useful in Pcbnew.
|
|
||||||
#if 0
|
|
||||||
wxString name = wxString::FromUTF8( aData.name.c_str() );
|
|
||||||
wxLogMessage( name );
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DXF2BRD_CONVERTER::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 );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DXF2BRD_CONVERTER::addPolyline(const DL_PolylineData& aData )
|
|
||||||
{
|
|
||||||
// Convert DXF Polylines into a series of KiCad Lines and Arcs.
|
|
||||||
// A Polyline (as opposed to a LWPolyline) may be a 3D line or
|
|
||||||
// even a 3D Mesh. The only type of Polyline which is guaranteed
|
|
||||||
// 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;
|
|
||||||
m_curr_entity.m_EntityType = DL_ENTITY_POLYLINE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DXF2BRD_CONVERTER::addVertex( const DL_VertexData& aData )
|
|
||||||
{
|
|
||||||
if( m_curr_entity.m_EntityParseStatus == 0 )
|
|
||||||
return; // Error
|
|
||||||
|
|
||||||
int lineWidth = mapWidth( attributes.getWidth() );
|
|
||||||
|
|
||||||
const DL_VertexData* vertex = &aData;
|
|
||||||
|
|
||||||
if( m_curr_entity.m_EntityParseStatus == 1 ) // This is the first vertex of an entity
|
|
||||||
{
|
|
||||||
m_curr_entity.m_LastCoordinate.x = m_xOffset + vertex->x * m_DXF2mm;
|
|
||||||
m_curr_entity.m_LastCoordinate.y = m_yOffset - vertex->y * m_DXF2mm;
|
|
||||||
m_curr_entity.m_PolylineStart = m_curr_entity.m_LastCoordinate;
|
|
||||||
m_curr_entity.m_BulgeVertex = vertex->bulge;
|
|
||||||
m_curr_entity.m_EntityParseStatus = 2;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
wxRealPoint seg_end( m_xOffset + vertex->x * m_DXF2mm,
|
|
||||||
m_yOffset - vertex->y * m_DXF2mm );
|
|
||||||
|
|
||||||
if( std::abs( m_curr_entity.m_BulgeVertex ) < MIN_BULGE )
|
|
||||||
insertLine( m_curr_entity.m_LastCoordinate, seg_end, lineWidth );
|
|
||||||
else
|
|
||||||
insertArc( m_curr_entity.m_LastCoordinate, seg_end, m_curr_entity.m_BulgeVertex, lineWidth );
|
|
||||||
|
|
||||||
m_curr_entity.m_LastCoordinate = seg_end;
|
|
||||||
m_curr_entity.m_BulgeVertex = vertex->bulge;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DXF2BRD_CONVERTER::endEntity()
|
|
||||||
{
|
|
||||||
if( m_curr_entity.m_EntityType == DL_ENTITY_POLYLINE ||
|
|
||||||
m_curr_entity.m_EntityType == DL_ENTITY_LWPOLYLINE )
|
|
||||||
{
|
|
||||||
// Polyline flags bit 0 indicates closed (1) or open (0) polyline
|
|
||||||
if( m_curr_entity.m_EntityFlag & 1 )
|
|
||||||
{
|
|
||||||
int 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 );
|
|
||||||
else
|
|
||||||
insertArc( m_curr_entity.m_LastCoordinate, m_curr_entity.m_PolylineStart,
|
|
||||||
m_curr_entity.m_BulgeVertex, lineWidth );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( m_curr_entity.m_EntityType == DL_ENTITY_SPLINE )
|
|
||||||
{
|
|
||||||
int lineWidth = mapWidth( attributes.getWidth() );
|
|
||||||
insertSpline( lineWidth );
|
|
||||||
}
|
|
||||||
|
|
||||||
m_curr_entity.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DXF2BRD_CONVERTER::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 );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Import Arc entities.
|
|
||||||
*/
|
|
||||||
void DXF2BRD_CONVERTER::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 );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DXF2BRD_CONVERTER::addText( const DL_TextData& aData )
|
|
||||||
{
|
|
||||||
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 ) );
|
|
||||||
|
|
||||||
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.8 factor gives a better height/width ratio with our font
|
|
||||||
textItem->SetTextWidth( mapDim( aData.height * 0.8 ) );
|
|
||||||
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 ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DXF2BRD_CONVERTER::addMText( const DL_MTextData& aData )
|
|
||||||
{
|
|
||||||
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.8 factor gives a better height/width ratio with our font
|
|
||||||
textItem->SetTextWidth( mapDim( aData.height * 0.8 ) );
|
|
||||||
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 ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DXF2BRD_CONVERTER::setVariableInt( const std::string& key, int value, int code )
|
|
||||||
{
|
|
||||||
// Called for every int variable in the DXF file (e.g. "$INSUNITS").
|
|
||||||
|
|
||||||
if( key == "$DWGCODEPAGE" )
|
|
||||||
{
|
|
||||||
m_codePage = value;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( key == "$INSUNITS" ) // Drawing units
|
|
||||||
{
|
|
||||||
switch( value )
|
|
||||||
{
|
|
||||||
case 1: // inches
|
|
||||||
m_DXF2mm = 25.4;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2: // feet
|
|
||||||
m_DXF2mm = 304.8;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 4: // mm
|
|
||||||
m_DXF2mm = 1.0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 5: // centimeters
|
|
||||||
m_DXF2mm = 10.0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 6: // meters
|
|
||||||
m_DXF2mm = 1000.0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 8: // microinches
|
|
||||||
m_DXF2mm = 2.54e-5;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 9: // mils
|
|
||||||
m_DXF2mm = 0.0254;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 10: // yards
|
|
||||||
m_DXF2mm = 914.4;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 11: // Angstroms
|
|
||||||
m_DXF2mm = 1.0e-7;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 12: // nanometers
|
|
||||||
m_DXF2mm = 1.0e-6;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 13: // micrometers
|
|
||||||
m_DXF2mm = 1.0e-3;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 14: // decimeters
|
|
||||||
m_DXF2mm = 100.0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
// use the default of 1.0 for:
|
|
||||||
// 0: Unspecified Units
|
|
||||||
// 3: miles
|
|
||||||
// 7: kilometers
|
|
||||||
// 15: decameters
|
|
||||||
// 16: hectometers
|
|
||||||
// 17: gigameters
|
|
||||||
// 18: AU
|
|
||||||
// 19: lightyears
|
|
||||||
// 20: parsecs
|
|
||||||
m_DXF2mm = 1.0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DXF2BRD_CONVERTER::setVariableString( const std::string& key, const std::string& value,
|
|
||||||
int code )
|
|
||||||
{
|
|
||||||
// Called for every string variable in the DXF file (e.g. "$ACADVER").
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
wxString DXF2BRD_CONVERTER::toDxfString( const wxString& aStr )
|
|
||||||
{
|
|
||||||
wxString res;
|
|
||||||
int j = 0;
|
|
||||||
|
|
||||||
for( unsigned i = 0; i<aStr.length(); ++i )
|
|
||||||
{
|
|
||||||
int c = aStr[i];
|
|
||||||
|
|
||||||
if( c > 175 || c < 11 )
|
|
||||||
{
|
|
||||||
res.append( aStr.Mid( j, i - j ) );
|
|
||||||
j = i;
|
|
||||||
|
|
||||||
switch( c )
|
|
||||||
{
|
|
||||||
case 0x0A:
|
|
||||||
res += wxT( "\\P" );
|
|
||||||
break;
|
|
||||||
|
|
||||||
// diameter:
|
|
||||||
#ifdef __WINDOWS_
|
|
||||||
// windows, as always, is special.
|
|
||||||
case 0x00D8:
|
|
||||||
#else
|
|
||||||
case 0x2205:
|
|
||||||
#endif
|
|
||||||
res += wxT( "%%C" );
|
|
||||||
break;
|
|
||||||
|
|
||||||
// degree:
|
|
||||||
case 0x00B0:
|
|
||||||
res += wxT( "%%D" );
|
|
||||||
break;
|
|
||||||
|
|
||||||
// plus/minus
|
|
||||||
case 0x00B1:
|
|
||||||
res += wxT( "%%P" );
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
j--;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
res.append( aStr.Mid( j ) );
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
wxString DXF2BRD_CONVERTER::toNativeString( const wxString& aData )
|
|
||||||
{
|
|
||||||
wxString res;
|
|
||||||
|
|
||||||
// Ignore font tags:
|
|
||||||
int j = 0;
|
|
||||||
|
|
||||||
for( unsigned i = 0; i < aData.length(); ++i )
|
|
||||||
{
|
|
||||||
if( aData[ i ] == 0x7B ) // is '{' ?
|
|
||||||
{
|
|
||||||
if( aData[ i + 1 ] == 0x5c && aData[ i + 2 ] == 0x66 ) // is "\f" ?
|
|
||||||
{
|
|
||||||
// found font tag, append parsed part
|
|
||||||
res.append( aData.Mid( j, i - j ) );
|
|
||||||
|
|
||||||
// skip to ';'
|
|
||||||
for( unsigned k = i + 3; k < aData.length(); ++k )
|
|
||||||
{
|
|
||||||
if( aData[ k ] == 0x3B )
|
|
||||||
{
|
|
||||||
i = j = ++k;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// add to '}'
|
|
||||||
for( unsigned k = i; k < aData.length(); ++k )
|
|
||||||
{
|
|
||||||
if( aData[ k ] == 0x7D )
|
|
||||||
{
|
|
||||||
res.append( aData.Mid( i, k - i ) );
|
|
||||||
i = j = ++k;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
res.append( aData.Mid( j ) );
|
|
||||||
|
|
||||||
#if 1
|
|
||||||
wxRegEx regexp;
|
|
||||||
// Line feed:
|
|
||||||
regexp.Compile( wxT( "\\\\P" ) );
|
|
||||||
regexp.Replace( &res, wxT( "\n" ) );
|
|
||||||
|
|
||||||
// Space:
|
|
||||||
regexp.Compile( wxT( "\\\\~" ) );
|
|
||||||
regexp.Replace( &res, wxT( " " ) );
|
|
||||||
|
|
||||||
// diameter:
|
|
||||||
regexp.Compile( wxT( "%%[cC]" ) );
|
|
||||||
#ifdef __WINDOWS__
|
|
||||||
// windows, as always, is special.
|
|
||||||
regexp.Replace( &res, wxChar( 0xD8 ) );
|
|
||||||
#else
|
|
||||||
// Empty_set, diameter is 0x2300
|
|
||||||
regexp.Replace( &res, wxChar( 0x2205 ) );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// degree:
|
|
||||||
regexp.Compile( wxT( "%%[dD]" ) );
|
|
||||||
regexp.Replace( &res, wxChar( 0x00B0 ) );
|
|
||||||
// plus/minus
|
|
||||||
regexp.Compile( wxT( "%%[pP]" ) );
|
|
||||||
regexp.Replace( &res, wxChar( 0x00B1 ) );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DXF2BRD_CONVERTER::addTextStyle( const DL_StyleData& aData )
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DXF2BRD_CONVERTER::insertLine( const wxRealPoint& aSegStart,
|
|
||||||
const wxRealPoint& aSegEnd, int aWidth )
|
|
||||||
{
|
|
||||||
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 );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DXF2BRD_CONVERTER::insertArc( const wxRealPoint& aSegStart, const wxRealPoint& aSegEnd,
|
|
||||||
double aBulge, int aWidth )
|
|
||||||
{
|
|
||||||
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 ) );
|
|
||||||
|
|
||||||
// ensure aBulge represents an angle from +/- ( 0 .. approx 359.8 deg )
|
|
||||||
if( aBulge < -2000.0 )
|
|
||||||
aBulge = -2000.0;
|
|
||||||
else if( aBulge > 2000.0 )
|
|
||||||
aBulge = 2000.0;
|
|
||||||
|
|
||||||
double ang = 4.0 * atan( aBulge );
|
|
||||||
|
|
||||||
// reflect the Y values to put everything in a RHCS
|
|
||||||
wxRealPoint sp( aSegStart.x, -aSegStart.y );
|
|
||||||
wxRealPoint ep( aSegEnd.x, -aSegEnd.y );
|
|
||||||
// angle from end->start
|
|
||||||
double offAng = atan2( ep.y - sp.y, ep.x - sp.x );
|
|
||||||
// length of subtended segment = 1/2 distance between the 2 points
|
|
||||||
double d = 0.5 * sqrt( (sp.x - ep.x) * (sp.x - ep.x) + (sp.y - ep.y) * (sp.y - ep.y) );
|
|
||||||
// midpoint of the subtended segment
|
|
||||||
double xm = ( sp.x + ep.x ) * 0.5;
|
|
||||||
double ym = ( sp.y + ep.y ) * 0.5;
|
|
||||||
double radius = d / sin( ang * 0.5 );
|
|
||||||
|
|
||||||
if( radius < 0.0 )
|
|
||||||
radius = -radius;
|
|
||||||
|
|
||||||
// calculate the height of the triangle with base d and hypotenuse r
|
|
||||||
double dh2 = radius * radius - d * d;
|
|
||||||
|
|
||||||
// this should only ever happen due to rounding errors when r == d
|
|
||||||
if( dh2 < 0.0 )
|
|
||||||
dh2 = 0.0;
|
|
||||||
|
|
||||||
double h = sqrt( dh2 );
|
|
||||||
|
|
||||||
if( ang < 0.0 )
|
|
||||||
offAng -= M_PI_2;
|
|
||||||
else
|
|
||||||
offAng += M_PI_2;
|
|
||||||
|
|
||||||
// for angles greater than 180 deg we need to flip the
|
|
||||||
// direction in which the arc center is found relative
|
|
||||||
// to the midpoint of the subtended segment.
|
|
||||||
if( ang < -M_PI )
|
|
||||||
offAng += M_PI;
|
|
||||||
else if( ang > M_PI )
|
|
||||||
offAng -= M_PI;
|
|
||||||
|
|
||||||
// center point
|
|
||||||
double cx = h * cos( offAng ) + xm;
|
|
||||||
double cy = h * sin( offAng ) + ym;
|
|
||||||
|
|
||||||
segm->SetLayer( ToLAYER_ID( m_brdLayer ) );
|
|
||||||
segm->SetShape( S_ARC );
|
|
||||||
segm->SetCenter( wxPoint( Millimeter2iu( cx ), Millimeter2iu( -cy ) ) );
|
|
||||||
|
|
||||||
if( ang < 0.0 )
|
|
||||||
{
|
|
||||||
segm->SetArcStart( wxPoint( Millimeter2iu( ep.x ), Millimeter2iu( -ep.y ) ) );
|
|
||||||
segm->SetAngle( RAD2DECIDEG( ang ) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
segm->SetArcStart( wxPoint( Millimeter2iu( sp.x ), Millimeter2iu( -sp.y ) ) );
|
|
||||||
segm->SetAngle( RAD2DECIDEG( -ang ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
segm->SetWidth( aWidth );
|
|
||||||
|
|
||||||
m_newItemsList.push_back( segm );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#include "tinyspline_lib/tinysplinecpp.h"
|
|
||||||
|
|
||||||
void DXF2BRD_CONVERTER::insertSpline( int aWidth )
|
|
||||||
{
|
|
||||||
#if 0 // Debug only
|
|
||||||
wxLogMessage("spl deg %d kn %d ctr %d fit %d",
|
|
||||||
m_curr_entity.m_SplineDegree,
|
|
||||||
m_curr_entity.m_SplineKnotsList.size(),
|
|
||||||
m_curr_entity.m_SplineControlPointList.size(),
|
|
||||||
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 ),
|
|
||||||
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 ) );
|
|
||||||
|
|
||||||
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 );
|
|
||||||
startpoint = endpoint;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else // Use bezier curves, supported by pcbnew, to approximate the spline
|
|
||||||
tinyspline::BSpline dxfspline( m_curr_entity.m_SplineControlPointList.size(),
|
|
||||||
/* coord dim */ 2, m_curr_entity.m_SplineDegree );
|
|
||||||
std::vector<double> ctrlp;
|
|
||||||
|
|
||||||
for( unsigned ii = 0; ii < imax; ++ii )
|
|
||||||
{
|
|
||||||
ctrlp.push_back( m_curr_entity.m_SplineControlPointList[ii].m_x );
|
|
||||||
ctrlp.push_back( m_curr_entity.m_SplineControlPointList[ii].m_y );
|
|
||||||
}
|
|
||||||
|
|
||||||
dxfspline.setCtrlp( ctrlp );
|
|
||||||
dxfspline.setKnots( m_curr_entity.m_SplineKnotsList );
|
|
||||||
tinyspline::BSpline beziers( dxfspline.toBeziers() );
|
|
||||||
|
|
||||||
std::vector<double> coords = beziers.ctrlp();
|
|
||||||
|
|
||||||
// Each Bezier curve uses 4 vertices (a start point, 2 control points and a end point).
|
|
||||||
// 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 )
|
|
||||||
{
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,311 +0,0 @@
|
||||||
/****************************************************************************
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2
|
|
||||||
* of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, you may find one here:
|
|
||||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|
||||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
|
||||||
* or you may write to the Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
||||||
**********************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef DXF2BRD_ITEMS_H
|
|
||||||
#define DXF2BRD_ITEMS_H
|
|
||||||
|
|
||||||
#include "dl_dxf.h"
|
|
||||||
#include "dl_creationadapter.h"
|
|
||||||
#include "wx/wx.h"
|
|
||||||
#include <list>
|
|
||||||
|
|
||||||
class BOARD;
|
|
||||||
class BOARD_ITEM;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A helper class to store a spline control point (in X,Y plane only)
|
|
||||||
*/
|
|
||||||
struct SPLINE_CTRL_POINT
|
|
||||||
{
|
|
||||||
double m_x;
|
|
||||||
double m_y;
|
|
||||||
double m_weight;
|
|
||||||
|
|
||||||
SPLINE_CTRL_POINT( double a_x, double a_y, double a_weight )
|
|
||||||
: m_x( a_x ), m_y( a_y ), m_weight( a_weight )
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A helper class to parse a DXF entity (polyline and spline)
|
|
||||||
*/
|
|
||||||
class DXF2BRD_ENTITY_DATA
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
int m_EntityType; // the DXF type of entity
|
|
||||||
int m_EntityParseStatus; // Inside a entity: status od parsing:
|
|
||||||
// 0 = no entity
|
|
||||||
// 1 = first item of entity
|
|
||||||
// 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)
|
|
||||||
double m_BulgeVertex; // the last vertex bulge value read
|
|
||||||
|
|
||||||
// for spline parsing: parameters
|
|
||||||
unsigned int m_SplineDegree;
|
|
||||||
unsigned int m_SplineKnotsCount;
|
|
||||||
unsigned int m_SplineControlCount;
|
|
||||||
unsigned int m_SplineFitCount;
|
|
||||||
double m_SplineTangentStartX; // tangeant dir X for the start point
|
|
||||||
double m_SplineTangentStartY; // tangeant dir Y for the start point
|
|
||||||
double m_SplineTangentEndX; // tangeant dir X for the end point
|
|
||||||
double m_SplineTangentEndY; // tangeant dir Y for the end point
|
|
||||||
|
|
||||||
// for spline parsing: buffers to store control points, fit points and knot
|
|
||||||
std::vector<double> m_SplineKnotsList; // knots list, code 40
|
|
||||||
// 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;
|
|
||||||
|
|
||||||
DXF2BRD_ENTITY_DATA() { Clear(); };
|
|
||||||
|
|
||||||
// Reset the entity parameters
|
|
||||||
void Clear()
|
|
||||||
{
|
|
||||||
m_EntityType = DL_UNKNOWN;
|
|
||||||
m_EntityParseStatus = 0;
|
|
||||||
m_EntityFlag = 0;
|
|
||||||
m_SplineDegree = 1;
|
|
||||||
m_SplineKnotsCount = 0;
|
|
||||||
m_SplineControlCount = 0;
|
|
||||||
m_SplineFitCount = 0;
|
|
||||||
m_SplineTangentStartX = 0.0;
|
|
||||||
m_SplineTangentStartY = 0.0;
|
|
||||||
m_SplineTangentEndX = 0.0;
|
|
||||||
m_SplineTangentEndY = 0.0;
|
|
||||||
m_SplineKnotsList.clear();
|
|
||||||
m_SplineControlPointList.clear();
|
|
||||||
m_SplineFitPointList.clear();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class import DXF ASCII files and convert basic entities to board entities.
|
|
||||||
* It depends on the dxflib library.
|
|
||||||
*/
|
|
||||||
class DXF2BRD_CONVERTER : 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)
|
|
||||||
double m_DXF2mm; // The scale factor to convert DXF units to mm
|
|
||||||
int m_brdLayer; // The board layer to place imported DXF items
|
|
||||||
int m_version; // the dxf version, not used here
|
|
||||||
std::string m_codePage; // The code page, not used here
|
|
||||||
bool m_importAsfootprintGraphicItems; // Use module items instead of board items when true.
|
|
||||||
// true when the items are imported in the footprint editor
|
|
||||||
std::string m_messages; // messages generated during dxf file parsing.
|
|
||||||
// Each message ends by '\n'
|
|
||||||
DXF2BRD_ENTITY_DATA m_curr_entity; // the current entity parameters when parsing a DXF entity
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
DXF2BRD_CONVERTER();
|
|
||||||
~DXF2BRD_CONVERTER();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allows the import DXF items converted to board graphic items or footprint
|
|
||||||
* graphic items.
|
|
||||||
* @param aImportAsFootprintGraphic = true to import in a footprint, false to import on a board
|
|
||||||
*/
|
|
||||||
void ImportAsFootprintGraphic( bool aImportAsFootprintGraphic )
|
|
||||||
{
|
|
||||||
m_importAsfootprintGraphicItems = aImportAsFootprintGraphic;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the default line width when importing dxf items like lines to Pcbnew.
|
|
||||||
* because dxf files have no line width explicit parameter, it will be most
|
|
||||||
* of time the line width of imported lines
|
|
||||||
* @param aWidth = line width in mm
|
|
||||||
*/
|
|
||||||
void SetDefaultLineWidthMM( double aWidth )
|
|
||||||
{
|
|
||||||
m_defaultThickness = aWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the coordinate offset between the imported dxf items
|
|
||||||
* and Pcbnew.
|
|
||||||
* because dxf files have the Y axis from bottom to top;
|
|
||||||
* aOffsetX = 0, and aOffsetY = - vertical page size to import a full page
|
|
||||||
* @param aOffsetX = the X offset in mm
|
|
||||||
* @param aOffsetY = the Y offset in mm
|
|
||||||
*/
|
|
||||||
void SetOffset( double aOffsetX, double aOffsetY )
|
|
||||||
{
|
|
||||||
m_xOffset = aOffsetX;
|
|
||||||
m_yOffset = aOffsetY;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the layer number to import dxf items.
|
|
||||||
* the layer should be a techicanl layer, not a copper layer
|
|
||||||
*/
|
|
||||||
void SetBrdLayer( int aBrdLayer ) { m_brdLayer = aBrdLayer; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementation of the method used for communicate
|
|
||||||
* with this filter.
|
|
||||||
*
|
|
||||||
* @param aFile = the full filename.
|
|
||||||
*/
|
|
||||||
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; }
|
|
||||||
|
|
||||||
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
|
|
||||||
// or m_defaultThickness
|
|
||||||
int 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,
|
|
||||||
double aBulge, int aWidth );
|
|
||||||
// Add a dxf spline (stored in m_curr_entity) to the board, after conversion to segments
|
|
||||||
void insertSpline( int aWidth );
|
|
||||||
|
|
||||||
// Methods from DL_CreationAdapter:
|
|
||||||
// They are something like"call back" fonctions,
|
|
||||||
// called when the corresponding object is read in dxf file
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called for every string variable in the DXF file (e.g. "$ACADVER").
|
|
||||||
*/
|
|
||||||
virtual void setVariableString( const std::string& key, const std::string& value,
|
|
||||||
int code ) override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called for every int variable in the DXF file (e.g. "$ACADMAINTVER").
|
|
||||||
*/
|
|
||||||
virtual void setVariableInt( const std::string& key, int value, int code ) override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called for every double variable in the DXF file (e.g. "$DIMEXO").
|
|
||||||
*/
|
|
||||||
virtual void setVariableDouble( const std::string& key, double value, int code ) override {}
|
|
||||||
|
|
||||||
virtual void addLayer( const DL_LayerData& aData ) override;
|
|
||||||
virtual void addLine( const DL_LineData& aData) override;
|
|
||||||
virtual void addCircle( const DL_CircleData& aData ) override;
|
|
||||||
virtual void addArc( const DL_ArcData& aData ) override;
|
|
||||||
//virtual void addLWPolyline( const DRW_LWPolyline& aData ) override;
|
|
||||||
virtual void addText( const DL_TextData& aData ) override;
|
|
||||||
virtual void addPolyline( const DL_PolylineData& aData ) override;
|
|
||||||
|
|
||||||
/** Called for every polyline vertex */
|
|
||||||
virtual void addVertex( const DL_VertexData& aData ) override;
|
|
||||||
virtual void addMText( const DL_MTextData& aData) override;
|
|
||||||
virtual void addTextStyle( const DL_StyleData& aData ) override;
|
|
||||||
|
|
||||||
virtual void endEntity() override;
|
|
||||||
|
|
||||||
/** Called for every spline */
|
|
||||||
virtual void addSpline( const DL_SplineData& aData ) override;
|
|
||||||
|
|
||||||
/** Called for every spline control point */
|
|
||||||
virtual void addControlPoint( const DL_ControlPointData& aData ) override;
|
|
||||||
|
|
||||||
/** Called for every spline fit point */
|
|
||||||
virtual void addFitPoint( const DL_FitPointData& aData ) override;
|
|
||||||
|
|
||||||
/** Called for every spline knot value */
|
|
||||||
virtual void addKnot( const DL_KnotData& aData ) override;
|
|
||||||
|
|
||||||
// Not yet handled DXF entities:
|
|
||||||
virtual void addDimAlign( const DL_DimensionData&,
|
|
||||||
const DL_DimAlignedData& ) override { reportMsg( "DL_Dimension not managed" ); }
|
|
||||||
virtual void addDimLinear( const DL_DimensionData&,
|
|
||||||
const DL_DimLinearData& ) override { reportMsg( "DL_Dimension not managed" ); }
|
|
||||||
virtual void addDimRadial( const DL_DimensionData&,
|
|
||||||
const DL_DimRadialData& ) override { reportMsg( "DL_Dimension not managed" ); }
|
|
||||||
virtual void addDimDiametric( const DL_DimensionData&,
|
|
||||||
const DL_DimDiametricData& ) override { reportMsg( "DL_Dimension not managed" ); }
|
|
||||||
virtual void addDimAngular( const DL_DimensionData&,
|
|
||||||
const DL_DimAngularData& ) override { reportMsg( "DL_Dimension not managed" ); }
|
|
||||||
virtual void addDimAngular3P( const DL_DimensionData&,
|
|
||||||
const DL_DimAngular3PData& ) override { reportMsg( "DL_Dimension not managed" ); }
|
|
||||||
virtual void addDimOrdinate( const DL_DimensionData&,
|
|
||||||
const DL_DimOrdinateData& ) override { reportMsg( "DL_Dimension not managed" ); }
|
|
||||||
virtual void addLeader( const DL_LeaderData& ) override { reportMsg( "DL_Leader not managed" ); }
|
|
||||||
virtual void addLeaderVertex( const DL_LeaderVertexData& ) override { reportMsg( "DL_LeaderVertex not managed" ); }
|
|
||||||
|
|
||||||
virtual void addHatch( const DL_HatchData& ) override { reportMsg( "DL_Hatch not managed" ); }
|
|
||||||
|
|
||||||
virtual void addTrace( const DL_TraceData& ) override { reportMsg( "DL_Trace not managed" ); }
|
|
||||||
virtual void add3dFace( const DL_3dFaceData& ) override { reportMsg( "DL_3dFace not managed" ); }
|
|
||||||
virtual void addSolid( const DL_SolidData& ) override { reportMsg( "DL_Solid not managed" ); }
|
|
||||||
|
|
||||||
virtual void addImage( const DL_ImageData& ) override { reportMsg( "DL_ImageDa not managed" ); }
|
|
||||||
virtual void linkImage( const DL_ImageDefData& ) override { reportMsg( "DL_ImageDef not managed" ); }
|
|
||||||
virtual void addHatchLoop( const DL_HatchLoopData& ) override { reportMsg( "DL_HatchLoop not managed" ); }
|
|
||||||
virtual void addHatchEdge( const DL_HatchEdgeData& ) override { reportMsg( "DL_HatchEdge not managed" ); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts a native unicode string into a DXF encoded string.
|
|
||||||
*
|
|
||||||
* DXF endoding includes the following special sequences:
|
|
||||||
* - %%%c for a diameter sign
|
|
||||||
* - %%%d for a degree sign
|
|
||||||
* - %%%p for a plus/minus sign
|
|
||||||
*/
|
|
||||||
static wxString toDxfString( const wxString& aStr );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts a DXF encoded string into a native Unicode string.
|
|
||||||
*/
|
|
||||||
static wxString toNativeString( const wxString& aData );
|
|
||||||
|
|
||||||
void writeLine();
|
|
||||||
void writeMtext();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // DXF2BRD_ITEMS_H
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue