Browse Source
REMOVED: standalone IDF utils
REMOVED: standalone IDF utils
These were vestigial and not necessary Fold IDF code into common Migrate enums to enum classesmaster
44 changed files with 466 additions and 4209 deletions
-
4CMakeLists.txt
-
8common/CMakeLists.txt
-
185common/io/idf/idf_common.cpp
-
24common/io/idf/idf_common.h
-
64common/io/idf/idf_helpers.cpp
-
2common/io/idf/idf_helpers.h
-
320common/io/idf/idf_outlines.cpp
-
2common/io/idf/idf_outlines.h
-
249common/io/idf/idf_parser.cpp
-
9common/io/idf/idf_parser.h
-
2common/io/idf/vrml_layer.cpp
-
0common/io/idf/vrml_layer.h
-
1pcbnew/CMakeLists.txt
-
1pcbnew/drc/rule_editor/panel_drc_rule_editor.cpp
-
30pcbnew/exporters/export_idf.cpp
-
2pcbnew/exporters/exporter_vrml.cpp
-
2pcbnew/pcb_io/odbpp/odb_util.cpp
-
6plugins/3d/idf/CMakeLists.txt
-
12plugins/3d/idf/s3d_plugin_idf.cpp
-
1qa/fuzz/CMakeLists.txt
-
1qa/pcbnew_utils/CMakeLists.txt
-
1qa/tests/api/CMakeLists.txt
-
1qa/tests/pcbnew/CMakeLists.txt
-
1qa/tools/drc_benchmark/CMakeLists.txt
-
1qa/tools/drc_proto/CMakeLists.txt
-
1qa/tools/ibis/CMakeLists.txt
-
1qa/tools/pcbnew_tools/CMakeLists.txt
-
2qa/tools/pns/CMakeLists.txt
-
4utils/CMakeLists.txt
-
58utils/idftools/CMakeLists.txt
-
404utils/idftools/dxf2idf.cpp
-
88utils/idftools/dxf2idf.h
-
197utils/idftools/dxf2idfmain.cpp
-
970utils/idftools/idf2vrml.cpp
-
681utils/idftools/idf_cylinder.cpp
-
149utils/idftools/idf_examples/Arduino_MEGA_2560-Rev3.emn
-
4utils/idftools/idf_examples/Arduino_MEGA_2560-Rev3.emp
-
269utils/idftools/idf_examples/idf_example.emn
-
69utils/idftools/idf_examples/idf_example.emp
-
45utils/idftools/idf_examples/test_donut.emn
-
5utils/idftools/idf_examples/test_donut.emp
-
71utils/idftools/idf_examples/test_idf2.emn
-
290utils/idftools/idf_examples/test_idf2.emp
-
438utils/idftools/idf_rect.cpp
@ -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() |
|||
@ -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 ); |
|||
} |
|||
@ -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 |
|||
@ -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; |
|||
} |
|||
@ -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; |
|||
} |
|||
@ -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 ); |
|||
} |
|||
} |
|||
@ -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 |
|||
@ -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 |
|||
|
|||
@ -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 |
|||
@ -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 |
|||
@ -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 |
|||
@ -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 |
|||
@ -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 |
|||
@ -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 |
|||
|
|||
@ -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 ); |
|||
} |
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue