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;
283 std::optional<LIBRARY_TABLE_ROW*> fpRow =
289 if( crefdes.empty() || !crefdes.compare(
"~" ) )
295 if( cvalue.empty() || !cvalue.compare(
"~" ) )
298 crefdes =
"NOREFDES";
311 double scale = aIDFBoard.GetUserScale();
312 IDF3::KEY_PLATING kplate;
318 aIDFBoard.GetUserOffset( dx, dy );
320 for(
auto pad : aFootprint->
Pads() )
322 drill = (double)
pad->GetDrillSize().x *
scale;
323 x =
pad->GetPosition().x *
scale + dx;
324 y = -
pad->GetPosition().y *
scale + dy;
338 if( tstr.empty() || !tstr.compare(
"0" ) || !tstr.compare(
"~" )
339 || ( kplate == IDF3::NPTH )
354 && (
pad->GetDrillSize().x !=
pad->GetDrillSize().y ) )
360 double dlength =
pad->GetDrillSize().y *
scale;
365 double angle =
pad->GetOrientation().AsDegrees();
373 if( dlength < drill )
375 std::swap( drill, dlength );
386 aIDFBoard.AddSlot( drill, dlength, angle, x, y );
390 IDF_DRILL_DATA *dp =
new IDF_DRILL_DATA( drill, x, y, kplate, crefdes,
391 pintype, IDF3::ECAD );
393 if( !aIDFBoard.AddDrill( dp ) )
397 std::ostringstream ostr;
398 ostr << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__;
399 ostr <<
"(): could not add drill";
401 throw std::runtime_error( ostr.str() );
410 if( aFootprint->
IsDNP() && !aIncludeDNP )
416 IDF3_COMPONENT*
comp =
nullptr;
418 auto sM = aFootprint->
Models().begin();
419 auto eM = aFootprint->
Models().end();
431 std::vector<const EMBEDDED_FILES*> embeddedFilesStack;
435 idfFile.Assign(
resolver->ResolvePath( sM->m_Filename, footprintBasePath, std::move( embeddedFilesStack ) ) );
436 idfExt = idfFile.GetExt();
438 if( idfExt.Cmp( wxT(
"idf" ) ) && idfExt.Cmp( wxT(
"IDF" ) ) )
452 if( refdes.empty() || !refdes.compare(
"~" ) )
453 refdes = aIDFBoard.GetNewRefDes();
456 IDF3_COMP_OUTLINE* outline;
458 outline = aIDFBoard.GetComponentOutline( idfFile.GetFullPath() );
461 throw( std::runtime_error( aIDFBoard.GetError() ) );
464 double locx = sM->m_Offset.x;
465 double locy = sM->m_Offset.y;
466 double locz = sM->m_Offset.z;
467 double lrot = sM->m_Rotation.z;
487 while( rotz >= 360.0 ) rotz -= 360.0;
490 while( rotz <= -360.0 ) rotz += 360.0;
493 if(
comp ==
nullptr )
494 comp = aIDFBoard.FindComponent( refdes );
496 if(
comp ==
nullptr )
498 comp =
new IDF3_COMPONENT( &aIDFBoard );
500 if(
comp ==
nullptr )
501 throw( std::runtime_error( aIDFBoard.GetError() ) );
503 comp->SetRefDes( refdes );
509 rotz, IDF3::LYR_TOP );
515 rotz, IDF3::LYR_BOTTOM );
518 comp->SetPlacement( IDF3::PS_ECAD );
520 aIDFBoard.AddComponent(
comp );
524 double refX, refY, refA;
525 IDF3::IDF_LAYER side;
527 if( !
comp->GetPosition( refX, refY, refA, side ) )
534 rotz, IDF3::LYR_TOP );
540 rotz, IDF3::LYR_BOTTOM );
543 comp->SetPlacement( IDF3::PS_ECAD );
559 if( (
top && side == IDF3::LYR_BOTTOM ) || ( !
top && side == IDF3::LYR_TOP )
560 || ( refA > 0.0001 ) || ( refX > 0.0001 ) )
562 comp->GetPosition( refX, refY, refA, side );
564 std::ostringstream ostr;
565 ostr <<
"* " << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__ <<
"():\n";
566 ostr <<
"* conflicting Reference Designator '" << refdes <<
"'\n";
568 ostr <<
" vs. " << refX <<
"\n";
570 ostr <<
" vs. " << refY <<
"\n";
571 ostr <<
"* angle: " << rotz;
572 ostr <<
" vs. " << refA <<
"\n";
575 ostr <<
"* TOP vs. ";
577 ostr <<
"* BOTTOM vs. ";
579 if( side == IDF3::LYR_TOP )
584 throw( std::runtime_error( ostr.str() ) );
590 IDF3_COMP_OUTLINE_DATA* data =
new IDF3_COMP_OUTLINE_DATA(
comp, outline );
592 data->SetOffsets( locx, locy, locz, lrot );
593 comp->AddOutlineData( data );
604 bool aUseThou,
double aXRef,
double aYRef,
605 bool aIncludeUnspecified,
bool aIncludeDNP )
607 IDF3_BOARD idfBoard( IDF3::CAD_ELEC );
616 IDF3::IDF_UNIT idfUnit;
620 idfUnit = IDF3::UNIT_THOU;
621 idfBoard.SetUserPrecision( 1 );
625 idfUnit = IDF3::UNIT_MM;
626 idfBoard.SetUserPrecision( 5 );
631 idfBoard.SetUserScale(
scale );
633 idfBoard.SetBoardName(
TO_UTF8( brdName.GetFullName() ) );
634 idfBoard.SetBoardVersion( 0 );
635 idfBoard.SetLibraryVersion( 0 );
637 std::ostringstream ostr;
639 idfBoard.SetIDFSource( ostr.str() );
644 idfBoard.SetUserOffset( -aXRef, aYRef );
653 if( !idfBoard.WriteFile( aFullFileName, idfUnit,
false ) )
656 msg <<
_(
"IDF Export Failed:\n" ) <<
From_UTF8( idfBoard.GetError().c_str() );
665 msg <<
_(
"IDF Export Failed:\n" ) << ioe.
What();
670 catch(
const std::exception& e )
673 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.
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) const
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.
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 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