34#include <idf_parser.h>
50#define LINE_WIDTH (pcbIUScale.mmToIU( 0.1 ))
62 double scale = aIDFBoard.GetUserScale();
64 std::list< IDF_SEGMENT* > lines;
65 IDF_OUTLINE* outline =
nullptr;
73 aIDFBoard.GetUserOffset( offX, offY );
94 IDF_SEGMENT* seg =
new IDF_SEGMENT( sp, ep );
97 lines.push_back( seg );
112 IDF_POINT corners[4];
113 corners[0] = IDF_POINT(
left, top );
114 corners[1] = IDF_POINT(
right, top );
115 corners[2] = IDF_POINT(
right, bottom );
116 corners[3] = IDF_POINT(
left, bottom );
118 lines.push_back(
new IDF_SEGMENT( corners[0], corners[1] ) );
119 lines.push_back(
new IDF_SEGMENT( corners[1], corners[2] ) );
120 lines.push_back(
new IDF_SEGMENT( corners[2], corners[3] ) );
121 lines.push_back(
new IDF_SEGMENT( corners[3], corners[0] ) );
137 lines.push_back( seg );
154 IDF_SEGMENT* seg =
new IDF_SEGMENT( sp, ep, 360.0,
true );
157 lines.push_back( seg );
177 outline =
new IDF_OUTLINE;
178 IDF3::GetOutline( lines, *outline );
180 if( outline->empty() )
183 aIDFBoard.AddBoardOutline( outline );
187 while( !lines.empty() )
190 outline =
new IDF_OUTLINE;
192 IDF3::GetOutline( lines, *outline );
194 if( outline->empty() )
200 aIDFBoard.AddBoardOutline( outline );
209 while( !lines.empty() )
211 delete lines.front();
218 outline =
new IDF_OUTLINE;
251 outline->push(
new IDF_SEGMENT( p1, p2 ) );
253 for(
int i = 1; i < 4; ++i )
260 outline->push(
new IDF_SEGMENT( p1, p2 ) );
263 aIDFBoard.AddBoardOutline( outline );
273 bool aIncludeUnspecified,
bool aIncludeDNP )
279 wxString footprintBasePath = wxEmptyString;
295 footprintBasePath = fpRow->
GetFullURI(
true );
298 if( crefdes.empty() || !crefdes.compare(
"~" ) )
304 if( cvalue.empty() || !cvalue.compare(
"~" ) )
307 crefdes =
"NOREFDES";
320 double scale = aIDFBoard.GetUserScale();
321 IDF3::KEY_PLATING kplate;
327 aIDFBoard.GetUserOffset( dx, dy );
329 for(
auto pad : aFootprint->
Pads() )
331 drill = (double)
pad->GetDrillSize().x *
scale;
332 x =
pad->GetPosition().x *
scale + dx;
333 y = -
pad->GetPosition().y *
scale + dy;
347 if( tstr.empty() || !tstr.compare(
"0" ) || !tstr.compare(
"~" )
348 || ( kplate == IDF3::NPTH )
363 && (
pad->GetDrillSize().x !=
pad->GetDrillSize().y ) )
369 double dlength =
pad->GetDrillSize().y *
scale;
374 double angle =
pad->GetOrientation().AsDegrees();
382 if( dlength < drill )
384 std::swap( drill, dlength );
395 aIDFBoard.AddSlot( drill, dlength, angle, x, y );
399 IDF_DRILL_DATA *dp =
new IDF_DRILL_DATA( drill, x, y, kplate, crefdes,
400 pintype, IDF3::ECAD );
402 if( !aIDFBoard.AddDrill( dp ) )
406 std::ostringstream ostr;
407 ostr << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__;
408 ostr <<
"(): could not add drill";
410 throw std::runtime_error( ostr.str() );
419 if( aFootprint->
IsDNP() && !aIncludeDNP )
425 IDF3_COMPONENT* comp =
nullptr;
427 auto sM = aFootprint->
Models().begin();
428 auto eM = aFootprint->
Models().end();
440 std::vector<const EMBEDDED_FILES*> embeddedFilesStack;
444 idfFile.Assign(
resolver->
ResolvePath( sM->m_Filename, footprintBasePath, std::move( embeddedFilesStack ) ) );
445 idfExt = idfFile.GetExt();
447 if( idfExt.Cmp( wxT(
"idf" ) ) && idfExt.Cmp( wxT(
"IDF" ) ) )
461 if( refdes.empty() || !refdes.compare(
"~" ) )
462 refdes = aIDFBoard.GetNewRefDes();
465 IDF3_COMP_OUTLINE* outline;
467 outline = aIDFBoard.GetComponentOutline( idfFile.GetFullPath() );
470 throw( std::runtime_error( aIDFBoard.GetError() ) );
473 double locx = sM->m_Offset.x;
474 double locy = sM->m_Offset.y;
475 double locz = sM->m_Offset.z;
476 double lrot = sM->m_Rotation.z;
478 bool top = ( aFootprint->
GetLayer() ==
B_Cu ) ?
false :
true;
496 while( rotz >= 360.0 ) rotz -= 360.0;
499 while( rotz <= -360.0 ) rotz += 360.0;
502 if( comp ==
nullptr )
503 comp = aIDFBoard.FindComponent( refdes );
505 if( comp ==
nullptr )
507 comp =
new IDF3_COMPONENT( &aIDFBoard );
509 if( comp ==
nullptr )
510 throw( std::runtime_error( aIDFBoard.GetError() ) );
512 comp->SetRefDes( refdes );
518 rotz, IDF3::LYR_TOP );
524 rotz, IDF3::LYR_BOTTOM );
527 comp->SetPlacement( IDF3::PS_ECAD );
529 aIDFBoard.AddComponent( comp );
533 double refX, refY, refA;
534 IDF3::IDF_LAYER side;
536 if( ! comp->GetPosition( refX, refY, refA, side ) )
543 rotz, IDF3::LYR_TOP );
549 rotz, IDF3::LYR_BOTTOM );
552 comp->SetPlacement( IDF3::PS_ECAD );
568 if( ( top && side == IDF3::LYR_BOTTOM ) || ( !top && side == IDF3::LYR_TOP )
569 || ( refA > 0.0001 ) || ( refX > 0.0001 ) )
571 comp->GetPosition( refX, refY, refA, side );
573 std::ostringstream ostr;
574 ostr <<
"* " << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__ <<
"():\n";
575 ostr <<
"* conflicting Reference Designator '" << refdes <<
"'\n";
577 ostr <<
" vs. " << refX <<
"\n";
579 ostr <<
" vs. " << refY <<
"\n";
580 ostr <<
"* angle: " << rotz;
581 ostr <<
" vs. " << refA <<
"\n";
584 ostr <<
"* TOP vs. ";
586 ostr <<
"* BOTTOM vs. ";
588 if( side == IDF3::LYR_TOP )
593 throw( std::runtime_error( ostr.str() ) );
599 IDF3_COMP_OUTLINE_DATA* data =
new IDF3_COMP_OUTLINE_DATA( comp, outline );
601 data->SetOffsets( locx, locy, locz, lrot );
602 comp->AddOutlineData( data );
613 bool aUseThou,
double aXRef,
double aYRef,
614 bool aIncludeUnspecified,
bool aIncludeDNP )
616 IDF3_BOARD idfBoard( IDF3::CAD_ELEC );
625 IDF3::IDF_UNIT idfUnit;
629 idfUnit = IDF3::UNIT_THOU;
630 idfBoard.SetUserPrecision( 1 );
634 idfUnit = IDF3::UNIT_MM;
635 idfBoard.SetUserPrecision( 5 );
640 idfBoard.SetUserScale(
scale );
642 idfBoard.SetBoardName(
TO_UTF8( brdName.GetFullName() ) );
643 idfBoard.SetBoardVersion( 0 );
644 idfBoard.SetLibraryVersion( 0 );
646 std::ostringstream ostr;
648 idfBoard.SetIDFSource( ostr.str() );
653 idfBoard.SetUserOffset( -aXRef, aYRef );
662 if( !idfBoard.WriteFile( aFullFileName, idfUnit,
false ) )
665 msg <<
_(
"IDF Export Failed:\n" ) <<
From_UTF8( idfBoard.GetError().c_str() );
674 msg <<
_(
"IDF Export Failed:\n" ) << ioe.
What();
679 catch(
const std::exception& e )
682 msg <<
_(
"IDF Export Failed:\n" ) <<
From_UTF8( e.what() );
constexpr EDA_IU_SCALE pcbIUScale
wxString GetBuildVersion()
Get the full KiCad version string.
int GetBoardThickness() const
The full thickness of the board including copper and masks.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Information pertinent to a Pcbnew printed circuit board.
EMBEDDED_FILES * GetEmbeddedFiles() override
const BOX2I GetBoardEdgesBoundingBox() const
Return the board bounding box calculated using exclusively the board edges (graphics on Edge....
const FOOTPRINTS & Footprints() const
const wxString & GetFileName() const
PROJECT * GetProject() const
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
const DRAWINGS & Drawings() const
constexpr const Vec & GetOrigin() const
constexpr const SizeVec & GetSize() const
EDA_ANGLE GetArcAngle() const
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
Provide an extensible class to resolve 3D model paths.
wxString ResolvePath(const wxString &aFileName, const wxString &aWorkingPath, std::vector< const EMBEDDED_FILES * > aEmbeddedFilesStack)
Determine the full path of the given file name.
Hold a record identifying a library accessed by the appropriate footprint library #PLUGIN object in t...
const FP_LIB_TABLE_ROW * FindRow(const wxString &aNickName, bool aCheckIfEnabled=false)
Return an FP_LIB_TABLE_ROW if aNickName is found in this table or in any chained fall back table frag...
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
const wxString GetFullURI(bool aSubstituted=false) const
Return the full location specifying URI for the LIB, either in original UI form or in environment var...
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
bool Export_IDF3(BOARD *aPcb, const wxString &aFullFileName, bool aUseThou, double aXRef, double aYRef, bool aIncludeUnspecified, bool aIncludeDNP)
Create an IDF3 compliant BOARD (*.emn) and LIBRARY (*.emp) file.
VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
wxString GetShownText(bool aAllowExtraText, int aDepth=0) const override
Return the string actually shown after processing of the base text.
static FP_LIB_TABLE * PcbFootprintLibs(PROJECT *aProject)
Return the table of footprint libraries without Kiway.
static S3D_CACHE * Get3DCacheManager(PROJECT *aProject, bool updateProjDir=false)
Return a pointer to an instance of the 3D cache manager.
FILENAME_RESOLVER * GetResolver() noexcept
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
static void idf_export_outline(BOARD *aPcb, IDF3_BOARD &aIDFBoard)
Retrieve line segment information from the edge layer and compiles the data into a form which can be ...
static FILENAME_RESOLVER * resolver
static void idf_export_footprint(BOARD *aPcb, FOOTPRINT *aFootprint, IDF3_BOARD &aIDFBoard, bool aIncludeUnspecified, bool aIncludeDNP)
Retrieve information from all board footprints, adds drill holes to the DRILLED_HOLES or BOARD_OUTLIN...
This file contains miscellaneous commonly used macros and functions.
@ NPTH
like PAD_PTH, but not plated mechanical use only, no connection allowed
wxString From_UTF8(const char *cstring)
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers