Commit fbe84842 authored by Cirilo Bernardo's avatar Cirilo Bernardo Committed by jean-pierre charras

Apply IDF tools patch from Cirilo Bernardo

parent b39408b1
...@@ -542,6 +542,7 @@ add_subdirectory( potrace ) ...@@ -542,6 +542,7 @@ add_subdirectory( potrace )
add_subdirectory( bitmap2component ) add_subdirectory( bitmap2component )
add_subdirectory( pcb_calculator ) add_subdirectory( pcb_calculator )
add_subdirectory( tools ) add_subdirectory( tools )
add_subdirectory( utils )
add_subdirectory( qa ) add_subdirectory( qa )
#add_subdirectory( new ) #add_subdirectory( new )
......
...@@ -129,6 +129,7 @@ set( PCBNEW_EXPORTERS ...@@ -129,6 +129,7 @@ set( PCBNEW_EXPORTERS
exporters/export_gencad.cpp exporters/export_gencad.cpp
exporters/export_idf.cpp exporters/export_idf.cpp
exporters/export_vrml.cpp exporters/export_vrml.cpp
exporters/idf_common.cpp
exporters/idf.cpp exporters/idf.cpp
exporters/gen_drill_report_files.cpp exporters/gen_drill_report_files.cpp
exporters/gen_modules_placefile.cpp exporters/gen_modules_placefile.cpp
......
This diff is collapsed.
...@@ -31,269 +31,7 @@ ...@@ -31,269 +31,7 @@
#include <wx/string.h> #include <wx/string.h>
#include <set> #include <set>
#include <string> #include <string>
#include <idf_common.h>
#ifndef M_PI
#define M_PI 3.1415926535897932384626433832795028841
#endif
#ifndef M_PI2
#define M_PI2 ( M_PI / 2.0 )
#endif
#ifndef M_PI4
#define M_PI4 ( M_PI / 4.0 )
#endif
class IDF_POINT;
class IDF_SEGMENT;
class IDF_DRILL_DATA;
class IDF_OUTLINE;
class IDF_LIB;
namespace IDF3 {
enum KEY_OWNER
{
UNOWNED = 0, // < either MCAD or ECAD may modify a feature
MCAD, // < only MCAD may modify a feature
ECAD // < only ECAD may modify a feature
};
enum KEY_HOLETYPE
{
PIN = 0, // < drill hole is for a pin
VIA, // < drill hole is for a via
MTG, // < drill hole is for mounting
TOOL, // < drill hole is for tooling
OTHER // < user has specified a custom type
};
enum KEY_PLATING
{
PTH = 0, // < Plate-Through Hole
NPTH // < Non-Plate-Through Hole
};
enum KEY_REFDES
{
BOARD = 0, // < feature is associated with the board
NOREFDES, // < feature is associated with a component with no RefDes
PANEL, // < feature is associated with an IDF panel
REFDES // < reference designator as assigned by the CAD software
};
// calculate the angle between the horizon and the segment aStartPoint to aEndPoint
double CalcAngleRad( const IDF_POINT& aStartPoint, const IDF_POINT& aEndPoint );
double CalcAngleDeg( const IDF_POINT& aStartPoint, const IDF_POINT& aEndPoint );
// take contiguous elements from 'lines' and stuff them into 'outline'
void GetOutline( std::list<IDF_SEGMENT*>& aLines,
IDF_OUTLINE& aOutline );
}
/**
* @Struct IDF_POINT
* represents a vector of three doubles; this may be represent
* a point in space, or scaling, translation or rotation along
* three axes.
*/
struct IDF_VECTOR
{
double x;
double y;
double z;
};
/**
* @Class IDF_POINT
* represents a point
*/
class IDF_POINT
{
public:
double x; // < X coordinate
double y; // < Y coordinate
IDF_POINT()
{
x = 0.0;
y = 0.0;
}
/**
* Function Matches()
* returns true if the given coordinate point is within the given radius
* of the point.
* @param aPoint : coordinates of the point being compared
* @param aRadius : radius within which the points are considered the same
*/
bool Matches( const IDF_POINT& aPoint, double aRadius = 1e-5 );
double CalcDistance( const IDF_POINT& aPoint ) const;
};
/**
* @Class IDF_SEGMENT
* represents a geometry segment as used in IDFv3 outlines
*/
class IDF_SEGMENT
{
private:
/**
* Function CalcCenterAndRadius()
* Calculates the center, radius, and angle between center and start point given the
* IDF compliant points and included angle.
* @var startPoint, @var endPoint, and @var angle must be set prior as per IDFv3
*/
void CalcCenterAndRadius( void );
public:
IDF_POINT startPoint; // starting point in IDF coordinates
IDF_POINT endPoint; // end point in IDF coordinates
IDF_POINT center; // center of an arc or circle; used primarily for calculating min X
double angle; // included angle (degrees) according to IDFv3 specification
double offsetAngle; // angle between center and start of arc; used to speed up some calcs.
double radius; // radius of the arc or circle; used to speed up some calcs.
/**
* Function IDF_SEGMENT()
* initializes the internal variables
*/
IDF_SEGMENT();
/**
* Function IDF_SEGMENT( start, end )
* creates a straight segment
*/
IDF_SEGMENT( const IDF_POINT& aStartPoint, const IDF_POINT& aEndPoint );
/**
* Function IDF_SEGMENT( start, end )
* creates a straight segment, arc, or circle depending on the angle
* @param aStartPoint : start point (center if using KiCad convention, otherwise IDF convention)
* @param aEndPoint : end point (start of arc if using KiCad convention, otherwise IDF convention)
* @param aAngle : included angle; the KiCad convention is equivalent to the IDF convention
* @param fromKicad : set true if we need to convert from KiCad to IDF convention
*/
IDF_SEGMENT( const IDF_POINT& aStartPoint,
const IDF_POINT& aEndPoint,
double aAngle,
bool aFromKicad );
/**
* Function MatchesStart()
* returns true if the given coordinate is within a radius 'rad'
* of the start point.
* @param aPoint : coordinates of the point being compared
* @param aRadius : radius within which the points are considered the same
*/
bool MatchesStart( const IDF_POINT& aPoint, double aRadius = 1e-3 );
/**
* Function MatchesEnd()
* returns true if the given coordinate is within a radius 'rad'
* of the end point.
* @param aPoint : coordinates of the point being compared
* @param aRadius : radius within which the points are considered the same
*/
bool MatchesEnd( const IDF_POINT& aPoint, double aRadius = 1e-3 );
/**
* Function IsCircle()
* returns true if this segment is a circle
*/
bool IsCircle( void );
/**
* Function GetMinX()
* returns the minimum X coordinate of this segment
*/
double GetMinX( void );
/**
* Function SwapEnds()
* Swaps the start and end points and alters internal
* variables as necessary for arcs
*/
void SwapEnds( void );
};
/**
* @Class IDF_OUTLINE
* contains segment and winding information for an IDF outline
*/
class IDF_OUTLINE
{
private:
double dir;
std::list<IDF_SEGMENT*> outline;
public:
IDF_OUTLINE() { dir = 0.0; }
~IDF_OUTLINE() { Clear(); }
// returns true if the current list of points represents a counterclockwise winding
bool IsCCW( void )
{
if( dir > 0.0 )
return false;
return true;
}
// clears the internal list of outline segments
void Clear( void )
{
dir = 0.0;
while( !outline.empty() )
{
delete outline.front();
outline.pop_front();
}
}
// returns the size of the internal segment list
size_t size( void )
{
return outline.size();
}
// returns true if the internal segment list is empty
bool empty( void )
{
return outline.empty();
}
// return the front() of the internal segment list
IDF_SEGMENT*& front( void )
{
return outline.front();
}
// return the back() of the internal segment list
IDF_SEGMENT*& back( void )
{
return outline.back();
}
// return the begin() iterator of the internal segment list
std::list<IDF_SEGMENT*>::iterator begin( void )
{
return outline.begin();
}
// return the end() iterator of the internal segment list
std::list<IDF_SEGMENT*>::iterator end( void )
{
return outline.end();
}
// push a segment onto the internal list
void push( IDF_SEGMENT* item );
};
/** /**
......
This diff is collapsed.
/**
* @file idf_common.h
*/
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2013-2014 Cirilo Bernardo
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef IDF_COMMON_H
#define IDF_COMMON_H
#include <list>
#ifndef M_PI
#define M_PI 3.1415926535897932384626433832795028841
#endif
#ifndef M_PI2
#define M_PI2 ( M_PI / 2.0 )
#endif
#ifndef M_PI4
#define M_PI4 ( M_PI / 4.0 )
#endif
// differences in angle smaller than MIN_ANG are considered equal
#define MIN_ANG (0.01)
class IDF_POINT;
class IDF_SEGMENT;
class IDF_DRILL_DATA;
class IDF_OUTLINE;
class IDF_LIB;
namespace IDF3 {
enum KEY_OWNER
{
UNOWNED = 0, // < either MCAD or ECAD may modify a feature
MCAD, // < only MCAD may modify a feature
ECAD // < only ECAD may modify a feature
};
enum KEY_HOLETYPE
{
PIN = 0, // < drill hole is for a pin
VIA, // < drill hole is for a via
MTG, // < drill hole is for mounting
TOOL, // < drill hole is for tooling
OTHER // < user has specified a custom type
};
enum KEY_PLATING
{
PTH = 0, // < Plate-Through Hole
NPTH // < Non-Plate-Through Hole
};
enum KEY_REFDES
{
BOARD = 0, // < feature is associated with the board
NOREFDES, // < feature is associated with a component with no RefDes
PANEL, // < feature is associated with an IDF panel
REFDES // < reference designator as assigned by the CAD software
};
// calculate the angle between the horizon and the segment aStartPoint to aEndPoint
double CalcAngleRad( const IDF_POINT& aStartPoint, const IDF_POINT& aEndPoint );
double CalcAngleDeg( const IDF_POINT& aStartPoint, const IDF_POINT& aEndPoint );
// take contiguous elements from 'lines' and stuff them into 'outline'
void GetOutline( std::list<IDF_SEGMENT*>& aLines,
IDF_OUTLINE& aOutline );
#ifdef DEBUG_IDF
// prints out segment information for debug purposes
void PrintSeg( IDF_SEGMENT* aSegment );
#endif
}
/**
* @Class IDF_POINT
* represents a point
*/
class IDF_POINT
{
public:
double x; // < X coordinate
double y; // < Y coordinate
IDF_POINT()
{
x = 0.0;
y = 0.0;
}
/**
* Function Matches()
* returns true if the given coordinate point is within the given radius
* of the point.
* @param aPoint : coordinates of the point being compared
* @param aRadius : radius within which the points are considered the same
*/
bool Matches( const IDF_POINT& aPoint, double aRadius = 1e-5 );
double CalcDistance( const IDF_POINT& aPoint ) const;
};
/**
* @Class IDF_SEGMENT
* represents a geometry segment as used in IDFv3 outlines
*/
class IDF_SEGMENT
{
private:
/**
* Function CalcCenterAndRadius()
* Calculates the center, radius, and angle between center and start point given the
* IDF compliant points and included angle.
* @var startPoint, @var endPoint, and @var angle must be set prior as per IDFv3
*/
void CalcCenterAndRadius( void );
public:
IDF_POINT startPoint; // starting point in IDF coordinates
IDF_POINT endPoint; // end point in IDF coordinates
IDF_POINT center; // center of an arc or circle; used primarily for calculating min X
double angle; // included angle (degrees) according to IDFv3 specification
double offsetAngle; // angle between center and start of arc; used to speed up some calcs.
double radius; // radius of the arc or circle; used to speed up some calcs.
/**
* Function IDF_SEGMENT()
* initializes the internal variables
*/
IDF_SEGMENT();
/**
* Function IDF_SEGMENT( start, end )
* creates a straight segment
*/
IDF_SEGMENT( const IDF_POINT& aStartPoint, const IDF_POINT& aEndPoint );
/**
* Function IDF_SEGMENT( start, end )
* creates a straight segment, arc, or circle depending on the angle
* @param aStartPoint : start point (center if using KiCad convention, otherwise IDF convention)
* @param aEndPoint : end point (start of arc if using KiCad convention, otherwise IDF convention)
* @param aAngle : included angle; the KiCad convention is equivalent to the IDF convention
* @param fromKicad : set true if we need to convert from KiCad to IDF convention
*/
IDF_SEGMENT( const IDF_POINT& aStartPoint,
const IDF_POINT& aEndPoint,
double aAngle,
bool aFromKicad );
/**
* Function MatchesStart()
* returns true if the given coordinate is within a radius 'rad'
* of the start point.
* @param aPoint : coordinates of the point being compared
* @param aRadius : radius within which the points are considered the same
*/
bool MatchesStart( const IDF_POINT& aPoint, double aRadius = 1e-3 );
/**
* Function MatchesEnd()
* returns true if the given coordinate is within a radius 'rad'
* of the end point.
* @param aPoint : coordinates of the point being compared
* @param aRadius : radius within which the points are considered the same
*/
bool MatchesEnd( const IDF_POINT& aPoint, double aRadius = 1e-3 );
/**
* Function IsCircle()
* returns true if this segment is a circle
*/
bool IsCircle( void );
/**
* Function GetMinX()
* returns the minimum X coordinate of this segment
*/
double GetMinX( void );
/**
* Function SwapEnds()
* Swaps the start and end points and alters internal
* variables as necessary for arcs
*/
void SwapEnds( void );
};
/**
* @Class IDF_OUTLINE
* contains segment and winding information for an IDF outline
*/
class IDF_OUTLINE
{
private:
double dir;
std::list<IDF_SEGMENT*> outline;
public:
IDF_OUTLINE() { dir = 0.0; }
~IDF_OUTLINE() { Clear(); }
// returns true if the current list of points represents a counterclockwise winding
bool IsCCW( void )
{
if( dir > 0.0 )
return false;
return true;
}
// clears the internal list of outline segments
void Clear( void )
{
dir = 0.0;
while( !outline.empty() )
{
delete outline.front();
outline.pop_front();
}
}
// returns the size of the internal segment list
size_t size( void )
{
return outline.size();
}
// returns true if the internal segment list is empty
bool empty( void )
{
return outline.empty();
}
// return the front() of the internal segment list
IDF_SEGMENT*& front( void )
{
return outline.front();
}
// return the back() of the internal segment list
IDF_SEGMENT*& back( void )
{
return outline.back();
}
// return the begin() iterator of the internal segment list
std::list<IDF_SEGMENT*>::iterator begin( void )
{
return outline.begin();
}
// return the end() iterator of the internal segment list
std::list<IDF_SEGMENT*>::iterator end( void )
{
return outline.end();
}
// push a segment onto the internal list
void push( IDF_SEGMENT* item );
};
#endif // IDF_COMMON_H
add_subdirectory( idftools )
include_directories(
"${CMAKE_SOURCE_DIR}/include"
"${CMAKE_SOURCE_DIR}/lib_dxf"
"${CMAKE_SOURCE_DIR}/pcbnew/exporters"
"${CMAKE_SOURCE_DIR}/utils/idftools"
)
link_directories(
"${CMAKE_BINARY_DIR}/lib_dxf"
)
add_executable( idfcyl idf_cylinder.cpp )
add_executable( idfrect idf_rect.cpp )
add_executable( dxf2idf dxf2idfmain.cpp dxf2idf.cpp
"${CMAKE_SOURCE_DIR}/pcbnew/exporters/idf_common.cpp"
"${CMAKE_SOURCE_DIR}/common/richio.cpp"
)
target_link_libraries( dxf2idf lib_dxf ${wxWidgets_LIBRARIES} )
install( TARGETS idfcyl idfrect dxf2idf
DESTINATION ${KICAD_BIN}
COMPONENT binary )
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014 Cirilo Bernardo
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <cstdio>
#include <iostream>
#include <libdxfrw.h>
#include <dxf2idf.h>
// differences in angle smaller than MIN_ANG are considered equal
#define MIN_ANG (0.01)
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 )
{
dxfRW* reader = new dxfRW( aFile.c_str() );
if( !reader )
return false;
bool success = reader->read( this, true );
delete reader;
return success;
}
void DXF2IDF::addLine( const DRW_Line& data )
{
IDF_POINT p1, p2;
p1.x = data.basePoint.x;
p1.y = data.basePoint.y;
p2.x = data.secPoint.x;
p2.y = data.secPoint.y;
IDF_SEGMENT* seg = new IDF_SEGMENT( p1, p2 );
if( !seg )
{
std::cerr << "* FAULT: could not add a linear segment to the outline\n";
}
else
{
lines.push_back( seg );
}
return;
}
void DXF2IDF::addCircle( const DRW_Circle& data )
{
IDF_POINT p1, p2;
p1.x = data.basePoint.x;
p1.y = data.basePoint.y;
p2.x = p1.x + data.radious;
p2.y = p1.y;
IDF_SEGMENT* seg = new IDF_SEGMENT( p1, p2, 360, true );
if( !seg )
{
std::cerr << "* FAULT: could not add a linear segment to the outline\n";
}
else
{
lines.push_back( seg );
}
return;
}
void DXF2IDF::addArc( const DRW_Arc& data )
{
IDF_POINT p1, p2;
p1.x = data.basePoint.x;
p1.y = data.basePoint.y;
// note: DXF circles always run CCW
double ea = data.endangle;
while( ea < data.staangle )
ea += M_PI;
p2.x = p1.x + cos( data.staangle ) * data.radious;
p2.y = p1.y + sin( data.staangle ) * data.radious;
double angle = ( ea - data.staangle ) * 180.0 / M_PI;
IDF_SEGMENT* seg = new IDF_SEGMENT( p1, p2, angle, true );
if( !seg )
{
std::cerr << "* FAULT: could not add a linear segment to the outline\n";
}
else
{
lines.push_back( seg );
}
return;
}
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() )
{
std::cerr << "* DXF2IDF::WriteOutline(): no valid outline in file\n";
return false;
}
if( !lines.empty() )
{
std::cerr << "* DXF2IDF::WriteOutline(): WARNING: more than 1 outline in file\n";
std::cerr << "* Only the first outline will be used\n";
}
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() )
{
std::cerr << "* DXF2IDF::WriteOutline(): bad outline\n";
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;
}
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014 Cirilo Bernardo
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef DXF2IDF_H
#define DXF2IDF_H
#include <string>
#include <drw_interface.h>
#include <idf_common.h>
class DXF2IDF : public DRW_Interface
{
private:
std::list< IDF_SEGMENT* > lines; // Unsorted list of graphical segments
public:
~DXF2IDF();
bool ReadDxf( const std::string aFile );
bool WriteOutline( FILE* aFile, bool isInch );
private:
// DRW_Interface implemented callback functions
virtual void addLine(const DRW_Line& data);
virtual void addArc(const DRW_Arc& data );
virtual void addCircle(const DRW_Circle& data );
// DRW_Interface callbacks unsupported by DXF2IDF
virtual void addHeader( const DRW_Header* data ){}
virtual void addLType( const DRW_LType& data ){}
virtual void addLayer( const DRW_Layer& data ){}
virtual void addDimStyle( const DRW_Dimstyle& data ){}
virtual void addVport(const DRW_Vport& data){}
virtual void addTextStyle(const DRW_Textstyle& data){}
virtual void addBlock(const DRW_Block& data ){}
virtual void setBlock(const int handle){}
virtual void endBlock(){}
virtual void addPoint(const DRW_Point& data ){}
virtual void addRay(const DRW_Ray& data ){}
virtual void addXline(const DRW_Xline& data ){}
virtual void addEllipse(const DRW_Ellipse& data ){}
virtual void addLWPolyline(const DRW_LWPolyline& data ){}
virtual void addPolyline(const DRW_Polyline& data ){}
virtual void addSpline(const DRW_Spline* data ){}
virtual void addKnot(const DRW_Entity&){}
virtual void addInsert(const DRW_Insert& data ){}
virtual void addTrace(const DRW_Trace& data ){}
virtual void add3dFace(const DRW_3Dface& data ){}
virtual void addSolid(const DRW_Solid& data ){}
virtual void addMText(const DRW_MText& data){}
virtual void addText(const DRW_Text& data ){}
virtual void addDimAlign(const DRW_DimAligned *data ){}
virtual void addDimLinear(const DRW_DimLinear *data ){}
virtual void addDimRadial(const DRW_DimRadial *data ){}
virtual void addDimDiametric(const DRW_DimDiametric *data ){}
virtual void addDimAngular(const DRW_DimAngular *data ){}
virtual void addDimAngular3P(const DRW_DimAngular3p *data ){}
virtual void addDimOrdinate(const DRW_DimOrdinate *data ){}
virtual void addLeader(const DRW_Leader *data ){}
virtual void addHatch(const DRW_Hatch* data ){}
virtual void addViewport(const DRW_Viewport& data){}
virtual void addImage(const DRW_Image* data ){}
virtual void linkImage(const DRW_ImageDef* data ){}
virtual void addComment(const char*){}
virtual void writeHeader(DRW_Header& data){}
virtual void writeBlocks(){}
virtual void writeBlockRecords(){}
virtual void writeEntities(){}
virtual void writeLTypes(){}
virtual void writeLayers(){}
virtual void writeTextstyles(){}
virtual void writeVports(){}
virtual void writeDimstyles(){}
};
#endif // DXF2IDF_H
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014 Cirilo Bernardo
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <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; // 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 );
if( (tstr >> height ) && 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;
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment