30#include <idf_parser.h>
46#define LINE_WIDTH (pcbIUScale.mmToIU( 0.1 ))
58 double scale = aIDFBoard.GetUserScale();
60 std::list< IDF_SEGMENT* > lines;
61 IDF_OUTLINE* outline =
nullptr;
69 aIDFBoard.GetUserOffset( offX, offY );
90 IDF_SEGMENT* seg =
new IDF_SEGMENT( sp, ep );
93 lines.push_back( seg );
108 IDF_POINT corners[4];
109 corners[0] = IDF_POINT(
left,
top );
110 corners[1] = IDF_POINT(
right,
top );
111 corners[2] = IDF_POINT(
right, bottom );
112 corners[3] = IDF_POINT(
left, bottom );
114 lines.push_back(
new IDF_SEGMENT( corners[0], corners[1] ) );
115 lines.push_back(
new IDF_SEGMENT( corners[1], corners[2] ) );
116 lines.push_back(
new IDF_SEGMENT( corners[2], corners[3] ) );
117 lines.push_back(
new IDF_SEGMENT( corners[3], corners[0] ) );
133 lines.push_back( seg );
150 IDF_SEGMENT* seg =
new IDF_SEGMENT( sp, ep, 360.0,
true );
153 lines.push_back( seg );
173 outline =
new IDF_OUTLINE;
174 IDF3::GetOutline( lines, *outline );
176 if( outline->empty() )
179 aIDFBoard.AddBoardOutline( outline );
183 while( !lines.empty() )
186 outline =
new IDF_OUTLINE;
188 IDF3::GetOutline( lines, *outline );
190 if( outline->empty() )
196 aIDFBoard.AddBoardOutline( outline );
205 while( !lines.empty() )
207 delete lines.front();
214 outline =
new IDF_OUTLINE;
247 outline->push(
new IDF_SEGMENT( p1, p2 ) );
249 for(
int i = 1; i < 4; ++i )
256 outline->push(
new IDF_SEGMENT( p1, p2 ) );
259 aIDFBoard.AddBoardOutline( outline );
269 bool aIncludeUnspecified,
bool aIncludeDNP )
275 wxString footprintBasePath = wxEmptyString;
279 std::optional<LIBRARY_TABLE_ROW*> fpRow =
285 if( crefdes.empty() || !crefdes.compare(
"~" ) )
291 if( cvalue.empty() || !cvalue.compare(
"~" ) )
294 crefdes =
"NOREFDES";
307 double scale = aIDFBoard.GetUserScale();
308 IDF3::KEY_PLATING kplate;
314 aIDFBoard.GetUserOffset( dx, dy );
316 for(
auto pad : aFootprint->
Pads() )
318 drill = (double)
pad->GetDrillSize().x *
scale;
319 x =
pad->GetPosition().x *
scale + dx;
320 y = -
pad->GetPosition().y *
scale + dy;
334 if( tstr.empty() || !tstr.compare(
"0" ) || !tstr.compare(
"~" )
335 || ( kplate == IDF3::NPTH )
350 && (
pad->GetDrillSize().x !=
pad->GetDrillSize().y ) )
356 double dlength =
pad->GetDrillSize().y *
scale;
361 double angle =
pad->GetOrientation().AsDegrees();
369 if( dlength < drill )
371 std::swap( drill, dlength );
382 aIDFBoard.AddSlot( drill, dlength, angle, x, y );
386 IDF_DRILL_DATA *dp =
new IDF_DRILL_DATA( drill, x, y, kplate, crefdes,
387 pintype, IDF3::ECAD );
389 if( !aIDFBoard.AddDrill( dp ) )
393 std::ostringstream ostr;
394 ostr << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__;
395 ostr <<
"(): could not add drill";
397 throw std::runtime_error( ostr.str() );
413 IDF3_COMPONENT*
comp =
nullptr;
415 auto sM = aFootprint->
Models().begin();
416 auto eM = aFootprint->
Models().end();
428 std::vector<const EMBEDDED_FILES*> embeddedFilesStack;
432 idfFile.Assign(
resolver->ResolvePath( sM->m_Filename, footprintBasePath, std::move( embeddedFilesStack ) ) );
433 idfExt = idfFile.GetExt();
435 if( idfExt.Cmp( wxT(
"idf" ) ) && idfExt.Cmp( wxT(
"IDF" ) ) )
449 if( refdes.empty() || !refdes.compare(
"~" ) )
450 refdes = aIDFBoard.GetNewRefDes();
453 IDF3_COMP_OUTLINE* outline;
455 outline = aIDFBoard.GetComponentOutline( idfFile.GetFullPath() );
458 throw( std::runtime_error( aIDFBoard.GetError() ) );
461 double locx = sM->m_Offset.x;
462 double locy = sM->m_Offset.y;
463 double locz = sM->m_Offset.z;
464 double lrot = sM->m_Rotation.z;
484 while( rotz >= 360.0 ) rotz -= 360.0;
487 while( rotz <= -360.0 ) rotz += 360.0;
490 if(
comp ==
nullptr )
491 comp = aIDFBoard.FindComponent( refdes );
493 if(
comp ==
nullptr )
495 comp =
new IDF3_COMPONENT( &aIDFBoard );
497 if(
comp ==
nullptr )
498 throw( std::runtime_error( aIDFBoard.GetError() ) );
500 comp->SetRefDes( refdes );
506 rotz, IDF3::LYR_TOP );
512 rotz, IDF3::LYR_BOTTOM );
515 comp->SetPlacement( IDF3::PS_ECAD );
517 aIDFBoard.AddComponent(
comp );
521 double refX, refY, refA;
522 IDF3::IDF_LAYER side;
524 if( !
comp->GetPosition( refX, refY, refA, side ) )
531 rotz, IDF3::LYR_TOP );
537 rotz, IDF3::LYR_BOTTOM );
540 comp->SetPlacement( IDF3::PS_ECAD );
556 if( (
top && side == IDF3::LYR_BOTTOM ) || ( !
top && side == IDF3::LYR_TOP )
557 || ( refA > 0.0001 ) || ( refX > 0.0001 ) )
559 comp->GetPosition( refX, refY, refA, side );
561 std::ostringstream ostr;
562 ostr <<
"* " << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__ <<
"():\n";
563 ostr <<
"* conflicting Reference Designator '" << refdes <<
"'\n";
565 ostr <<
" vs. " << refX <<
"\n";
567 ostr <<
" vs. " << refY <<
"\n";
568 ostr <<
"* angle: " << rotz;
569 ostr <<
" vs. " << refA <<
"\n";
572 ostr <<
"* TOP vs. ";
574 ostr <<
"* BOTTOM vs. ";
576 if( side == IDF3::LYR_TOP )
581 throw( std::runtime_error( ostr.str() ) );
587 IDF3_COMP_OUTLINE_DATA* data =
new IDF3_COMP_OUTLINE_DATA(
comp, outline );
589 data->SetOffsets( locx, locy, locz, lrot );
590 comp->AddOutlineData( data );
601 bool aUseThou,
double aXRef,
double aYRef,
602 bool aIncludeUnspecified,
bool aIncludeDNP )
604 IDF3_BOARD idfBoard( IDF3::CAD_ELEC );
613 IDF3::IDF_UNIT idfUnit;
617 idfUnit = IDF3::UNIT_THOU;
618 idfBoard.SetUserPrecision( 1 );
622 idfUnit = IDF3::UNIT_MM;
623 idfBoard.SetUserPrecision( 5 );
628 idfBoard.SetUserScale(
scale );
630 idfBoard.SetBoardName(
TO_UTF8( brdName.GetFullName() ) );
631 idfBoard.SetBoardVersion( 0 );
632 idfBoard.SetLibraryVersion( 0 );
634 std::ostringstream ostr;
636 idfBoard.SetIDFSource( ostr.str() );
641 idfBoard.SetUserOffset( -aXRef, aYRef );
650 if( !idfBoard.WriteFile( aFullFileName, idfUnit,
false ) )
653 msg <<
_(
"IDF Export Failed:\n" ) <<
From_UTF8( idfBoard.GetError().c_str() );
662 msg <<
_(
"IDF Export Failed:\n" ) << ioe.
What();
667 catch(
const std::exception& e )
670 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
wxString GetCurrentVariant() 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.
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()
std::optional< LIBRARY_TABLE_ROW * > GetRow(const wxString &aNickname, LIBRARY_TABLE_SCOPE aScope=LIBRARY_TABLE_SCOPE::BOTH) const
Like LIBRARY_MANAGER::GetRow but filtered to the LIBRARY_TABLE_TYPE of this adapter.
std::optional< wxString > GetFullURI(LIBRARY_TABLE_TYPE aType, const wxString &aNickname, bool aSubstituted=false)
Return the full location specifying URI for the LIB, either in original UI form or in environment var...
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
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.
wxString GetShownText(bool aAllowExtraText, int aDepth=0) const override
Return the string actually shown after processing of the base text.
VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
static S3D_CACHE * Get3DCacheManager(PROJECT *aProject, bool updateProjDir=false)
Return a pointer to an instance of the 3D cache manager.
static FOOTPRINT_LIBRARY_ADAPTER * FootprintLibAdapter(PROJECT *aProject)
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.
KIBIS top(path, &reporter)
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