Browse Source

REMOVED: standalone IDF utils

These were vestigial and not necessary
Fold IDF code into common
Migrate enums to enum classes
master
Jon Evans 1 week ago
parent
commit
eadb9d6434
  1. 4
      CMakeLists.txt
  2. 8
      common/CMakeLists.txt
  3. 185
      common/io/idf/idf_common.cpp
  4. 24
      common/io/idf/idf_common.h
  5. 64
      common/io/idf/idf_helpers.cpp
  6. 2
      common/io/idf/idf_helpers.h
  7. 320
      common/io/idf/idf_outlines.cpp
  8. 2
      common/io/idf/idf_outlines.h
  9. 249
      common/io/idf/idf_parser.cpp
  10. 9
      common/io/idf/idf_parser.h
  11. 2
      common/io/idf/vrml_layer.cpp
  12. 0
      common/io/idf/vrml_layer.h
  13. 1
      pcbnew/CMakeLists.txt
  14. 1
      pcbnew/drc/rule_editor/panel_drc_rule_editor.cpp
  15. 30
      pcbnew/exporters/export_idf.cpp
  16. 2
      pcbnew/exporters/exporter_vrml.cpp
  17. 2
      pcbnew/pcb_io/odbpp/odb_util.cpp
  18. 6
      plugins/3d/idf/CMakeLists.txt
  19. 12
      plugins/3d/idf/s3d_plugin_idf.cpp
  20. 1
      qa/fuzz/CMakeLists.txt
  21. 1
      qa/pcbnew_utils/CMakeLists.txt
  22. 1
      qa/tests/api/CMakeLists.txt
  23. 1
      qa/tests/pcbnew/CMakeLists.txt
  24. 1
      qa/tools/drc_benchmark/CMakeLists.txt
  25. 1
      qa/tools/drc_proto/CMakeLists.txt
  26. 1
      qa/tools/ibis/CMakeLists.txt
  27. 1
      qa/tools/pcbnew_tools/CMakeLists.txt
  28. 2
      qa/tools/pns/CMakeLists.txt
  29. 4
      utils/CMakeLists.txt
  30. 58
      utils/idftools/CMakeLists.txt
  31. 404
      utils/idftools/dxf2idf.cpp
  32. 88
      utils/idftools/dxf2idf.h
  33. 197
      utils/idftools/dxf2idfmain.cpp
  34. 970
      utils/idftools/idf2vrml.cpp
  35. 681
      utils/idftools/idf_cylinder.cpp
  36. 149
      utils/idftools/idf_examples/Arduino_MEGA_2560-Rev3.emn
  37. 4
      utils/idftools/idf_examples/Arduino_MEGA_2560-Rev3.emp
  38. 269
      utils/idftools/idf_examples/idf_example.emn
  39. 69
      utils/idftools/idf_examples/idf_example.emp
  40. 45
      utils/idftools/idf_examples/test_donut.emn
  41. 5
      utils/idftools/idf_examples/test_donut.emp
  42. 71
      utils/idftools/idf_examples/test_idf2.emn
  43. 290
      utils/idftools/idf_examples/test_idf2.emp
  44. 438
      utils/idftools/idf_rect.cpp

4
CMakeLists.txt

@ -281,10 +281,6 @@ option( KICAD_GAL_PROFILE
"Enable profiling info for GAL"
OFF )
option( KICAD_IDF_TOOLS
"Build additional idf tools"
ON )
# Global setting: exports are explicit
set( CMAKE_CXX_VISIBILITY_PRESET "hidden" )
set( CMAKE_VISIBILITY_INLINES_HIDDEN ON )

8
common/CMakeLists.txt

@ -779,6 +779,14 @@ set( COMMON_IO_SRCS
# P-CAD
io/pcad/s_expr_loader.cpp
# IDFv3
io/idf/idf_common.cpp
io/idf/idf_helpers.cpp
io/idf/idf_outlines.cpp
io/idf/idf_parser.cpp
io/idf/vrml_layer.cpp
io/csv.cpp
)

185
utils/idftools/idf_common.cpp → common/io/idf/idf_common.cpp

@ -30,8 +30,8 @@
#include <cerrno>
#include <cstdio>
#include <cmath>
#include <idf_common.h>
#include <idf_helpers.h>
#include <io/idf/idf_common.h>
#include <io/idf/idf_helpers.h>
using namespace IDF3;
using namespace std;
@ -97,13 +97,13 @@ bool IDF_NOTE::readNote( std::istream& aBoardFile, IDF3::FILE_STATE& aBoardState
if( ( !aBoardFile.good() && !aBoardFile.eof() ) || iline.empty() )
{
aBoardState = IDF3::FILE_INVALID;
aBoardState = FILE_STATE::FILE_INVALID;
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, "problems reading board notes" ) );
}
if( isComment )
{
aBoardState = IDF3::FILE_INVALID;
aBoardState = FILE_STATE::FILE_INVALID;
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDFv3 file\n"
"* Violation of specification: comment within a section (NOTES)" ) );
@ -114,7 +114,7 @@ bool IDF_NOTE::readNote( std::istream& aBoardFile, IDF3::FILE_STATE& aBoardState
if( quoted )
{
aBoardState = IDF3::FILE_INVALID;
aBoardState = FILE_STATE::FILE_INVALID;
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDFv3 file\n"
"* Violation of specification: X position in NOTES section must not be "
@ -131,7 +131,7 @@ bool IDF_NOTE::readNote( std::istream& aBoardFile, IDF3::FILE_STATE& aBoardState
if( istr.fail() )
{
aBoardState = IDF3::FILE_INVALID;
aBoardState = FILE_STATE::FILE_INVALID;
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDFv3 file\n"
"* Violation of specification: X position in NOTES section is not "
@ -140,7 +140,7 @@ bool IDF_NOTE::readNote( std::istream& aBoardFile, IDF3::FILE_STATE& aBoardState
if( !GetIDFString( iline, token, quoted, idx ) )
{
aBoardState = IDF3::FILE_INVALID;
aBoardState = FILE_STATE::FILE_INVALID;
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDFv3 file\n"
"* Violation of specification: Y position in NOTES section is "
@ -149,7 +149,7 @@ bool IDF_NOTE::readNote( std::istream& aBoardFile, IDF3::FILE_STATE& aBoardState
if( quoted )
{
aBoardState = IDF3::FILE_INVALID;
aBoardState = FILE_STATE::FILE_INVALID;
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDFv3 file\n"
"* Violation of specification: Y position in NOTES section must not be "
@ -163,7 +163,7 @@ bool IDF_NOTE::readNote( std::istream& aBoardFile, IDF3::FILE_STATE& aBoardState
if( istr.fail() )
{
aBoardState = IDF3::FILE_INVALID;
aBoardState = FILE_STATE::FILE_INVALID;
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDFv3 file\n"
"* Violation of specification: Y position in NOTES section is not "
@ -172,7 +172,7 @@ bool IDF_NOTE::readNote( std::istream& aBoardFile, IDF3::FILE_STATE& aBoardState
if( !GetIDFString( iline, token, quoted, idx ) )
{
aBoardState = IDF3::FILE_INVALID;
aBoardState = FILE_STATE::FILE_INVALID;
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDFv3 file\n"
"* Violation of specification: text height in NOTES section is "
@ -181,7 +181,7 @@ bool IDF_NOTE::readNote( std::istream& aBoardFile, IDF3::FILE_STATE& aBoardState
if( quoted )
{
aBoardState = IDF3::FILE_INVALID;
aBoardState = FILE_STATE::FILE_INVALID;
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDFv3 file\n"
"* Violation of specification: text height in NOTES section must not "
@ -195,7 +195,7 @@ bool IDF_NOTE::readNote( std::istream& aBoardFile, IDF3::FILE_STATE& aBoardState
if( istr.fail() )
{
aBoardState = IDF3::FILE_INVALID;
aBoardState = FILE_STATE::FILE_INVALID;
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDFv3 file\n"
"* Violation of specification: text height in NOTES section is not "
@ -204,7 +204,7 @@ bool IDF_NOTE::readNote( std::istream& aBoardFile, IDF3::FILE_STATE& aBoardState
if( !GetIDFString( iline, token, quoted, idx ) )
{
aBoardState = IDF3::FILE_INVALID;
aBoardState = FILE_STATE::FILE_INVALID;
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDFv3 file\n"
"* Violation of specification: text length in NOTES section is "
@ -213,7 +213,7 @@ bool IDF_NOTE::readNote( std::istream& aBoardFile, IDF3::FILE_STATE& aBoardState
if( quoted )
{
aBoardState = IDF3::FILE_INVALID;
aBoardState = FILE_STATE::FILE_INVALID;
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDFv3 file\n"
"* Violation of specification: text length in NOTES section must not "
@ -227,7 +227,7 @@ bool IDF_NOTE::readNote( std::istream& aBoardFile, IDF3::FILE_STATE& aBoardState
if( istr.fail() )
{
aBoardState = IDF3::FILE_INVALID;
aBoardState = FILE_STATE::FILE_INVALID;
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDFv3 file\n"
"* Violation of specification: text length in NOTES section is not "
@ -236,7 +236,7 @@ bool IDF_NOTE::readNote( std::istream& aBoardFile, IDF3::FILE_STATE& aBoardState
if( !GetIDFString( iline, token, quoted, idx ) )
{
aBoardState = IDF3::FILE_INVALID;
aBoardState = FILE_STATE::FILE_INVALID;
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDFv3 file\n"
"* Violation of specification: text value in NOTES section is "
@ -245,7 +245,7 @@ bool IDF_NOTE::readNote( std::istream& aBoardFile, IDF3::FILE_STATE& aBoardState
text = token;
if( aBoardUnit == UNIT_THOU )
if( aBoardUnit == IDF_UNIT::UNIT_THOU )
{
xpos *= IDF_THOU_TO_MM;
ypos *= IDF_THOU_TO_MM;
@ -259,7 +259,7 @@ bool IDF_NOTE::readNote( std::istream& aBoardFile, IDF3::FILE_STATE& aBoardState
bool IDF_NOTE::writeNote( std::ostream& aBoardFile, IDF3::IDF_UNIT aBoardUnit )
{
if( aBoardUnit == UNIT_THOU )
if( aBoardUnit == IDF_UNIT::UNIT_THOU )
{
aBoardFile << setiosflags( ios::fixed ) << setprecision( 1 ) << ( xpos / IDF_THOU_TO_MM )
<< " " << ( ypos / IDF_THOU_TO_MM ) << " " << ( height / IDF_THOU_TO_MM ) << " "
@ -321,10 +321,10 @@ IDF_DRILL_DATA::IDF_DRILL_DATA() :
dia( 0.0 ),
x( 0.0 ),
y( 0.0 ),
plating( NPTH ),
kref( NOREFDES ),
khole( MTG ),
owner( UNOWNED )
plating( KEY_PLATING::NPTH ),
kref( KEY_REFDES::NOREFDES ),
khole( KEY_HOLETYPE::MTG ),
owner( KEY_OWNER::UNOWNED )
{
}
@ -344,41 +344,41 @@ IDF_DRILL_DATA::IDF_DRILL_DATA( double aDrillDia, double aPosX, double aPosY,
if( !aRefDes.compare( "BOARD" ) )
{
kref = BOARD;
kref = KEY_REFDES::BOARD;
}
else if( aRefDes.empty() || !aRefDes.compare( "NOREFDES" ) )
{
kref = NOREFDES;
kref = KEY_REFDES::NOREFDES;
}
else if( !aRefDes.compare( "PANEL" ) )
{
kref = PANEL;
kref = KEY_REFDES::PANEL;
}
else
{
kref = REFDES;
kref = KEY_REFDES::REFDES;
refdes = aRefDes;
}
if( !aHoleType.compare( "PIN" ) )
{
khole = PIN;
khole = KEY_HOLETYPE::PIN;
}
else if( !aHoleType.compare( "VIA" ) )
{
khole = VIA;
khole = KEY_HOLETYPE::VIA;
}
else if( aHoleType.empty() || !aHoleType.compare( "MTG" ) )
{
khole = MTG;
khole = KEY_HOLETYPE::MTG;
}
else if( !aHoleType.compare( "TOOL" ) )
{
khole = TOOL;
khole = KEY_HOLETYPE::TOOL;
}
else
{
khole = OTHER;
khole = KEY_HOLETYPE::OTHER;
holetype = aHoleType;
}
@ -455,9 +455,9 @@ bool IDF_DRILL_DATA::read( std::istream& aBoardFile, IDF3::IDF_UNIT aBoardUnit,
"* Violation of specification: drill diameter is not numeric" ) );
}
if( ( aBoardUnit == UNIT_MM && dia < IDF_MIN_DIA_MM )
|| ( aBoardUnit == UNIT_THOU && dia < IDF_MIN_DIA_THOU )
|| ( aBoardUnit == UNIT_TNM && dia < IDF_MIN_DIA_TNM ) )
if( ( aBoardUnit == IDF_UNIT::UNIT_MM && dia < IDF_MIN_DIA_MM )
|| ( aBoardUnit == IDF_UNIT::UNIT_THOU && dia < IDF_MIN_DIA_THOU )
|| ( aBoardUnit == IDF_UNIT::UNIT_TNM && dia < IDF_MIN_DIA_TNM ) )
{
ostringstream ostr;
ostr << "invalid IDF file\n";
@ -522,7 +522,7 @@ bool IDF_DRILL_DATA::read( std::istream& aBoardFile, IDF3::IDF_UNIT aBoardUnit,
"not numeric" ) );
}
if( aIdfVersion > IDF_V2 )
if( aIdfVersion > IDF_VERSION::IDF_V2 )
{
if( !GetIDFString( iline, token, quoted, idx ) )
{
@ -533,11 +533,11 @@ bool IDF_DRILL_DATA::read( std::istream& aBoardFile, IDF3::IDF_UNIT aBoardUnit,
if( CompareToken( "PTH", token ) )
{
plating = IDF3::PTH;
plating = KEY_PLATING::PTH;
}
else if( CompareToken( "NPTH", token ) )
{
plating = IDF3::NPTH;
plating = KEY_PLATING::NPTH;
}
else
{
@ -550,12 +550,12 @@ bool IDF_DRILL_DATA::read( std::istream& aBoardFile, IDF3::IDF_UNIT aBoardUnit,
}
else
{
plating = IDF3::PTH;
plating = KEY_PLATING::PTH;
}
if( !GetIDFString( iline, token, quoted, idx ) )
{
if( aIdfVersion > IDF_V2 )
if( aIdfVersion > IDF_VERSION::IDF_V2 )
{
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDFv3 file\n"
@ -574,7 +574,7 @@ bool IDF_DRILL_DATA::read( std::istream& aBoardFile, IDF3::IDF_UNIT aBoardUnit,
if( !GetIDFString( iline, token, quoted, idx ) )
{
if( aIdfVersion > IDF_V2 )
if( aIdfVersion > IDF_VERSION::IDF_V2 )
{
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDFv3 file\n"
@ -591,55 +591,55 @@ bool IDF_DRILL_DATA::read( std::istream& aBoardFile, IDF3::IDF_UNIT aBoardUnit,
std::string tok2 = token;
if( aIdfVersion > IDF_V2 )
if( aIdfVersion > IDF_VERSION::IDF_V2 )
token = tok1;
if( CompareToken( "BOARD", token ) )
{
kref = IDF3::BOARD;
kref = KEY_REFDES::BOARD;
}
else if( CompareToken( "NOREFDES", token ) )
{
kref = IDF3::NOREFDES;
kref = KEY_REFDES::NOREFDES;
}
else if( CompareToken( "PANEL", token ) )
{
kref = IDF3::PANEL;
kref = KEY_REFDES::PANEL;
}
else
{
kref = IDF3::REFDES;
kref = KEY_REFDES::REFDES;
refdes = token;
}
if( aIdfVersion > IDF_V2 )
if( aIdfVersion > IDF_VERSION::IDF_V2 )
token = tok2;
else
token = tok1;
if( CompareToken( "PIN", token ) )
{
khole = IDF3::PIN;
khole = KEY_HOLETYPE::PIN;
}
else if( CompareToken( "VIA", token ) )
{
khole = IDF3::VIA;
khole = KEY_HOLETYPE::VIA;
}
else if( CompareToken( "MTG", token ) )
{
khole = IDF3::MTG;
khole = KEY_HOLETYPE::MTG;
}
else if( CompareToken( "TOOL", token ) )
{
khole = IDF3::TOOL;
khole = KEY_HOLETYPE::TOOL;
}
else
{
khole = IDF3::OTHER;
khole = KEY_HOLETYPE::OTHER;
holetype = token;
}
if( aIdfVersion > IDF_V2 )
if( aIdfVersion > IDF_VERSION::IDF_V2 )
{
if( !GetIDFString( iline, token, quoted, idx ) )
{
@ -660,25 +660,25 @@ bool IDF_DRILL_DATA::read( std::istream& aBoardFile, IDF3::IDF_UNIT aBoardUnit,
}
else
{
owner = IDF3::UNOWNED;
owner = KEY_OWNER::UNOWNED;
}
if( aBoardUnit == UNIT_THOU )
if( aBoardUnit == IDF_UNIT::UNIT_THOU )
{
dia *= IDF_THOU_TO_MM;
x *= IDF_THOU_TO_MM;
y *= IDF_THOU_TO_MM;
}
else if( ( aIdfVersion == IDF_V2 ) && ( aBoardUnit == UNIT_TNM ) )
else if( ( aIdfVersion == IDF_VERSION::IDF_V2 ) && ( aBoardUnit == IDF_UNIT::UNIT_TNM ) )
{
dia *= IDF_TNM_TO_MM;
x *= IDF_TNM_TO_MM;
y *= IDF_TNM_TO_MM;
}
else if( aBoardUnit != UNIT_MM )
else if( aBoardUnit != IDF_UNIT::UNIT_MM )
{
ostringstream ostr;
ostr << "\n* BUG: invalid UNIT type: " << aBoardUnit;
ostr << "\n* BUG: invalid UNIT type: " << static_cast<int>( aBoardUnit );
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
}
@ -696,34 +696,34 @@ void IDF_DRILL_DATA::write( std::ostream& aBoardFile, IDF3::IDF_UNIT aBoardUnit
switch( khole )
{
case PIN: holestr = "PIN"; break;
case VIA: holestr = "VIA"; break;
case TOOL: holestr = "TOOL"; break;
case OTHER: holestr = "\"" + holetype + "\""; break;
default: holestr = "MTG"; break;
case KEY_HOLETYPE::PIN: holestr = "PIN"; break;
case KEY_HOLETYPE::VIA: holestr = "VIA"; break;
case KEY_HOLETYPE::TOOL: holestr = "TOOL"; break;
case KEY_HOLETYPE::OTHER: holestr = "\"" + holetype + "\""; break;
default: holestr = "MTG"; break;
}
switch( kref )
{
case BOARD: refstr = "BOARD"; break;
case PANEL: refstr = "PANEL"; break;
case REFDES: refstr = "\"" + refdes + "\""; break;
default: refstr = "NOREFDES"; break;
case KEY_REFDES::BOARD: refstr = "BOARD"; break;
case KEY_REFDES::PANEL: refstr = "PANEL"; break;
case KEY_REFDES::REFDES: refstr = "\"" + refdes + "\""; break;
default: refstr = "NOREFDES"; break;
}
if( plating == PTH )
if( plating == KEY_PLATING::PTH )
pltstr = "PTH";
else
pltstr = "NPTH";
switch( owner )
{
case MCAD: ownstr = "MCAD"; break;
case ECAD: ownstr = "ECAD"; break;
default: ownstr = "UNOWNED"; break;
case KEY_OWNER::MCAD: ownstr = "MCAD"; break;
case KEY_OWNER::ECAD: ownstr = "ECAD"; break;
default: ownstr = "UNOWNED"; break;
}
if( aBoardUnit == UNIT_MM )
if( aBoardUnit == IDF_UNIT::UNIT_MM )
{
aBoardFile << std::setiosflags( std::ios::fixed ) << std::setprecision( 3 ) << dia << " "
<< std::setprecision( 5 ) << x << " " << y << " " << pltstr.c_str() << " "
@ -768,10 +768,10 @@ const std::string& IDF_DRILL_DATA::GetDrillRefDes()
{
switch( kref )
{
case BOARD: refdes = "BOARD"; break;
case PANEL: refdes = "PANEL"; break;
case REFDES: break;
default: refdes = "NOREFDES"; break;
case KEY_REFDES::BOARD: refdes = "BOARD"; break;
case KEY_REFDES::PANEL: refdes = "PANEL"; break;
case KEY_REFDES::REFDES: break;
default: refdes = "NOREFDES"; break;
}
return refdes;
@ -782,42 +782,17 @@ const std::string& IDF_DRILL_DATA::GetDrillHoleType()
{
switch( khole )
{
case PIN: holetype = "PIN"; break;
case VIA: holetype = "VIA"; break;
case TOOL: holetype = "TOOL"; break;
case OTHER: break;
default: holetype = "MTG"; break;
case KEY_HOLETYPE::PIN: holetype = "PIN"; break;
case KEY_HOLETYPE::VIA: holetype = "VIA"; break;
case KEY_HOLETYPE::TOOL: holetype = "TOOL"; break;
case KEY_HOLETYPE::OTHER: break;
default: holetype = "MTG"; break;
}
return holetype;
}
#ifdef DEBUG_IDF
void IDF3::PrintSeg( IDF_SEGMENT* aSegment )
{
if( aSegment->IsCircle() )
{
fprintf( stdout, "printSeg(): CIRCLE: C(%.3f, %.3f) P(%.3f, %.3f) rad. %.3f\n",
aSegment->startPoint.x, aSegment->startPoint.y, aSegment->endPoint.x,
aSegment->endPoint.y, aSegment->radius );
return;
}
if( aSegment->angle < -MIN_ANG || aSegment->angle > MIN_ANG )
{
fprintf( stdout, "printSeg(): ARC: p1(%.3f, %.3f) p2(%.3f, %.3f) ang. %.3f\n",
aSegment->startPoint.x, aSegment->startPoint.y, aSegment->endPoint.x,
aSegment->endPoint.y, aSegment->angle );
return;
}
fprintf( stdout, "printSeg(): LINE: p1(%.3f, %.3f) p2(%.3f, %.3f)\n", aSegment->startPoint.x,
aSegment->startPoint.y, aSegment->endPoint.x, aSegment->endPoint.y );
}
#endif
bool IDF_POINT::Matches( const IDF_POINT& aPoint, double aRadius ) const
{
double dx = x - aPoint.x;

24
utils/idftools/idf_common.h → common/io/idf/idf_common.h

@ -59,7 +59,7 @@ namespace IDF3 {
/**
* State values for the IDF parser's input.
*/
enum FILE_STATE
enum class FILE_STATE
{
FILE_START = 0, // no data has been read; expecting .HEADER
FILE_HEADER, // header has been read; expecting .BOARD_OUTLINE
@ -72,7 +72,7 @@ enum FILE_STATE
/**
* The supported IDF versions (3.0 and 2.0 ONLY).
*/
enum IDF_VERSION
enum class IDF_VERSION
{
IDF_V2 = 0, // version 2 has read support only; files written as IDFv3
IDF_V3 // version 3 has full read/write support
@ -81,7 +81,7 @@ enum IDF_VERSION
/**
* The type of CAD which has ownership an object.
*/
enum KEY_OWNER
enum class KEY_OWNER
{
UNOWNED = 0, //< either MCAD or ECAD may modify a feature
MCAD, //< only MCAD may modify a feature
@ -91,7 +91,7 @@ enum KEY_OWNER
/**
* The purpose of an IDF hole.
*/
enum KEY_HOLETYPE
enum class KEY_HOLETYPE
{
PIN = 0, //< drill hole is for a pin
VIA, //< drill hole is for a via
@ -103,7 +103,7 @@ enum KEY_HOLETYPE
/**
* The plating condition of a hole.
*/
enum KEY_PLATING
enum class KEY_PLATING
{
PTH = 0, //< Plate-Through Hole
NPTH //< Non-Plate-Through Hole
@ -112,7 +112,7 @@ enum KEY_PLATING
/**
* A component's Reference Designator.
*/
enum KEY_REFDES
enum class KEY_REFDES
{
BOARD = 0, //< feature is associated with the board
NOREFDES, //< feature is associated with a component with no RefDes
@ -123,7 +123,7 @@ enum KEY_REFDES
/**
* The class of CAD program which is opening or modifying a file.
*/
enum CAD_TYPE
enum class CAD_TYPE
{
CAD_ELEC = 0, //< An Electrical CAD is opening/modifying the file
CAD_MECH, //< A Mechanical CAD is opening/modifying the file
@ -133,7 +133,7 @@ enum CAD_TYPE
/**
* The various IDF layer classes and groupings.
*/
enum IDF_LAYER
enum class IDF_LAYER
{
LYR_TOP = 0,
LYR_BOTTOM,
@ -146,7 +146,7 @@ enum IDF_LAYER
/**
* The class of outline.
*/
enum OUTLINE_TYPE
enum class OUTLINE_TYPE
{
OTLN_BOARD = 0,
OTLN_OTHER,
@ -163,7 +163,7 @@ enum OUTLINE_TYPE
/**
* Whether a component is a mechanical or electrical part.
*/
enum COMP_TYPE
enum class COMP_TYPE
{
COMP_ELEC = 0, //< Component library object is an electrical part
COMP_MECH, //< Component library object is a mechanical part
@ -173,7 +173,7 @@ enum COMP_TYPE
/**
* The native unit of the board and of component outlines.
*/
enum IDF_UNIT
enum class IDF_UNIT
{
UNIT_MM = 0, //< Units in the file are in millimeters
UNIT_THOU, //< Units in the file are in mils (aka thou)
@ -184,7 +184,7 @@ enum IDF_UNIT
/**
* The placement status of a component.
*/
enum IDF_PLACEMENT
enum class IDF_PLACEMENT
{
PS_UNPLACED = 0, //< component location on the board has not been specified
PS_PLACED, //< component location has been specified and may be modified by ECAD or MCAD

64
utils/idftools/idf_helpers.cpp → common/io/idf/idf_helpers.cpp

@ -22,8 +22,8 @@
#include <iostream>
#include <sstream>
#include <idf_common.h>
#include <idf_helpers.h>
#include <io/idf/idf_common.h>
#include <io/idf/idf_helpers.h>
using namespace std;
using namespace IDF3;
@ -146,17 +146,17 @@ bool IDF3::ParseOwner( const std::string& aToken, IDF3::KEY_OWNER& aOwner )
{
if( CompareToken( "UNOWNED", aToken ) )
{
aOwner = UNOWNED;
aOwner = KEY_OWNER::UNOWNED;
return true;
}
else if( CompareToken( "ECAD", aToken ) )
{
aOwner = ECAD;
aOwner = KEY_OWNER::ECAD;
return true;
}
else if( CompareToken( "MCAD", aToken ) )
{
aOwner = MCAD;
aOwner = KEY_OWNER::MCAD;
return true;
}
@ -170,33 +170,33 @@ bool IDF3::ParseIDFLayer( const std::string& aToken, IDF3::IDF_LAYER& aLayer )
{
if( CompareToken( "TOP", aToken ) )
{
aLayer = LYR_TOP;
aLayer = IDF_LAYER::LYR_TOP;
return true;
}
else if( CompareToken( "BOTTOM", aToken ) )
{
aLayer = LYR_BOTTOM;
aLayer = IDF_LAYER::LYR_BOTTOM;
return true;
}
else if( CompareToken( "BOTH", aToken ) )
{
aLayer = LYR_BOTH;
aLayer = IDF_LAYER::LYR_BOTH;
return true;
}
else if( CompareToken( "INNER", aToken ) )
{
aLayer = LYR_INNER;
aLayer = IDF_LAYER::LYR_INNER;
return true;
}
else if( CompareToken( "ALL", aToken ) )
{
aLayer = LYR_ALL;
aLayer = IDF_LAYER::LYR_ALL;
return true;
}
ERROR_IDF << "unrecognized IDF LAYER: '" << aToken << "'\n";
aLayer = LYR_INVALID;
aLayer = IDF_LAYER::LYR_INVALID;
return false;
}
@ -205,23 +205,23 @@ bool IDF3::WriteLayersText( std::ostream& aBoardFile, IDF3::IDF_LAYER aLayer )
{
switch( aLayer )
{
case LYR_TOP:
case IDF_LAYER::LYR_TOP:
aBoardFile << "TOP";
break;
case LYR_BOTTOM:
case IDF_LAYER::LYR_BOTTOM:
aBoardFile << "BOTTOM";
break;
case LYR_BOTH:
case IDF_LAYER::LYR_BOTH:
aBoardFile << "BOTH";
break;
case LYR_INNER:
case IDF_LAYER::LYR_INNER:
aBoardFile << "INNER";
break;
case LYR_ALL:
case IDF_LAYER::LYR_ALL:
aBoardFile << "ALL";
break;
@ -229,7 +229,7 @@ bool IDF3::WriteLayersText( std::ostream& aBoardFile, IDF3::IDF_LAYER aLayer )
do
{
std::ostringstream ostr;
ostr << "invalid IDF layer: " << aLayer;
ostr << "invalid IDF layer: " << static_cast<int>( aLayer );
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
} while( 0 );
@ -245,16 +245,16 @@ std::string IDF3::GetPlacementString( IDF3::IDF_PLACEMENT aPlacement )
{
switch( aPlacement )
{
case PS_UNPLACED:
case IDF_PLACEMENT::PS_UNPLACED:
return "UNPLACED";
case PS_PLACED:
case IDF_PLACEMENT::PS_PLACED:
return "PLACED";
case PS_MCAD:
case IDF_PLACEMENT::PS_MCAD:
return "MCAD";
case PS_ECAD:
case IDF_PLACEMENT::PS_ECAD:
return "ECAD";
default:
@ -262,7 +262,7 @@ std::string IDF3::GetPlacementString( IDF3::IDF_PLACEMENT aPlacement )
}
std::ostringstream ostr;
ostr << "[INVALID PLACEMENT VALUE]:" << aPlacement;
ostr << "[INVALID PLACEMENT VALUE]:" << static_cast<int>( aPlacement );
return ostr.str();
}
@ -272,19 +272,19 @@ std::string IDF3::GetLayerString( IDF3::IDF_LAYER aLayer )
{
switch( aLayer )
{
case LYR_TOP:
case IDF_LAYER::LYR_TOP:
return "TOP";
case LYR_BOTTOM:
case IDF_LAYER::LYR_BOTTOM:
return "BOTTOM";
case LYR_BOTH:
case IDF_LAYER::LYR_BOTH:
return "BOTH";
case LYR_INNER:
case IDF_LAYER::LYR_INNER:
return "INNER";
case LYR_ALL:
case IDF_LAYER::LYR_ALL:
return "ALL";
default:
@ -292,7 +292,7 @@ std::string IDF3::GetLayerString( IDF3::IDF_LAYER aLayer )
}
std::ostringstream ostr;
ostr << "[INVALID LAYER VALUE]:" << aLayer;
ostr << "[INVALID LAYER VALUE]:" << static_cast<int>( aLayer );
return ostr.str();
}
@ -302,13 +302,13 @@ std::string IDF3::GetOwnerString( IDF3::KEY_OWNER aOwner )
{
switch( aOwner )
{
case IDF3::UNOWNED:
case KEY_OWNER::UNOWNED:
return "UNOWNED";
case IDF3::MCAD:
case KEY_OWNER::MCAD:
return "MCAD";
case IDF3::ECAD:
case KEY_OWNER::ECAD:
return "ECAD";
default:
@ -316,7 +316,7 @@ std::string IDF3::GetOwnerString( IDF3::KEY_OWNER aOwner )
}
ostringstream ostr;
ostr << "UNKNOWN: " << aOwner;
ostr << "UNKNOWN: " << static_cast<int>( aOwner );
return ostr.str();
}

2
utils/idftools/idf_helpers.h → common/io/idf/idf_helpers.h

@ -24,7 +24,7 @@
#include <wx/string.h>
#include <iostream>
#include <string>
#include <idf_common.h>
#include <io/idf/idf_common.h>
/**
* Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.

320
utils/idftools/idf_outlines.cpp → common/io/idf/idf_outlines.cpp

@ -24,9 +24,9 @@
#include <cmath>
#include <utility>
#include <idf_helpers.h>
#include <idf_outlines.h>
#include <idf_parser.h>
#include <io/idf/idf_helpers.h>
#include <io/idf/idf_outlines.h>
#include <io/idf/idf_parser.h>
using namespace IDF3;
using namespace std;
@ -36,31 +36,31 @@ static std::string GetOutlineTypeString( IDF3::OUTLINE_TYPE aOutlineType )
{
switch( aOutlineType )
{
case OTLN_BOARD:
case OUTLINE_TYPE::OTLN_BOARD:
return ".BOARD_OUTLINE";
case OTLN_OTHER:
case OUTLINE_TYPE::OTLN_OTHER:
return ".OTHER_OUTLINE";
case OTLN_PLACE:
case OUTLINE_TYPE::OTLN_PLACE:
return ".PLACEMENT_OUTLINE";
case OTLN_ROUTE:
case OUTLINE_TYPE::OTLN_ROUTE:
return ".ROUTE_OUTLINE";
case OTLN_PLACE_KEEPOUT:
case OUTLINE_TYPE::OTLN_PLACE_KEEPOUT:
return ".PLACE_KEEPOUT";
case OTLN_ROUTE_KEEPOUT:
case OUTLINE_TYPE::OTLN_ROUTE_KEEPOUT:
return ".ROUTE_KEEPOUT";
case OTLN_VIA_KEEPOUT:
case OUTLINE_TYPE::OTLN_VIA_KEEPOUT:
return ".VIA_KEEPOUT";
case OTLN_GROUP_PLACE:
case OUTLINE_TYPE::OTLN_GROUP_PLACE:
return ".PLACE_REGION";
case OTLN_COMPONENT:
case OUTLINE_TYPE::OTLN_COMPONENT:
return "COMPONENT OUTLINE";
default:
@ -68,7 +68,7 @@ static std::string GetOutlineTypeString( IDF3::OUTLINE_TYPE aOutlineType )
}
std::ostringstream ostr;
ostr << "[INVALID OUTLINE TYPE VALUE]:" << aOutlineType;
ostr << "[INVALID OUTLINE TYPE VALUE]:" << static_cast<int>( aOutlineType );
return ostr.str();
}
@ -92,15 +92,15 @@ static bool CheckOwnership( int aSourceLine, const char* aSourceFunc,
// note: component outlines have no owner so we don't care about
// who modifies them
if( aOwnerCAD == UNOWNED || aOutlineType == IDF3::OTLN_COMPONENT )
if( aOwnerCAD == KEY_OWNER::UNOWNED || aOutlineType == IDF3::OUTLINE_TYPE::OTLN_COMPONENT )
return true;
IDF3::CAD_TYPE parentCAD = aParent->GetCadType();
if( aOwnerCAD == MCAD && parentCAD == CAD_MECH )
if( aOwnerCAD == KEY_OWNER::MCAD && parentCAD == CAD_TYPE::CAD_MECH )
return true;
if( aOwnerCAD == ECAD && parentCAD == CAD_ELEC )
if( aOwnerCAD == KEY_OWNER::ECAD && parentCAD == CAD_TYPE::CAD_ELEC )
return true;
do
@ -109,7 +109,7 @@ static bool CheckOwnership( int aSourceLine, const char* aSourceFunc,
ostr << __FILE__ << ":" << aSourceLine << ":" << aSourceFunc << "():\n";
ostr << "* ownership violation; CAD type is ";
if( parentCAD == CAD_MECH )
if( parentCAD == CAD_TYPE::CAD_MECH )
ostr << "MCAD ";
else
ostr << "ECAD ";
@ -127,12 +127,12 @@ static bool CheckOwnership( int aSourceLine, const char* aSourceFunc,
BOARD_OUTLINE::BOARD_OUTLINE()
{
outlineType = OTLN_BOARD;
outlineType = OUTLINE_TYPE::OTLN_BOARD;
single = false;
owner = UNOWNED;
owner = KEY_OWNER::UNOWNED;
parent = nullptr;
thickness = 0.0;
unit = UNIT_MM;
unit = IDF_UNIT::UNIT_MM;
}
@ -245,7 +245,7 @@ void BOARD_OUTLINE::readOutlines( std::istream& aBoardFile, IDF3::IDF_VERSION aI
if( tstr.fail() )
{
if( outlineType == OTLN_COMPONENT && CompareToken( "PROP", entry ) )
if( outlineType == OUTLINE_TYPE::OTLN_COMPONENT && CompareToken( "PROP", entry ) )
{
aBoardFile.seekg( pos );
return;
@ -555,20 +555,20 @@ void BOARD_OUTLINE::readOutlines( std::istream& aBoardFile, IDF3::IDF_VERSION aI
}
// the line was successfully read; convert to mm if necessary
if( unit == UNIT_THOU )
if( unit == IDF_UNIT::UNIT_THOU )
{
x *= IDF_THOU_TO_MM;
y *= IDF_THOU_TO_MM;
}
else if( ( aIdfVersion == IDF_V2 ) && ( unit == UNIT_TNM ) )
else if( ( aIdfVersion == IDF_VERSION::IDF_V2 ) && ( unit == IDF_UNIT::UNIT_TNM ) )
{
x *= IDF_TNM_TO_MM;
y *= IDF_TNM_TO_MM;
}
else if( unit != UNIT_MM )
else if( unit != IDF_UNIT::UNIT_MM )
{
ostringstream ostr;
ostr << "\n* BUG: invalid UNIT type: " << unit;
ostr << "\n* BUG: invalid UNIT type: " << static_cast<int>( unit );
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
}
@ -694,11 +694,11 @@ bool BOARD_OUTLINE::writeOwner( std::ostream& aBoardFile )
{
switch( owner )
{
case ECAD:
case KEY_OWNER::ECAD:
aBoardFile << "ECAD\n";
break;
case MCAD:
case KEY_OWNER::MCAD:
aBoardFile << "MCAD\n";
break;
@ -731,7 +731,7 @@ void BOARD_OUTLINE::writeOutline( std::ostream& aBoardFile, IDF_OUTLINE* aOutlin
// NOTE: a circle always has an angle of 360, never -360,
// otherwise SolidWorks chokes on the file.
if( unit != UNIT_THOU )
if( unit != IDF_UNIT::UNIT_THOU )
{
aBoardFile << aIndex << " " << setiosflags(ios::fixed) << setprecision(5)
<< aOutline->front()->startPoint.x << " "
@ -782,7 +782,7 @@ void BOARD_OUTLINE::writeOutline( std::ostream& aBoardFile, IDF_OUTLINE* aOutlin
}
// for the first item we write out both points
if( unit != UNIT_THOU )
if( unit != IDF_UNIT::UNIT_THOU )
{
if( aOutline->front()->angle < MIN_ANG && aOutline->front()->angle > -MIN_ANG )
{
@ -834,7 +834,7 @@ void BOARD_OUTLINE::writeOutline( std::ostream& aBoardFile, IDF_OUTLINE* aOutlin
// for all other segments we only write out the start point
while( bo != eo )
{
if( unit != UNIT_THOU )
if( unit != IDF_UNIT::UNIT_THOU )
{
if( ( *bo )->angle < MIN_ANG && ( *bo )->angle > -MIN_ANG )
{
@ -878,7 +878,7 @@ void BOARD_OUTLINE::writeOutline( std::ostream& aBoardFile, IDF_OUTLINE* aOutlin
eo = aOutline->end();
// for the first item we write out both points
if( unit != UNIT_THOU )
if( unit != IDF_UNIT::UNIT_THOU )
{
if( ( *bo )->angle < MIN_ANG && ( *bo )->angle > -MIN_ANG )
{
@ -928,7 +928,7 @@ void BOARD_OUTLINE::writeOutline( std::ostream& aBoardFile, IDF_OUTLINE* aOutlin
// for all other segments we only write out the last point
while( bo != eo )
{
if( unit != UNIT_THOU )
if( unit != IDF_UNIT::UNIT_THOU )
{
if( ( *bo )->angle < MIN_ANG && ( *bo )->angle > -MIN_ANG )
{
@ -984,13 +984,13 @@ void BOARD_OUTLINE::writeOutlines( std::ostream& aBoardFile )
bool BOARD_OUTLINE::SetUnit( IDF3::IDF_UNIT aUnit )
{
// note: although UNIT_TNM is accepted here without reservation,
// note: although IDF_UNIT::UNIT_TNM is accepted here without reservation,
// this can only affect data being read from a file.
if( aUnit != UNIT_MM && aUnit != UNIT_THOU && aUnit != UNIT_TNM )
if( aUnit != IDF_UNIT::UNIT_MM && aUnit != IDF_UNIT::UNIT_THOU && aUnit != IDF_UNIT::UNIT_TNM )
{
ostringstream ostr;
ostr << __FILE__ << ":" << __LINE__ << ":" << __FUNCTION__ << "():\n";
ostr << "* BUG: invalid IDF UNIT (must be one of UNIT_MM or UNIT_THOU): " << aUnit << "\n";
ostr << "* BUG: invalid IDF UNIT: " << static_cast<int>( aUnit ) << "\n";
ostr << "* outline type: " << GetOutlineTypeString( outlineType );
errormsg = ostr.str();
@ -1088,17 +1088,17 @@ void BOARD_OUTLINE::readData( std::istream& aBoardFile, const std::string& aHead
if( !GetIDFString( aHeader, token, quoted, idx ) )
{
if( aIdfVersion > IDF_V2 )
if( aIdfVersion > IDF_VERSION::IDF_V2 )
ERROR_IDF << "no OWNER; setting to UNOWNED\n";
owner = UNOWNED;
owner = KEY_OWNER::UNOWNED;
}
else
{
if( !ParseOwner( token, owner ) )
{
ERROR_IDF << "invalid OWNER (reverting to UNOWNED): " << token << "\n";
owner = UNOWNED;
owner = KEY_OWNER::UNOWNED;
}
}
@ -1160,18 +1160,18 @@ void BOARD_OUTLINE::readData( std::istream& aBoardFile, const std::string& aHead
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
}
if( unit == UNIT_THOU )
if( unit == IDF_UNIT::UNIT_THOU )
{
thickness *= IDF_THOU_TO_MM;
}
else if( ( aIdfVersion == IDF_V2 ) && ( unit == UNIT_TNM ) )
else if( ( aIdfVersion == IDF_VERSION::IDF_V2 ) && ( unit == IDF_UNIT::UNIT_TNM ) )
{
thickness *= IDF_TNM_TO_MM;
}
else if( unit != UNIT_MM )
else if( unit != IDF_UNIT::UNIT_MM )
{
ostringstream ostr;
ostr << "\n* BUG: invalid UNIT type: " << unit;
ostr << "\n* BUG: invalid UNIT type: " << static_cast<int>( unit );
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
}
@ -1247,7 +1247,7 @@ void BOARD_OUTLINE::writeData( std::ostream& aBoardFile )
writeOwner( aBoardFile );
if( unit != UNIT_THOU )
if( unit != IDF_UNIT::UNIT_THOU )
aBoardFile << setiosflags( ios::fixed ) << setprecision( 5 ) << thickness << "\n";
else
aBoardFile << setiosflags( ios::fixed ) << setprecision( 1 )
@ -1263,7 +1263,7 @@ void BOARD_OUTLINE::clear( void )
comments.clear();
clearOutlines();
owner = UNOWNED;
owner = KEY_OWNER::UNOWNED;
return;
}
@ -1576,8 +1576,8 @@ void BOARD_OUTLINE::ClearComments( void )
OTHER_OUTLINE::OTHER_OUTLINE( IDF3_BOARD* aParent )
{
setParent( aParent );
outlineType = OTLN_OTHER;
side = LYR_INVALID;
outlineType = OUTLINE_TYPE::OTLN_OTHER;
side = IDF_LAYER::LYR_INVALID;
single = false;
}
@ -1610,8 +1610,8 @@ bool OTHER_OUTLINE::SetSide( IDF3::IDF_LAYER aSide )
switch( aSide )
{
case LYR_TOP:
case LYR_BOTTOM:
case IDF_LAYER::LYR_TOP:
case IDF_LAYER::LYR_BOTTOM:
side = aSide;
break;
@ -1620,12 +1620,12 @@ bool OTHER_OUTLINE::SetSide( IDF3::IDF_LAYER aSide )
{
ostringstream ostr;
ostr << __FILE__ << ":" << __LINE__ << ":" << __FUNCTION__ << "():\n";
ostr << "* BUG: invalid side (" << aSide << "); must be one of TOP/BOTTOM\n";
ostr << "* BUG: invalid side (" << static_cast<int>( aSide ) << "); must be one of TOP/BOTTOM\n";
ostr << "* outline type: " << GetOutlineTypeString( outlineType );
errormsg = ostr.str();
} while( 0 );
side = LYR_INVALID;
side = IDF_LAYER::LYR_INVALID;
return false;
break;
@ -1675,7 +1675,7 @@ void OTHER_OUTLINE::readData( std::istream& aBoardFile, const std::string& aHead
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
}
if( outlineType == OTLN_OTHER )
if( outlineType == OUTLINE_TYPE::OTLN_OTHER )
{
if( !CompareToken( ".OTHER_OUTLINE", token ) )
{
@ -1702,24 +1702,24 @@ void OTHER_OUTLINE::readData( std::istream& aBoardFile, const std::string& aHead
if( !GetIDFString( aHeader, token, quoted, idx ) )
{
if( aIdfVersion > IDF_V2 )
if( aIdfVersion > IDF_VERSION::IDF_V2 )
ERROR_IDF << "no OWNER; setting to UNOWNED\n";
owner = UNOWNED;
owner = KEY_OWNER::UNOWNED;
}
else
{
if( !ParseOwner( token, owner ) )
{
ERROR_IDF << "invalid OWNER (reverting to UNOWNED): " << token << "\n";
owner = UNOWNED;
owner = KEY_OWNER::UNOWNED;
}
}
std::string iline;
bool comment = false;
if( outlineType == OTLN_OTHER )
if( outlineType == OUTLINE_TYPE::OTLN_OTHER )
{
// check RECORD 2
// [outline identifier] [thickness] [board side: Top/Bot]
@ -1792,25 +1792,25 @@ void OTHER_OUTLINE::readData( std::istream& aBoardFile, const std::string& aHead
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
}
if( unit == UNIT_THOU )
if( unit == IDF_UNIT::UNIT_THOU )
{
thickness *= IDF_THOU_TO_MM;
}
else if( ( aIdfVersion == IDF_V2 ) && ( unit == UNIT_TNM ) )
else if( ( aIdfVersion == IDF_VERSION::IDF_V2 ) && ( unit == IDF_UNIT::UNIT_TNM ) )
{
thickness *= IDF_TNM_TO_MM;
}
else if( unit != UNIT_MM )
else if( unit != IDF_UNIT::UNIT_MM )
{
ostringstream ostr;
ostr << "\n* BUG: invalid UNIT type: " << unit;
ostr << "\n* BUG: invalid UNIT type: " << static_cast<int>( unit );
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
}
if( aIdfVersion == IDF_V2 )
if( aIdfVersion == IDF_VERSION::IDF_V2 )
{
side = LYR_TOP;
side = IDF_LAYER::LYR_TOP;
}
else
{
@ -1826,7 +1826,7 @@ void OTHER_OUTLINE::readData( std::istream& aBoardFile, const std::string& aHead
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
}
if( !ParseIDFLayer( token, side ) || ( side != LYR_TOP && side != LYR_BOTTOM ) )
if( !ParseIDFLayer( token, side ) || ( side != IDF_LAYER::LYR_TOP && side != IDF_LAYER::LYR_BOTTOM ) )
{
ostringstream ostr;
@ -1872,7 +1872,7 @@ void OTHER_OUTLINE::readData( std::istream& aBoardFile, const std::string& aHead
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
}
if( outlineType == OTLN_OTHER )
if( outlineType == OUTLINE_TYPE::OTLN_OTHER )
{
if( !CompareToken( ".END_OTHER_OUTLINE", iline ) )
{
@ -1910,7 +1910,7 @@ void OTHER_OUTLINE::writeData( std::ostream& aBoardFile )
writeComments( aBoardFile );
// write RECORD 1
if( outlineType == OTLN_OTHER )
if( outlineType == OUTLINE_TYPE::OTLN_OTHER )
aBoardFile << ".OTHER_OUTLINE ";
else
aBoardFile << ".VIA_KEEPOUT ";
@ -1918,11 +1918,11 @@ void OTHER_OUTLINE::writeData( std::ostream& aBoardFile )
writeOwner( aBoardFile );
// write RECORD 2
if( outlineType == OTLN_OTHER )
if( outlineType == OUTLINE_TYPE::OTLN_OTHER )
{
aBoardFile << "\"" << uniqueID << "\" ";
if( unit != UNIT_THOU )
if( unit != IDF_UNIT::UNIT_THOU )
aBoardFile << setiosflags( ios::fixed ) << setprecision( 5 ) << thickness << " ";
else
aBoardFile << setiosflags( ios::fixed ) << setprecision( 1 )
@ -1930,8 +1930,8 @@ void OTHER_OUTLINE::writeData( std::ostream& aBoardFile )
switch( side )
{
case LYR_TOP:
case LYR_BOTTOM:
case IDF_LAYER::LYR_TOP:
case IDF_LAYER::LYR_BOTTOM:
WriteLayersText( aBoardFile, side );
break;
@ -1940,7 +1940,7 @@ void OTHER_OUTLINE::writeData( std::ostream& aBoardFile )
{
ostringstream ostr;
ostr << "\n* invalid OTHER_OUTLINE side (neither top nor bottom): ";
ostr << side;
ostr << static_cast<int>( side );
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
} while( 0 );
@ -1952,7 +1952,7 @@ void OTHER_OUTLINE::writeData( std::ostream& aBoardFile )
writeOutlines( aBoardFile );
// write RECORD 4
if( outlineType == OTLN_OTHER )
if( outlineType == OUTLINE_TYPE::OTLN_OTHER )
aBoardFile << ".END_OTHER_OUTLINE\n\n";
else
aBoardFile << ".END_VIA_KEEPOUT\n\n";
@ -1967,7 +1967,7 @@ bool OTHER_OUTLINE::Clear( void )
#endif
clear();
side = LYR_INVALID;
side = IDF_LAYER::LYR_INVALID;
uniqueID.clear();
return true;
@ -1977,9 +1977,9 @@ bool OTHER_OUTLINE::Clear( void )
ROUTE_OUTLINE::ROUTE_OUTLINE( IDF3_BOARD* aParent )
{
setParent( aParent );
outlineType = OTLN_ROUTE;
outlineType = OUTLINE_TYPE::OTLN_ROUTE;
single = true;
layers = LYR_INVALID;
layers = IDF_LAYER::LYR_INVALID;
}
@ -2034,7 +2034,7 @@ void ROUTE_OUTLINE::readData( std::istream& aBoardFile, const std::string& aHead
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
}
if( outlineType == OTLN_ROUTE )
if( outlineType == OUTLINE_TYPE::OTLN_ROUTE )
{
if( !CompareToken( ".ROUTE_OUTLINE", token ) )
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
@ -2049,17 +2049,17 @@ void ROUTE_OUTLINE::readData( std::istream& aBoardFile, const std::string& aHead
if( !GetIDFString( aHeader, token, quoted, idx ) )
{
if( aIdfVersion > IDF_V2 )
if( aIdfVersion > IDF_VERSION::IDF_V2 )
ERROR_IDF << "no OWNER; setting to UNOWNED\n";
owner = UNOWNED;
owner = KEY_OWNER::UNOWNED;
}
else
{
if( !ParseOwner( token, owner ) )
{
ERROR_IDF << "invalid OWNER (reverting to UNOWNED): " << token << "\n";
owner = UNOWNED;
owner = KEY_OWNER::UNOWNED;
}
}
@ -2068,7 +2068,7 @@ void ROUTE_OUTLINE::readData( std::istream& aBoardFile, const std::string& aHead
std::string iline;
bool comment = false;
if( aIdfVersion > IDF_V2 || outlineType == OTLN_ROUTE_KEEPOUT )
if( aIdfVersion > IDF_VERSION::IDF_V2 || outlineType == OUTLINE_TYPE::OTLN_ROUTE_KEEPOUT )
{
while( aBoardFile.good() && !FetchIDFLine( aBoardFile, iline, comment, pos ) );
@ -2133,9 +2133,9 @@ void ROUTE_OUTLINE::readData( std::istream& aBoardFile, const std::string& aHead
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
}
if( aIdfVersion == IDF_V2 )
if( aIdfVersion == IDF_VERSION::IDF_V2 )
{
if( layers == LYR_INNER || layers == LYR_ALL )
if( layers == IDF_LAYER::LYR_INNER || layers == IDF_LAYER::LYR_ALL )
{
ostringstream ostr;
@ -2151,7 +2151,7 @@ void ROUTE_OUTLINE::readData( std::istream& aBoardFile, const std::string& aHead
}
else
{
layers = LYR_ALL;
layers = IDF_LAYER::LYR_ALL;
}
// read RECORD 3 values
@ -2185,7 +2185,7 @@ void ROUTE_OUTLINE::readData( std::istream& aBoardFile, const std::string& aHead
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
}
if( outlineType == OTLN_ROUTE )
if( outlineType == OUTLINE_TYPE::OTLN_ROUTE )
{
if( !CompareToken( ".END_ROUTE_OUTLINE", iline ) )
{
@ -2220,14 +2220,14 @@ void ROUTE_OUTLINE::writeData( std::ostream& aBoardFile )
if( outlines.empty() )
return;
if( layers == LYR_INVALID )
if( layers == IDF_LAYER::LYR_INVALID )
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"layer not specified" ) );
writeComments( aBoardFile );
// write RECORD 1
if( outlineType == OTLN_ROUTE )
if( outlineType == OUTLINE_TYPE::OTLN_ROUTE )
aBoardFile << ".ROUTE_OUTLINE ";
else
aBoardFile << ".ROUTE_KEEPOUT ";
@ -2242,7 +2242,7 @@ void ROUTE_OUTLINE::writeData( std::ostream& aBoardFile )
writeOutlines( aBoardFile );
// write RECORD 4
if( outlineType == OTLN_ROUTE )
if( outlineType == OUTLINE_TYPE::OTLN_ROUTE )
aBoardFile << ".END_ROUTE_OUTLINE\n\n";
else
aBoardFile << ".END_ROUTE_KEEPOUT\n\n";
@ -2257,7 +2257,7 @@ bool ROUTE_OUTLINE::Clear( void )
#endif
clear();
layers = LYR_INVALID;
layers = IDF_LAYER::LYR_INVALID;
return true;
}
@ -2266,10 +2266,10 @@ bool ROUTE_OUTLINE::Clear( void )
PLACE_OUTLINE::PLACE_OUTLINE( IDF3_BOARD* aParent )
{
setParent( aParent );
outlineType = OTLN_PLACE;
outlineType = OUTLINE_TYPE::OTLN_PLACE;
single = true;
thickness = -1.0;
side = LYR_INVALID;
side = IDF_LAYER::LYR_INVALID;
}
@ -2282,19 +2282,19 @@ bool PLACE_OUTLINE::SetSide( IDF3::IDF_LAYER aSide )
switch( aSide )
{
case LYR_TOP:
case LYR_BOTTOM:
case LYR_BOTH:
case IDF_LAYER::LYR_TOP:
case IDF_LAYER::LYR_BOTTOM:
case IDF_LAYER::LYR_BOTH:
side = aSide;
break;
default:
do
{
side = LYR_INVALID;
side = IDF_LAYER::LYR_INVALID;
ostringstream ostr;
ostr << __FILE__ << ":" << __LINE__ << ":" << __FUNCTION__ << "():\n";
ostr << "* BUG: invalid layer (" << aSide << "): must be one of TOP/BOTTOM/BOTH\n";
ostr << "* BUG: invalid layer (" << static_cast<int>( aSide ) << "): must be one of TOP/BOTTOM/BOTH\n";
ostr << "* outline type: " << GetOutlineTypeString( outlineType );
errormsg = ostr.str();
@ -2378,7 +2378,7 @@ void PLACE_OUTLINE::readData( std::istream& aBoardFile, const std::string& aHead
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
}
if( outlineType == OTLN_PLACE )
if( outlineType == OUTLINE_TYPE::OTLN_PLACE )
{
if( !CompareToken( ".PLACE_OUTLINE", token ) )
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
@ -2393,17 +2393,17 @@ void PLACE_OUTLINE::readData( std::istream& aBoardFile, const std::string& aHead
if( !GetIDFString( aHeader, token, quoted, idx ) )
{
if( aIdfVersion > IDF_V2 )
if( aIdfVersion > IDF_VERSION::IDF_V2 )
ERROR_IDF << "no OWNER; setting to UNOWNED\n";
owner = UNOWNED;
owner = KEY_OWNER::UNOWNED;
}
else
{
if( !ParseOwner( token, owner ) )
{
ERROR_IDF << "invalid OWNER (reverting to UNOWNED): " << token << "\n";
owner = UNOWNED;
owner = KEY_OWNER::UNOWNED;
}
}
@ -2412,7 +2412,7 @@ void PLACE_OUTLINE::readData( std::istream& aBoardFile, const std::string& aHead
std::string iline;
bool comment = false;
if( aIdfVersion > IDF_V2 || outlineType == OTLN_PLACE_KEEPOUT )
if( aIdfVersion > IDF_VERSION::IDF_V2 || outlineType == OUTLINE_TYPE::OTLN_PLACE_KEEPOUT )
{
while( aBoardFile.good() && !FetchIDFLine( aBoardFile, iline, comment, pos ) );
@ -2454,7 +2454,7 @@ void PLACE_OUTLINE::readData( std::istream& aBoardFile, const std::string& aHead
}
if( !ParseIDFLayer( token, side ) ||
( side != LYR_TOP && side != LYR_BOTTOM && side != LYR_BOTH ) )
( side != IDF_LAYER::LYR_TOP && side != IDF_LAYER::LYR_BOTTOM && side != IDF_LAYER::LYR_BOTH ) )
{
ostringstream ostr;
@ -2497,18 +2497,18 @@ void PLACE_OUTLINE::readData( std::istream& aBoardFile, const std::string& aHead
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
}
if( unit == UNIT_THOU )
if( unit == IDF_UNIT::UNIT_THOU )
{
thickness *= IDF_THOU_TO_MM;
}
else if( ( aIdfVersion == IDF_V2 ) && ( unit == UNIT_TNM ) )
else if( ( aIdfVersion == IDF_VERSION::IDF_V2 ) && ( unit == IDF_UNIT::UNIT_TNM ) )
{
thickness *= IDF_TNM_TO_MM;
}
else if( unit != UNIT_MM )
else if( unit != IDF_UNIT::UNIT_MM )
{
ostringstream ostr;
ostr << "\n* BUG: invalid UNIT type: " << unit;
ostr << "\n* BUG: invalid UNIT type: " << static_cast<int>( unit );
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
}
@ -2518,8 +2518,8 @@ void PLACE_OUTLINE::readData( std::istream& aBoardFile, const std::string& aHead
}
else
{
// for OTLN_PLACE, thickness may be omitted, but is required for OTLN_PLACE_KEEPOUT
if( outlineType == OTLN_PLACE_KEEPOUT )
// for OUTLINE_TYPE::OTLN_PLACE, thickness may be omitted, but is required for OUTLINE_TYPE::OTLN_PLACE_KEEPOUT
if( outlineType == OUTLINE_TYPE::OTLN_PLACE_KEEPOUT )
{
ostringstream ostr;
@ -2536,7 +2536,7 @@ void PLACE_OUTLINE::readData( std::istream& aBoardFile, const std::string& aHead
}
else
{
side = LYR_TOP;
side = IDF_LAYER::LYR_TOP;
thickness = 0.0;
}
@ -2571,7 +2571,7 @@ void PLACE_OUTLINE::readData( std::istream& aBoardFile, const std::string& aHead
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
}
if( outlineType == OTLN_PLACE )
if( outlineType == OUTLINE_TYPE::OTLN_PLACE )
{
if( !GetIDFString( iline, token, quoted, idx )
|| !CompareToken( ".END_PLACE_OUTLINE", token ) )
@ -2597,7 +2597,7 @@ void PLACE_OUTLINE::writeData( std::ostream& aBoardFile )
writeComments( aBoardFile );
// write RECORD 1
if( outlineType == OTLN_PLACE )
if( outlineType == OUTLINE_TYPE::OTLN_PLACE )
aBoardFile << ".PLACE_OUTLINE ";
else
aBoardFile << ".PLACE_KEEPOUT ";
@ -2607,9 +2607,9 @@ void PLACE_OUTLINE::writeData( std::ostream& aBoardFile )
// write RECORD 2
switch( side )
{
case LYR_TOP:
case LYR_BOTTOM:
case LYR_BOTH:
case IDF_LAYER::LYR_TOP:
case IDF_LAYER::LYR_BOTTOM:
case IDF_LAYER::LYR_BOTH:
WriteLayersText( aBoardFile, side );
break;
@ -2618,15 +2618,15 @@ void PLACE_OUTLINE::writeData( std::ostream& aBoardFile )
{
ostringstream ostr;
ostr << "\n* invalid PLACE_OUTLINE/KEEPOUT side (";
ostr << side << "); must be one of TOP/BOTTOM/BOTH";
ostr << static_cast<int>( side ) << "); must be one of TOP/BOTTOM/BOTH";
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
} while( 0 );
break;
}
// thickness is optional for OTLN_PLACE, but mandatory for OTLN_PLACE_KEEPOUT
if( thickness < 0.0 && outlineType == OTLN_PLACE_KEEPOUT )
// thickness is optional for OUTLINE_TYPE::OTLN_PLACE, but mandatory for OUTLINE_TYPE::OTLN_PLACE_KEEPOUT
if( thickness < 0.0 && outlineType == OUTLINE_TYPE::OTLN_PLACE_KEEPOUT )
{
aBoardFile << "\n";
}
@ -2634,7 +2634,7 @@ void PLACE_OUTLINE::writeData( std::ostream& aBoardFile )
{
aBoardFile << " ";
if( unit != UNIT_THOU )
if( unit != IDF_UNIT::UNIT_THOU )
aBoardFile << setiosflags( ios::fixed ) << setprecision( 5 ) << thickness << "\n";
else
aBoardFile << setiosflags( ios::fixed ) << setprecision( 1 )
@ -2645,7 +2645,7 @@ void PLACE_OUTLINE::writeData( std::ostream& aBoardFile )
writeOutlines( aBoardFile );
// write RECORD 4
if( outlineType == OTLN_PLACE )
if( outlineType == OUTLINE_TYPE::OTLN_PLACE )
aBoardFile << ".END_PLACE_OUTLINE\n\n";
else
aBoardFile << ".END_PLACE_KEEPOUT\n\n";
@ -2663,7 +2663,7 @@ bool PLACE_OUTLINE::Clear( void )
clear();
thickness = 0.0;
side = LYR_INVALID;
side = IDF_LAYER::LYR_INVALID;
return true;
}
@ -2672,7 +2672,7 @@ bool PLACE_OUTLINE::Clear( void )
ROUTE_KO_OUTLINE::ROUTE_KO_OUTLINE( IDF3_BOARD* aParent )
: ROUTE_OUTLINE( aParent )
{
outlineType = OTLN_ROUTE_KEEPOUT;
outlineType = OUTLINE_TYPE::OTLN_ROUTE_KEEPOUT;
return;
}
@ -2680,7 +2680,7 @@ ROUTE_KO_OUTLINE::ROUTE_KO_OUTLINE( IDF3_BOARD* aParent )
PLACE_KO_OUTLINE::PLACE_KO_OUTLINE( IDF3_BOARD* aParent )
: PLACE_OUTLINE( aParent )
{
outlineType = OTLN_PLACE_KEEPOUT;
outlineType = OUTLINE_TYPE::OTLN_PLACE_KEEPOUT;
return;
}
@ -2689,16 +2689,16 @@ VIA_KO_OUTLINE::VIA_KO_OUTLINE( IDF3_BOARD* aParent )
: OTHER_OUTLINE( aParent )
{
single = true;
outlineType = OTLN_VIA_KEEPOUT;
outlineType = OUTLINE_TYPE::OTLN_VIA_KEEPOUT;
}
GROUP_OUTLINE::GROUP_OUTLINE( IDF3_BOARD* aParent )
{
setParent( aParent );
outlineType = OTLN_GROUP_PLACE;
outlineType = OUTLINE_TYPE::OTLN_GROUP_PLACE;
thickness = 0.0;
side = LYR_INVALID;
side = IDF_LAYER::LYR_INVALID;
single = true;
return;
}
@ -2713,9 +2713,9 @@ bool GROUP_OUTLINE::SetSide( IDF3::IDF_LAYER aSide )
switch( aSide )
{
case LYR_TOP:
case LYR_BOTTOM:
case LYR_BOTH:
case IDF_LAYER::LYR_TOP:
case IDF_LAYER::LYR_BOTTOM:
case IDF_LAYER::LYR_BOTH:
side = aSide;
break;
@ -2723,7 +2723,7 @@ bool GROUP_OUTLINE::SetSide( IDF3::IDF_LAYER aSide )
do
{
ostringstream ostr;
ostr << "invalid side (" << aSide << "); must be one of TOP/BOTTOM/BOTH\n";
ostr << "invalid side (" << static_cast<int>( aSide ) << "); must be one of TOP/BOTTOM/BOTH\n";
ostr << "* outline type: " << GetOutlineTypeString( outlineType );
errormsg = ostr.str();
@ -2797,17 +2797,17 @@ void GROUP_OUTLINE::readData( std::istream& aBoardFile, const std::string& aHead
if( !GetIDFString( aHeader, token, quoted, idx ) )
{
if( aIdfVersion > IDF_V2 )
if( aIdfVersion > IDF_VERSION::IDF_V2 )
ERROR_IDF << "no OWNER; setting to UNOWNED\n";
owner = UNOWNED;
owner = KEY_OWNER::UNOWNED;
}
else
{
if( !ParseOwner( token, owner ) )
{
ERROR_IDF << "invalid OWNER (reverting to UNOWNED): " << token << "\n";
owner = UNOWNED;
owner = KEY_OWNER::UNOWNED;
}
}
@ -2856,7 +2856,7 @@ void GROUP_OUTLINE::readData( std::istream& aBoardFile, const std::string& aHead
}
if( !ParseIDFLayer( token, side ) ||
( side != LYR_TOP && side != LYR_BOTTOM && side != LYR_BOTH ) )
( side != IDF_LAYER::LYR_TOP && side != IDF_LAYER::LYR_BOTTOM && side != IDF_LAYER::LYR_BOTH ) )
{
ostringstream ostr;
@ -2937,9 +2937,9 @@ void GROUP_OUTLINE::writeData( std::ostream& aBoardFile )
// write RECORD 2
switch( side )
{
case LYR_TOP:
case LYR_BOTTOM:
case LYR_BOTH:
case IDF_LAYER::LYR_TOP:
case IDF_LAYER::LYR_BOTTOM:
case IDF_LAYER::LYR_BOTH:
WriteLayersText( aBoardFile, side );
break;
@ -2948,7 +2948,7 @@ void GROUP_OUTLINE::writeData( std::ostream& aBoardFile )
{
ostringstream ostr;
ostr << "\n* invalid PLACE_REGION side (must be TOP/BOTTOM/BOTH): ";
ostr << side;
ostr << static_cast<int>( side );
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
} while( 0 );
@ -2975,7 +2975,7 @@ bool GROUP_OUTLINE::Clear( void )
clear();
thickness = 0.0;
side = LYR_INVALID;
side = IDF_LAYER::LYR_INVALID;
groupName.clear();
return true;
@ -2986,8 +2986,8 @@ IDF3_COMP_OUTLINE::IDF3_COMP_OUTLINE( IDF3_BOARD* aParent )
{
setParent( aParent );
single = true;
outlineType = OTLN_COMPONENT;
compType = COMP_INVALID;
outlineType = OUTLINE_TYPE::OTLN_COMPONENT;
compType = COMP_TYPE::COMP_INVALID;
refNum = 0;
return;
}
@ -3161,11 +3161,11 @@ void IDF3_COMP_OUTLINE::readData( std::istream& aLibFile, const std::string& aHe
if( CompareToken( ".ELECTRICAL", token ) )
{
compType = COMP_ELEC;
compType = COMP_TYPE::COMP_ELEC;
}
else if( CompareToken( ".MECHANICAL", token ) )
{
compType = COMP_MECH;
compType = COMP_TYPE::COMP_MECH;
}
else
{
@ -3265,15 +3265,15 @@ void IDF3_COMP_OUTLINE::readData( std::istream& aLibFile, const std::string& aHe
if( CompareToken( "MM", token ) )
{
unit = UNIT_MM;
unit = IDF_UNIT::UNIT_MM;
}
else if( CompareToken( "THOU", token ) )
{
unit = UNIT_THOU;
unit = IDF_UNIT::UNIT_THOU;
}
else if( aIdfVersion == IDF_V2 && !CompareToken( "TNM", token ) )
else if( aIdfVersion == IDF_VERSION::IDF_V2 && !CompareToken( "TNM", token ) )
{
unit = UNIT_TNM;
unit = IDF_UNIT::UNIT_TNM;
}
else
{
@ -3315,18 +3315,18 @@ void IDF3_COMP_OUTLINE::readData( std::istream& aLibFile, const std::string& aHe
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
}
if( unit == UNIT_THOU )
if( unit == IDF_UNIT::UNIT_THOU )
{
thickness *= IDF_THOU_TO_MM;
}
else if( ( aIdfVersion == IDF_V2 ) && ( unit == UNIT_TNM ) )
else if( ( aIdfVersion == IDF_VERSION::IDF_V2 ) && ( unit == IDF_UNIT::UNIT_TNM ) )
{
thickness *= IDF_TNM_TO_MM;
}
else if( unit != UNIT_MM )
else if( unit != IDF_UNIT::UNIT_MM )
{
ostringstream ostr;
ostr << "\n* BUG: invalid UNIT type: " << unit;
ostr << "\n* BUG: invalid UNIT type: " << static_cast<int>( unit );
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
}
@ -3334,7 +3334,7 @@ void IDF3_COMP_OUTLINE::readData( std::istream& aLibFile, const std::string& aHe
// read RECORD 3 values
readOutlines( aLibFile, aIdfVersion );
if( compType == COMP_ELEC && aIdfVersion > IDF_V2 )
if( compType == COMP_TYPE::COMP_ELEC && aIdfVersion > IDF_VERSION::IDF_V2 )
readProperties( aLibFile );
// check RECORD 4
@ -3365,7 +3365,7 @@ void IDF3_COMP_OUTLINE::readData( std::istream& aLibFile, const std::string& aHe
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
}
if( compType == COMP_ELEC )
if( compType == COMP_TYPE::COMP_ELEC )
{
if( !CompareToken( ".END_ELECTRICAL", iline ) )
{
@ -3401,10 +3401,10 @@ void IDF3_COMP_OUTLINE::writeData( std::ostream& aLibFile )
if( refNum == 0 )
return; // nothing to do
if( compType != COMP_ELEC && compType != COMP_MECH )
if( compType != COMP_TYPE::COMP_ELEC && compType != COMP_TYPE::COMP_MECH )
{
ostringstream ostr;
ostr << "\n* component type not set or invalid: " << compType;
ostr << "\n* component type not set or invalid: " << static_cast<int>( compType );
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
}
@ -3412,7 +3412,7 @@ void IDF3_COMP_OUTLINE::writeData( std::ostream& aLibFile )
writeComments( aLibFile );
// note: the outline section is required, even if it is empty
if( compType == COMP_ELEC )
if( compType == COMP_TYPE::COMP_ELEC )
aLibFile << ".ELECTRICAL\n";
else
aLibFile << ".MECHANICAL\n";
@ -3421,7 +3421,7 @@ void IDF3_COMP_OUTLINE::writeData( std::ostream& aLibFile )
// [GEOM] [PART] [UNIT] [HEIGHT]
aLibFile << "\"" << geometry << "\" \"" << part << "\" ";
if( unit != UNIT_THOU )
if( unit != IDF_UNIT::UNIT_THOU )
aLibFile << "MM " << setiosflags( ios::fixed ) << setprecision( 5 ) << thickness << "\n";
else
aLibFile << "THOU " << setiosflags( ios::fixed ) << setprecision( 1 )
@ -3429,7 +3429,7 @@ void IDF3_COMP_OUTLINE::writeData( std::ostream& aLibFile )
writeOutlines( aLibFile );
if( compType == COMP_ELEC )
if( compType == COMP_TYPE::COMP_ELEC )
{
writeProperties( aLibFile );
aLibFile << ".END_ELECTRICAL\n\n";
@ -3452,7 +3452,7 @@ bool IDF3_COMP_OUTLINE::Clear( void )
uid.clear();
geometry.clear();
part.clear();
compType = COMP_INVALID;
compType = COMP_TYPE::COMP_INVALID;
refNum = 0;
props.clear();
@ -3464,8 +3464,8 @@ bool IDF3_COMP_OUTLINE::SetComponentClass( IDF3::COMP_TYPE aCompClass )
{
switch( aCompClass )
{
case COMP_ELEC:
case COMP_MECH:
case COMP_TYPE::COMP_ELEC:
case COMP_TYPE::COMP_MECH:
compType = aCompClass;
break;
@ -3475,7 +3475,7 @@ bool IDF3_COMP_OUTLINE::SetComponentClass( IDF3::COMP_TYPE aCompClass )
ostringstream ostr;
ostr << __FILE__ << ":" << __LINE__ << ":" << __FUNCTION__ << "():\n";
ostr << "* BUG: invalid component class (must be ELECTRICAL or MECHANICAL): ";
ostr << aCompClass << "\n";
ostr << static_cast<int>( aCompClass ) << "\n";
errormsg = ostr.str();
return false;
@ -3574,9 +3574,9 @@ bool IDF3_COMP_OUTLINE::CreateDefaultOutline( const std::string& aGeom, const st
uid = aGeom + "_" + aPart;
}
compType = COMP_ELEC;
compType = COMP_TYPE::COMP_ELEC;
thickness = 5.0;
unit = UNIT_MM;
unit = IDF_UNIT::UNIT_MM;
// Create a star shape 5mm high with points on 5 and 3 mm circles
double a, da;

2
utils/idftools/idf_outlines.h → common/io/idf/idf_outlines.h

@ -26,7 +26,7 @@
#include <list>
#include <map>
#include <idf_common.h>
#include <io/idf/idf_common.h>
/*
* NOTES ON OUTLINE TYPES:

249
utils/idftools/idf_parser.cpp → common/io/idf/idf_parser.cpp

@ -29,8 +29,8 @@
#include <wx/string.h>
#include <wx/filename.h>
#include "idf_parser.h"
#include "idf_helpers.h"
#include <io/idf/idf_parser.h>
#include <io/idf/idf_helpers.h>
#include "streamwrapper.h"
#include <reporter.h>
@ -144,13 +144,13 @@ bool IDF3_COMP_OUTLINE_DATA::checkOwnership( int aSourceLine, const char* aSourc
IDF3::IDF_PLACEMENT placement = parent->GetPlacement();
IDF3::CAD_TYPE parentCAD = parent->GetCadType();
if( placement == PS_PLACED || placement == PS_UNPLACED )
if( placement == IDF_PLACEMENT::PS_PLACED || placement == IDF_PLACEMENT::PS_UNPLACED )
return true;
if( placement == PS_MCAD && parentCAD == CAD_MECH )
if( placement == IDF_PLACEMENT::PS_MCAD && parentCAD == CAD_TYPE::CAD_MECH )
return true;
if( placement == PS_ECAD && parentCAD == CAD_ELEC )
if( placement == IDF_PLACEMENT::PS_ECAD && parentCAD == CAD_TYPE::CAD_ELEC )
return true;
do
@ -159,7 +159,7 @@ bool IDF3_COMP_OUTLINE_DATA::checkOwnership( int aSourceLine, const char* aSourc
ostr << "* " << __FILE__ << ":" << aSourceLine << ":" << aSourceFunc << "():\n";
ostr << "* ownership violation; CAD type is ";
if( parentCAD == CAD_MECH )
if( parentCAD == CAD_TYPE::CAD_MECH )
ostr << "MCAD ";
else
ostr << "ECAD ";
@ -225,11 +225,8 @@ bool IDF3_COMP_OUTLINE_DATA::SetOutline( IDF3_COMP_OUTLINE* aOutline )
}
bool IDF3_COMP_OUTLINE_DATA::readPlaceData( std::istream &aBoardFile,
IDF3::FILE_STATE& aBoardState,
IDF3_BOARD *aBoard,
IDF3::IDF_VERSION aIdfVersion,
bool aNoSubstituteOutlines )
bool IDF3_COMP_OUTLINE_DATA::readPlaceData( std::istream& aBoardFile, FILE_STATE& aBoardState, IDF3_BOARD* aBoard,
IDF_VERSION aIdfVersion, bool aNoSubstituteOutlines )
{
if( !aBoard )
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
@ -247,8 +244,8 @@ bool IDF3_COMP_OUTLINE_DATA::readPlaceData( std::istream &aBoardFile,
std::string token;
std::string uid;
std::string refdes;
IDF3::IDF_PLACEMENT placement = IDF3::PS_UNPLACED;
IDF3::IDF_LAYER side = IDF3::LYR_TOP;
IDF3::IDF_PLACEMENT placement = IDF3::IDF_PLACEMENT::PS_UNPLACED;
IDF3::IDF_LAYER side = IDF3::IDF_LAYER::LYR_TOP;
// RECORD 2: 'package name', 'part number', 'Refdes' (any, NOREFDES, BOARD)
while( !FetchIDFLine( aBoardFile, iline, isComment, pos ) && aBoardFile.good() );
@ -281,7 +278,7 @@ bool IDF3_COMP_OUTLINE_DATA::readPlaceData( std::istream &aBoardFile,
if( !quoted && CompareToken( ".END_PLACEMENT", token ) )
{
aBoardState = IDF3::FILE_PLACEMENT;
aBoardState = FILE_STATE::FILE_PLACEMENT;
return false;
}
@ -450,7 +447,7 @@ bool IDF3_COMP_OUTLINE_DATA::readPlaceData( std::istream &aBoardFile,
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
}
if( aIdfVersion > IDF_V2 )
if( aIdfVersion > IDF_VERSION::IDF_V2 )
{
if( !GetIDFString( iline, token, quoted, idx ) )
{
@ -523,11 +520,11 @@ bool IDF3_COMP_OUTLINE_DATA::readPlaceData( std::istream &aBoardFile,
if( CompareToken( "TOP", token ) )
{
side = IDF3::LYR_TOP;
side = IDF3::IDF_LAYER::LYR_TOP;
}
else if( CompareToken( "BOTTOM", token ) )
{
side = IDF3::LYR_BOTTOM;
side = IDF3::IDF_LAYER::LYR_BOTTOM;
}
else
{
@ -556,26 +553,26 @@ bool IDF3_COMP_OUTLINE_DATA::readPlaceData( std::istream &aBoardFile,
if( CompareToken( "PLACED", token ) )
{
placement = IDF3::PS_PLACED;
placement = IDF3::IDF_PLACEMENT::PS_PLACED;
}
else if( CompareToken( "UNPLACED", token ) )
{
placement = IDF3::PS_UNPLACED;
placement = IDF3::IDF_PLACEMENT::PS_UNPLACED;
}
else if( aIdfVersion > IDF_V2 && CompareToken( "MCAD", token ) )
else if( aIdfVersion > IDF_VERSION::IDF_V2 && CompareToken( "MCAD", token ) )
{
placement = IDF3::PS_MCAD;
placement = IDF3::IDF_PLACEMENT::PS_MCAD;
}
else if( aIdfVersion > IDF_V2 && CompareToken( "ECAD", token ) )
else if( aIdfVersion > IDF_VERSION::IDF_V2 && CompareToken( "ECAD", token ) )
{
placement = IDF3::PS_ECAD;
placement = IDF3::IDF_PLACEMENT::PS_ECAD;
}
else if( aIdfVersion < IDF_V3 && CompareToken( "FIXED", token ) )
else if( aIdfVersion < IDF_VERSION::IDF_V3 && CompareToken( "FIXED", token ) )
{
if( aBoard->GetCadType() == CAD_ELEC )
placement = IDF3::PS_MCAD;
if( aBoard->GetCadType() == CAD_TYPE::CAD_ELEC )
placement = IDF3::IDF_PLACEMENT::PS_MCAD;
else
placement = IDF3::PS_ECAD;
placement = IDF3::IDF_PLACEMENT::PS_ECAD;
}
else
{
@ -604,7 +601,7 @@ bool IDF3_COMP_OUTLINE_DATA::readPlaceData( std::istream &aBoardFile,
"\n* missing outline: cannot create default" ) );
}
if( aBoard->GetUnit() == IDF3::UNIT_THOU )
if( aBoard->GetUnit() == IDF3::IDF_UNIT::UNIT_THOU )
{
xoff *= IDF_THOU_TO_MM;
yoff *= IDF_THOU_TO_MM;
@ -726,13 +723,13 @@ void IDF3_COMP_OUTLINE_DATA::writePlaceData( std::ostream& aBoardFile,
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"empty GEOM and PART names" ) );
if( aPlacement == PS_INVALID )
if( aPlacement == IDF_PLACEMENT::PS_INVALID )
{
ERROR_IDF << "placement invalid (" << aRefDes << ":";
aPlacement = PS_PLACED;
aPlacement = IDF_PLACEMENT::PS_PLACED;
}
if( aSide != LYR_TOP && aSide != LYR_BOTTOM )
if( aSide != IDF_LAYER::LYR_TOP && aSide != IDF_LAYER::LYR_BOTTOM )
{
ostringstream ostr;
ostr << "\n* invalid side (" << GetLayerString( aSide ) << "); ";
@ -746,7 +743,7 @@ void IDF3_COMP_OUTLINE_DATA::writePlaceData( std::ostream& aBoardFile,
switch( aSide )
{
case LYR_TOP:
case IDF_LAYER::LYR_TOP:
xpos = aXpos + xoff;
ypos = aYpos + yoff;
ang = aAngle + aoff;
@ -768,12 +765,12 @@ void IDF3_COMP_OUTLINE_DATA::writePlaceData( std::ostream& aBoardFile,
aBoardFile << "\"" << outline->GetGeomName() << "\" \"" << outline->GetPartName() << "\" "
<< arefdes << "\n";
IDF3::IDF_UNIT unit = UNIT_MM;
IDF3::IDF_UNIT unit = IDF_UNIT::UNIT_MM;
if( parent )
unit = parent->GetUnit();
if( unit == UNIT_MM )
if( unit == IDF_UNIT::UNIT_MM )
{
aBoardFile << setiosflags(ios::fixed) << setprecision(5) << xpos << " "
<< ypos << " " << setprecision(3) << zoff << " "
@ -790,15 +787,15 @@ void IDF3_COMP_OUTLINE_DATA::writePlaceData( std::ostream& aBoardFile,
switch( aPlacement )
{
case PS_PLACED:
case IDF_PLACEMENT::PS_PLACED:
aBoardFile << " PLACED\n";
break;
case PS_UNPLACED:
case IDF_PLACEMENT::PS_UNPLACED:
aBoardFile << " UNPLACED\n";
break;
case PS_MCAD:
case IDF_PLACEMENT::PS_MCAD:
aBoardFile << " MCAD\n";
break;
@ -816,8 +813,8 @@ IDF3_COMPONENT::IDF3_COMPONENT( IDF3_BOARD* aParent )
angle = 0.0;
hasPosition = false;
placement = PS_INVALID;
layer = LYR_INVALID;
placement = IDF_PLACEMENT::PS_INVALID;
layer = IDF_LAYER::LYR_INVALID;
parent = aParent;
}
@ -866,14 +863,14 @@ bool IDF3_COMPONENT::checkOwnership( int aSourceLine, const char* aSourceFunc )
switch( placement )
{
case PS_UNPLACED:
case PS_PLACED:
case PS_INVALID:
case IDF_PLACEMENT::PS_UNPLACED:
case IDF_PLACEMENT::PS_PLACED:
case IDF_PLACEMENT::PS_INVALID:
break;
case PS_MCAD:
case IDF_PLACEMENT::PS_MCAD:
if( pcad != CAD_MECH )
if( pcad != CAD_TYPE::CAD_MECH )
{
ostringstream ostr;
ostr << __FILE__ << ":" << __LINE__ << ":" << __FUNCTION__ << "():\n";
@ -887,9 +884,9 @@ bool IDF3_COMPONENT::checkOwnership( int aSourceLine, const char* aSourceFunc )
break;
case PS_ECAD:
case IDF_PLACEMENT::PS_ECAD:
if( pcad != CAD_ELEC )
if( pcad != CAD_TYPE::CAD_ELEC )
{
ostringstream ostr;
ostr << __FILE__ << ":" << __LINE__ << ":" << __FUNCTION__ << "():\n";
@ -906,7 +903,7 @@ bool IDF3_COMPONENT::checkOwnership( int aSourceLine, const char* aSourceFunc )
do
{
ostringstream ostr;
ostr << "\n* BUG: unhandled internal placement value (" << placement << ")";
ostr << "\n* BUG: unhandled internal placement value (" << static_cast<int>( placement ) << ")";
errormsg = ostr.str();
return false;
@ -931,7 +928,7 @@ IDF3::CAD_TYPE IDF3_COMPONENT::GetCadType( void )
if( parent )
return parent->GetCadType();
return CAD_INVALID;
return CAD_TYPE::CAD_INVALID;
}
IDF3::IDF_UNIT IDF3_COMPONENT::GetUnit( void )
@ -939,7 +936,7 @@ IDF3::IDF_UNIT IDF3_COMPONENT::GetUnit( void )
if( parent )
return parent->GetUnit();
return UNIT_INVALID;
return IDF_UNIT::UNIT_INVALID;
}
bool IDF3_COMPONENT::SetRefDes( const std::string& aRefDes )
@ -1223,7 +1220,7 @@ bool IDF3_COMPONENT::GetPosition( double& aXpos, double& aYpos, double& aAngle,
aXpos = 0.0;
aYpos = 0.0;
aAngle = 0.0;
aLayer = IDF3::LYR_INVALID;
aLayer = IDF3::IDF_LAYER::LYR_INVALID;
return false;
}
@ -1247,8 +1244,8 @@ bool IDF3_COMPONENT::SetPosition( double aXpos, double aYpos, double aAngle,
switch( aLayer )
{
case LYR_TOP:
case LYR_BOTTOM:
case IDF_LAYER::LYR_TOP:
case IDF_LAYER::LYR_BOTTOM:
break;
default:
@ -1286,11 +1283,11 @@ IDF3::IDF_PLACEMENT IDF3_COMPONENT::GetPlacement( void )
bool IDF3_COMPONENT::SetPlacement( IDF3::IDF_PLACEMENT aPlacementValue )
{
if( aPlacementValue < PS_UNPLACED || aPlacementValue >= PS_INVALID )
if( aPlacementValue < IDF_PLACEMENT::PS_UNPLACED || aPlacementValue >= IDF_PLACEMENT::PS_INVALID )
{
ostringstream ostr;
ostr << __FILE__ << ":" << __LINE__ << ":" << __FUNCTION__ << "():\n";
ostr << "\n* invalid PLACEMENT value (" << aPlacementValue << ")";
ostr << "\n* invalid PLACEMENT value (" << static_cast<int>( aPlacementValue ) << ")";
errormsg = ostr.str();
return false;
@ -1345,7 +1342,7 @@ bool IDF3_COMPONENT::writePlaceData( std::ostream& aBoardFile )
IDF3_BOARD::IDF3_BOARD( IDF3::CAD_TYPE aCadType )
{
m_idfVer = IDF_V3;
m_idfVer = IDF_VERSION::IDF_V3;
m_cadType = aCadType;
m_userPrec = 5;
m_userScale = 1.0;
@ -1354,7 +1351,7 @@ IDF3_BOARD::IDF3_BOARD( IDF3::CAD_TYPE aCadType )
m_brdFileVersion = 0;
m_libFileVersion = 0;
m_refDesCounter = 0;
m_unit = UNIT_MM;
m_unit = IDF_UNIT::UNIT_MM;
// unlike other outlines which are created as necessary,
// the board outline always exists and its parent must
@ -1401,13 +1398,13 @@ bool IDF3_BOARD::checkComponentOwnership( int aSourceLine, const char* aSourceFu
IDF3::IDF_PLACEMENT place = aComponent->GetPlacement();
if( place == PS_PLACED || place == PS_UNPLACED )
if( place == IDF_PLACEMENT::PS_PLACED || place == IDF_PLACEMENT::PS_UNPLACED )
return true;
if( place == PS_MCAD && m_cadType == CAD_MECH )
if( place == IDF_PLACEMENT::PS_MCAD && m_cadType == CAD_TYPE::CAD_MECH )
return true;
if( place == PS_ECAD && m_cadType == CAD_ELEC )
if( place == IDF_PLACEMENT::PS_ECAD && m_cadType == CAD_TYPE::CAD_ELEC )
return true;
do
@ -1416,7 +1413,7 @@ bool IDF3_BOARD::checkComponentOwnership( int aSourceLine, const char* aSourceFu
ostr << "* " << __FILE__ << ":" << aSourceLine << ":" << aSourceFunc << "():\n";
ostr << "* ownership violation; CAD type is ";
if( m_cadType == CAD_MECH )
if( m_cadType == CAD_TYPE::CAD_MECH )
ostr << "MCAD ";
else
ostr << "ECAD ";
@ -1435,14 +1432,14 @@ bool IDF3_BOARD::setUnit( IDF3::IDF_UNIT aUnit, bool convert )
{
switch( aUnit )
{
case UNIT_MM:
case UNIT_THOU:
case IDF_UNIT::UNIT_MM:
case IDF_UNIT::UNIT_THOU:
m_unit = aUnit;
break;
case UNIT_TNM:
case IDF_UNIT::UNIT_TNM:
ERROR_IDF << "\n* TNM unit is not supported; defaulting to mm\n";
m_unit = UNIT_MM;
m_unit = IDF_UNIT::UNIT_MM;
break;
default:
@ -1450,7 +1447,7 @@ bool IDF3_BOARD::setUnit( IDF3::IDF_UNIT aUnit, bool convert )
{
ostringstream ostr;
ostr << __FILE__ << ":" << __LINE__ << ":" << __FUNCTION__ << "():\n";
ostr << "* invalid board unit (" << aUnit << ")";
ostr << "* invalid board unit (" << static_cast<int>( aUnit ) << ")";
m_errormsg = ostr.str();
return false;
@ -1602,7 +1599,7 @@ double IDF3_BOARD::GetBoardThickness( void )
}
void IDF3_BOARD::readBrdDrills( std::istream& aBoardFile, IDF3::FILE_STATE& aBoardState )
void IDF3_BOARD::readBrdDrills( std::istream& aBoardFile, FILE_STATE& aBoardState )
{
IDF_DRILL_DATA drill;
@ -1622,7 +1619,7 @@ void IDF3_BOARD::readBrdDrills( std::istream& aBoardFile, IDF3::FILE_STATE& aBoa
}
void IDF3_BOARD::readBrdNotes( std::istream& aBoardFile, IDF3::FILE_STATE& aBoardState )
void IDF3_BOARD::readBrdNotes( std::istream& aBoardFile, FILE_STATE& aBoardState )
{
IDF_NOTE note;
@ -1635,7 +1632,7 @@ void IDF3_BOARD::readBrdNotes( std::istream& aBoardFile, IDF3::FILE_STATE& aBoar
}
void IDF3_BOARD::readBrdPlacement( std::istream& aBoardFile, IDF3::FILE_STATE& aBoardState,
void IDF3_BOARD::readBrdPlacement( std::istream& aBoardFile, FILE_STATE& aBoardState,
bool aNoSubstituteOutlines )
{
IDF3_COMP_OUTLINE_DATA oldata;
@ -1644,7 +1641,7 @@ void IDF3_BOARD::readBrdPlacement( std::istream& aBoardFile, IDF3::FILE_STATE& a
}
void IDF3_BOARD::readBrdHeader( std::istream& aBoardFile, IDF3::FILE_STATE& aBoardState )
void IDF3_BOARD::readBrdHeader( std::istream& aBoardFile, FILE_STATE& aBoardState )
{
std::string iline; // the input line
bool isComment; // true if a line just read in is a comment line
@ -1737,11 +1734,11 @@ void IDF3_BOARD::readBrdHeader( std::istream& aBoardFile, IDF3::FILE_STATE& aBoa
if( !token.compare( "3.0" ) || !token.compare( "3." ) || !token.compare( "3" ) )
{
m_idfVer = IDF_V3;
m_idfVer = IDF_VERSION::IDF_V3;
}
else if( !token.compare( "2.0" ) || !token.compare( "2." ) || !token.compare( "2" ) )
{
m_idfVer = IDF_V2;
m_idfVer = IDF_VERSION::IDF_V2;
}
else
{
@ -1839,15 +1836,15 @@ void IDF3_BOARD::readBrdHeader( std::istream& aBoardFile, IDF3::FILE_STATE& aBoa
if( CompareToken( "MM", token ) )
{
m_unit = IDF3::UNIT_MM;
m_unit = IDF3::IDF_UNIT::UNIT_MM;
}
else if( CompareToken( "THOU", token ) )
{
m_unit = IDF3::UNIT_THOU;
m_unit = IDF3::IDF_UNIT::UNIT_THOU;
}
else if( ( m_idfVer == IDF_V2 ) && CompareToken( "TNM", token ) )
else if( ( m_idfVer == IDF_VERSION::IDF_V2 ) && CompareToken( "TNM", token ) )
{
m_unit = IDF3::UNIT_TNM;
m_unit = IDF3::IDF_UNIT::UNIT_TNM;
}
else
{
@ -1887,11 +1884,11 @@ void IDF3_BOARD::readBrdHeader( std::istream& aBoardFile, IDF3::FILE_STATE& aBoa
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
}
aBoardState = IDF3::FILE_HEADER;
aBoardState = FILE_STATE::FILE_HEADER;
}
void IDF3_BOARD::readBrdSection( std::istream& aBoardFile, IDF3::FILE_STATE& aBoardState,
void IDF3_BOARD::readBrdSection( std::istream& aBoardFile, FILE_STATE& aBoardState,
bool aNoSubstituteOutlines )
{
std::list< std::string > comments; // comments associated with a section
@ -1923,8 +1920,8 @@ void IDF3_BOARD::readBrdSection( std::istream& aBoardFile, IDF3::FILE_STATE& aBo
if( !aBoardFile.good() )
{
if( aBoardFile.eof() && aBoardState >= IDF3::FILE_HEADER &&
aBoardState < IDF3::FILE_INVALID )
if( aBoardFile.eof() && aBoardState >= FILE_STATE::FILE_HEADER &&
aBoardState < FILE_STATE::FILE_INVALID )
{
if( !comments.empty() )
ERROR_IDF << "[warning]: trailing comments in IDF file (comments will be lost)\n";
@ -1959,9 +1956,9 @@ void IDF3_BOARD::readBrdSection( std::istream& aBoardFile, IDF3::FILE_STATE& aBo
if( CompareToken( ".BOARD_OUTLINE", token ) )
{
if( aBoardState != IDF3::FILE_HEADER )
if( aBoardState != FILE_STATE::FILE_HEADER )
{
aBoardState = IDF3::FILE_INVALID;
aBoardState = FILE_STATE::FILE_INVALID;
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDF file\n"
"* Violation of specification: no HEADER section" ) );
@ -1981,7 +1978,7 @@ void IDF3_BOARD::readBrdSection( std::istream& aBoardFile, IDF3::FILE_STATE& aBo
}
}
aBoardState = IDF3::FILE_OUTLINE;
aBoardState = FILE_STATE::FILE_OUTLINE;
return;
}
@ -1990,7 +1987,7 @@ void IDF3_BOARD::readBrdSection( std::istream& aBoardFile, IDF3::FILE_STATE& aBo
if( CompareToken( ".OTHER_OUTLINE", token ) )
{
if( aBoardState != IDF3::FILE_OUTLINE )
if( aBoardState != FILE_STATE::FILE_OUTLINE )
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDF file\n"
"* Violation of specification: expecting .BOARD_OUTLINE, have .OTHER_OUTLINE" ) );
@ -2042,7 +2039,7 @@ void IDF3_BOARD::readBrdSection( std::istream& aBoardFile, IDF3::FILE_STATE& aBo
if( CompareToken( ".ROUTE_OUTLINE", token ) )
{
if( aBoardState != IDF3::FILE_OUTLINE )
if( aBoardState != FILE_STATE::FILE_OUTLINE )
{
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDF file\n"
@ -2083,7 +2080,7 @@ void IDF3_BOARD::readBrdSection( std::istream& aBoardFile, IDF3::FILE_STATE& aBo
if( CompareToken( ".PLACE_OUTLINE", token ) )
{
if( aBoardState != IDF3::FILE_OUTLINE )
if( aBoardState != FILE_STATE::FILE_OUTLINE )
{
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDF file\n"
@ -2124,7 +2121,7 @@ void IDF3_BOARD::readBrdSection( std::istream& aBoardFile, IDF3::FILE_STATE& aBo
if( CompareToken( ".ROUTE_KEEPOUT", token ) )
{
if( aBoardState != IDF3::FILE_OUTLINE )
if( aBoardState != FILE_STATE::FILE_OUTLINE )
{
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDF file\n"
@ -2165,7 +2162,7 @@ void IDF3_BOARD::readBrdSection( std::istream& aBoardFile, IDF3::FILE_STATE& aBo
if( CompareToken( ".VIA_KEEPOUT", token ) )
{
if( aBoardState != IDF3::FILE_OUTLINE )
if( aBoardState != FILE_STATE::FILE_OUTLINE )
{
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDF file\n"
@ -2205,7 +2202,7 @@ void IDF3_BOARD::readBrdSection( std::istream& aBoardFile, IDF3::FILE_STATE& aBo
if( CompareToken( ".PLACE_KEEPOUT", token ) )
{
if( aBoardState != IDF3::FILE_OUTLINE )
if( aBoardState != FILE_STATE::FILE_OUTLINE )
{
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDF file\n"
@ -2244,7 +2241,7 @@ void IDF3_BOARD::readBrdSection( std::istream& aBoardFile, IDF3::FILE_STATE& aBo
if( CompareToken( ".PLACE_REGION", token ) )
{
if( aBoardState != IDF3::FILE_OUTLINE )
if( aBoardState != FILE_STATE::FILE_OUTLINE )
{
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDF file\n"
@ -2284,7 +2281,7 @@ void IDF3_BOARD::readBrdSection( std::istream& aBoardFile, IDF3::FILE_STATE& aBo
if( CompareToken( ".DRILLED_HOLES", token ) )
{
if( aBoardState != IDF3::FILE_OUTLINE )
if( aBoardState != FILE_STATE::FILE_OUTLINE )
{
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDF file\n"
@ -2310,14 +2307,14 @@ void IDF3_BOARD::readBrdSection( std::istream& aBoardFile, IDF3::FILE_STATE& aBo
if( CompareToken( ".NOTES", token ) )
{
if( aBoardState != IDF3::FILE_OUTLINE )
if( aBoardState != FILE_STATE::FILE_OUTLINE )
{
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDF file\n"
"* Violation of specification: expecting .BOARD_OUTLINE, have .NOTES" ) );
}
if( m_idfVer < IDF_V3 )
if( m_idfVer < IDF_VERSION::IDF_V3 )
{
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDFv2 file\n"
@ -2343,7 +2340,7 @@ void IDF3_BOARD::readBrdSection( std::istream& aBoardFile, IDF3::FILE_STATE& aBo
if( CompareToken( ".PLACEMENT", token ) )
{
if( aBoardState != IDF3::FILE_OUTLINE )
if( aBoardState != FILE_STATE::FILE_OUTLINE )
{
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDF file\n"
@ -2390,7 +2387,7 @@ void IDF3_BOARD::readBoardFile( const std::string& aFileName, bool aNoSubstitute
std::string iline; // the input line
bool isComment; // true if a line just read in is a comment line
std::streampos pos;
IDF3::FILE_STATE state = IDF3::FILE_START;
FILE_STATE state = FILE_STATE::FILE_START;
// note: as per IDFv3 specification:
// "The Header section must be the first section in the file, the second
@ -2406,13 +2403,13 @@ void IDF3_BOARD::readBoardFile( const std::string& aFileName, bool aNoSubstitute
readBrdHeader( brd, state );
// read the various sections
while( state != IDF3::FILE_PLACEMENT && brd.good() )
while( state != FILE_STATE::FILE_PLACEMENT && brd.good() )
readBrdSection( brd, state, aNoSubstituteOutlines );
if( !brd.good() )
{
// check if we have valid data
if( brd.eof() && state >= IDF3::FILE_OUTLINE && state < IDF3::FILE_INVALID )
if( brd.eof() && state >= FILE_STATE::FILE_OUTLINE && state < FILE_STATE::FILE_INVALID )
{
CLOSE_STREAM( brd );
return;
@ -2425,7 +2422,7 @@ void IDF3_BOARD::readBoardFile( const std::string& aFileName, bool aNoSubstitute
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
}
if( brd.good() && state == IDF3::FILE_PLACEMENT )
if( brd.good() && state == FILE_STATE::FILE_PLACEMENT )
{
// read in any trailing lines and report on ignored comments (minor fault)
// and any non-comment item (non-compliance with IDFv3)
@ -2464,7 +2461,7 @@ void IDF3_BOARD::readBoardFile( const std::string& aFileName, bool aNoSubstitute
}
void IDF3_BOARD::readLibSection( std::istream& aLibFile, IDF3::FILE_STATE& aLibState,
void IDF3_BOARD::readLibSection( std::istream& aLibFile, FILE_STATE& aLibState,
IDF3_BOARD* aBoard )
{
if( aBoard == nullptr )
@ -2596,7 +2593,7 @@ void IDF3_BOARD::readLibSection( std::istream& aLibFile, IDF3::FILE_STATE& aLibS
// read the library HEADER
void IDF3_BOARD::readLibHeader( std::istream& aLibFile, IDF3::FILE_STATE& aLibState )
void IDF3_BOARD::readLibHeader( std::istream& aLibFile, FILE_STATE& aLibState )
{
std::string iline; // the input line
bool isComment; // true if a line just read in is a comment line
@ -2688,11 +2685,11 @@ void IDF3_BOARD::readLibHeader( std::istream& aLibFile, IDF3::FILE_STATE& aLibSt
if( !token.compare( "3.0" ) || !token.compare( "3." ) || !token.compare( "3" ) )
{
m_idfVer = IDF_V3;
m_idfVer = IDF_VERSION::IDF_V3;
}
else if( !token.compare( "2.0" ) || !token.compare( "2." ) || !token.compare( "2" ) )
{
m_idfVer = IDF_V2;
m_idfVer = IDF_VERSION::IDF_V2;
}
else
{
@ -2775,7 +2772,7 @@ void IDF3_BOARD::readLibHeader( std::istream& aLibFile, IDF3::FILE_STATE& aLibSt
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
}
aLibState = IDF3::FILE_HEADER;
aLibState = FILE_STATE::FILE_HEADER;
}
@ -2796,7 +2793,7 @@ void IDF3_BOARD::readLibFile( const std::string& aFileName )
}
lib.imbue( std::locale( "C" ) );
IDF3::FILE_STATE state = IDF3::FILE_START;
FILE_STATE state = FILE_STATE::FILE_START;
readLibHeader( lib, state );
@ -3010,7 +3007,7 @@ void IDF3_BOARD::writeBoardFile( const std::string& aFileName )
brd << setw(1) << setfill( ' ' );
if( m_unit == IDF3::UNIT_MM )
if( m_unit == IDF3::IDF_UNIT::UNIT_MM )
brd << "MM\n";
else
brd << "THOU\n";
@ -3490,8 +3487,8 @@ bool IDF3_BOARD::DelBoardDrill( double aDia, double aXpos, double aYpos )
#ifndef DISABLE_IDF_OWNERSHIP
IDF3::KEY_OWNER keyo = (*sp)->GetDrillOwner();
if( keyo == UNOWNED || ( keyo == MCAD && m_cadType == CAD_MECH )
|| ( keyo == ECAD && m_cadType == CAD_ELEC ) )
if( keyo == KEY_OWNER::UNOWNED || ( keyo == KEY_OWNER::MCAD && m_cadType == CAD_TYPE::CAD_MECH )
|| ( keyo == KEY_OWNER::ECAD && m_cadType == CAD_TYPE::CAD_ELEC ) )
{
rval = true;
delete *sp;
@ -3506,22 +3503,22 @@ bool IDF3_BOARD::DelBoardDrill( double aDia, double aXpos, double aYpos )
switch( keyo )
{
case ECAD:
case KEY_OWNER::ECAD:
ostr << "ECAD";
break;
case MCAD:
case KEY_OWNER::MCAD:
ostr << "MCAD";
break;
default:
ostr << "invalid: " << keyo;
ostr << "invalid: " << static_cast<int>( keyo );
break;
}
ostr << ") may not be modified by ";
if( m_cadType == CAD_MECH )
if( m_cadType == CAD_TYPE::CAD_MECH )
ostr << "MCAD";
else
ostr << "ECAD";
@ -4114,6 +4111,36 @@ IDF3_COMP_OUTLINE* IDF3_BOARD::GetComponentOutline( const std::string& aComponen
}
IDF3_COMP_OUTLINE* IDF3_BOARD::GetComponentOutline( const std::string& aGeomName,
const std::string& aPartName )
{
IDF3_COMP_OUTLINE* cp = GetComponentOutline( aGeomName + "_" + aPartName );
if( cp != nullptr )
return cp;
try
{
cp = new IDF3_COMP_OUTLINE( this );
}
catch( std::bad_alloc& )
{
ostringstream ostr;
ostr << __FILE__ << ":" << __LINE__ << ":" << __FUNCTION__ << "(): \n";
cerr << "could not create new outline";
m_errormsg = ostr.str();
return nullptr;
}
cp->SetGeomName( aGeomName );
cp->SetPartName( aPartName );
m_componentOutlines.emplace( cp->GetUID(), cp );
return cp;
}
IDF3_COMP_OUTLINE* IDF3_BOARD::GetInvalidOutline( const std::string& aGeomName,
const std::string& aPartName )
{
@ -4351,7 +4378,7 @@ void IDF3_BOARD::Clear( void )
m_boardName.clear();
m_boardOutline.setThickness( thickness );
m_unit = UNIT_MM;
m_unit = IDF_UNIT::UNIT_MM;
m_userScale = 1.0;
m_userXoff = 0.0;
m_userYoff = 0.0;

9
utils/idftools/idf_parser.h → common/io/idf/idf_parser.h

@ -52,7 +52,8 @@
#ifndef IDF_PARSER_H
#define IDF_PARSER_H
#include <idf_outlines.h>
#include <io/idf/idf_common.h>
#include <io/idf/idf_outlines.h>
class IDF3_COMPONENT;
class REPORTER;
@ -560,6 +561,12 @@ public:
// returns a pointer to the component outline object with the
// unique ID aComponentID
IDF3_COMP_OUTLINE* GetComponentOutline( const std::string& aComponentID );
// Return a pointer to a component outline registered under the unique ID
// GEOM_PART; if no such outline exists, create one, register it, and
// return it. The component class, unit, and height must be set by the
// caller; the outline has no file backing.
IDF3_COMP_OUTLINE* GetComponentOutline( const std::string& aGeomName,
const std::string& aPartName );
// returns a pointer to the outline "NOGEOM NOPART" which is substituted
// whenever a true outline cannot be found or is defective

2
utils/idftools/vrml_layer.cpp → common/io/idf/vrml_layer.cpp

@ -33,7 +33,7 @@
#include <string>
#include <iomanip>
#include <cmath>
#include <vrml_layer.h>
#include <io/idf/vrml_layer.h>
#include <trigo.h>
#ifndef CALLBACK

0
utils/idftools/vrml_layer.h → common/io/idf/vrml_layer.h

1
pcbnew/CMakeLists.txt

@ -808,7 +808,6 @@ set( PCBNEW_KIFACE_LIBRARIES
common
gal
core
idf3
markdown_lib
${PCBNEW_IO_LIBRARIES}
${wxWidgets_LIBRARIES}

1
pcbnew/drc/rule_editor/panel_drc_rule_editor.cpp

@ -37,7 +37,6 @@
#include <layer_range.h>
#include <board.h>
#include <project/net_settings.h>
#include <idf_parser.h>
#include <scintilla_tricks.h>
#include <wx/stc/stc.h>
#include <dialogs/html_message_box.h>

30
pcbnew/exporters/export_idf.cpp

@ -27,7 +27,7 @@
#include <board_design_settings.h>
#include <footprint.h>
#include <footprint_library_adapter.h>
#include <idf_parser.h>
#include <io/idf/idf_parser.h>
#include <pad.h>
#include <pcb_shape.h>
#include <build_version.h>
@ -416,15 +416,15 @@ void IDF_EXPORTER::exportFootprint( FOOTPRINT* aFootprint, IDF3_BOARD& aIDFBoard
{
// plating
if( pad->GetAttribute() == PAD_ATTRIB::NPTH )
kplate = IDF3::NPTH;
kplate = IDF3::KEY_PLATING::NPTH;
else
kplate = IDF3::PTH;
kplate = IDF3::KEY_PLATING::PTH;
// hole type
tstr = TO_UTF8( pad->GetNumber() );
if( tstr.empty() || !tstr.compare( "0" ) || !tstr.compare( "~" )
|| ( kplate == IDF3::NPTH )
|| ( kplate == IDF3::KEY_PLATING::NPTH )
|| ( pad->GetDrillShape() == PAD_DRILL_SHAPE::OBLONG ) )
pintype = "MTG";
else
@ -476,7 +476,7 @@ void IDF_EXPORTER::exportFootprint( FOOTPRINT* aFootprint, IDF3_BOARD& aIDFBoard
else
{
IDF_DRILL_DATA *dp = new IDF_DRILL_DATA( drill, x, y, kplate, crefdes,
pintype, IDF3::ECAD );
pintype, IDF3::KEY_OWNER::ECAD );
if( !aIDFBoard.AddDrill( dp ) )
{
@ -603,16 +603,16 @@ void IDF_EXPORTER::exportFootprint( FOOTPRINT* aFootprint, IDF3_BOARD& aIDFBoard
{
comp->SetPosition( aFootprint->GetPosition().x * scale + dx,
-aFootprint->GetPosition().y * scale + dy,
rotz, IDF3::LYR_TOP );
rotz, IDF3::IDF_LAYER::LYR_TOP );
}
else
{
comp->SetPosition( aFootprint->GetPosition().x * scale + dx,
-aFootprint->GetPosition().y * scale + dy,
rotz, IDF3::LYR_BOTTOM );
rotz, IDF3::IDF_LAYER::LYR_BOTTOM );
}
comp->SetPlacement( IDF3::PS_ECAD );
comp->SetPlacement( IDF3::IDF_PLACEMENT::PS_ECAD );
aIDFBoard.AddComponent( comp );
}
@ -628,16 +628,16 @@ void IDF_EXPORTER::exportFootprint( FOOTPRINT* aFootprint, IDF3_BOARD& aIDFBoard
{
comp->SetPosition( aFootprint->GetPosition().x * scale + dx,
-aFootprint->GetPosition().y * scale + dy,
rotz, IDF3::LYR_TOP );
rotz, IDF3::IDF_LAYER::LYR_TOP );
}
else
{
comp->SetPosition( aFootprint->GetPosition().x * scale + dx,
-aFootprint->GetPosition().y * scale + dy,
rotz, IDF3::LYR_BOTTOM );
rotz, IDF3::IDF_LAYER::LYR_BOTTOM );
}
comp->SetPlacement( IDF3::PS_ECAD );
comp->SetPlacement( IDF3::IDF_PLACEMENT::PS_ECAD );
}
else
@ -653,7 +653,7 @@ void IDF_EXPORTER::exportFootprint( FOOTPRINT* aFootprint, IDF3_BOARD& aIDFBoard
// conditions: same side, X,Y coordinates within 10 microns,
// angle within 0.01 degree
if( ( top && side == IDF3::LYR_BOTTOM ) || ( !top && side == IDF3::LYR_TOP )
if( ( top && side == IDF3::IDF_LAYER::LYR_BOTTOM ) || ( !top && side == IDF3::IDF_LAYER::LYR_TOP )
|| ( refA > 0.0001 ) || ( refX > 0.0001 ) )
{
if( m_reporter )
@ -717,7 +717,7 @@ bool IDF_EXPORTER::Export( const wxString& aFullFileName ) const
wxCHECK( m_resolver, false );
wxCHECK( m_settings, false );
IDF3_BOARD idfBoard( IDF3::CAD_ELEC );
IDF3_BOARD idfBoard( IDF3::CAD_TYPE::CAD_ELEC );
// Switch the locale to standard C (needed to print floating point numbers)
LOCALE_IO toggle;
@ -728,12 +728,12 @@ bool IDF_EXPORTER::Export( const wxString& aFullFileName ) const
if( m_settings->m_units == JOB_EXPORT_PCB_IDF::UNITS::MILS )
{
idfUnit = IDF3::UNIT_THOU;
idfUnit = IDF3::IDF_UNIT::UNIT_THOU;
idfBoard.SetUserPrecision( 1 );
}
else
{
idfUnit = IDF3::UNIT_MM;
idfUnit = IDF3::IDF_UNIT::UNIT_MM;
idfBoard.SetUserPrecision( 5 );
}

2
pcbnew/exporters/exporter_vrml.cpp

@ -43,7 +43,7 @@
#include <filename_resolver.h>
#include "plugins/3dapi/ifsg_all.h"
#include "streamwrapper.h"
#include "vrml_layer.h"
#include <io/idf/vrml_layer.h>
#include "pcb_edit_frame.h"
#include <convert_basic_shapes_to_polygon.h>

2
pcbnew/pcb_io/odbpp/odb_util.cpp

@ -25,7 +25,7 @@
#include <wx/chartype.h>
#include <wx/dir.h>
#include <wx/regex.h>
#include "idf_helpers.h"
#include <io/idf/idf_helpers.h>
#include "odb_defines.h"
#include "pcb_io_odbpp.h"

6
plugins/3d/idf/CMakeLists.txt

@ -14,17 +14,15 @@
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_SOURCE_DIR}/utils/idftools
)
add_library( s3d_plugin_idf MODULE
s3d_plugin_idf.cpp
${CMAKE_SOURCE_DIR}/utils/idftools/vrml_layer.cpp
${CMAKE_SOURCE_DIR}/common/io/idf/vrml_layer.cpp
)
target_link_libraries( s3d_plugin_idf
kicad_3dsg
idf3
common
${OPENGL_LIBRARIES}
${wxWidgets_LIBRARIES} )
@ -45,4 +43,4 @@ install( TARGETS
if( KICAD_WIN32_INSTALL_PDBS )
# Get the PDBs to copy over for MSVC
install(FILES $<TARGET_PDB_FILE:s3d_plugin_idf> DESTINATION ${KICAD_USER_PLUGIN}/3d)
endif()
endif()

12
plugins/3d/idf/s3d_plugin_idf.cpp

@ -29,8 +29,8 @@
#include "plugins/3d/3d_plugin.h"
#include "plugins/3dapi/ifsg_all.h"
#include "idf_parser.h"
#include "vrml_layer.h"
#include <io/idf/idf_parser.h>
#include <io/idf/vrml_layer.h>
#define PLUGIN_3D_IDF_MAJOR 1
#define PLUGIN_3D_IDF_MINOR 0
@ -601,7 +601,7 @@ static SCENEGRAPH* addOutline( IDF3_COMP_OUTLINE* outline, int idxColor, SGNODE*
static SCENEGRAPH* loadIDFOutline( const wxString& aFileName )
{
LOCALESWITCH switcher;
IDF3_BOARD brd( IDF3::CAD_ELEC );
IDF3_BOARD brd( IDF3::CAD_TYPE::CAD_ELEC );
IDF3_COMP_OUTLINE* outline = nullptr;
outline = brd.GetComponentOutline( aFileName );
@ -628,7 +628,7 @@ static SCENEGRAPH* loadIDFOutline( const wxString& aFileName )
static SCENEGRAPH* loadIDFBoard( const wxString& aFileName )
{
LOCALESWITCH switcher;
IDF3_BOARD brd( IDF3::CAD_ELEC );
IDF3_BOARD brd( IDF3::CAD_TYPE::CAD_ELEC );
// note: if the IDF model is defective no outline substitutes shall be made
if( !brd.ReadFile( aFileName, true ) )
@ -761,7 +761,7 @@ static bool makeComponents( IDF3_BOARD& brd, SGNODE* aParent )
{
sc->second->GetPosition( vX, vY, vA, lyr );
if( lyr == IDF3::LYR_BOTTOM )
if( lyr == IDF3::IDF_LAYER::LYR_BOTTOM )
bottom = true;
else
bottom = false;
@ -896,7 +896,7 @@ static bool makeOtherOutlines( IDF3_BOARD& brd, SGNODE* aParent )
while( nvcont > 0 )
vpcb.EnsureWinding( nvcont--, true );
if( pout->GetSide() == IDF3::LYR_BOTTOM )
if( pout->GetSide() == IDF3::IDF_LAYER::LYR_BOTTOM )
{
top = 0.0;
bot = -pout->GetThickness();

1
qa/fuzz/CMakeLists.txt

@ -76,7 +76,6 @@ if(KICAD_BUILD_FUZZ_TESTS)
dxflib_qcad
tinyspline_lib
nanosvg
idf3
common
qa_utils
markdown_lib

1
qa/pcbnew_utils/CMakeLists.txt

@ -69,7 +69,6 @@ target_link_libraries( qa_pcbnew_utils PUBLIC
# gal
# qa_utils
# lib_dxf
# idf3
# unit_test_utils
# ${PCBNEW_IO_LIBRARIES}
# ${wxWidgets_LIBRARIES}

1
qa/tests/api/CMakeLists.txt

@ -50,7 +50,6 @@ target_link_libraries( qa_api
pnsrouter
gal
common
idf3
markdown_lib
${PCBNEW_IO_LIBRARIES}
${wxWidgets_LIBRARIES}

1
qa/tests/pcbnew/CMakeLists.txt

@ -389,7 +389,6 @@ target_link_libraries( qa_pcbnew
tinyspline_lib
nanosvg
planegcs
idf3
markdown_lib
${PCBNEW_IO_LIBRARIES}
${wxWidgets_LIBRARIES}

1
qa/tools/drc_benchmark/CMakeLists.txt

@ -65,7 +65,6 @@ target_link_libraries( qa_drc_benchmark
dxflib_qcad
tinyspline_lib
nanosvg
idf3
markdown_lib
nlohmann_json
${PCBNEW_IO_LIBRARIES}

1
qa/tools/drc_proto/CMakeLists.txt

@ -98,7 +98,6 @@ target_link_libraries( drc_proto
tinyspline_lib
nanosvg
markdown_lib
idf3
Boost::headers
${PCBNEW_IO_LIBRARIES}
${wxWidgets_LIBRARIES}

1
qa/tools/ibis/CMakeLists.txt

@ -57,7 +57,6 @@ target_link_libraries( ibis_proto
dxflib_qcad
tinyspline_lib
nanosvg
idf3
Boost::headers
${wxWidgets_LIBRARIES}
${GDI_PLUS_LIBRARIES}

1
qa/tools/pcbnew_tools/CMakeLists.txt

@ -56,7 +56,6 @@ target_link_libraries( qa_pcbnew_tools
dxflib_qcad
tinyspline_lib
nanosvg
idf3
common
qa_utils
markdown_lib

2
qa/tools/pns/CMakeLists.txt

@ -111,7 +111,6 @@ target_link_libraries( pns_debug_tool
dxflib_qcad
tinyspline_lib
nanosvg
idf3
pcbcommon
markdown_lib
3d-viewer
@ -135,7 +134,6 @@ target_link_libraries( qa_pns_regressions
dxflib_qcad
tinyspline_lib
nanosvg
idf3
pcbcommon
markdown_lib
3d-viewer

4
utils/CMakeLists.txt

@ -4,10 +4,6 @@ if( COMPILER_SUPPORTS_WARNINGS )
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARN_FLAGS_C}")
endif()
if( KICAD_IDF_TOOLS )
add_subdirectory( idftools )
endif()
# The Quick Look extensions are Objective-C++ app extensions, so they build with the rest of the
# tree under whichever generator KiCad is configured with.
set( KICAD_BUILD_QUICKLOOK OFF CACHE INTERNAL "Quick Look model preview extensions are buildable" FORCE )

58
utils/idftools/CMakeLists.txt

@ -1,58 +0,0 @@
include_directories(
"${CMAKE_SOURCE_DIR}/include"
"${CMAKE_SOURCE_DIR}/utils/idftools"
${OPENGL_INCLUDE_DIR}
)
set( IDF3_FILES
idf_helpers.cpp
idf_common.cpp
idf_outlines.cpp
idf_parser.cpp
vrml_layer.cpp
)
if( MINGW )
list( APPEND IDF3_FILES ${CMAKE_SOURCE_DIR}/common/streamwrapper.cpp )
endif( MINGW )
add_library( idf3 STATIC ${IDF3_FILES} )
target_link_libraries( idf3
kimath
glad
Boost::headers
)
add_executable( idfcyl idf_cylinder.cpp )
add_executable( idfrect idf_rect.cpp )
add_executable( dxf2idf dxf2idfmain.cpp dxf2idf.cpp )
add_executable( idf2vrml idf2vrml.cpp )
target_link_libraries( dxf2idf
dxflib_qcad
idf3
kimath
${wxWidgets_LIBRARIES}
)
target_link_libraries( idf2vrml
idf3
kimath
${OPENGL_LIBRARIES}
${wxWidgets_LIBRARIES}
)
if( APPLE )
# puts binaries into the *.app bundle while linking
set_target_properties( idfcyl idfrect dxf2idf idf2vrml PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${OSX_BUNDLE_BUILD_BIN_DIR}
)
set_target_properties( idfcyl idfrect dxf2idf idf2vrml PROPERTIES INSTALL_RPATH
"@executable_path/../Frameworks" )
set_target_properties( idfcyl idfrect dxf2idf idf2vrml PROPERTIES BUILD_WITH_INSTALL_RPATH 1 )
else()
install( TARGETS idfcyl idfrect idf2vrml
dxf2idf
DESTINATION ${KICAD_BIN}
COMPONENT binary )
endif()

404
utils/idftools/dxf2idf.cpp

@ -1,404 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014 Cirilo Bernardo
* Copyright The 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, see <https://www.gnu.org/licenses/>.
*/
#include <cstdio>
#include <iostream>
#include <dxf2idf.h>
// differences in angle smaller than MIN_ANG are considered equal
#define MIN_ANG (0.01)
// min and max bulge bracketing min. arc before transition to line segment
// and max. arc limit
// MIN_BULGE = 0.002 ~0.45 degrees
// MAX_BULGE = 2000 ~89.97 degrees
#define MIN_BULGE 0.002
#define MAX_BULGE 2000.0
DXF2IDF::~DXF2IDF()
{
while( !lines.empty() )
{
#ifdef DEBUG_IDF
IDF3::printSeg( lines.back() );
#endif
delete lines.back();
lines.pop_back();
}
}
bool DXF2IDF::ReadDxf( const std::string& aFile )
{
DL_Dxf dxf_reader;
bool success = true;
if( !dxf_reader.in( aFile, this ) ) // if file open failed
success = false;
return success;
}
void DXF2IDF::addLine( const DL_LineData& aData )
{
IDF_POINT p1, p2;
p1.x = aData.x1 * m_scale;
p1.y = aData.y1 * m_scale;
p2.x = aData.x2 * m_scale;
p2.y = aData.y2 * m_scale;
insertLine( p1, p2 );
}
void DXF2IDF::addCircle( const DL_CircleData& aData )
{
IDF_POINT p1, p2;
p1.x = aData.cx * m_scale;
p1.y = aData.cy * m_scale;
p2.x = p1.x + aData.radius * m_scale;
p2.y = p1.y;
IDF_SEGMENT* seg = new IDF_SEGMENT( p1, p2, 360, true );
if( seg )
lines.push_back( seg );
}
void DXF2IDF::addArc( const DL_ArcData& aData )
{
IDF_POINT p1, p2;
p1.x = aData.cx * m_scale;
p1.y = aData.cy * m_scale;
// note: DXF circles always run CCW
double ea = aData.angle2;
while( ea < aData.angle1 )
ea += M_PI;
p2.x = p1.x + cos( aData.angle1 ) * aData.radius * m_scale;
p2.y = p1.y + sin( aData.angle1 ) * aData.radius * m_scale;
double angle = ( ea - aData.angle1 ) * 180.0 / M_PI;
IDF_SEGMENT* seg = new IDF_SEGMENT( p1, p2, angle, true );
if( seg )
lines.push_back( seg );
}
bool DXF2IDF::WriteOutline( FILE* aFile, bool isInch )
{
if( lines.empty() )
{
std::cerr << "* DXF2IDF: empty outline\n";
return false;
}
// 1. find lowest X value
// 2. string an outline together
// 3. emit warnings if more than 1 outline
IDF_OUTLINE outline;
IDF3::GetOutline( lines, outline );
if( outline.empty() )
{
return false;
}
char loopDir = '1';
if( outline.IsCCW() )
loopDir = '0';
std::list<IDF_SEGMENT*>::iterator bo;
std::list<IDF_SEGMENT*>::iterator eo;
if( outline.size() == 1 )
{
if( !outline.front()->IsCircle() )
{
return false;
}
// NOTE: a circle always has an angle of 360, never -360,
// otherwise SolidWorks chokes on the file.
if( isInch )
{
fprintf( aFile, "%c %d %d 0\n", loopDir, (int) ( 1000 * outline.front()->startPoint.x ),
(int) ( 1000 * outline.front()->startPoint.y ) );
fprintf( aFile, "%c %d %d 360\n", loopDir, (int) ( 1000 * outline.front()->endPoint.x ),
(int) ( 1000 * outline.front()->endPoint.y ) );
}
else
{
fprintf( aFile, "%c %.3f %.3f 0\n", loopDir, outline.front()->startPoint.x,
outline.front()->startPoint.y );
fprintf( aFile, "%c %.3f %.3f 360\n", loopDir, outline.front()->endPoint.x,
outline.front()->endPoint.y );
}
return true;
}
// ensure that the very last point is the same as the very first point
outline.back()-> endPoint = outline.front()->startPoint;
bo = outline.begin();
eo = outline.end();
// for the first item we write out both points
if( ( *bo )->angle < MIN_ANG && ( *bo )->angle > -MIN_ANG )
{
if( isInch )
{
fprintf( aFile, "%c %d %d 0\n", loopDir, (int) ( 1000 * ( *bo )->startPoint.x ),
(int) ( 1000 * ( *bo )->startPoint.y ) );
fprintf( aFile, "%c %d %d 0\n", loopDir, (int) ( 1000 * ( *bo )->endPoint.x ),
(int) ( 1000 * ( *bo )->endPoint.y ) );
}
else
{
fprintf( aFile, "%c %.3f %.3f 0\n", loopDir, ( *bo )->startPoint.x,
( *bo )->startPoint.y );
fprintf( aFile, "%c %.3f %.3f 0\n", loopDir, ( *bo )->endPoint.x, ( *bo )->endPoint.y );
}
}
else
{
if( isInch )
{
fprintf( aFile, "%c %d %d 0\n", loopDir, (int) ( 1000 * ( *bo )->startPoint.x ),
(int) ( 1000 * ( *bo )->startPoint.y ) );
fprintf( aFile, "%c %d %d %.2f\n", loopDir, (int) ( 1000 * ( *bo )->endPoint.x ),
(int) ( 1000 * ( *bo )->endPoint.y ), ( *bo )->angle );
}
else
{
fprintf( aFile, "%c %.3f %.3f 0\n", loopDir, ( *bo )->startPoint.x,
( *bo )->startPoint.y );
fprintf( aFile, "%c %.3f %.3f %.2f\n", loopDir, ( *bo )->endPoint.x,
( *bo )->endPoint.y, ( *bo )->angle );
}
}
++bo;
// for all other segments we only write out the last point
while( bo != eo )
{
if( isInch )
{
if( ( *bo )->angle < MIN_ANG && ( *bo )->angle > -MIN_ANG )
{
fprintf( aFile, "%c %d %d 0\n", loopDir, (int) ( 1000 * ( *bo )->endPoint.x ),
(int) ( 1000 * ( *bo )->endPoint.y ) );
}
else
{
fprintf( aFile, "%c %d %d %.2f\n", loopDir, (int) ( 1000 * ( *bo )->endPoint.x ),
(int) ( 1000 * ( *bo )->endPoint.y ), ( *bo )->angle );
}
}
else
{
if( ( *bo )->angle < MIN_ANG && ( *bo )->angle > -MIN_ANG )
{
fprintf( aFile, "%c %.5f %.5f 0\n", loopDir, ( *bo )->endPoint.x,
( *bo )->endPoint.y );
}
else
{
fprintf( aFile, "%c %.5f %.5f %.2f\n", loopDir, ( *bo )->endPoint.x,
( *bo )->endPoint.y, ( *bo )->angle );
}
}
++bo;
}
return true;
}
void DXF2IDF::setVariableInt( const std::string& key, int value, int code )
{
// Called for every int variable in the DXF file (e.g. "$INSUNITS").
if( key == "$INSUNITS" ) // Drawing units
{
switch( value )
{
case 1: // inches
m_scale = 25.4;
break;
case 2: // feet
m_scale = 304.8;
break;
case 4: // mm
m_scale = 1.0;
break;
case 5: // centimeters
m_scale = 10.0;
break;
case 6: // meters
m_scale = 1000.0;
break;
case 8: // microinches
m_scale = 2.54e-5;
break;
case 9: // mils
m_scale = 0.0254;
break;
case 10: // yards
m_scale = 914.4;
break;
case 11: // Angstroms
m_scale = 1.0e-7;
break;
case 12: // nanometers
m_scale = 1.0e-6;
break;
case 13: // micrometers
m_scale = 1.0e-3;
break;
case 14: // decimeters
m_scale = 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_scale = 1.0;
break;
}
}
}
void DXF2IDF::addPolyline(const DL_PolylineData& aData )
{
// Convert DXF Polylines into a series of 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_entityParseStatus = 1;
m_entity_flags = aData.flags;
m_entityType = DL_ENTITY_POLYLINE;
}
void DXF2IDF::addVertex( const DL_VertexData& aData )
{
if( m_entityParseStatus == 0 )
return; // Error
if( m_entityParseStatus == 1 ) // This is the first vertex of an entity
{
m_lastCoordinate.x = aData.x * m_scale;
m_lastCoordinate.y = aData.y * m_scale;
m_polylineStart = m_lastCoordinate;
m_bulgeVertex = aData.bulge;
m_entityParseStatus = 2;
return;
}
IDF_POINT seg_end;
seg_end.x = aData.x * m_scale;
seg_end.y = aData.y * m_scale;
insertLine( m_lastCoordinate, seg_end );
m_lastCoordinate = seg_end;
}
void DXF2IDF::endEntity()
{
if( m_entityType == DL_ENTITY_POLYLINE )
{
// Polyline flags bit 0 indicates closed (1) or open (0) polyline
if( m_entity_flags & 1 )
{
if( std::abs( m_bulgeVertex ) < MIN_BULGE )
insertLine( m_lastCoordinate, m_polylineStart );
else
insertArc( m_lastCoordinate, m_polylineStart, m_bulgeVertex );
}
}
m_entityType = 0 ;
m_entity_flags = 0;
m_entityParseStatus = 0;
}
void DXF2IDF::insertLine( const IDF_POINT& aSegStart, const IDF_POINT& aSegEnd )
{
IDF_SEGMENT* seg = new IDF_SEGMENT( aSegStart, aSegEnd );
if( seg )
lines.push_back( seg );
}
void DXF2IDF::insertArc( const IDF_POINT& aSegStart, const IDF_POINT& aSegEnd, double aBulge )
{
if( aBulge < -MAX_BULGE )
aBulge = -MAX_BULGE;
else if( aBulge > MAX_BULGE )
aBulge = MAX_BULGE;
double ang = 720.0 * atan( aBulge ) / M_PI;
IDF_SEGMENT* seg = new IDF_SEGMENT( aSegStart, aSegEnd, ang, false );
if( seg )
lines.push_back( seg );
}

88
utils/idftools/dxf2idf.h

@ -1,88 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014 Cirilo Bernardo
* Copyright The 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, see <https://www.gnu.org/licenses/>.
*/
#ifndef DXF2IDF_H
#define DXF2IDF_H
#include <string>
#include "dl_dxf.h"
#include "dl_creationadapter.h"
#include <idf_common.h>
class DXF2IDF : public DL_CreationAdapter
{
public:
DXF2IDF() : m_scale( 1.0 ), m_entityType( 0 ), m_entityParseStatus( 0 ),
m_entity_flags( 0 ), m_bulgeVertex( 0.0 ) {};
~DXF2IDF();
bool ReadDxf( const std::string& aFile );
bool WriteOutline( FILE* aFile, bool isInch );
private:
// DRW_Interface implemented callback functions
virtual void addLine( const DL_LineData& aData ) override;
virtual void addArc( const DL_ArcData& aData ) override;
virtual void addCircle( const DL_CircleData& aData ) override;
virtual void addPolyline( const DL_PolylineData& aData ) override;
/**
* Called for every polyline vertex.
*/
virtual void addVertex( const DL_VertexData& aData ) override;
/**
* 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 endEntity() override;
private:
std::list< IDF_SEGMENT* > lines; // Unsorted list of graphical segments
double m_scale; // scaling factor to mm
int m_entityType; // the DXF type of entity
int m_entityParseStatus; // Inside a entity: status of parsing:
// 0 = no entity
// 1 = first item of entity
// 2 = entity in progress
int m_entity_flags; // state of flags read from last entity
IDF_POINT m_lastCoordinate; // the last vertex coordinate read (unit = mm)
// The first point of the polyline entity, when reading a polyline (unit = mm).
IDF_POINT m_polylineStart;
double m_bulgeVertex; // the last vertex bulge value read
void insertLine( const IDF_POINT& aSegStart, const IDF_POINT& aSegEnd );
void insertArc( const IDF_POINT& aSegStart, const IDF_POINT& aSegEnd, double aBulge );
};
#endif // DXF2IDF_H

197
utils/idftools/dxf2idfmain.cpp

@ -1,197 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014 Cirilo Bernardo
* Copyright The 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, see <https://www.gnu.org/licenses/>.
*/
#include <cstdio>
#include <iostream>
#include <sstream>
#include <string>
#include <list>
#include <dxf2idf.h>
using namespace std;
int main( int argc, char **argv )
{
list< string > comments;
string line;
stringstream tstr;
string dname; // DXF filename
string gname; // Geometry Name
string pname; // Part Name
double height = 0; // extrusion height
bool inch = false; // true = inches, false = mm
bool ok;
if( argc == 1 )
{
// no arguments; print out usage information
cout << "dxf2idf: this program takes line, arc, and circle segments\n";
cout << " from a DXF file and creates an IDF component outline file.\n\n";
cout << "Input:\n";
cout << " DXF filename: the input file, must end in '.dxf'\n";
cout << " Units: mm, in (millimeters or inches)\n";
cout << " Geometry Name: string, as per IDF version 3.0 specification\n";
cout << " Part Name: as per IDF version 3.0 specification of Part Number\n";
cout << " Height: extruded height of the outline\n";
cout << " Comments: all non-empty lines are comments to be added to\n";
cout << " the IDF file. An empty line signifies the end of\n";
cout << " the comment block.\n";
cout << " File name: output filename, must end in '.idf'\n\n";
}
line.clear();
while( line.empty() || line.find( ".dxf" ) == string::npos )
{
cout << "* DXF filename: ";
line.clear();
std::getline( cin, line );
}
dname = line;
line.clear();
while( line.compare( "mm" ) && line.compare( "in" )
&& line.compare( "MM" ) && line.compare( "IN" ) )
{
cout << "* Units (mm,in): ";
line.clear();
std::getline( cin, line );
}
if( line.compare( "mm" ) && line.compare( "MM" ) )
inch = true;
line.clear();
while( line.empty() )
{
cout << "* Geometry name: ";
line.clear();
std::getline( cin, line );
if( line.find( '\"' ) != string::npos )
{
cerr << "[INFO] geometry name may not contain quotation marks\n";
line.clear();
}
}
gname = line;
line.clear();
while( line.empty() )
{
cout << "* Part name: ";
line.clear();
std::getline( cin, line );
if( line.find( '\"' ) != string::npos )
{
cerr << "[INFO] part name may not contain quotation marks\n";
line.clear();
}
}
pname = line;
ok = false;
while( !ok )
{
cout << "* Height: ";
line.clear();
std::getline( cin, line );
tstr.clear();
tstr.str( line );
tstr >> height;
if( !tstr.fail() && height > 0.001 )
ok = true;
}
cout << "* COMMENTS: any non-blank line is a comment;\n";
cout << " a blank line signifies the end of comments.\n";
ok = false;
while( !ok )
{
line.clear();
std::getline( cin, line );
if( line.empty() )
{
ok = true;
}
else
{
if( line[0] != '#' )
line.insert( 0, "# " );
comments.push_back( line );
}
}
line.clear();
while( line.empty() || line.find( ".idf" ) == string::npos )
{
cout << "* File name (*.idf): ";
line.clear();
std::getline( cin, line );
}
DXF2IDF dxf;
dxf.ReadDxf( dname.c_str() );
FILE* fp = fopen( line.c_str(), "w" );
list< string >::const_iterator scom = comments.begin();
list< string >::const_iterator ecom = comments.end();
while( scom != ecom )
{
fprintf( fp, "%s\n", (*scom).c_str() );
++scom;
}
fprintf( fp, ".ELECTRICAL\n" );
if( inch )
fprintf( fp, "\"%s\" \"%s\" THOU %d\n", gname.c_str(), pname.c_str(),
(int) ( height * 1000.0 ) );
else
fprintf( fp, "\"%s\" \"%s\" MM %.3f\n", gname.c_str(), pname.c_str(), height );
dxf.WriteOutline( fp, inch );
fprintf( fp, ".END_ELECTRICAL\n" );
return 0;
}

970
utils/idftools/idf2vrml.cpp

@ -1,970 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014-2017 Cirilo Bernardo
* Copyright The 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, see <https://www.gnu.org/licenses/>.
*/
/*
* This program takes an IDF base name, loads the board outline
* and component outine files, and creates a single VRML file.
* The VRML file can be used to visually verify the IDF files
* before sending them to a mechanical designer. The output scale
* is 10:1; this scale was chosen because VRML was originally
* intended to describe large virtual worlds and rounding errors
* would be more likely if we used a 1:1 scale.
*/
#include <wx/app.h>
#include <wx/cmdline.h>
#include <wx/log.h>
#include <wx/string.h>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <sstream>
#include <cmath>
#include <cstdio>
#include <cerrno>
#include <list>
#include <utility>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <boost/ptr_container/ptr_map.hpp>
#include <wx_filename.h>
#include "idf_helpers.h"
#include "idf_common.h"
#include "idf_parser.h"
#include "streamwrapper.h"
#include "vrml_layer.h"
#ifndef MIN_ANG
#define MIN_ANG 0.01
#endif
class IDF2VRML : public wxAppConsole
{
public:
virtual bool OnInit() override;
virtual int OnRun() override;
virtual void OnInitCmdLine(wxCmdLineParser& parser) override;
virtual bool OnCmdLineParsed(wxCmdLineParser& parser) override;
private:
double m_ScaleFactor;
bool m_Compact;
bool m_NoOutlineSubs;
wxString m_filename;
};
static const wxCmdLineEntryDesc cmdLineDesc[] =
{
{ wxCMD_LINE_OPTION, "f", NULL, "input file name",
wxCMD_LINE_VAL_STRING, wxCMD_LINE_OPTION_MANDATORY },
{ wxCMD_LINE_OPTION, "s", NULL, "scale factor",
wxCMD_LINE_VAL_DOUBLE, wxCMD_LINE_PARAM_OPTIONAL },
{ wxCMD_LINE_SWITCH, "k", NULL, "produce KiCad-friendly VRML output; default is compact VRML",
wxCMD_LINE_VAL_NONE, wxCMD_LINE_PARAM_OPTIONAL },
{ wxCMD_LINE_SWITCH, "d", NULL, "suppress substitution of default outlines",
wxCMD_LINE_VAL_NONE, wxCMD_LINE_PARAM_OPTIONAL },
{ wxCMD_LINE_SWITCH, "z", NULL, "suppress rendering of zero-height outlines",
wxCMD_LINE_VAL_NONE, wxCMD_LINE_PARAM_OPTIONAL },
{ wxCMD_LINE_SWITCH, "m", NULL, "print object mapping to stdout for debugging",
wxCMD_LINE_VAL_NONE, wxCMD_LINE_PARAM_OPTIONAL },
{ wxCMD_LINE_SWITCH, "h", NULL, "display this message",
wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },
{ wxCMD_LINE_NONE, nullptr, nullptr, nullptr, wxCMD_LINE_VAL_NONE, 0 }
};
wxIMPLEMENT_APP_CONSOLE( IDF2VRML );
bool nozeroheights;
bool showObjectMapping;
bool IDF2VRML::OnInit()
{
m_ScaleFactor = 1.0;
m_Compact = true;
m_NoOutlineSubs = false;
nozeroheights = false;
showObjectMapping = false;
if( !wxAppConsole::OnInit() )
return false;
return true;
}
void IDF2VRML::OnInitCmdLine( wxCmdLineParser& parser )
{
parser.SetDesc( cmdLineDesc );
parser.SetSwitchChars( wxT( "-" ) );
return;
}
bool IDF2VRML::OnCmdLineParsed( wxCmdLineParser& parser )
{
if( parser.Found( wxT( "k" ) ) )
m_Compact = false;
double scale;
if( parser.Found( wxT( "s" ), &scale ) )
m_ScaleFactor = scale;
wxString fname;
if( parser.Found( wxT( "f" ), &fname ) )
m_filename = fname;
if( parser.Found( wxT( "d" ) ) )
m_NoOutlineSubs = true;
if( parser.Found( wxT( "z" ) ) )
nozeroheights = true;
if( parser.Found( wxT( "m" ) ) )
showObjectMapping = true;
return true;
}
using namespace boost;
// define colors
struct VRML_COLOR
{
double diff[3];
double emis[3];
double spec[3];
double ambi;
double tran;
double shin;
};
struct VRML_IDS
{
int colorIndex;
std::string objectName;
bool used;
bool bottom;
double dX, dY, dZ, dA;
VRML_IDS()
{
colorIndex = 0;
used = false;
bottom = false;
dX = 0.0;
dY = 0.0;
dZ = 0.0;
dA = 0.0;
}
};
#define NCOLORS 7
VRML_COLOR colors[NCOLORS] =
{
{ { 0, 0.82, 0.247 }, { 0, 0, 0 }, { 0, 0.82, 0.247 }, 0.9, 0, 0.1 },
{ { 1, 0, 0 }, { 1, 0, 0 }, { 1, 0, 0 }, 0.9, 0, 0.1 },
{ { 0.659, 0, 0.463 }, { 0, 0, 0 }, { 0.659, 0, 0.463 }, 0.9, 0, 0.1 },
{ { 0.659, 0.294, 0 }, { 0, 0, 0 }, { 0.659, 0.294, 0 }, 0.9, 0, 0.1 },
{ { 0, 0.918, 0.659 }, { 0, 0, 0 }, { 0, 0.918, 0.659 }, 0.9, 0, 0.1 },
{ { 0.808, 0.733, 0.071 }, { 0, 0, 0 }, { 0.808, 0.733 , 0.071 }, 0.9, 0, 0.1 },
{ { 0.102, 1, 0.984 }, { 0, 0, 0 }, { 0.102, 1, 0.984 }, 0.9, 0, 0.1 }
};
bool WriteHeader( IDF3_BOARD& board, std::ostream& file );
bool MakeBoard( IDF3_BOARD& board, std::ostream& file );
bool MakeComponents( IDF3_BOARD& board, std::ostream& file, bool compact );
bool MakeOtherOutlines( IDF3_BOARD& board, std::ostream& file );
bool PopulateVRML( VRML_LAYER& model, const std::list< IDF_OUTLINE* >* items, bool bottom,
double scale, double dX = 0.0, double dY = 0.0, double angle = 0.0 );
bool AddSegment( VRML_LAYER& model, IDF_SEGMENT* seg, int icont, int iseg );
bool WriteTriangles( std::ostream& file, VRML_IDS* vID, VRML_LAYER* layer, bool plane,
bool top, double top_z, double bottom_z, int precision, bool compact );
inline void TransformPoint( IDF_SEGMENT& seg, double frac, bool bottom,
double dX, double dY, double angle );
VRML_IDS* GetColor( boost::ptr_map<const std::string, VRML_IDS>& cmap,
int& index, const std::string& uid );
int IDF2VRML::OnRun()
{
// Essential inputs:
// 1. IDF file
// 2. Output scale: internal IDF units are mm, so 1 = 1mm per VRML unit,
// 0.1 = 1cm per VRML unit, 0.01 = 1m per VRML unit,
// 1/25.4 = 1in per VRML unit, 1/2.54 = 0.1in per VRML unit (KiCad model)
// 3. KiCad-friendly output (do not reuse features via DEF+USE)
// Render each component to VRML; if the user wants
// a KiCad friendly output then we must avoid DEF+USE;
// otherwise we employ DEF+USE to minimize file size
if( m_ScaleFactor < 0.001 || m_ScaleFactor > 10.0 )
{
wxLogMessage( wxT( "scale factor out of range (%d); range is 0.001 to 10.0" ),
m_ScaleFactor);
return -1;
}
IDF3_BOARD pcb( IDF3::CAD_ELEC );
wxLogMessage( wxT( "Reading file: '%s'" ), m_filename );
if( !pcb.ReadFile( m_filename, m_NoOutlineSubs ) )
{
wxLogMessage( wxT( "Failed to read IDF data: %s" ), pcb.GetError() );
return -1;
}
// set the scale and output precision ( scale 1 == precision 5)
pcb.SetUserScale( m_ScaleFactor );
if( m_ScaleFactor < 0.01 )
pcb.SetUserPrecision( 8 );
else if( m_ScaleFactor < 0.1 )
pcb.SetUserPrecision( 7 );
else if( m_ScaleFactor < 1.0 )
pcb.SetUserPrecision( 6 );
else if( m_ScaleFactor < 10.0 )
pcb.SetUserPrecision( 5 );
else
pcb.SetUserPrecision( 4 );
// Create the VRML file and write the header
wxFileName fname( m_filename );
fname.SetExt( wxT( "wrl" ) );
fname.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS );
wxLogMessage( wxT( "Writing file: '%s'" ), fname.GetFullName() );
OPEN_OSTREAM( ofile, fname.GetFullPath().ToUTF8() );
if( ofile.fail() )
wxLogMessage( wxT( "Could not open file: '%s'" ), fname.GetFullName() );
ofile.imbue( std::locale( "C" ) );
ofile << std::fixed; // do not use exponents in VRML output
WriteHeader( pcb, ofile );
// STEP 1: Render the PCB alone
MakeBoard( pcb, ofile );
// STEP 2: Render the components
MakeComponents( pcb, ofile, m_Compact );
// STEP 3: Render the OTHER outlines
MakeOtherOutlines( pcb, ofile );
ofile << "]\n}\n";
CLOSE_STREAM( ofile );
return 0;
}
bool WriteHeader( IDF3_BOARD& board, std::ostream& file )
{
std::string bname = board.GetBoardName();
if( bname.empty() )
{
bname = "BoardWithNoName";
}
else
{
std::string::iterator ss = bname.begin();
std::string::iterator se = bname.end();
while( ss != se )
{
if( *ss == '/' || *ss == ' ' || *ss == ':' )
*ss = '_';
++ss;
}
}
file << "#VRML V2.0 utf8\n\n";
file << "WorldInfo {\n";
file << " title \"" << bname << "\"\n}\n\n";
file << "Transform {\n";
file << "children [\n";
return !file.fail();
}
bool MakeBoard( IDF3_BOARD& board, std::ostream& file )
{
VRML_LAYER vpcb;
if( board.GetBoardOutlinesSize() < 1 )
{
wxLogMessage( wxT( "Cannot proceed; no board outline in IDF object" ) );
return false;
}
double scale = board.GetUserScale();
// set the arc parameters according to output scale
int tI;
double tMin, tMax;
vpcb.GetArcParams( tI, tMin, tMax );
vpcb.SetArcParams( tI, tMin * scale, tMax * scale );
if( !PopulateVRML( vpcb, board.GetBoardOutline()->GetOutlines(), false, board.GetUserScale() ) )
{
return false;
}
vpcb.EnsureWinding( 0, false );
int nvcont = vpcb.GetNContours() - 1;
while( nvcont > 0 )
vpcb.EnsureWinding( nvcont--, true );
// Add the drill holes
const std::list<IDF_DRILL_DATA*>* drills = &board.GetBoardDrills();
std::list<IDF_DRILL_DATA*>::const_iterator sd = drills->begin();
std::list<IDF_DRILL_DATA*>::const_iterator ed = drills->end();
while( sd != ed )
{
vpcb.AddCircle( (*sd)->GetDrillXPos() * scale, (*sd)->GetDrillYPos() * scale,
(*sd)->GetDrillDia() * scale / 2.0, true );
++sd;
}
std::map< std::string, IDF3_COMPONENT* >*const comp = board.GetComponents();
std::map< std::string, IDF3_COMPONENT* >::const_iterator sc = comp->begin();
std::map< std::string, IDF3_COMPONENT* >::const_iterator ec = comp->end();
while( sc != ec )
{
drills = sc->second->GetDrills();
sd = drills->begin();
ed = drills->end();
while( sd != ed )
{
vpcb.AddCircle( (*sd)->GetDrillXPos() * scale, (*sd)->GetDrillYPos() * scale,
(*sd)->GetDrillDia() * scale / 2.0, true );
++sd;
}
++sc;
}
// tesselate and write out
vpcb.Tesselate( NULL );
double thick = board.GetBoardThickness() / 2.0 * scale;
VRML_IDS tvid;
tvid.colorIndex = 0;
WriteTriangles( file, &tvid, &vpcb, false, false,
thick, -thick, board.GetUserPrecision(), false );
return true;
}
bool PopulateVRML( VRML_LAYER& model, const std::list< IDF_OUTLINE* >* items, bool bottom, double scale,
double dX, double dY, double angle )
{
// empty outlines are not unusual so we fail quietly
if( items->size() < 1 )
return false;
int nvcont = 0;
int iseg = 0;
std::list< IDF_OUTLINE* >::const_iterator scont = items->begin();
std::list< IDF_OUTLINE* >::const_iterator econt = items->end();
std::list<IDF_SEGMENT*>::iterator sseg;
std::list<IDF_SEGMENT*>::iterator eseg;
IDF_SEGMENT lseg;
while( scont != econt )
{
nvcont = model.NewContour();
if( nvcont < 0 )
{
wxLogMessage( wxT( "Cannot create an outline" ) );
return false;
}
if( (*scont)->size() < 1 )
{
wxLogMessage( wxT( "Invalid contour: no vertices" ) );
return false;
}
sseg = (*scont)->begin();
eseg = (*scont)->end();
iseg = 0;
while( sseg != eseg )
{
lseg = **sseg;
TransformPoint( lseg, scale, bottom, dX, dY, angle );
if( !AddSegment( model, &lseg, nvcont, iseg ) )
return false;
++iseg;
++sseg;
}
++scont;
}
return true;
}
bool AddSegment( VRML_LAYER& model, IDF_SEGMENT* seg, int icont, int iseg )
{
// note: in all cases we must add all but the last point in the segment
// to avoid redundant points
if( seg->angle != 0.0 )
{
if( seg->IsCircle() )
{
if( iseg != 0 )
{
wxLogMessage( wxT( "Adding a circle to an existing vertex list" ) );
return false;
}
return model.AppendCircle( seg->center.x, seg->center.y, seg->radius, icont );
}
else
{
return model.AppendArc( seg->center.x, seg->center.y, seg->radius,
seg->offsetAngle, seg->angle, icont );
}
}
if( !model.AddVertex( icont, seg->startPoint.x, seg->startPoint.y ) )
return false;
return true;
}
bool WriteTriangles( std::ostream& file, VRML_IDS* vID, VRML_LAYER* layer, bool plane,
bool top, double top_z, double bottom_z, int precision, bool compact )
{
if( vID == NULL || layer == NULL )
return false;
file << "Transform {\n";
if( compact && !vID->objectName.empty() )
{
file << "translation " << std::setprecision( precision ) << vID->dX;
file << " " << vID->dY << " ";
if( vID->bottom )
{
file << -vID->dZ << "\n";
double tx, ty;
// calculate the rotation axis and angle
tx = cos( M_PI2 - vID->dA / 2.0 );
ty = sin( M_PI2 - vID->dA / 2.0 );
file << "rotation " << std::setprecision( precision );
file << tx << " " << ty << " 0 ";
file << std::setprecision(5) << M_PI << "\n";
}
else
{
file << vID->dZ << "\n";
file << "rotation 0 0 1 " << std::setprecision(5) << vID->dA << "\n";
}
file << "children [\n";
if( vID->used )
{
file << "USE " << vID->objectName << "\n";
file << "]\n";
file << "}\n";
return true;
}
file << "DEF " << vID->objectName << " Transform {\n";
if( !plane && top_z <= bottom_z )
{
// the height specification is faulty; make the component
// a bright red to highlight it
vID->colorIndex = 1;
// we don't know the scale, but 5 units is huge in most situations
top_z = bottom_z + 5.0;
}
}
VRML_COLOR* color = &colors[vID->colorIndex];
vID->used = true;
file << "children [\n";
file << "Group {\n";
file << "children [\n";
file << "Shape {\n";
file << "appearance Appearance {\n";
file << "material Material {\n";
// material definition
file << "diffuseColor " << std::setprecision(3) << color->diff[0] << " ";
file << color->diff[1] << " " << color->diff[2] << "\n";
file << "specularColor " << color->spec[0] << " " << color->spec[1];
file << " " << color->spec[2] << "\n";
file << "emissiveColor " << color->emis[0] << " " << color->emis[1];
file << " " << color->emis[2] << "\n";
file << "ambientIntensity " << color->ambi << "\n";
file << "transparency " << color->tran << "\n";
file << "shininess " << color->shin << "\n";
file << "}\n";
file << "}\n";
file << "geometry IndexedFaceSet {\n";
file << "solid TRUE\n";
file << "coord Coordinate {\n";
file << "point [\n";
// Coordinates (vertices)
if( plane )
{
if( !layer->WriteVertices( top_z, file, precision ) )
{
wxLogMessage( wxT( "Errors writing planar vertices to %s\n%s" ),
vID->objectName, layer->GetError() );
}
}
else
{
if( !layer->Write3DVertices( top_z, bottom_z, file, precision ) )
{
wxLogMessage( wxT( "Errors writing 3D vertices to %s\n%s" ),
vID->objectName, layer->GetError() );
}
}
file << "\n";
file << "]\n";
file << "}\n";
file << "coordIndex [\n";
// Indices
if( plane )
layer->WriteIndices( top, file );
else
layer->Write3DIndices( file );
file << "\n";
file << "]\n";
file << "}\n";
file << "}\n";
file << "]\n";
file << "}\n";
file << "]\n";
file << "}\n";
if( compact && !vID->objectName.empty() )
{
file << "]\n";
file << "}\n";
}
return !file.fail();
}
inline void TransformPoint( IDF_SEGMENT& seg, double frac, bool bottom,
double dX, double dY, double angle )
{
dX *= frac;
dY *= frac;
if( bottom )
{
// mirror points on the Y axis
seg.startPoint.x = -seg.startPoint.x;
seg.endPoint.x = -seg.endPoint.x;
seg.center.x = -seg.center.x;
angle = -angle;
}
seg.startPoint.x *= frac;
seg.startPoint.y *= frac;
seg.endPoint.x *= frac;
seg.endPoint.y *= frac;
seg.center.x *= frac;
seg.center.y *= frac;
double tsin = 0.0;
double tcos = 0.0;
if( angle > MIN_ANG || angle < -MIN_ANG )
{
double ta = angle * M_PI / 180.0;
double tx, ty;
tsin = sin( ta );
tcos = cos( ta );
tx = seg.startPoint.x * tcos - seg.startPoint.y * tsin;
ty = seg.startPoint.x * tsin + seg.startPoint.y * tcos;
seg.startPoint.x = tx;
seg.startPoint.y = ty;
tx = seg.endPoint.x * tcos - seg.endPoint.y * tsin;
ty = seg.endPoint.x * tsin + seg.endPoint.y * tcos;
seg.endPoint.x = tx;
seg.endPoint.y = ty;
if( seg.angle != 0 )
{
tx = seg.center.x * tcos - seg.center.y * tsin;
ty = seg.center.x * tsin + seg.center.y * tcos;
seg.center.x = tx;
seg.center.y = ty;
}
}
seg.startPoint.x += dX;
seg.startPoint.y += dY;
seg.endPoint.x += dX;
seg.endPoint.y += dY;
seg.center.x += dX;
seg.center.y += dY;
if( seg.angle != 0 )
{
seg.radius *= frac;
if( bottom )
{
if( !seg.IsCircle() )
{
seg.angle = -seg.angle;
if( seg.offsetAngle > 0.0 )
seg.offsetAngle = 180 - seg.offsetAngle;
else
seg.offsetAngle = -seg.offsetAngle - 180;
}
}
if( angle > MIN_ANG || angle < -MIN_ANG )
seg.offsetAngle += angle;
}
return;
}
bool MakeComponents( IDF3_BOARD& board, std::ostream& file, bool compact )
{
int cidx = 2; // color index; start at 2 since 0,1 are special (board, NOGEOM_NOPART)
VRML_LAYER vpcb;
double scale = board.GetUserScale();
double thick = board.GetBoardThickness() / 2.0;
// set the arc parameters according to output scale
int tI;
double tMin, tMax;
vpcb.GetArcParams( tI, tMin, tMax );
vpcb.SetArcParams( tI, tMin * scale, tMax * scale );
// Add the component outlines
const std::map< std::string, IDF3_COMPONENT* >*const comp = board.GetComponents();
std::map< std::string, IDF3_COMPONENT* >::const_iterator sc = comp->begin();
std::map< std::string, IDF3_COMPONENT* >::const_iterator ec = comp->end();
std::list< IDF3_COMP_OUTLINE_DATA* >::const_iterator so;
std::list< IDF3_COMP_OUTLINE_DATA* >::const_iterator eo;
double vX, vY, vA;
double tX, tY, tZ, tA;
double top, bot;
bool bottom;
IDF3::IDF_LAYER lyr;
boost::ptr_map< const std::string, VRML_IDS> cmap; // map colors by outline UID
VRML_IDS* vcp;
IDF3_COMP_OUTLINE* pout;
while( sc != ec )
{
sc->second->GetPosition( vX, vY, vA, lyr );
if( lyr == IDF3::LYR_BOTTOM )
bottom = true;
else
bottom = false;
so = sc->second->GetOutlinesData()->begin();
eo = sc->second->GetOutlinesData()->end();
while( so != eo )
{
if( (*so)->GetOutline()->GetThickness() < 0.00000001 && nozeroheights )
{
vpcb.Clear();
++so;
continue;
}
(*so)->GetOffsets( tX, tY, tZ, tA );
tX += vX;
tY += vY;
tA += vA;
if( ( pout = (IDF3_COMP_OUTLINE*)((*so)->GetOutline()) ) != nullptr )
{
vcp = GetColor( cmap, cidx, pout->GetUID() );
}
else
{
vpcb.Clear();
++so;
continue;
}
if( !compact )
{
if( !PopulateVRML( vpcb, (*so)->GetOutline()->GetOutlines(), bottom,
board.GetUserScale(), tX, tY, tA ) )
{
return false;
}
}
else
{
if( !vcp->used && !PopulateVRML( vpcb, (*so)->GetOutline()->GetOutlines(), false,
board.GetUserScale() ) )
{
return false;
}
vcp->dX = tX * scale;
vcp->dY = tY * scale;
vcp->dZ = tZ * scale;
vcp->dA = tA * M_PI / 180.0;
}
if( !compact || !vcp->used )
{
vpcb.EnsureWinding( 0, false );
int nvcont = vpcb.GetNContours() - 1;
while( nvcont > 0 )
vpcb.EnsureWinding( nvcont--, true );
vpcb.Tesselate( NULL );
}
if( !compact )
{
if( bottom )
{
top = -thick - tZ;
bot = (top - (*so)->GetOutline()->GetThickness() ) * scale;
top *= scale;
}
else
{
bot = thick + tZ;
top = (bot + (*so)->GetOutline()->GetThickness() ) * scale;
bot *= scale;
}
}
else
{
bot = thick;
top = (bot + (*so)->GetOutline()->GetThickness() ) * scale;
bot *= scale;
}
vcp = GetColor( cmap, cidx, ((IDF3_COMP_OUTLINE*)((*so)->GetOutline()))->GetUID() );
vcp->bottom = bottom;
// note: this can happen because IDF allows some negative heights/thicknesses
if( bot > top )
std::swap( bot, top );
WriteTriangles( file, vcp, &vpcb, false,
false, top, bot, board.GetUserPrecision(), compact );
vpcb.Clear();
++so;
}
++sc;
}
return true;
}
VRML_IDS* GetColor( boost::ptr_map<const std::string, VRML_IDS>& cmap, int& index, const std::string& uid )
{
static int refnum = 0;
if( index < 2 )
index = 2; // 0 and 1 are special (BOARD, UID=NOGEOM_NOPART)
boost::ptr_map<const std::string, VRML_IDS>::iterator cit = cmap.find( uid );
if( cit == cmap.end() )
{
VRML_IDS* id = new VRML_IDS;
if( !uid.compare( "NOGEOM_NOPART" ) )
id->colorIndex = 1;
else
id->colorIndex = index++;
std::ostringstream ostr;
ostr << "OBJECTn" << refnum++;
id->objectName = ostr.str();
if( showObjectMapping )
wxLogMessage( wxT( "* %s = '%s'" ), ostr.str(), uid );
cmap.insert( uid, id );
if( index >= NCOLORS )
index = 2;
return id;
}
return cit->second;
}
bool MakeOtherOutlines( IDF3_BOARD& board, std::ostream& file )
{
int cidx = 2; // color index; start at 2 since 0,1 are special (board, NOGEOM_NOPART)
VRML_LAYER vpcb;
double scale = board.GetUserScale();
double thick = board.GetBoardThickness() / 2.0;
// set the arc parameters according to output scale
int tI;
double tMin, tMax;
vpcb.GetArcParams( tI, tMin, tMax );
vpcb.SetArcParams( tI, tMin * scale, tMax * scale );
// Add the component outlines
const std::map< std::string, OTHER_OUTLINE* >*const comp = board.GetOtherOutlines();
std::map< std::string, OTHER_OUTLINE* >::const_iterator sc = comp->begin();
std::map< std::string, OTHER_OUTLINE* >::const_iterator ec = comp->end();
double top, bot;
bool bottom;
int nvcont;
boost::ptr_map< const std::string, VRML_IDS> cmap; // map colors by outline UID
VRML_IDS* vcp;
OTHER_OUTLINE* pout;
while( sc != ec )
{
pout = sc->second;
if( pout->GetThickness() < 0.00000001 && nozeroheights )
{
vpcb.Clear();
++sc;
continue;
}
vcp = GetColor( cmap, cidx, pout->GetOutlineIdentifier() );
if( !PopulateVRML( vpcb, pout->GetOutlines(), false,
board.GetUserScale(), 0, 0, 0 ) )
{
return false;
}
vpcb.EnsureWinding( 0, false );
nvcont = vpcb.GetNContours() - 1;
while( nvcont > 0 )
vpcb.EnsureWinding( nvcont--, true );
vpcb.Tesselate( NULL );
if( pout->GetSide() == IDF3::LYR_BOTTOM )
bottom = true;
else
bottom = false;
if( bottom )
{
top = -thick;
bot = ( top - pout->GetThickness() ) * scale;
top *= scale;
}
else
{
bot = thick;
top = (bot + pout->GetThickness() ) * scale;
bot *= scale;
}
// note: this can happen because IDF allows some negative heights/thicknesses
if( bot > top )
std::swap( bot, top );
vcp->bottom = bottom;
WriteTriangles( file, vcp, &vpcb, false,
false, top, bot, board.GetUserPrecision(), false );
vpcb.Clear();
++sc;
}
return true;
}

681
utils/idftools/idf_cylinder.cpp

@ -1,681 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014 Cirilo Bernardo
* Copyright The 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, see <https://www.gnu.org/licenses/>.
*/
/*
* This program creates an outline for a horizontal or vertically
* oriented axial or radial leaded cylinder with dimensions based
* on the user's input.
*/
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <cmath>
#include <cstdio>
#include <list>
#include <utility>
#include <clocale>
using namespace std;
void make_vcyl( bool inch, bool axial, double dia, double length, double z, double wireDia );
void make_hcyl( bool inch, bool axial, double dia, double length, double z, double wireDia );
void writeAxialCyl( FILE* fp, bool inch, double dia, double length, double wireDia, double pitch );
void writeRadialCyl( FILE* fp, bool inch, double dia, double length, double wireDia, double pitch,
double lead );
int main( int argc, char** argv )
{
// IDF implicitly requires the C locale
setlocale( LC_ALL, "C" );
if( argc == 1 )
{
cout << "idfcyl: This program generates an outline for a cylindrical component.\n";
cout << " The cylinder may be horizontal or vertical.\n";
cout << " A horizontal cylinder may have wires at one or both ends.\n";
cout << " A vertical cylinder may have at most one wire which may be\n";
cout << " placed on the left or right side.\n\n";
cout << "Input:\n";
cout << " Unit: mm, in (millimeters or inches)\n";
cout << " Orientation: V (vertical)\n";
cout << " Lead type: X, R (axial, radial)\n";
cout << " Diameter of body\n";
cout << " Length of body\n";
cout << " Board offset\n";
cout << " * Wire diameter\n";
cout << " * Pitch\n";
cout << " ** Wire side: L, R (left, right)\n";
cout << " *** Lead length\n";
cout << " File name (must end in *.idf)\n\n";
cout << " NOTES:\n";
cout << " * only required for horizontal orientation or\n";
cout << " vertical orientation with axial leads\n\n";
cout << " ** only required for vertical orientation with axial leads\n\n";
cout << " *** only required for horizontal orientation with radial leads\n\n";
}
char orientation = '\0';
bool inch = false; // default mm
double dia = 0.0;
double length = 0.0;
double extraZ = 0.0;
double wireDia = 0.0;
bool axial = false;
stringstream tstr;
string line;
line.clear();
while( line.compare( "mm" ) && line.compare( "in" ) )
{
cout << "* Units (mm,in): ";
line.clear();
std::getline( cin, line );
}
if( line.compare( "mm" ) )
inch = true;
line.clear();
while( line.compare( "H" ) && line.compare( "h" ) && line.compare( "V" )
&& line.compare( "v" ) )
{
cout << "* Orientation (H,V): ";
line.clear();
std::getline( cin, line );
}
if( line.compare( "H" ) && line.compare( "h" ) )
orientation = 'v';
else
orientation = 'h';
bool ok = false;
while( !ok )
{
cout << "* Axial or Radial (X,R): ";
line.clear();
std::getline( cin, line );
if( !line.compare( "x" ) || !line.compare( "X" ) )
{
axial = true;
ok = true;
}
else if( !line.compare( "r" ) || !line.compare( "R" ) )
{
axial = false;
ok = true;
}
}
// cylinder dimensions
ok = false;
while( !ok )
{
cout << "* Diameter: ";
line.clear();
std::getline( cin, line );
tstr.clear();
tstr.str( line );
tstr >> dia;
if( !tstr.fail() && dia > 0.0 )
ok = true;
}
ok = false;
while( !ok )
{
cout << "* Length: ";
line.clear();
std::getline( cin, line );
tstr.clear();
tstr.str( line );
tstr >> length;
if( !tstr.fail() && length > 0.0 )
ok = true;
}
ok = false;
while( !ok )
{
cout << "* Board offset: ";
line.clear();
std::getline( cin, line );
tstr.clear();
tstr.str( line );
tstr >> extraZ;
if( !tstr.fail() && extraZ >= 0.0 )
ok = true;
}
ok = false;
while( ( axial || orientation == 'h' ) && !ok )
{
cout << "* Wire diameter: ";
line.clear();
std::getline( cin, line );
tstr.clear();
tstr.str( line );
tstr >> wireDia;
if( !tstr.fail() && wireDia > 0.0 )
{
if( wireDia < dia )
ok = true;
else
cout << "* WARNING: wire diameter must be < cylinder diameter\n";
}
}
switch( orientation )
{
case 'v': make_vcyl( inch, axial, dia, length, extraZ, wireDia ); break;
case 'h': make_hcyl( inch, axial, dia, length, extraZ, wireDia ); break;
default: break;
}
setlocale( LC_ALL, "" );
return 0;
}
void make_vcyl( bool inch, bool axial, double dia, double length, double z, double wireDia )
{
bool ok = false;
bool left = false;
stringstream tstr;
string line;
double pitch = 0.0;
while( axial && !ok )
{
cout << "* Pitch: ";
line.clear();
std::getline( cin, line );
tstr.clear();
tstr.str( line );
tstr >> pitch;
if( !tstr.fail() && pitch > 0.0 )
{
if( ( pitch - wireDia ) <= ( dia / 2.0 ) )
{
cout << "* WARNING: Pitch must be > dia/2 + wireDia\n";
}
else
{
ok = true;
}
}
}
ok = false;
while( axial && !ok )
{
cout << "* Pin side (L,R): ";
line.clear();
std::getline( cin, line );
if( !line.compare( "l" ) || !line.compare( "L" ) )
{
left = true;
ok = true;
}
else if( !line.compare( "r" ) || !line.compare( "R" ) )
{
ok = true;
}
}
line.clear();
while( line.empty() || line.find( ".idf" ) == string::npos )
{
cout << "* File name (*.idf): ";
line.clear();
std::getline( cin, line );
}
FILE* fp = fopen( line.c_str(), "w" );
if( !fp )
{
cerr << "Could not open output file: " << line << "\n";
return;
}
fprintf( fp, "# cylindrical outline, vertical, " );
if( !axial )
fprintf( fp, "radial leads\n" );
else
fprintf( fp, "axial lead on %s\n", left ? "left" : "right" );
fprintf( fp, "# file: \"%s\"\n", line.c_str() );
if( inch )
{
fprintf( fp, "# dia: %d THOU\n", (int) ( dia * 1000 ) );
fprintf( fp, "# length: %d THOU\n", (int) ( length * 1000 ) );
fprintf( fp, "# board offset: %d THOU\n", (int) ( z * 1000 ) );
if( axial )
{
fprintf( fp, "# wire dia: %d THOU\n", (int) ( wireDia * 1000 ) );
fprintf( fp, "# pitch: %d THOU\n", (int) ( pitch * 1000 ) );
}
}
else
{
fprintf( fp, "# dia: %.3f mm\n", dia );
fprintf( fp, "# length: %.3f mm\n", length );
fprintf( fp, "# board offset: %.3f mm\n", z );
if( axial )
{
fprintf( fp, "# wire dia: %.3f mm\n", wireDia );
fprintf( fp, "# pitch: %.3f mm\n", pitch );
}
}
fprintf( fp, ".ELECTRICAL\n" );
if( !axial )
{
fprintf( fp, "\"CYLV_%s_RAD\" \"D%.3f_H%.3f_Z%.3f\" ", inch ? "IN" : "MM", dia, length, z );
}
else
{
fprintf( fp, "\"CYLV_%s_AX%s\" \"D%.3f_H%.3f_Z%.3f_WD%.3f_P%.3f\" ", inch ? "IN" : "MM",
left ? "L" : "R", dia, length, z, wireDia, pitch );
}
if( inch )
fprintf( fp, "THOU %d\n", (int) ( ( length + z ) * 1000 ) );
else
fprintf( fp, "MM %.3f\n", length + z );
if( !axial )
{
fprintf( fp, "0 0 0 0\n" );
if( inch )
fprintf( fp, "0 %d 0 360\n", (int) ( dia * 500 ) );
else
fprintf( fp, "0 %.3f 0 360\n", dia / 2.0 );
fprintf( fp, ".END_ELECTRICAL\n" );
fclose( fp );
return;
}
double px[4], py[4];
// points are:
// [0] = upper point on cylinder perimeter
// [1] = lower point on cylinder perimeter
// [2] = point beneath wire center
// [3] = point above wire center
if( inch )
{
dia *= 1000.0;
pitch *= 1000.0;
wireDia *= 1000.0;
}
double ang = asin( wireDia / dia );
px[0] = dia * cos( ang ) / 2.0 - pitch / 2.0;
px[1] = px[0];
px[2] = pitch / 2.0;
px[3] = px[2];
py[0] = wireDia / 2.0;
py[1] = -py[0];
py[2] = py[1];
py[3] = py[0];
char li = '0';
double fullAng = 360.0;
if( left )
{
li = '1';
fullAng = -360.0;
for( int i = 0; i < 4; ++i )
px[i] = -px[i];
}
if( inch )
{
fprintf( fp, "%c %d %d 0\n", li, (int) px[0], (int) py[0] );
fprintf( fp, "%c %d %d %.3f\n", li, (int) px[1], (int) py[1],
fullAng * ( 1 - ang / M_PI ) );
fprintf( fp, "%c %d %d 0\n", li, (int) px[2], (int) py[2] );
fprintf( fp, "%c %d %d %s\n", li, (int) px[3], (int) py[3], left ? "-180" : "180" );
fprintf( fp, "%c %d %d 0\n", li, (int) px[0], (int) py[0] );
}
else
{
fprintf( fp, "%c %.3f %.3f 0\n", li, px[0], py[0] );
fprintf( fp, "%c %.3f %.3f %.3f\n", li, px[1], py[1], fullAng * ( 1 - ang / M_PI ) );
fprintf( fp, "%c %.3f %.3f 0\n", li, px[2], py[2] );
fprintf( fp, "%c %.3f %.3f %s\n", li, px[3], py[3], left ? "-180" : "180" );
fprintf( fp, "%c %.3f %.3f 0\n", li, px[0], py[0] );
}
fprintf( fp, ".END_ELECTRICAL\n" );
fclose( fp );
}
void make_hcyl( bool inch, bool axial, double dia, double length, double z, double wireDia )
{
stringstream tstr;
string line;
double pitch = 0.0;
double lead = 0.0; // lead length for radial leads
bool ok = false;
while( !ok )
{
if( axial )
cout << "* Axial pitch: ";
else
cout << "* Radial pitch: ";
line.clear();
std::getline( cin, line );
tstr.clear();
tstr.str( line );
tstr >> pitch;
if( !tstr.fail() && pitch > 0.0 )
{
if( axial )
{
if( ( pitch - wireDia ) <= length )
{
cout << "* WARNING: Axial pitch must be > length + wireDia\n";
}
else
{
ok = true;
}
}
else
{
if( ( pitch + wireDia ) >= dia )
{
cout << "* WARNING: Radial pitch must be < dia - wireDia\n";
}
else if( pitch <= wireDia )
{
cout << "* WARNING: Radial pitch must be > wireDia\n";
}
else
{
ok = true;
}
}
}
}
ok = false;
while( !axial && !ok )
{
cout << "* Lead length: ";
line.clear();
std::getline( cin, line );
tstr.clear();
tstr.str( line );
tstr >> lead;
if( !tstr.fail() && lead > 0.0 )
{
if( lead < wireDia )
cout << "* WARNING: lead length must be >= wireDia\n";
else
ok = true;
}
}
line.clear();
while( line.empty() || line.find( ".idf" ) == string::npos )
{
cout << "* File name (*.idf): ";
line.clear();
std::getline( cin, line );
}
FILE* fp = fopen( line.c_str(), "w" );
if( !fp )
{
cerr << "Could not open output file: " << line << "\n";
return;
}
fprintf( fp, "# cylindrical outline, horiz., " );
fprintf( fp, "%s pins\n", axial ? "axial" : "radial" );
fprintf( fp, "# file: \"%s\"\n", line.c_str() );
if( inch )
{
fprintf( fp, "# dia: %d THOU\n", (int) ( dia * 1000 ) );
fprintf( fp, "# length: %d THOU\n", (int) ( length * 1000 ) );
fprintf( fp, "# extra height: %d THOU\n", (int) ( z * 1000 ) );
fprintf( fp, "# wire dia: %d THOU\n", (int) ( wireDia * 1000 ) );
fprintf( fp, "# pitch: %d THOU\n", (int) ( pitch * 1000 ) );
if( !axial )
fprintf( fp, "# lead: %d THOU\n", (int) ( lead * 1000 ) );
}
else
{
fprintf( fp, "# dia: %.3f mm\n", dia );
fprintf( fp, "# length: %.3f mm\n", length );
fprintf( fp, "# extra height: %.3f mm\n", z );
fprintf( fp, "# wire dia: %.3f mm\n", wireDia );
fprintf( fp, "# pitch: %.3f mm\n", pitch );
if( !axial )
fprintf( fp, "# lead: %.3f mm\n", lead );
}
fprintf( fp, ".ELECTRICAL\n" );
if( axial )
{
fprintf( fp, "\"CYLH_%s_AXI\" \"D%.3f_H%.3f_Z%.3f_WD%.3f_P%.3f\" ", inch ? "IN" : "MM", dia,
length, z, wireDia, pitch );
}
else
{
fprintf( fp, "\"CYLH_%s_RAD\" \"D%.3f_H%.3f_Z%.3f_WD%.3f_P%.3f_L%.3f\" ",
inch ? "IN" : "MM", dia, length, z, wireDia, pitch, lead );
}
if( inch )
{
fprintf( fp, "THOU %d\n", (int) ( ( dia + z ) * 1000 ) );
dia *= 1000.0;
length *= 1000.0;
wireDia *= 1000.0;
pitch *= 1000.0;
if( !axial )
lead *= 1000.0;
}
else
{
fprintf( fp, "MM %.3f\n", dia + z );
}
if( axial )
writeAxialCyl( fp, inch, dia, length, wireDia, pitch );
else
writeRadialCyl( fp, inch, dia, length, wireDia, pitch, lead );
fprintf( fp, ".END_ELECTRICAL\n" );
fclose( fp );
}
void writeAxialCyl( FILE* fp, bool inch, double dia, double length, double wireDia, double pitch )
{
double x1, y1;
double x2, y2;
x1 = -length / 2.0;
x2 = -pitch / 2.0;
y1 = dia / 2.0;
y2 = wireDia / 2.0;
if( inch )
{
fprintf( fp, "0 %d %d 0\n", (int) x1, (int) y1 );
fprintf( fp, "0 %d %d 0\n", (int) x1, (int) y2 );
fprintf( fp, "0 %d %d 0\n", (int) x2, (int) y2 );
fprintf( fp, "0 %d %d 180\n", (int) x2, (int) -y2 );
fprintf( fp, "0 %d %d 0\n", (int) x1, (int) -y2 );
fprintf( fp, "0 %d %d 0\n", (int) x1, (int) -y1 );
fprintf( fp, "0 %d %d 0\n", (int) -x1, (int) -y1 );
fprintf( fp, "0 %d %d 0\n", (int) -x1, (int) -y2 );
fprintf( fp, "0 %d %d 0\n", (int) -x2, (int) -y2 );
fprintf( fp, "0 %d %d 180\n", (int) -x2, (int) y2 );
fprintf( fp, "0 %d %d 0\n", (int) -x1, (int) y2 );
fprintf( fp, "0 %d %d 0\n", (int) -x1, (int) y1 );
fprintf( fp, "0 %d %d 0\n", (int) x1, (int) y1 );
}
else
{
fprintf( fp, "0 %.3f %.3f 0\n", x1, y1 );
fprintf( fp, "0 %.3f %.3f 0\n", x1, y2 );
fprintf( fp, "0 %.3f %.3f 0\n", x2, y2 );
fprintf( fp, "0 %.3f %.3f 180\n", x2, -y2 );
fprintf( fp, "0 %.3f %.3f 0\n", x1, -y2 );
fprintf( fp, "0 %.3f %.3f 0\n", x1, -y1 );
fprintf( fp, "0 %.3f %.3f 0\n", -x1, -y1 );
fprintf( fp, "0 %.3f %.3f 0\n", -x1, -y2 );
fprintf( fp, "0 %.3f %.3f 0\n", -x2, -y2 );
fprintf( fp, "0 %.3f %.3f 180\n", -x2, y2 );
fprintf( fp, "0 %.3f %.3f 0\n", -x1, y2 );
fprintf( fp, "0 %.3f %.3f 0\n", -x1, y1 );
fprintf( fp, "0 %.3f %.3f 0\n", x1, y1 );
}
}
void writeRadialCyl( FILE* fp, bool inch, double dia, double length, double wireDia, double pitch,
double lead )
{
double x1, y1;
double x2, y2;
double x3;
// center is between the mounting holes which are on a horizontal line
y1 = lead + length;
y2 = lead;
x1 = dia / 2.0;
x2 = ( pitch + wireDia ) / 2.0;
x3 = x2 - wireDia;
if( inch )
{
fprintf( fp, "0 %d %d 0\n", (int) -x1, (int) y1 );
fprintf( fp, "0 %d %d 0\n", (int) -x1, (int) y2 );
fprintf( fp, "0 %d %d 0\n", (int) -x2, (int) y2 );
fprintf( fp, "0 %d 0 0\n", (int) -x2 );
fprintf( fp, "0 %d 0 180\n", (int) -x3 );
fprintf( fp, "0 %d %d 0\n", (int) -x3, (int) y2 );
fprintf( fp, "0 %d %d 0\n", (int) x3, (int) y2 );
fprintf( fp, "0 %d 0 0\n", (int) x3 );
fprintf( fp, "0 %d 0 180\n", (int) x2 );
fprintf( fp, "0 %d %d 0\n", (int) x2, (int) y2 );
fprintf( fp, "0 %d %d 0\n", (int) x1, (int) y2 );
fprintf( fp, "0 %d %d 0\n", (int) x1, (int) y1 );
fprintf( fp, "0 %d %d 0\n", (int) -x1, (int) y1 );
}
else
{
fprintf( fp, "0 %.3f %.3f 0\n", -x1, y1 );
fprintf( fp, "0 %.3f %.3f 0\n", -x1, y2 );
fprintf( fp, "0 %.3f %.3f 0\n", -x2, y2 );
fprintf( fp, "0 %.3f 0 0\n", -x2 );
fprintf( fp, "0 %.3f 0 180\n", -x3 );
fprintf( fp, "0 %.3f %.3f 0\n", -x3, y2 );
fprintf( fp, "0 %.3f %.3f 0\n", x3, y2 );
fprintf( fp, "0 %.3f 0 0\n", x3 );
fprintf( fp, "0 %.3f 0 180\n", x2 );
fprintf( fp, "0 %.3f %.3f 0\n", x2, y2 );
fprintf( fp, "0 %.3f %.3f 0\n", x1, y2 );
fprintf( fp, "0 %.3f %.3f 0\n", x1, y1 );
fprintf( fp, "0 %.3f %.3f 0\n", -x1, y1 );
}
}

149
utils/idftools/idf_examples/Arduino_MEGA_2560-Rev3.emn

@ -1,149 +0,0 @@
.HEADER
BOARD_FILE 3.0 "Created by KiCad (2014-01-21 BZR 4629)-product" 2014/01/23.09:19:46 1
"Arduino_MEGA_2560-Rev3.kicad_pcb" MM
.END_HEADER
.BOARD_OUTLINE ECAD
1.60000
0 246.20220 -25.67000 0
0 247.20220 -26.67000 0
0 344.26220 -26.67000 0
0 345.26220 -25.67000 0
0 345.26220 -25.40000 0
0 347.80220 -22.86000 0
0 347.80220 11.43000 0
0 345.26220 13.97000 0
0 345.26220 24.13000 0
0 342.72220 26.67000 0
0 247.20220 26.67000 0
0 246.20220 25.67000 0
0 246.20220 -25.67000 0
.END_BOARD_OUTLINE
.DRILLED_HOLES
3.200 342.72220 -24.13000 NPTH "@HOLE0" MTG ECAD
3.200 261.44220 24.13000 NPTH "@HOLE1" MTG ECAD
3.200 336.37220 24.13000 NPTH "@HOLE2" MTG ECAD
3.200 260.17220 -24.13000 NPTH "@HOLE3" MTG ECAD
3.200 312.24220 8.89000 NPTH "@HOLE4" MTG ECAD
3.200 312.24220 -19.05000 NPTH "@HOLE5" MTG ECAD
0.950 309.82920 3.81000 PTH "ICSP" PIN ECAD
0.950 312.36920 3.81000 PTH "ICSP" PIN ECAD
0.950 309.82920 1.27000 PTH "ICSP" PIN ECAD
0.950 312.36920 1.27000 PTH "ICSP" PIN ECAD
0.950 309.82920 -1.27000 PTH "ICSP" PIN ECAD
0.950 312.36920 -1.27000 PTH "ICSP" PIN ECAD
0.850 309.70220 24.13000 PTH "PWML" PIN ECAD
0.850 307.16220 24.13000 PTH "PWML" PIN ECAD
0.850 304.62220 24.13000 PTH "PWML" PIN ECAD
0.850 302.08220 24.13000 PTH "PWML" PIN ECAD
0.850 299.54220 24.13000 PTH "PWML" PIN ECAD
0.850 297.00220 24.13000 PTH "PWML" PIN ECAD
0.850 294.46220 24.13000 PTH "PWML" PIN ECAD
0.850 291.92220 24.13000 PTH "PWML" PIN ECAD
1.400 254.88900 -23.36800 PTH "X1" PIN ECAD
1.400 257.88620 -18.36420 PTH "X1" PIN ECAD
1.400 251.89180 -18.36420 PTH "X1" PIN ECAD
1.400 255.65100 -23.36800 PTH "X1" PIN ECAD
1.400 254.12700 -23.36800 PTH "X1" PIN ECAD
1.400 251.89180 -19.12620 PTH "X1" PIN ECAD
1.400 251.89180 -17.60220 PTH "X1" PIN ECAD
1.400 257.88620 -19.12620 PTH "X1" PIN ECAD
1.400 257.88620 -17.60220 PTH "X1" PIN ECAD
0.850 297.00220 -24.13000 PTH "ADCL" PIN ECAD
0.850 299.54220 -24.13000 PTH "ADCL" PIN ECAD
0.850 302.08220 -24.13000 PTH "ADCL" PIN ECAD
0.850 304.62220 -24.13000 PTH "ADCL" PIN ECAD
0.850 307.16220 -24.13000 PTH "ADCL" PIN ECAD
0.850 309.70220 -24.13000 PTH "ADCL" PIN ECAD
0.850 312.24220 -24.13000 PTH "ADCL" PIN ECAD
0.850 314.78220 -24.13000 PTH "ADCL" PIN ECAD
0.850 332.56220 24.13000 PTH "COMMUNICATION" PIN ECAD
0.850 330.02220 24.13000 PTH "COMMUNICATION" PIN ECAD
0.850 327.48220 24.13000 PTH "COMMUNICATION" PIN ECAD
0.850 324.94220 24.13000 PTH "COMMUNICATION" PIN ECAD
0.850 322.40220 24.13000 PTH "COMMUNICATION" PIN ECAD
0.850 319.86220 24.13000 PTH "COMMUNICATION" PIN ECAD
0.850 317.32220 24.13000 PTH "COMMUNICATION" PIN ECAD
0.850 314.78220 24.13000 PTH "COMMUNICATION" PIN ECAD
0.850 319.86220 -24.13000 PTH "ADCH" PIN ECAD
0.850 322.40220 -24.13000 PTH "ADCH" PIN ECAD
0.850 324.94220 -24.13000 PTH "ADCH" PIN ECAD
0.850 327.48220 -24.13000 PTH "ADCH" PIN ECAD
0.850 330.02220 -24.13000 PTH "ADCH" PIN ECAD
0.850 332.56220 -24.13000 PTH "ADCH" PIN ECAD
0.850 335.10220 -24.13000 PTH "ADCH" PIN ECAD
0.850 337.64220 -24.13000 PTH "ADCH" PIN ECAD
0.950 254.72220 10.18000 PTH "X2" PIN ECAD
0.950 254.72220 12.68000 PTH "X2" PIN ECAD
0.950 252.72220 12.68000 PTH "X2" PIN ECAD
0.950 252.72220 10.18000 PTH "X2" PIN ECAD
2.200 250.01220 17.43000 PTH "X2" PIN ECAD
2.200 250.01220 5.43000 PTH "X2" PIN ECAD
0.950 267.03020 20.82800 PTH "ICSP1" PIN ECAD
0.950 267.03020 18.28800 PTH "ICSP1" PIN ECAD
0.950 264.49020 20.82800 PTH "ICSP1" PIN ECAD
0.950 264.49020 18.28800 PTH "ICSP1" PIN ECAD
0.950 261.95020 20.82800 PTH "ICSP1" PIN ECAD
0.950 261.95020 18.28800 PTH "ICSP1" PIN ECAD
0.850 267.15720 -0.63500 PTH "Y2" PIN ECAD
0.850 262.07720 -0.63500 PTH "Y2" PIN ECAD
0.950 267.03020 13.20800 PTH "JP5" PIN ECAD
0.950 264.49020 13.20800 PTH "JP5" PIN ECAD
0.950 267.03020 15.74800 PTH "JP5" PIN ECAD
0.950 264.49020 15.74800 PTH "JP5" PIN ECAD
0.950 340.18220 24.13000 PTH "XIO" PIN ECAD
0.950 342.72220 24.13000 PTH "XIO" PIN ECAD
0.950 340.18220 21.59000 PTH "XIO" PIN ECAD
0.950 342.72220 21.59000 PTH "XIO" PIN ECAD
0.950 340.18220 19.05000 PTH "XIO" PIN ECAD
0.950 342.72220 19.05000 PTH "XIO" PIN ECAD
0.950 340.18220 16.51000 PTH "XIO" PIN ECAD
0.950 342.72220 16.51000 PTH "XIO" PIN ECAD
0.950 340.18220 13.97000 PTH "XIO" PIN ECAD
0.950 342.72220 13.97000 PTH "XIO" PIN ECAD
0.950 340.18220 11.43000 PTH "XIO" PIN ECAD
0.950 342.72220 11.43000 PTH "XIO" PIN ECAD
0.950 340.18220 8.89000 PTH "XIO" PIN ECAD
0.950 342.72220 8.89000 PTH "XIO" PIN ECAD
0.950 340.18220 6.35000 PTH "XIO" PIN ECAD
0.950 342.72220 6.35000 PTH "XIO" PIN ECAD
0.950 340.18220 3.81000 PTH "XIO" PIN ECAD
0.950 342.72220 3.81000 PTH "XIO" PIN ECAD
0.950 340.18220 1.27000 PTH "XIO" PIN ECAD
0.950 342.72220 1.27000 PTH "XIO" PIN ECAD
0.950 340.18220 -1.27000 PTH "XIO" PIN ECAD
0.950 342.72220 -1.27000 PTH "XIO" PIN ECAD
0.950 340.18220 -3.81000 PTH "XIO" PIN ECAD
0.950 342.72220 -3.81000 PTH "XIO" PIN ECAD
0.950 340.18220 -6.35000 PTH "XIO" PIN ECAD
0.950 342.72220 -6.35000 PTH "XIO" PIN ECAD
0.950 340.18220 -8.89000 PTH "XIO" PIN ECAD
0.950 342.72220 -8.89000 PTH "XIO" PIN ECAD
0.950 340.18220 -11.43000 PTH "XIO" PIN ECAD
0.950 342.72220 -11.43000 PTH "XIO" PIN ECAD
0.950 340.18220 -13.97000 PTH "XIO" PIN ECAD
0.950 342.72220 -13.97000 PTH "XIO" PIN ECAD
0.950 340.18220 -16.51000 PTH "XIO" PIN ECAD
0.950 342.72220 -16.51000 PTH "XIO" PIN ECAD
0.950 340.18220 -19.05000 PTH "XIO" PIN ECAD
0.950 342.72220 -19.05000 PTH "XIO" PIN ECAD
0.850 264.99820 24.13000 PTH "JP6" PIN ECAD
0.850 267.53820 24.13000 PTH "JP6" PIN ECAD
0.850 270.07820 24.13000 PTH "JP6" PIN ECAD
0.850 272.61820 24.13000 PTH "JP6" PIN ECAD
0.850 275.15820 24.13000 PTH "JP6" PIN ECAD
0.850 277.69820 24.13000 PTH "JP6" PIN ECAD
0.850 280.23820 24.13000 PTH "JP6" PIN ECAD
0.850 282.77820 24.13000 PTH "JP6" PIN ECAD
0.850 285.31820 24.13000 PTH "JP6" PIN ECAD
0.850 287.85820 24.13000 PTH "JP6" PIN ECAD
0.850 274.14220 -24.13000 PTH "POWER" PIN ECAD
0.850 276.68220 -24.13000 PTH "POWER" PIN ECAD
0.850 279.22220 -24.13000 PTH "POWER" PIN ECAD
0.850 281.76220 -24.13000 PTH "POWER" PIN ECAD
0.850 284.30220 -24.13000 PTH "POWER" PIN ECAD
0.850 286.84220 -24.13000 PTH "POWER" PIN ECAD
0.850 289.38220 -24.13000 PTH "POWER" PIN ECAD
0.850 291.92220 -24.13000 PTH "POWER" PIN ECAD
.END_DRILLED_HOLES

4
utils/idftools/idf_examples/Arduino_MEGA_2560-Rev3.emp

@ -1,4 +0,0 @@
.HEADER
LIBRARY_FILE 3.0 "Created by KiCad (2014-01-21 BZR 4629)-product" 2014/01/23.09:19:46 1
.END_HEADER

269
utils/idftools/idf_examples/idf_example.emn

@ -1,269 +0,0 @@
.HEADER
BOARD_FILE 3.0 "Sample File Generator" 10/22/96.16:02:44 1
sample_board THOU
.END_HEADER
# This is the first BOARD section
# SEC1-0
# SEC1-1
.BOARD_OUTLINE MCAD
62.0
0 5030.5 -120.0 0.0
0 5187.5 -120.0 0.0
0 5187.5 2130.0 0.0
0 5155.0 2130.0 0.0
0 5155.0 2550.0 -180.0
0 5187.5 2550.0 0.0
0 5187.5 4935.0 0.0
0 4945.0 5145.0 0.0
0 4945.0 5420.0 0.0
0 4865.0 5500.0 0.0
0 210.0 5500.0 0.0
0 130.0 5420.0 0.0
0 130.0 5145.0 0.0
0 -112.5 4935.0 0.0
0 -112.5 2550.0 0.0
0 -80.0 2550.0 0.0
0 -80.0 2130.0 -180.0
0 -112.5 2130.0 0.0
0 -112.5 -140.0 0.0
0 45.5 -140.0 0.0
0 45.5 -400.0 0.0
0 2442.5 -400.0 0.0
0 2442.5 -140.0 0.0
0 2631.5 -140.0 0.0
0 2631.5 -400.0 0.0
0 5030.5 -400.0 0.0
0 5030.5 -120.0 0.0
1 2650.0 2350.0 0.0
1 3000.0 2350.0 360.0
.END_BOARD_OUTLINE
# This is the second BOARD section
# SEC2-0
# SEC2-1
# NOT SEC1-1
.ROUTE_OUTLINE ECAD
ALL
0 5112.5 150.0 0.0
0 5112.5 2058.2 0.0
0 5112.5 2621.8 -162.9
0 5112.5 4863.2 0.0
0 4878.8 5075.0 0.0
0 226.4 5075.0 0.0
0 138.0 4910.3 0.0
0 138.0 4800.0 0.0
0 -37.5 4662.5 0.0
0 -37.5 2621.8 0.0
0 -37.5 2058.2 -162.9
0 -37.5 150.0 0.0
0 162.5 0.0 0.0
0 4912.5 0.0 0.0
0 5112.5 150.0 0.0
.END_ROUTE_OUTLINE
# This is the third BOARD section
# SEC3-0
# SEC3-1
.PLACE_OUTLINE MCAD
TOP 1000.0
0 5080.0 2034.9 0.0
0 5080.0 2645.1 -152.9
0 5080.0 4837.3 0.0
0 4855.3 5042.5 0.0
0 252.9 5042.5 0.0
0 170.5 4896.9 0.0
0 170.5 4798.4 0.0
0 -5.0 4659.0 0.0
0 -5.0 2645.1 0.0
0 -5.0 2034.9 -152.9
0 -5.0 182.5 0.0
0 192.0 32.5 0.0
0 4883.1 32.5 0.0
0 5080.0 182.5 0.0
0 5080.0 2034.9 0.0
.END_PLACE_OUTLINE
# This is the fourth BOARD section
# SEC4-0
# SEC4-1
.PLACE_OUTLINE UNOWNED
BOTTOM 200.0
0 300.0 200.0 0.0
0 4800.0 200.0 0.0
0 4800.0 4800.0 0.0
0 300.0 4800.0 0.0
0 300.0 200.0 0.0
.END_PLACE_OUTLINE
# This is the fifth BOARD section
# SEC5-0
# SEC5-1
.ROUTE_KEEPOUT ECAD
ALL
0 2650.0 2350.0 0.0
0 3100.0 2350.0 360.0
.END_ROUTE_KEEPOUT
# This is the sixth BOARD section
# SEC6-0
# SEC6-1
.PLACE_KEEPOUT MCAD
BOTH 0.0
0 2650.0 2350.0 0.0
0 3100.0 2350.0 360.0
.END_PLACE_KEEPOUT
# This is the seventh BOARD section
# SEC7-0
# SEC7-1
.PLACE_KEEPOUT MCAD
TOP 300.0
0 3700.0 5000.0 0.0
0 3700.0 4300.0 0.0
0 4000.0 4300.0 0.0
0 4000.0 3700.0 0.0
0 5000.0 3700.0 0.0
0 5000.0 4800.0 0.0
0 4800.0 5000.0 0.0
0 3700.0 5000.0 0.0
.END_PLACE_KEEPOUT
# This is the eighth BOARD section
# SEC8-0
# SEC8-1
.DRILLED_HOLES
30.0 1800.0 100.0 PTH J1 PIN ECAD
30.0 1700.0 100.0 PTH J1 PIN ECAD
30.0 1600.0 100.0 PTH J1 PIN ECAD
30.0 1500.0 100.0 PTH J1 PIN ECAD
30.0 1400.0 100.0 PTH J1 PIN ECAD
30.0 1300.0 100.0 PTH J1 PIN ECAD
30.0 1200.0 100.0 PTH J1 PIN ECAD
30.0 1100.0 100.0 PTH J1 PIN ECAD
30.0 1000.0 100.0 PTH J1 PIN ECAD
30.0 0900.0 100.0 PTH J1 PIN ECAD
30.0 0800.0 100.0 PTH J1 PIN ECAD
30.0 0700.0 100.0 PTH J1 PIN ECAD
30.0 0700.0 200.0 PTH J1 PIN ECAD
30.0 0800.0 200.0 PTH J1 PIN ECAD
30.0 0900.0 200.0 PTH J1 PIN ECAD
30.0 1000.0 200.0 PTH J1 PIN ECAD
30.0 1100.0 200.0 PTH J1 PIN ECAD
30.0 1200.0 200.0 PTH J1 PIN ECAD
30.0 1300.0 200.0 PTH J1 PIN ECAD
30.0 1400.0 200.0 PTH J1 PIN ECAD
30.0 1500.0 200.0 PTH J1 PIN ECAD
30 1600 200 PTH J1 PIN ECAD
30 1700 200 PTH J1 PIN ECAD
30 1800 200 PTH J1 PIN ECAD
30 4400 100 PTH J2 PIN ECAD
30 4300 100 PTH J2 PIN ECAD
30 4200 100 PTH J2 PIN ECAD
30 4100 100 PTH J2 PIN ECAD
30 4000 100 PTH J2 PIN ECAD
30 3900 100 PTH J2 PIN ECAD
30 3800 100 PTH J2 PIN ECAD
30 3700 100 PTH J2 PIN ECAD
30 3600 100 PTH J2 PIN ECAD
30 3500 100 PTH J2 PIN ECAD
30 3400 100 PTH J2 PIN ECAD
30 3300 100 PTH J2 PIN ECAD
30 3300 200 PTH J2 PIN ECAD
30 3400 200 PTH J2 PIN ECAD
30 3500 200 PTH J2 PIN ECAD
30 3600 200 PTH J2 PIN ECAD
30 3700 200 PTH J2 PIN ECAD
30 3800 200 PTH J2 PIN ECAD
30 3900 200 PTH J2 PIN ECAD
30 4000 200 PTH J2 PIN ECAD
30 4100 200 PTH J2 PIN ECAD
30 4200 200 PTH J2 PIN ECAD
30 4300 200 PTH J2 PIN ECAD
30 4400 200 PTH J2 PIN ECAD
30 3000 3300 PTH U3 PIN ECAD
30 3024.2 3203 PTH U3 PIN ECAD
30 3048.4 3105.9 PTH U3 PIN ECAD
30 3072.6 3008.9 PTH U3 PIN ECAD
30 3096.8 2911.9 PTH U3 PIN ECAD
30 3121 2814.9 PTH U3 PIN ECAD
30 3145.2 2717.8 PTH U3 PIN ECAD
30 3436.2 2790.4 PTH U3 PIN ECAD
30 3412.1 2887.4 PTH U3 PIN ECAD
30 3387.9 2984.5 PTH U3 PIN ECAD
30 3363.7 3081.5 PTH U3 PIN ECAD
30 3339.5 3178.5 PTH U3 PIN ECAD
30 3315.3 3275.6 PTH U3 PIN ECAD
30 3291.1 3372.6 PTH U3 PIN ECAD
30 2200 2500 PTH U4 PIN ECAD
30 2100 2500 PTH U4 PIN ECAD
30 2000 2500 PTH U4 PIN ECAD
30 1900 2500 PTH U4 PIN ECAD
30 1800 2500 PTH U4 PIN ECAD
30 1700 2500 PTH U4 PIN ECAD
30 1600 2500 PTH U4 PIN ECAD
30 1600 2200 PTH U4 PIN ECAD
30 1700 2200 PTH U4 PIN ECAD
30 1800 2200 PTH U4 PIN ECAD
30 1900 2200 PTH U4 PIN ECAD
30 2000 2200 PTH U4 PIN ECAD
30 2100 2200 PTH U4 PIN ECAD
30 2200 2200 PTH U4 PIN ECAD
20 2500 3100 PTH BOARD VIA ECAD
20 2500 3200 PTH BOARD VIA ECAD
20 2500 3300 PTH BOARD VIA ECAD
20 2000 1600 PTH BOARD VIA ECAD
20 1100 900 PTH BOARD VIA ECAD
20 1200 1600 PTH BOARD VIA ECAD
20 3900 3800 PTH BOARD VIA ECAD
20 3900 2300 PTH BOARD VIA ECAD
100.0 3100.0 -50.0 NPTH J2 MTG ECAD
100.0 4600.0 -50.0 NPTH J2 MTG ECAD
100.0 500.0 -50.0 NPTH J1 MTG ECAD
100.0 2000.0 -50.0 NPTH J1 MTG ECAD
93.0 5075.0 0.0 PTH BOARD MTG UNOWNED
93.0 0.0 4800.0 NPTH BOARD TOOL MCAD
93.0 0.0 0.0 PTH BOARD MTG UNOWNED
.END_DRILLED_HOLES
# This is the ninth BOARD section
# SEC9-0
# SEC9-1
.NOTES
3500.0 3300.0 75.0 2500.0 "This component rotated 14 degrees"
400.0 4400.0 75.0 3200.0 "Component height limited by enclosure latch"
1800.0 300.0 75.0 1700.0 "Do not move connectors!"
.END_NOTES
# This is the tenth and ALWAYS FINAL BOARD section
# SEC10-0
# SEC10-1
.PLACEMENT
cs13_a pn-cap C1
4000.0 1000.0 100.0 0.0 TOP PLACED
cc1210 pn-cc1210 C2
3000.0 3500.0 0.0 0.0 TOP PLACED
cc1210 pn-cc1210 C3
3200.0 1800.0 0.0 0.0 BOTTOM PLACED
cc1210 pn-cc1210 C4
1400.0 2300.0 0.0 270.0 TOP PLACED
cc1210 pn-cc1210 C5
1799.5 3518.1 0.0 0.0 BOTTOM PLACED
conn_din24 connector J1
1800.0 100.0 0.0 0.0 TOP MCAD
conn_din24 connector J2
4400.0 100.0 0.0 0.0 TOP MCAD
plcc_20 pn-pal16l8-plcc U1
1800.0 3200.0 0.0 0.0 BOTTOM ECAD
plcc_20 pn-pal16l8-plcc U2
3200.0 1800.0 0.0 0.0 TOP PLACED
dip_14w pn-hs346-dip U3
3000.0 3300.0 0.0 14.0 TOP PLACED
dip_14w pn-hs346-dip U4
2200.0 2500.0 0.0 270.0 TOP PLACED
.END_PLACEMENT

69
utils/idftools/idf_examples/idf_example.emp

@ -1,69 +0,0 @@
.HEADER
LIBRARY_file 3.0 "Sample File Generator" 10/22/96.16:41:37 1
.END_HEADER
# Component #1/5
.ELECTRICAL
cs13_a pn-cap THOU 150.0
0 -55.0 55.0 0.0
0 -55.0 -55.0 0.0
0 135.0 -55.0 0.0
0 135.0 -80.0 0.0
0 565.0 -80.0 0.0
0 565.0 -55.0 0.0
0 755.0 -55.0 0.0
0 755.0 55.0 0.0
0 565.0 55.0 0.0
0 565.0 80.0 0.0
0 135.0 80.0 0.0
0 135.0 55.0 0.0
0 -55.0 55.0 0.0
PROP CAPACITANCE 100.0
PROP TOLERANCE 5.0
.END_ELECTRICAL
# Component #2/5
.ELECTRICAL
cc1210 pn-cc1210 THOU 67.0
0 -40.0 56.0 0.0
0 -40.0 -56.0 0.0
0 182.0 -56.0 0.0
0 182.0 56.0 0.0
0 -40.0 56.0 0.0
PROP CAPACITANCE 0.1
PROP TOLERANCE 5.0
.END_ELECTRICAL
# Component #3/5
.ELECTRICAL
conn_din24 connector THOU 435.0
0 -1400.0 -500.0 0.0
0 300.0 -500.0 0.0
0 300.0 150.0 0.0
0 -1400.0 150.0 0.0
0 -1400.0 -500.0 0.0
.END_ELECTRICAL
# Component #4/5
.ELECTRICAL
dip_14w pn-hs346-dip THOU 200.0
0 350.0 50.0 0.0
0 -50.0 50.0 0.0
0 -50.0 -650.0 0.0
0 350.0 -650.0 0.0
0 350.0 50.0 0.0
.END_ELECTRICAL
# Component #5/5
.ELECTRICAL
plcc_20 pn-pal16l8-plcc THOU 14.0
0 -200.0 240.0 0.0
0 -240.0 200.0 0.0
0 -240.0 -240.0 0.0
0 240.0 -240.0 0.0
0 240.0 240.0 0.0
0 -200.0 240.0 0.0
.END_ELECTRICAL

45
utils/idftools/idf_examples/test_donut.emn

@ -1,45 +0,0 @@
.HEADER
BOARD_FILE 3.0 "Created by some software" 2014/02/01.15:09:15 1
"test_donut" MM
.END_HEADER
# The board outline is a simple square with a small hole in it
.BOARD_OUTLINE ECAD
1.60000
0 -100 100 0
0 -100 -100 0
0 100 -100 0
0 100 100 0
0 -100 100 0
1 0 0 0
1 5 0 360
.END_BOARD_OUTLINE
# This OTHER OUTLINE is a square toroid
.OTHER_OUTLINE UNOWNED
MY_DONUT 30 TOP
0 0 0 0
0 75 0 360
1 0 0 0
1 30 0 360
.END_OTHER_OUTLINE
# This OTHER OUTLINE is a square with a hole
.OTHER_OUTLINE UNOWNED
MY_NOT_DONUT 2 BOTTOM
0 -50 50 0
0 -50 -50 0
0 50 -50 0
0 50 50 0
0 -50 50 0
1 0 0 0
1 10 0 360
2 0 50 0
2 0 75 360
3 50 0 0
3 75 0 360
4 0 -50 0
4 0 -75 360
5 -50 0 0
5 -75 0 360
.END_OTHER_OUTLINE

5
utils/idftools/idf_examples/test_donut.emp

@ -1,5 +0,0 @@
.HEADER
LIBRARY_FILE 3.0 "Created by some software" 2014/02/01.15:09:15 1
.END_HEADER
# This file contains no component outlines

71
utils/idftools/idf_examples/test_idf2.emn

@ -1,71 +0,0 @@
.HEADER
BOARD_FILE 3.0 "Created by KiCad (2014-01-25 BZR 4633)-product" 2014/02/01.15:09:15 1
"test_idf2.kicad_pcb" MM
.END_HEADER
.BOARD_OUTLINE ECAD
1.60000
0 -86.00000 42.00000 0
0 -86.00000 -42.00000 0
0 86.00000 -42.00000 0
0 86.00000 42.00000 0
0 -86.00000 42.00000 0
.END_BOARD_OUTLINE
.DRILLED_HOLES
0.800 -74.00000 16.00000 PTH BOARD PIN ECAD
0.800 -74.00000 -28.00000 PTH BOARD PIN ECAD
0.850 -55.75000 16.00000 PTH BOARD PIN ECAD
0.850 -52.25000 16.00000 PTH BOARD PIN ECAD
0.850 -35.75000 16.00000 PTH BOARD PIN ECAD
0.850 -32.25000 16.00000 PTH BOARD PIN ECAD
1.575 -57.17500 -28.00000 PTH BOARD PIN ECAD
1.575 -50.82500 -28.00000 PTH BOARD PIN ECAD
1.575 -37.17500 -28.00000 PTH BOARD PIN ECAD
1.575 -30.82500 -28.00000 PTH BOARD PIN ECAD
0.800 -14.00000 16.00000 PTH BOARD PIN ECAD
0.800 -14.00000 -28.00000 PTH BOARD PIN ECAD
0.800 6.00000 16.00000 PTH BOARD PIN ECAD
0.800 6.00000 -28.00000 PTH BOARD PIN ECAD
0.800 26.00000 16.00000 PTH BOARD PIN ECAD
0.800 26.00000 -28.00000 PTH BOARD PIN ECAD
0.800 46.00000 16.00000 PTH BOARD PIN ECAD
0.800 46.00000 -28.00000 PTH BOARD PIN ECAD
0.800 66.00000 16.00000 PTH BOARD PIN ECAD
0.800 66.00000 -28.00000 PTH BOARD PIN ECAD
.END_DRILLED_HOLES
.PLACEMENT
"CYLV_MM" "D5.000_H8.000_Z3.000" "NOREFDES_0"
-74.000000 16.000000 0.000000 0.000 TOP ECAD
"CYLV_IN" "D0.250_H0.250_Z0.127" "NOREFDES_1"
-74.000000 -28.000000 0.000000 0.000 TOP ECAD
"CYLV_MM_L" "D5.000_H8.000_Z3.000_WD0.800_P3.500" "NOREFDES_2"
-54.000000 16.000000 0.000000 0.000 TOP ECAD
"CYLV_MM_R" "D5.000_H8.000_Z3.000_WD0.800_P3.500" "NOREFDES_3"
-34.000000 16.000000 0.000000 0.000 TOP ECAD
"CYLV_IN_L" "D0.250_H0.250_Z0.127_WD0.062_P0.250" "NOREFDES_4"
-54.000000 -28.000000 0.000000 0.000 TOP ECAD
"CYLV_IN_R" "D0.250_H0.250_Z0.127_WD0.062_P0.250" "NOREFDES_5"
-34.000000 -28.000000 0.000000 0.000 TOP ECAD
"CYLH_MM_AXI" "D2.500_H4.000_Z0.500_WD0.600_P8.000" "NOREFDES_6"
-14.000000 16.000000 0.000000 0.000 TOP ECAD
"CYLH_IN_AXI" "D0.098_H0.157_Z0.020_WD0.024_P0.315" "NOREFDES_7"
-14.000000 -28.000000 0.000000 0.000 TOP ECAD
"CYLH_MM_RAD" "D5.000_H6.000_Z0.200_WD0.600_P2.500_L3.000" "NOREFDES_8"
6.000000 16.000000 0.000000 0.000 TOP ECAD
"CYLH_IN_RAD" "D0.197_H0.236_Z0.008_WD0.024_P0.098_L0.118" "NOREFDES_9"
6.000000 -28.000000 0.000000 0.000 TOP ECAD
"RECTMM" "W10.000_L10.000_H6.000_C0.000" "NOREFDES_10"
26.000000 16.000000 0.000000 0.000 TOP ECAD
"RECTIN" "W393_L393_H236_C0" "NOREFDES_11"
26.000000 -28.000000 0.000000 0.000 TOP ECAD
"RECTMM" "W10.000_L10.000_H2.000_C0.500" "NOREFDES_12"
46.000000 16.000000 0.000000 0.000 TOP ECAD
"RECTIN" "W393_L393_H78_C19" "NOREFDES_13"
46.000000 -28.000000 0.000000 0.000 TOP ECAD
"RECTLMM" "W10.000_L10.000_H12.000_D0.800_P6.000" "NOREFDES_14"
66.000000 16.000000 0.000000 0.000 TOP ECAD
"RECTLIN" "W393_L393_H472_D31_P236" "NOREFDES_15"
66.000000 -28.000000 0.000000 0.000 TOP ECAD
.END_PLACEMENT

290
utils/idftools/idf_examples/test_idf2.emp

@ -1,290 +0,0 @@
.HEADER
LIBRARY_FILE 3.0 "Created by KiCad (2014-01-25 BZR 4633)-product" 2014/02/01.15:09:15 1
.END_HEADER
# cylindrical outline, vertical, no pins
# file: "cylvmm_0_D5_L8_Z3.idf"
# dia: 5.000 mm
# length: 8.000 mm
# extra height: 3.000 mm
.ELECTRICAL
"CYLV_MM" "D5.000_H8.000_Z3.000" MM 11.000
0 0 0 0
0 5.000 0 360
.END_ELECTRICAL
# cylindrical outline, vertical, no pins
# file: "cylvin_0_D0.25_L0.25_Z0.127.idf"
# dia: 250 THOU
# length: 250 THOU
# extra height: 127 THOU
.ELECTRICAL
"CYLV_IN" "D0.250_H0.250_Z0.127" THOU 377
0 0 0 0
0 250 0 360
.END_ELECTRICAL
# cylindrical outline, vertical, 1 pin on left
# file: "cylvmm_1L_D5_L8_Z3_WD0.8_P3.5.idf"
# dia: 5.000 mm
# length: 8.000 mm
# extra height: 3.000 mm
# wire dia: 0.800 mm
# pitch: 3.500 mm
.ELECTRICAL
"CYLV_MM_L" "D5.000_H8.000_Z3.000_WD0.800_P3.500" MM 11.000
1 -0.718 0.400 0
1 -0.718 -0.400 -341.586
1 -1.750 -0.400 0
1 -1.750 0.400 -180
1 -0.718 0.400 0
.END_ELECTRICAL
# cylindrical outline, vertical, 1 pin on right
# file: "cylvmm_1R_D5_L8_Z3_WD0.8_P3.5.idf"
# dia: 5.000 mm
# length: 8.000 mm
# extra height: 3.000 mm
# wire dia: 0.800 mm
# pitch: 3.500 mm
.ELECTRICAL
"CYLV_MM_R" "D5.000_H8.000_Z3.000_WD0.800_P3.500" MM 11.000
0 0.718 0.400 0
0 0.718 -0.400 341.586
0 1.750 -0.400 0
0 1.750 0.400 180
0 0.718 0.400 0
.END_ELECTRICAL
# cylindrical outline, vertical, 1 pin on left
# file: "cylvin_1L_D0.25_L0.25_Z0.127_WD0.062_P0.25.idf"
# dia: 250 THOU
# length: 250 THOU
# extra height: 127 THOU
# wire dia: 62 THOU
# pitch: 250 THOU
.ELECTRICAL
"CYLV_IN_L" "D0.250_H0.250_Z0.127_WD0.062_P0.250" THOU 377
1 3 31 0
1 3 -31 -331.282
1 -125 -31 0
1 -125 31 -180
1 3 31 0
.END_ELECTRICAL
# cylindrical outline, vertical, 1 pin on right
# file: "cylvin_1R_D0.25_L0.25_Z0.127_WD0.062_P0.25.idf"
# dia: 250 THOU
# length: 250 THOU
# extra height: 127 THOU
# wire dia: 62 THOU
# pitch: 250 THOU
.ELECTRICAL
"CYLV_IN_R" "D0.250_H0.250_Z0.127_WD0.062_P0.250" THOU 377
0 -3 31 0
0 -3 -31 331.282
0 125 -31 0
0 125 31 180
0 -3 31 0
.END_ELECTRICAL
# cylindrical outline, horiz., axial pins
# file: "resistor.idf"
# dia: 2.500 mm
# length: 4.000 mm
# extra height: 0.500 mm
# wire dia: 0.600 mm
# pitch: 8.000 mm
.ELECTRICAL
"CYLH_MM_AXI" "D2.500_H4.000_Z0.500_WD0.600_P8.000" MM 3.000
0 -2.000 1.250 0
0 -2.000 0.300 0
0 -4.000 0.300 0
0 -4.000 -0.300 180
0 -2.000 -0.300 0
0 -2.000 -1.250 0
0 2.000 -1.250 0
0 2.000 -0.300 0
0 4.000 -0.300 0
0 4.000 0.300 180
0 2.000 0.300 0
0 2.000 1.250 0
0 -2.000 1.250 0
.END_ELECTRICAL
# cylindrical outline, horiz., axial pins
# file: "resistor_in.idf"
# dia: 98 THOU
# length: 157 THOU
# extra height: 20 THOU
# wire dia: 24 THOU
# pitch: 315 THOU
.ELECTRICAL
"CYLH_IN_AXI" "D0.098_H0.157_Z0.020_WD0.024_P0.315" THOU 118
0 -78 49 0
0 -78 12 0
0 -157 12 0
0 -157 -12 180
0 -78 -12 0
0 -78 -49 0
0 78 -49 0
0 78 -12 0
0 157 -12 0
0 157 12 180
0 78 12 0
0 78 49 0
0 -78 49 0
.END_ELECTRICAL
# cylindrical outline, horiz., radial pins
# file: "capacitor.idf"
# dia: 5.000 mm
# length: 6.000 mm
# extra height: 0.200 mm
# wire dia: 0.600 mm
# pitch: 2.500 mm
# lead: 3.000 mm
.ELECTRICAL
"CYLH_MM_RAD" "D5.000_H6.000_Z0.200_WD0.600_P2.500_L3.000" MM 5.200
0 -2.500 9.000 0
0 -2.500 3.000 0
0 -1.550 3.000 0
0 -1.550 0 0
0 -0.950 0 180
0 -0.950 3.000 0
0 0.950 3.000 0
0 0.950 0 0
0 1.550 0 180
0 1.550 3.000 0
0 2.500 3.000 0
0 2.500 9.000 0
0 -2.500 9.000 0
.END_ELECTRICAL
# cylindrical outline, horiz., radial pins
# file: "capacitor_in.idf"
# dia: 197 THOU
# length: 236 THOU
# extra height: 8 THOU
# wire dia: 24 THOU
# pitch: 98 THOU
# lead: 118 THOU
.ELECTRICAL
"CYLH_IN_RAD" "D0.197_H0.236_Z0.008_WD0.024_P0.098_L0.118" THOU 205
0 -98 354 0
0 -98 118 0
0 -61 118 0
0 -61 0 0
0 -37 0 180
0 -37 118 0
0 37 118 0
0 37 0 0
0 61 0 180
0 61 118 0
0 98 118 0
0 98 354 0
0 -98 354 0
.END_ELECTRICAL
# rectangular outline
# file: "rectMM_10x10x6_C0.idf"
# width: 10.000 mm
# length: 10.000 mm
# height: 6.000 mm
# chamfer: 0.000 mm
.ELECTRICAL
"RECTMM" "W10.000_L10.000_H6.000_C0.000" MM 6.000
0 5.000 5.000 0
0 -5.000 5.000 0
0 -5.000 -5.000 0
0 5.000 -5.000 0
0 5.000 5.000 0
.END_ELECTRICAL
# rectangular outline
# file: "rectIN_10x10x6mm_C0mm.idf"
# width: 393 THOU
# length: 393 THOU
# height: 236 THOU
# chamfer: 0 THOU
.ELECTRICAL
"RECTIN" "W393_L393_H236_C0" THOU 236
0 196 196 0
0 -196 196 0
0 -196 -196 0
0 196 -196 0
0 196 196 0
.END_ELECTRICAL
# rectangular outline
# file: "rectMM_10x10x2_C0.5.idf"
# width: 10.000 mm
# length: 10.000 mm
# height: 2.000 mm
# chamfer: 0.500 mm
.ELECTRICAL
"RECTMM" "W10.000_L10.000_H2.000_C0.500" MM 2.000
0 5.000 5.000 0
0 -4.500 5.000 0
0 -5.000 4.500 0
0 -5.000 -5.000 0
0 5.000 -5.000 0
0 5.000 5.000 0
.END_ELECTRICAL
# rectangular outline
# file: "rectIN_10x10x2mm_C0.5mm.idf"
# width: 393 THOU
# length: 393 THOU
# height: 78 THOU
# chamfer: 19 THOU
.ELECTRICAL
"RECTIN" "W393_L393_H78_C19" THOU 78
0 196 196 0
0 -176 196 0
0 -196 176 0
0 -196 -196 0
0 196 -196 0
0 196 196 0
.END_ELECTRICAL
# rectangular outline, leaded
# file: "rectLMM_10x10x12_D0.8_P6.0.idf"
# width: 10.000 mm
# length: 10.000 mm
# height: 12.000 mm
# wire dia: 0.800 mm
# pitch: 6.000 mm
.ELECTRICAL
"RECTLMM" "W10.000_L10.000_H12.000_D0.800_P6.000" MM 12.000
0 3.000 0.400 0
0 2.000 0.400 0
0 2.000 5.000 0
0 -8.000 5.000 0
0 -8.000 -5.000 0
0 2.000 -5.000 0
0 2.000 -0.400 0
0 3.000 -0.400 0
0 3.000 0.400 180
.END_ELECTRICAL
# rectangular outline, leaded
# file: "rectLIN_10x10x12mm_D0.8mm_P6.0mm.idf"
# width: 393 THOU
# length: 393 THOU
# height: 472 THOU
# wire dia: 31 THOU
# pitch: 236 THOU
.ELECTRICAL
"RECTLIN" "W393_L393_H472_D31_P236" THOU 472
0 118 15 0
0 78 15 0
0 78 196 0
0 -315 196 0
0 -315 -196 0
0 78 -196 0
0 78 -15 0
0 118 -15 0
0 118 15 180
.END_ELECTRICAL

438
utils/idftools/idf_rect.cpp

@ -1,438 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014 Cirilo Bernardo
* Copyright The 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, see <https://www.gnu.org/licenses/>.
*/
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <cmath>
#include <cstdio>
#include <list>
#include <utility>
#include <clocale>
using namespace std;
void writeLeaded( FILE* fp, double width, double length, double wireDia, double pitch, bool inch );
void writeLeadless( FILE* fp, double width, double length, double chamfer, bool inch );
int main( int argc, char** argv )
{
// IDF implicitly requires the C locale
setlocale( LC_ALL, "C" );
if( argc == 1 )
{
cout << "idfrect: This program generates an outline for a rectangular component.\n";
cout << " The component may have a single lead (axial) or a chamfer on the\n";
cout << " upper left corner.\n";
cout << "Input:\n";
cout << " Unit: mm, in (millimeters or inches)\n";
cout << " Width:\n";
cout << " Length:\n";
cout << " Height:\n";
cout << " Chamfer: length of the 45 deg. chamfer\n";
cout << " * Leaded: Y,N (lead is always to the right)\n";
cout << " ** Wire diameter\n";
cout << " ** Pitch\n";
cout << " File name (must end in *.idf)\n\n";
cout << " NOTES:\n";
cout << " * only required if chamfer = 0\n\n";
cout << " ** only required for leaded components\n\n";
}
bool inch = false; // default mm
double width = 0.0;
double length = 0.0;
double height = 0.0;
double wireDia = 0.0;
double pitch = 0.0;
double chamfer = 0.0;
bool leaded = false;
bool ok = false;
stringstream tstr;
string line;
line.clear();
while( line.compare( "mm" ) && line.compare( "in" ) )
{
cout << "* Units (mm,in): ";
line.clear();
std::getline( cin, line );
}
if( line.compare( "mm" ) )
inch = true;
ok = false;
while( !ok )
{
cout << "* Width: ";
line.clear();
std::getline( cin, line );
tstr.clear();
tstr.str( line );
tstr >> width;
if( !tstr.fail() && width >= 0.001 )
ok = true;
}
ok = false;
while( !ok )
{
cout << "* Length: ";
line.clear();
std::getline( cin, line );
tstr.clear();
tstr.str( line );
tstr >> length;
if( !tstr.fail() && length > 0.0 )
ok = true;
}
ok = false;
while( !ok )
{
cout << "* Height: ";
line.clear();
std::getline( cin, line );
tstr.clear();
tstr.str( line );
tstr >> height;
if( !tstr.fail() && height >= 0.001 )
ok = true;
}
ok = false;
while( !ok )
{
cout << "* Chamfer (0 for none): ";
line.clear();
std::getline( cin, line );
tstr.clear();
tstr.str( line );
tstr >> chamfer;
if( !tstr.fail() && chamfer >= 0.0 )
{
if( chamfer > width / 3.0 || chamfer > length / 3.0 )
cout << "* WARNING: chamfer must be <= MIN( width, length )/3\n";
else
ok = true;
}
}
if( chamfer < 1e-6 )
{
ok = false;
while( !ok )
{
cout << "* Leaded: Y, N: ";
line.clear();
std::getline( cin, line );
if( !line.compare( "Y" ) || !line.compare( "y" ) )
{
leaded = true;
ok = true;
}
else if( !line.compare( "N" ) || !line.compare( "n" ) )
{
leaded = false;
ok = true;
}
}
}
ok = false;
while( leaded && !ok )
{
cout << "* Wire dia.: ";
line.clear();
std::getline( cin, line );
tstr.clear();
tstr.str( line );
tstr >> wireDia;
if( !tstr.fail() && wireDia >= 0.001 )
{
if( wireDia >= length )
cout << "* WARNING: wire diameter must be < length\n";
else
ok = true;
}
}
ok = false;
while( leaded && !ok )
{
cout << "* Pitch: ";
line.clear();
std::getline( cin, line );
tstr.clear();
tstr.str( line );
tstr >> pitch;
if( !tstr.fail() && pitch >= 0.001 )
{
if( pitch <= ( length + wireDia ) / 2.0 )
cout << "* WARNING: pitch must be > (length + wireDia)/2\n";
else
ok = true;
}
}
line.clear();
while( line.empty() || line.find( ".idf" ) == string::npos )
{
cout << "* File name (*.idf): ";
line.clear();
std::getline( cin, line );
}
FILE* fp = fopen( line.c_str(), "w" );
if( !fp )
{
cerr << "Could not open output file: " << line << "\n";
}
else
{
fprintf( fp, "# rectangular outline%s\n", leaded ? ", leaded" : "" );
fprintf( fp, "# file: \"%s\"\n", line.c_str() );
if( inch )
{
width *= 1000.0;
length *= 1000.0;
height *= 1000.0;
wireDia *= 1000.0;
pitch *= 1000.0;
chamfer *= 1000.0;
fprintf( fp, "# width: %d THOU\n", (int) width );
fprintf( fp, "# length: %d THOU\n", (int) length );
fprintf( fp, "# height: %d THOU\n", (int) height );
if( leaded )
{
fprintf( fp, "# wire dia: %d THOU\n", (int) wireDia );
fprintf( fp, "# pitch: %d THOU\n", (int) pitch );
}
else
{
fprintf( fp, "# chamfer: %d THOU\n", (int) chamfer );
}
fprintf( fp, ".ELECTRICAL\n" );
fprintf( fp, "\"RECT%sIN\" \"W%d_L%d_H%d", leaded ? "L" : "", (int) width, (int) length,
(int) height );
if( leaded )
fprintf( fp, "_D%d_P%d\" ", (int) wireDia, (int) pitch );
else
fprintf( fp, "_C%d\" ", (int) chamfer );
fprintf( fp, "THOU %d\n", (int) height );
}
else
{
fprintf( fp, "# width: %.3f mm\n", width );
fprintf( fp, "# length: %.3f mm\n", length );
fprintf( fp, "# height: %.3f mm\n", height );
if( leaded )
{
fprintf( fp, "# wire dia: %.3f mm\n", wireDia );
fprintf( fp, "# pitch: %.3f mm\n", pitch );
}
else
{
fprintf( fp, "# chamfer: %.3f mm\n", chamfer );
}
fprintf( fp, ".ELECTRICAL\n" );
fprintf( fp, "\"RECT%sMM\" \"W%.3f_L%.3f_H%.3f_", leaded ? "L" : "", width, length,
height );
if( leaded )
fprintf( fp, "D%.3f_P%.3f\" ", wireDia, pitch );
else
fprintf( fp, "C%.3f\" ", chamfer );
fprintf( fp, "MM %.3f\n", height );
}
if( leaded )
writeLeaded( fp, width, length, wireDia, pitch, inch );
else
writeLeadless( fp, width, length, chamfer, inch );
fprintf( fp, ".END_ELECTRICAL\n" );
fclose( fp );
}
setlocale( LC_ALL, "" );
return 0;
}
void writeLeaded( FILE* fp, double width, double length, double wireDia, double pitch, bool inch )
{
if( inch )
{
int x1, x2, x3;
int y1, y2;
x1 = static_cast<int>( pitch / 2.0 );
x2 = static_cast<int>( width / 2.0 - x1 );
x3 = static_cast<int>( x2 - width );
y1 = static_cast<int>( wireDia / 2.0 );
y2 = static_cast<int>( length / 2.0 );
fprintf( fp, "0 %d %d 0\n", x1, y1 );
fprintf( fp, "0 %d %d 0\n", x2, y1 );
fprintf( fp, "0 %d %d 0\n", x2, y2 );
fprintf( fp, "0 %d %d 0\n", x3, y2 );
fprintf( fp, "0 %d %d 0\n", x3, -y2 );
fprintf( fp, "0 %d %d 0\n", x2, -y2 );
fprintf( fp, "0 %d %d 0\n", x2, -y1 );
fprintf( fp, "0 %d %d 0\n", x1, -y1 );
fprintf( fp, "0 %d %d 180\n", x1, y1 );
}
else
{
double x1, x2, x3;
double y1, y2;
x1 = pitch / 2.0;
x2 = width / 2.0 - x1;
x3 = x2 - width;
y1 = wireDia / 2.0;
y2 = length / 2.0;
fprintf( fp, "0 %.3f %.3f 0\n", x1, y1 );
fprintf( fp, "0 %.3f %.3f 0\n", x2, y1 );
fprintf( fp, "0 %.3f %.3f 0\n", x2, y2 );
fprintf( fp, "0 %.3f %.3f 0\n", x3, y2 );
fprintf( fp, "0 %.3f %.3f 0\n", x3, -y2 );
fprintf( fp, "0 %.3f %.3f 0\n", x2, -y2 );
fprintf( fp, "0 %.3f %.3f 0\n", x2, -y1 );
fprintf( fp, "0 %.3f %.3f 0\n", x1, -y1 );
fprintf( fp, "0 %.3f %.3f 180\n", x1, y1 );
}
}
void writeLeadless( FILE* fp, double width, double length, double chamfer, bool inch )
{
if( chamfer < 0.001 )
{
if( inch )
{
int x = static_cast<int>( width / 2.0 );
int y = static_cast<int>( length / 2.0 );
fprintf( fp, "0 %d %d 0\n", x, y );
fprintf( fp, "0 %d %d 0\n", -x, y );
fprintf( fp, "0 %d %d 0\n", -x, -y );
fprintf( fp, "0 %d %d 0\n", x, -y );
fprintf( fp, "0 %d %d 0\n", x, y );
}
else
{
double x = width / 2.0;
double y = length / 2.0;
fprintf( fp, "0 %.3f %.3f 0\n", x, y );
fprintf( fp, "0 %.3f %.3f 0\n", -x, y );
fprintf( fp, "0 %.3f %.3f 0\n", -x, -y );
fprintf( fp, "0 %.3f %.3f 0\n", x, -y );
fprintf( fp, "0 %.3f %.3f 0\n", x, y );
}
return;
}
if( inch )
{
int x = static_cast<int>( width / 2.0 );
int y = static_cast<int>( length / 2.0 );
int x1 = static_cast<int>( x - chamfer );
int y1 = static_cast<int>( y - chamfer );
fprintf( fp, "0 %d %d 0\n", x, y );
fprintf( fp, "0 %d %d 0\n", -x1, y );
fprintf( fp, "0 %d %d 0\n", -x, y1 );
fprintf( fp, "0 %d %d 0\n", -x, -y );
fprintf( fp, "0 %d %d 0\n", x, -y );
fprintf( fp, "0 %d %d 0\n", x, y );
}
else
{
double x = width / 2.0;
double y = length / 2.0;
double x1 = x - chamfer;
double y1 = y - chamfer;
fprintf( fp, "0 %.3f %.3f 0\n", x, y );
fprintf( fp, "0 %.3f %.3f 0\n", -x1, y );
fprintf( fp, "0 %.3f %.3f 0\n", -x, y1 );
fprintf( fp, "0 %.3f %.3f 0\n", -x, -y );
fprintf( fp, "0 %.3f %.3f 0\n", x, -y );
fprintf( fp, "0 %.3f %.3f 0\n", x, y );
}
}
Loading…
Cancel
Save