IDF code housekeeping.
This commit is contained in:
parent
c0f12cf8b0
commit
05a5a2416a
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2014 Cirilo Bernardo
|
||||
* Copyright (C) 2018-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2018-2021 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
|
||||
|
@ -36,6 +36,7 @@
|
|||
#define MIN_BULGE 0.002
|
||||
#define MAX_BULGE 2000.0
|
||||
|
||||
|
||||
DXF2IDF::~DXF2IDF()
|
||||
{
|
||||
while( !lines.empty() )
|
||||
|
@ -71,7 +72,6 @@ void DXF2IDF::addLine( const DL_LineData& aData )
|
|||
p2.y = aData.y2 * m_scale;
|
||||
|
||||
insertLine( p1, p2 );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
@ -89,8 +89,6 @@ void DXF2IDF::addCircle( const DL_CircleData& aData )
|
|||
|
||||
if( seg )
|
||||
lines.push_back( seg );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
@ -116,8 +114,6 @@ void DXF2IDF::addArc( const DL_ArcData& aData )
|
|||
|
||||
if( seg )
|
||||
lines.push_back( seg );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
@ -156,24 +152,22 @@ bool DXF2IDF::WriteOutline( FILE* aFile, bool isInch )
|
|||
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 );
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
|
@ -185,43 +179,37 @@ bool DXF2IDF::WriteOutline( FILE* aFile, bool isInch )
|
|||
eo = outline.end();
|
||||
|
||||
// for the first item we write out both points
|
||||
if( (*bo)->angle < MIN_ANG && (*bo)->angle > -MIN_ANG )
|
||||
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) );
|
||||
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 );
|
||||
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 );
|
||||
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 );
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -232,31 +220,28 @@ bool DXF2IDF::WriteOutline( FILE* aFile, bool isInch )
|
|||
{
|
||||
if( isInch )
|
||||
{
|
||||
if( (*bo)->angle < MIN_ANG && (*bo)->angle > -MIN_ANG )
|
||||
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) );
|
||||
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 );
|
||||
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 )
|
||||
if( ( *bo )->angle < MIN_ANG && ( *bo )->angle > -MIN_ANG )
|
||||
{
|
||||
fprintf( aFile, "%c %.5f %.5f 0\n", loopDir,
|
||||
(*bo)->endPoint.x, (*bo)->endPoint.y );
|
||||
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 );
|
||||
fprintf( aFile, "%c %.5f %.5f %.2f\n", loopDir, ( *bo )->endPoint.x,
|
||||
( *bo )->endPoint.y, ( *bo )->angle );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -336,8 +321,6 @@ void DXF2IDF::setVariableInt( const std::string& key, int value, int code )
|
|||
m_scale = 1.0;
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -400,20 +383,16 @@ void DXF2IDF::endEntity()
|
|||
}
|
||||
|
||||
|
||||
|
||||
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 );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void DXF2IDF::insertArc( const IDF_POINT& aSegStart, const IDF_POINT& aSegEnd,
|
||||
double aBulge )
|
||||
void DXF2IDF::insertArc( const IDF_POINT& aSegStart, const IDF_POINT& aSegEnd, double aBulge )
|
||||
{
|
||||
if( aBulge < -MAX_BULGE )
|
||||
aBulge = -MAX_BULGE;
|
||||
|
@ -426,6 +405,4 @@ void DXF2IDF::insertArc( const IDF_POINT& aSegStart, const IDF_POINT& aSegEnd,
|
|||
|
||||
if( seg )
|
||||
lines.push_back( seg );
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2014 Cirilo Bernardo
|
||||
* Copyright (C) 2018 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2018-2021 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
|
||||
|
@ -32,22 +32,6 @@
|
|||
|
||||
class DXF2IDF : public DL_CreationAdapter
|
||||
{
|
||||
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 od 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)
|
||||
IDF_POINT m_polylineStart; // The first point of the polyline entity, when reading a polyline (unit = mm)
|
||||
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 );
|
||||
|
||||
public:
|
||||
DXF2IDF() : m_scale( 1.0 ), m_entityType( 0 ), m_entityParseStatus( 0 ),
|
||||
m_entity_flags( 0 ), m_bulgeVertex( 0.0 ) {};
|
||||
|
@ -62,14 +46,17 @@ private:
|
|||
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 */
|
||||
|
||||
/**
|
||||
* 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 {};
|
||||
int code ) override {};
|
||||
|
||||
/**
|
||||
* Called for every int variable in the DXF file (e.g. "$ACADMAINTVER").
|
||||
|
@ -82,6 +69,24 @@ private:
|
|||
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,7 +1,8 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2014 Cirilo Bernardo
|
||||
* Copyright (C) 2014 Cirilo Bernardo
|
||||
* Copyright (C) 2021 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
|
||||
|
@ -61,6 +62,7 @@ int main( int argc, char **argv )
|
|||
}
|
||||
|
||||
line.clear();
|
||||
|
||||
while( line.empty() || line.find( ".dxf" ) == string::npos )
|
||||
{
|
||||
cout << "* DXF filename: ";
|
||||
|
@ -68,9 +70,11 @@ int main( int argc, char **argv )
|
|||
line.clear();
|
||||
std::getline( cin, line );
|
||||
}
|
||||
|
||||
dname = line;
|
||||
|
||||
line.clear();
|
||||
|
||||
while( line.compare( "mm" ) && line.compare( "in" )
|
||||
&& line.compare( "MM" ) && line.compare( "IN" ) )
|
||||
{
|
||||
|
@ -83,6 +87,7 @@ int main( int argc, char **argv )
|
|||
inch = true;
|
||||
|
||||
line.clear();
|
||||
|
||||
while( line.empty() )
|
||||
{
|
||||
cout << "* Geometry name: ";
|
||||
|
@ -95,9 +100,11 @@ int main( int argc, char **argv )
|
|||
line.clear();
|
||||
}
|
||||
}
|
||||
|
||||
gname = line;
|
||||
|
||||
line.clear();
|
||||
|
||||
while( line.empty() )
|
||||
{
|
||||
cout << "* Part name: ";
|
||||
|
@ -110,9 +117,11 @@ int main( int argc, char **argv )
|
|||
line.clear();
|
||||
}
|
||||
}
|
||||
|
||||
pname = line;
|
||||
|
||||
ok = false;
|
||||
|
||||
while( !ok )
|
||||
{
|
||||
cout << "* Height: ";
|
||||
|
@ -124,6 +133,7 @@ int main( int argc, char **argv )
|
|||
tstr.str( line );
|
||||
|
||||
tstr >> height;
|
||||
|
||||
if( !tstr.fail() && height > 0.001 )
|
||||
ok = true;
|
||||
}
|
||||
|
@ -131,6 +141,7 @@ int main( int argc, char **argv )
|
|||
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();
|
||||
|
@ -150,6 +161,7 @@ int main( int argc, char **argv )
|
|||
}
|
||||
|
||||
line.clear();
|
||||
|
||||
while( line.empty() || line.find( ".idf" ) == string::npos )
|
||||
{
|
||||
cout << "* File name (*.idf): ";
|
||||
|
@ -176,15 +188,14 @@ int main( int argc, char **argv )
|
|||
fprintf( fp, ".ELECTRICAL\n" );
|
||||
|
||||
if( inch )
|
||||
fprintf( fp, "\"%s\" \"%s\" THOU %d\n", gname.c_str(),
|
||||
pname.c_str(), (int) (height * 1000.0) );
|
||||
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 );
|
||||
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,9 +1,10 @@
|
|||
/**
|
||||
/*
|
||||
* file: idf_common.cpp
|
||||
*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2013-2017 Cirilo Bernardo
|
||||
* Copyright (C) 2013-2017 Cirilo Bernardo
|
||||
* Copyright (C) 2021 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
|
||||
|
@ -62,8 +63,6 @@ IDF_ERROR::IDF_ERROR( const char* aSourceFile, const char* aSourceMethod, int aS
|
|||
|
||||
ostr << aMessage;
|
||||
message = ostr.str();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
@ -122,7 +121,8 @@ bool IDF_NOTE::readNote( std::istream& aBoardFile, IDF3::FILE_STATE& aBoardState
|
|||
aBoardState = IDF3::FILE_INVALID;
|
||||
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
|
||||
"invalid IDFv3 file\n"
|
||||
"* Violation of specification: X position in NOTES section must not be in quotes" ) );
|
||||
"* Violation of specification: X position in NOTES section must not be "
|
||||
"in quotes" ) );
|
||||
}
|
||||
|
||||
if( CompareToken( ".END_NOTES", token ) )
|
||||
|
@ -132,12 +132,14 @@ bool IDF_NOTE::readNote( std::istream& aBoardFile, IDF3::FILE_STATE& aBoardState
|
|||
istr.str( token );
|
||||
|
||||
istr >> xpos;
|
||||
|
||||
if( istr.fail() )
|
||||
{
|
||||
aBoardState = IDF3::FILE_INVALID;
|
||||
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
|
||||
"invalid IDFv3 file\n"
|
||||
"* Violation of specification: X position in NOTES section is not numeric" ) );
|
||||
"* Violation of specification: X position in NOTES section is not "
|
||||
"numeric" ) );
|
||||
}
|
||||
|
||||
if( !GetIDFString( iline, token, quoted, idx ) )
|
||||
|
@ -145,7 +147,8 @@ bool IDF_NOTE::readNote( std::istream& aBoardFile, IDF3::FILE_STATE& aBoardState
|
|||
aBoardState = IDF3::FILE_INVALID;
|
||||
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
|
||||
"invalid IDFv3 file\n"
|
||||
"* Violation of specification: Y position in NOTES section is missing" ) );
|
||||
"* Violation of specification: Y position in NOTES section is "
|
||||
"missing" ) );
|
||||
}
|
||||
|
||||
if( quoted )
|
||||
|
@ -153,19 +156,22 @@ bool IDF_NOTE::readNote( std::istream& aBoardFile, IDF3::FILE_STATE& aBoardState
|
|||
aBoardState = IDF3::FILE_INVALID;
|
||||
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
|
||||
"invalid IDFv3 file\n"
|
||||
"* Violation of specification: Y position in NOTES section must not be in quotes" ) );
|
||||
"* Violation of specification: Y position in NOTES section must not be "
|
||||
"in quotes" ) );
|
||||
}
|
||||
|
||||
istr.clear();
|
||||
istr.str( token );
|
||||
|
||||
istr >> ypos;
|
||||
|
||||
if( istr.fail() )
|
||||
{
|
||||
aBoardState = IDF3::FILE_INVALID;
|
||||
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
|
||||
"invalid IDFv3 file\n"
|
||||
"* Violation of specification: Y position in NOTES section is not numeric" ) );
|
||||
"* Violation of specification: Y position in NOTES section is not "
|
||||
"numeric" ) );
|
||||
}
|
||||
|
||||
if( !GetIDFString( iline, token, quoted, idx ) )
|
||||
|
@ -173,7 +179,8 @@ bool IDF_NOTE::readNote( std::istream& aBoardFile, IDF3::FILE_STATE& aBoardState
|
|||
aBoardState = IDF3::FILE_INVALID;
|
||||
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
|
||||
"invalid IDFv3 file\n"
|
||||
"* Violation of specification: text height in NOTES section is missing" ) );
|
||||
"* Violation of specification: text height in NOTES section is "
|
||||
"missing" ) );
|
||||
}
|
||||
|
||||
if( quoted )
|
||||
|
@ -181,19 +188,22 @@ bool IDF_NOTE::readNote( std::istream& aBoardFile, IDF3::FILE_STATE& aBoardState
|
|||
aBoardState = IDF3::FILE_INVALID;
|
||||
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
|
||||
"invalid IDFv3 file\n"
|
||||
"* Violation of specification: text height in NOTES section must not be in quotes" ) );
|
||||
"* Violation of specification: text height in NOTES section must not "
|
||||
"be in quotes" ) );
|
||||
}
|
||||
|
||||
istr.clear();
|
||||
istr.str( token );
|
||||
|
||||
istr >> height;
|
||||
|
||||
if( istr.fail() )
|
||||
{
|
||||
aBoardState = IDF3::FILE_INVALID;
|
||||
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
|
||||
"invalid IDFv3 file\n"
|
||||
"* Violation of specification: text height in NOTES section is not numeric" ) );
|
||||
"* Violation of specification: text height in NOTES section is not "
|
||||
"numeric" ) );
|
||||
}
|
||||
|
||||
if( !GetIDFString( iline, token, quoted, idx ) )
|
||||
|
@ -201,7 +211,8 @@ bool IDF_NOTE::readNote( std::istream& aBoardFile, IDF3::FILE_STATE& aBoardState
|
|||
aBoardState = IDF3::FILE_INVALID;
|
||||
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
|
||||
"invalid IDFv3 file\n"
|
||||
"* Violation of specification: text length in NOTES section is missing" ) );
|
||||
"* Violation of specification: text length in NOTES section is "
|
||||
"missing" ) );
|
||||
}
|
||||
|
||||
if( quoted )
|
||||
|
@ -209,19 +220,22 @@ bool IDF_NOTE::readNote( std::istream& aBoardFile, IDF3::FILE_STATE& aBoardState
|
|||
aBoardState = IDF3::FILE_INVALID;
|
||||
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
|
||||
"invalid IDFv3 file\n"
|
||||
"* Violation of specification: text length in NOTES section must not be in quotes" ) );
|
||||
"* Violation of specification: text length in NOTES section must not "
|
||||
"be in quotes" ) );
|
||||
}
|
||||
|
||||
istr.clear();
|
||||
istr.str( token );
|
||||
|
||||
istr >> length;
|
||||
|
||||
if( istr.fail() )
|
||||
{
|
||||
aBoardState = IDF3::FILE_INVALID;
|
||||
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
|
||||
"invalid IDFv3 file\n"
|
||||
"* Violation of specification: text length in NOTES section is not numeric" ) );
|
||||
"* Violation of specification: text length in NOTES section is not "
|
||||
"numeric" ) );
|
||||
}
|
||||
|
||||
if( !GetIDFString( iline, token, quoted, idx ) )
|
||||
|
@ -229,7 +243,8 @@ bool IDF_NOTE::readNote( std::istream& aBoardFile, IDF3::FILE_STATE& aBoardState
|
|||
aBoardState = IDF3::FILE_INVALID;
|
||||
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
|
||||
"invalid IDFv3 file\n"
|
||||
"* Violation of specification: text value in NOTES section is missing" ) );
|
||||
"* Violation of specification: text value in NOTES section is "
|
||||
"missing" ) );
|
||||
}
|
||||
|
||||
text = token;
|
||||
|
@ -250,16 +265,14 @@ bool IDF_NOTE::writeNote( std::ostream& aBoardFile, IDF3::IDF_UNIT aBoardUnit )
|
|||
{
|
||||
if( aBoardUnit == UNIT_THOU )
|
||||
{
|
||||
aBoardFile << setiosflags(ios::fixed) << setprecision(1)
|
||||
<< (xpos / IDF_THOU_TO_MM) << " "
|
||||
<< (ypos / IDF_THOU_TO_MM) << " "
|
||||
<< (height / IDF_THOU_TO_MM) << " "
|
||||
<< (length / IDF_THOU_TO_MM) << " ";
|
||||
aBoardFile << setiosflags( ios::fixed ) << setprecision( 1 ) << ( xpos / IDF_THOU_TO_MM )
|
||||
<< " " << ( ypos / IDF_THOU_TO_MM ) << " " << ( height / IDF_THOU_TO_MM ) << " "
|
||||
<< ( length / IDF_THOU_TO_MM ) << " ";
|
||||
}
|
||||
else
|
||||
{
|
||||
aBoardFile << setiosflags(ios::fixed) << setprecision(5)
|
||||
<< xpos << " " << ypos << " " << height << " " << length << " ";
|
||||
aBoardFile << setiosflags( ios::fixed ) << setprecision( 5 ) << xpos << " " << ypos << " "
|
||||
<< height << " " << length << " ";
|
||||
}
|
||||
|
||||
aBoardFile << "\"" << text << "\"\n";
|
||||
|
@ -273,29 +286,34 @@ void IDF_NOTE::SetText( const std::string& aText )
|
|||
text = aText;
|
||||
}
|
||||
|
||||
|
||||
void IDF_NOTE::SetPosition( double aXpos, double aYpos )
|
||||
{
|
||||
xpos = aXpos;
|
||||
ypos = aYpos;
|
||||
}
|
||||
|
||||
|
||||
void IDF_NOTE::SetSize( double aHeight, double aLength )
|
||||
{
|
||||
height = aHeight;
|
||||
length = aLength;
|
||||
}
|
||||
|
||||
|
||||
const std::string& IDF_NOTE::GetText()
|
||||
{
|
||||
return text;
|
||||
}
|
||||
|
||||
|
||||
void IDF_NOTE::GetPosition( double& aXpos, double& aYpos )
|
||||
{
|
||||
aXpos = xpos;
|
||||
aYpos = ypos;
|
||||
}
|
||||
|
||||
|
||||
void IDF_NOTE::GetSize( double& aHeight, double& aLength )
|
||||
{
|
||||
aHeight = height;
|
||||
|
@ -303,9 +321,6 @@ void IDF_NOTE::GetSize( double& aHeight, double& aLength )
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* IDF_DRILL_DATA
|
||||
*/
|
||||
IDF_DRILL_DATA::IDF_DRILL_DATA() :
|
||||
dia( 0.0 ),
|
||||
x( 0.0 ),
|
||||
|
@ -319,10 +334,8 @@ IDF_DRILL_DATA::IDF_DRILL_DATA() :
|
|||
|
||||
|
||||
IDF_DRILL_DATA::IDF_DRILL_DATA( double aDrillDia, double aPosX, double aPosY,
|
||||
IDF3::KEY_PLATING aPlating,
|
||||
const std::string& aRefDes,
|
||||
const std::string& aHoleType,
|
||||
IDF3::KEY_OWNER aOwner )
|
||||
IDF3::KEY_PLATING aPlating, const std::string& aRefDes,
|
||||
const std::string& aHoleType, IDF3::KEY_OWNER aOwner )
|
||||
{
|
||||
if( aDrillDia < 0.3 )
|
||||
dia = 0.3;
|
||||
|
@ -374,7 +387,8 @@ IDF_DRILL_DATA::IDF_DRILL_DATA( double aDrillDia, double aPosX, double aPosY,
|
|||
}
|
||||
|
||||
owner = aOwner;
|
||||
} // IDF_DRILL_DATA::IDF_DRILL_DATA( ... )
|
||||
}
|
||||
|
||||
|
||||
bool IDF_DRILL_DATA::Matches( double aDrillDia, double aPosX, double aPosY ) const
|
||||
{
|
||||
|
@ -392,6 +406,7 @@ bool IDF_DRILL_DATA::Matches( double aDrillDia, double aPosX, double aPosY ) con
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool IDF_DRILL_DATA::read( std::istream& aBoardFile, IDF3::IDF_UNIT aBoardUnit,
|
||||
IDF3::FILE_STATE aBoardState, IDF3::IDF_VERSION aIdfVersion )
|
||||
{
|
||||
|
@ -415,7 +430,8 @@ bool IDF_DRILL_DATA::read( std::istream& aBoardFile, IDF3::IDF_UNIT aBoardUnit,
|
|||
{
|
||||
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
|
||||
"invalid IDF file\n"
|
||||
"* Violation of specification: comment within a section (DRILLED HOLES)" ) );
|
||||
"* Violation of specification: comment within a section (DRILLED "
|
||||
"HOLES)" ) );
|
||||
}
|
||||
|
||||
idx = 0;
|
||||
|
@ -435,6 +451,7 @@ bool IDF_DRILL_DATA::read( std::istream& aBoardFile, IDF3::IDF_UNIT aBoardUnit,
|
|||
istr.str( token );
|
||||
|
||||
istr >> dia;
|
||||
|
||||
if( istr.fail() )
|
||||
{
|
||||
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
|
||||
|
@ -464,18 +481,21 @@ bool IDF_DRILL_DATA::read( std::istream& aBoardFile, IDF3::IDF_UNIT aBoardUnit,
|
|||
{
|
||||
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
|
||||
"invalid IDF file\n"
|
||||
"* Violation of specification: X position in DRILLED HOLES section must not be in quotes" ) );
|
||||
"* Violation of specification: X position in DRILLED HOLES section "
|
||||
"must not be in quotes" ) );
|
||||
}
|
||||
|
||||
istr.clear();
|
||||
istr.str( token );
|
||||
|
||||
istr >> x;
|
||||
|
||||
if( istr.fail() )
|
||||
{
|
||||
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
|
||||
"invalid IDF file\n"
|
||||
"* Violation of specification: X position in DRILLED HOLES section is not numeric" ) );
|
||||
"* Violation of specification: X position in DRILLED HOLES section is "
|
||||
"not numeric" ) );
|
||||
}
|
||||
|
||||
if( !GetIDFString( iline, token, quoted, idx ) )
|
||||
|
@ -489,18 +509,21 @@ bool IDF_DRILL_DATA::read( std::istream& aBoardFile, IDF3::IDF_UNIT aBoardUnit,
|
|||
{
|
||||
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
|
||||
"invalid IDF file\n"
|
||||
"* Violation of specification: Y position in DRILLED HOLES section must not be in quotes" ) );
|
||||
"* Violation of specification: Y position in DRILLED HOLES section "
|
||||
"must not be in quotes" ) );
|
||||
}
|
||||
|
||||
istr.clear();
|
||||
istr.str( token );
|
||||
|
||||
istr >> y;
|
||||
|
||||
if( istr.fail() )
|
||||
{
|
||||
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
|
||||
"invalid IDF file\n"
|
||||
"* Violation of specification: Y position in DRILLED HOLES section is not numeric" ) );
|
||||
"* Violation of specification: Y position in DRILLED HOLES section is "
|
||||
"not numeric" ) );
|
||||
}
|
||||
|
||||
if( aIdfVersion > IDF_V2 )
|
||||
|
@ -546,7 +569,8 @@ bool IDF_DRILL_DATA::read( std::istream& aBoardFile, IDF3::IDF_UNIT aBoardUnit,
|
|||
{
|
||||
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
|
||||
"invalid IDFv2 file\n"
|
||||
"* Violation of specification: missing HOLE TYPE for drilled hole" ) );
|
||||
"* Violation of specification: missing HOLE TYPE for drilled "
|
||||
"hole" ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -558,7 +582,8 @@ bool IDF_DRILL_DATA::read( std::istream& aBoardFile, IDF3::IDF_UNIT aBoardUnit,
|
|||
{
|
||||
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
|
||||
"invalid IDFv3 file\n"
|
||||
"* Violation of specification: missing HOLE TYPE for drilled hole" ) );
|
||||
"* Violation of specification: missing HOLE TYPE for drilled "
|
||||
"hole" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -631,7 +656,8 @@ bool IDF_DRILL_DATA::read( std::istream& aBoardFile, IDF3::IDF_UNIT aBoardUnit,
|
|||
{
|
||||
ostringstream ostr;
|
||||
ostr << "invalid IDFv3 file\n";
|
||||
ostr << "* Violation of specification: invalid OWNER for drilled hole ('" << token << "')";
|
||||
ostr << "* Violation of specification: invalid OWNER for drilled hole ('" << token
|
||||
<< "')";
|
||||
|
||||
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
|
||||
}
|
||||
|
@ -664,6 +690,7 @@ bool IDF_DRILL_DATA::read( std::istream& aBoardFile, IDF3::IDF_UNIT aBoardUnit,
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
void IDF_DRILL_DATA::write( std::ostream& aBoardFile, IDF3::IDF_UNIT aBoardUnit )
|
||||
{
|
||||
std::string holestr;
|
||||
|
@ -673,19 +700,19 @@ void IDF_DRILL_DATA::write( std::ostream& aBoardFile, IDF3::IDF_UNIT aBoardUnit
|
|||
|
||||
switch( khole )
|
||||
{
|
||||
case PIN: holestr = "PIN"; break;
|
||||
case VIA: holestr = "VIA"; break;
|
||||
case TOOL: holestr = "TOOL"; break;
|
||||
case OTHER: holestr = "\"" + holetype + "\""; break;
|
||||
default: holestr = "MTG"; break;
|
||||
case PIN: holestr = "PIN"; break;
|
||||
case VIA: holestr = "VIA"; break;
|
||||
case TOOL: holestr = "TOOL"; break;
|
||||
case OTHER: holestr = "\"" + holetype + "\""; break;
|
||||
default: holestr = "MTG"; break;
|
||||
}
|
||||
|
||||
switch( kref )
|
||||
{
|
||||
case BOARD: refstr = "BOARD"; break;
|
||||
case PANEL: refstr = "PANEL"; break;
|
||||
case REFDES: refstr = "\"" + refdes + "\""; break;
|
||||
default: refstr = "NOREFDES"; break;
|
||||
case BOARD: refstr = "BOARD"; break;
|
||||
case PANEL: refstr = "PANEL"; break;
|
||||
case REFDES: refstr = "\"" + refdes + "\""; break;
|
||||
default: refstr = "NOREFDES"; break;
|
||||
}
|
||||
|
||||
if( plating == PTH )
|
||||
|
@ -695,26 +722,26 @@ void IDF_DRILL_DATA::write( std::ostream& aBoardFile, IDF3::IDF_UNIT aBoardUnit
|
|||
|
||||
switch( owner )
|
||||
{
|
||||
case MCAD: ownstr = "MCAD"; break;
|
||||
case ECAD: ownstr = "ECAD"; break;
|
||||
default: ownstr = "UNOWNED"; break;
|
||||
case MCAD: ownstr = "MCAD"; break;
|
||||
case ECAD: ownstr = "ECAD"; break;
|
||||
default: ownstr = "UNOWNED"; break;
|
||||
}
|
||||
|
||||
if( aBoardUnit == UNIT_MM )
|
||||
{
|
||||
aBoardFile << std::setiosflags( std::ios::fixed ) << std::setprecision( 3 ) << dia << " "
|
||||
<< std::setprecision( 5 ) << x << " " << y << " "
|
||||
<< pltstr.c_str() << " " << refstr.c_str() << " "
|
||||
<< holestr.c_str() << " " << ownstr.c_str() << "\n";
|
||||
<< std::setprecision( 5 ) << x << " " << y << " " << pltstr.c_str() << " "
|
||||
<< refstr.c_str() << " " << holestr.c_str() << " " << ownstr.c_str() << "\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
aBoardFile << std::setiosflags( std::ios::fixed ) << std::setprecision( 1 ) << (dia / IDF_THOU_TO_MM) << " "
|
||||
<< std::setprecision( 1 ) << (x / IDF_THOU_TO_MM) << " " << (y / IDF_THOU_TO_MM) << " "
|
||||
<< pltstr.c_str() << " " << refstr.c_str() << " "
|
||||
<< holestr.c_str() << " " << ownstr.c_str() << "\n";
|
||||
aBoardFile << std::setiosflags( std::ios::fixed ) << std::setprecision( 1 )
|
||||
<< ( dia / IDF_THOU_TO_MM ) << " " << std::setprecision( 1 )
|
||||
<< ( x / IDF_THOU_TO_MM ) << " " << ( y / IDF_THOU_TO_MM ) << " "
|
||||
<< pltstr.c_str() << " " << refstr.c_str() << " " << holestr.c_str() << " "
|
||||
<< ownstr.c_str() << "\n";
|
||||
}
|
||||
} // IDF_DRILL_DATA::Write( aBoardFile, unitMM )
|
||||
}
|
||||
|
||||
|
||||
double IDF_DRILL_DATA::GetDrillDia() const
|
||||
|
@ -722,43 +749,48 @@ double IDF_DRILL_DATA::GetDrillDia() const
|
|||
return dia;
|
||||
}
|
||||
|
||||
|
||||
double IDF_DRILL_DATA::GetDrillXPos() const
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
double IDF_DRILL_DATA::GetDrillYPos() const
|
||||
{
|
||||
return y;
|
||||
}
|
||||
|
||||
|
||||
IDF3::KEY_PLATING IDF_DRILL_DATA::GetDrillPlating()
|
||||
{
|
||||
return plating;
|
||||
}
|
||||
|
||||
|
||||
const std::string& IDF_DRILL_DATA::GetDrillRefDes()
|
||||
{
|
||||
switch( kref )
|
||||
{
|
||||
case BOARD: refdes = "BOARD"; break;
|
||||
case PANEL: refdes = "PANEL"; break;
|
||||
case REFDES: break;
|
||||
default: refdes = "NOREFDES"; break;
|
||||
case BOARD: refdes = "BOARD"; break;
|
||||
case PANEL: refdes = "PANEL"; break;
|
||||
case REFDES: break;
|
||||
default: refdes = "NOREFDES"; break;
|
||||
}
|
||||
|
||||
return refdes;
|
||||
}
|
||||
|
||||
|
||||
const std::string& IDF_DRILL_DATA::GetDrillHoleType()
|
||||
{
|
||||
switch( khole )
|
||||
{
|
||||
case PIN: holetype = "PIN"; break;
|
||||
case VIA: holetype = "VIA"; break;
|
||||
case TOOL: holetype = "TOOL"; break;
|
||||
case OTHER: break;
|
||||
default: holetype = "MTG"; break;
|
||||
case PIN: holetype = "PIN"; break;
|
||||
case VIA: holetype = "VIA"; break;
|
||||
case TOOL: holetype = "TOOL"; break;
|
||||
case OTHER: break;
|
||||
default: holetype = "MTG"; break;
|
||||
}
|
||||
|
||||
return holetype;
|
||||
|
@ -770,25 +802,22 @@ void IDF3::PrintSeg( IDF_SEGMENT* aSegment )
|
|||
{
|
||||
if( aSegment->IsCircle() )
|
||||
{
|
||||
fprintf(stdout, "printSeg(): CIRCLE: C(%.3f, %.3f) P(%.3f, %.3f) rad. %.3f\n",
|
||||
aSegment->startPoint.x, aSegment->startPoint.y,
|
||||
aSegment->endPoint.x, aSegment->endPoint.y,
|
||||
aSegment->radius );
|
||||
fprintf( stdout, "printSeg(): CIRCLE: C(%.3f, %.3f) P(%.3f, %.3f) rad. %.3f\n",
|
||||
aSegment->startPoint.x, aSegment->startPoint.y, aSegment->endPoint.x,
|
||||
aSegment->endPoint.y, aSegment->radius );
|
||||
return;
|
||||
}
|
||||
|
||||
if( aSegment->angle < -MIN_ANG || aSegment->angle > MIN_ANG )
|
||||
{
|
||||
fprintf(stdout, "printSeg(): ARC: p1(%.3f, %.3f) p2(%.3f, %.3f) ang. %.3f\n",
|
||||
aSegment->startPoint.x, aSegment->startPoint.y,
|
||||
aSegment->endPoint.x, aSegment->endPoint.y,
|
||||
aSegment->angle );
|
||||
fprintf( stdout, "printSeg(): ARC: p1(%.3f, %.3f) p2(%.3f, %.3f) ang. %.3f\n",
|
||||
aSegment->startPoint.x, aSegment->startPoint.y, aSegment->endPoint.x,
|
||||
aSegment->endPoint.y, aSegment->angle );
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(stdout, "printSeg(): LINE: p1(%.3f, %.3f) p2(%.3f, %.3f)\n",
|
||||
aSegment->startPoint.x, aSegment->startPoint.y,
|
||||
aSegment->endPoint.x, aSegment->endPoint.y );
|
||||
fprintf( stdout, "printSeg(): LINE: p1(%.3f, %.3f) p2(%.3f, %.3f)\n", aSegment->startPoint.x,
|
||||
aSegment->startPoint.y, aSegment->endPoint.x, aSegment->endPoint.y );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -836,8 +865,7 @@ double IDF3::CalcAngleDeg( const IDF_POINT& aStartPoint, const IDF_POINT& aEndPo
|
|||
}
|
||||
|
||||
|
||||
void IDF3::GetOutline( std::list<IDF_SEGMENT*>& aLines,
|
||||
IDF_OUTLINE& aOutline )
|
||||
void IDF3::GetOutline( std::list<IDF_SEGMENT*>& aLines, IDF_OUTLINE& aOutline )
|
||||
{
|
||||
aOutline.Clear();
|
||||
|
||||
|
@ -869,9 +897,11 @@ void IDF3::GetOutline( std::list<IDF_SEGMENT*>& aLines,
|
|||
}
|
||||
|
||||
aOutline.push( *idx );
|
||||
|
||||
#ifdef DEBUG_IDF
|
||||
PrintSeg( *idx );
|
||||
#endif
|
||||
|
||||
aLines.erase( idx );
|
||||
|
||||
// If the item is a circle then we're done
|
||||
|
@ -900,9 +930,11 @@ void IDF3::GetOutline( std::list<IDF_SEGMENT*>& aLines,
|
|||
else
|
||||
{
|
||||
matched = true;
|
||||
|
||||
#ifdef DEBUG_IDF
|
||||
PrintSeg( *bl );
|
||||
#endif
|
||||
|
||||
aOutline.push( *bl );
|
||||
bl = aLines.erase( bl );
|
||||
}
|
||||
|
@ -932,9 +964,11 @@ void IDF3::GetOutline( std::list<IDF_SEGMENT*>& aLines,
|
|||
{
|
||||
matched = true;
|
||||
(*bl)->SwapEnds();
|
||||
|
||||
#ifdef DEBUG_IDF
|
||||
printSeg( *bl );
|
||||
#endif
|
||||
|
||||
aOutline.push( *bl );
|
||||
bl = aLines.erase( bl );
|
||||
}
|
||||
|
@ -959,9 +993,11 @@ void IDF3::GetOutline( std::list<IDF_SEGMENT*>& aLines,
|
|||
if( seg )
|
||||
{
|
||||
complete = true;
|
||||
|
||||
#ifdef DEBUG_IDF
|
||||
printSeg( seg );
|
||||
#endif
|
||||
|
||||
aOutline.push( seg );
|
||||
break;
|
||||
}
|
||||
|
@ -1009,8 +1045,8 @@ IDF_SEGMENT::IDF_SEGMENT( const IDF_POINT& aStartPoint, const IDF_POINT& aEndPoi
|
|||
{
|
||||
double diff = abs( aAngle ) - 360.0;
|
||||
|
||||
if( ( diff < MIN_ANG
|
||||
&& diff > -MIN_ANG ) || ( aAngle < MIN_ANG && aAngle > -MIN_ANG ) || (!aFromKicad) )
|
||||
if( ( diff < MIN_ANG && diff > -MIN_ANG ) || ( aAngle < MIN_ANG && aAngle > -MIN_ANG )
|
||||
|| ( !aFromKicad ) )
|
||||
{
|
||||
angle = 0.0;
|
||||
startPoint = aStartPoint;
|
||||
|
@ -1169,6 +1205,7 @@ void IDF_SEGMENT::SwapEnds()
|
|||
|
||||
// change the direction of the arc
|
||||
angle = -angle;
|
||||
|
||||
// calculate the new offset angle
|
||||
offsetAngle = IDF3::CalcAngleDeg( center, startPoint );
|
||||
}
|
||||
|
@ -1201,15 +1238,13 @@ bool IDF_OUTLINE::IsCCW()
|
|||
double a1 = outline.front()->angle;
|
||||
double a2 = outline.back()->angle;
|
||||
|
||||
if( ( a1 < -MIN_ANG || a1 > MIN_ANG )
|
||||
&& ( a2 < -MIN_ANG || a2 > MIN_ANG ) )
|
||||
if( ( a1 < -MIN_ANG || a1 > MIN_ANG ) && ( a2 < -MIN_ANG || a2 > MIN_ANG ) )
|
||||
{
|
||||
// we have 2 arcs; the winding is determined by
|
||||
// the longer cord. although the angles are in
|
||||
// degrees, there is no need to convert to radians
|
||||
// to determine the longer cord.
|
||||
if( abs( a1 * outline.front()->radius ) >=
|
||||
abs( a2 * outline.back()->radius ) )
|
||||
if( abs( a1 * outline.front()->radius ) >= abs( a2 * outline.back()->radius ) )
|
||||
{
|
||||
// winding depends on a1
|
||||
if( a1 < 0.0 )
|
||||
|
@ -1258,7 +1293,6 @@ bool IDF_OUTLINE::IsCCW()
|
|||
}
|
||||
|
||||
|
||||
// returns true if the outline is a circle
|
||||
bool IDF_OUTLINE::IsCircle()
|
||||
{
|
||||
if( outline.front()->IsCircle() )
|
||||
|
@ -1293,8 +1327,10 @@ bool IDF_OUTLINE::push( IDF_SEGMENT* item )
|
|||
// startPoint[N] != endPoint[N -1]
|
||||
ERROR_IDF << "INVALID GEOMETRY\n";
|
||||
cerr << "* disjoint segments (current start point != last end point)\n";
|
||||
cerr << "* start point: " << item->startPoint.x << ", " << item->startPoint.y << "\n";
|
||||
cerr << "* end point: " << outline.back()->endPoint.x << ", " << outline.back()->endPoint.y << "\n";
|
||||
cerr << "* start point: " << item->startPoint.x << ", " << item->startPoint.y
|
||||
<< "\n";
|
||||
cerr << "* end point: " << outline.back()->endPoint.x << ", "
|
||||
<< outline.back()->endPoint.y << "\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1311,20 +1347,18 @@ bool IDF_OUTLINE::push( IDF_SEGMENT* item )
|
|||
// arcs require special consideration since the winding depends on
|
||||
// the arc length; the arc length is adequately represented by
|
||||
// taking 2 cords from the endpoints to the midpoint of the arc.
|
||||
oang = (oang + ang / 2.0) * M_PI / 180.0;
|
||||
oang = ( oang + ang / 2.0 ) * M_PI / 180.0;
|
||||
double midx = outline.back()->center.x + radius * cos( oang );
|
||||
double midy = outline.back()->center.y + radius * sin( oang );
|
||||
|
||||
dir += ( outline.back()->endPoint.x - midx )
|
||||
* ( outline.back()->endPoint.y + midy );
|
||||
dir += ( outline.back()->endPoint.x - midx ) * ( outline.back()->endPoint.y + midy );
|
||||
|
||||
dir += ( midx - outline.back()->startPoint.x )
|
||||
* ( midy + outline.back()->startPoint.y );
|
||||
dir += ( midx - outline.back()->startPoint.x ) * ( midy + outline.back()->startPoint.y );
|
||||
}
|
||||
else
|
||||
{
|
||||
dir += ( outline.back()->endPoint.x - outline.back()->startPoint.x )
|
||||
* ( outline.back()->endPoint.y + outline.back()->startPoint.y );
|
||||
* ( outline.back()->endPoint.y + outline.back()->startPoint.y );
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +1,8 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2014 Cirilo Bernardo
|
||||
* Copyright (C) 2014 Cirilo Bernardo
|
||||
* Copyright (C) 2021 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
|
||||
|
@ -39,18 +40,16 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
void make_vcyl( bool inch, bool axial, double dia, double length,
|
||||
double z, double wireDia );
|
||||
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 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 );
|
||||
void writeRadialCyl( FILE* fp, bool inch, double dia, double length, double wireDia, double pitch,
|
||||
double lead );
|
||||
|
||||
int main( int argc, char **argv )
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
// IDF implicitly requires the C locale
|
||||
setlocale( LC_ALL, "C" );
|
||||
|
@ -81,18 +80,19 @@ int main( int argc, char **argv )
|
|||
cout << " *** only required for horizontal orientation with radial leads\n\n";
|
||||
}
|
||||
|
||||
char orientation = '\0';
|
||||
bool inch = false; // default mm
|
||||
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;
|
||||
bool axial = false;
|
||||
|
||||
stringstream tstr;
|
||||
string line;
|
||||
string line;
|
||||
|
||||
line.clear();
|
||||
|
||||
while( line.compare( "mm" ) && line.compare( "in" ) )
|
||||
{
|
||||
cout << "* Units (mm,in): ";
|
||||
|
@ -104,8 +104,9 @@ int main( int argc, char **argv )
|
|||
inch = true;
|
||||
|
||||
line.clear();
|
||||
while( line.compare( "H" ) && line.compare( "h" )
|
||||
&& line.compare( "V" ) && line.compare( "v" ) )
|
||||
|
||||
while( line.compare( "H" ) && line.compare( "h" ) && line.compare( "V" )
|
||||
&& line.compare( "v" ) )
|
||||
{
|
||||
cout << "* Orientation (H,V): ";
|
||||
line.clear();
|
||||
|
@ -140,6 +141,7 @@ int main( int argc, char **argv )
|
|||
|
||||
// cylinder dimensions
|
||||
ok = false;
|
||||
|
||||
while( !ok )
|
||||
{
|
||||
cout << "* Diameter: ";
|
||||
|
@ -151,11 +153,13 @@ int main( int argc, char **argv )
|
|||
tstr.str( line );
|
||||
|
||||
tstr >> dia;
|
||||
|
||||
if( !tstr.fail() && dia > 0.0 )
|
||||
ok = true;
|
||||
}
|
||||
|
||||
ok = false;
|
||||
|
||||
while( !ok )
|
||||
{
|
||||
cout << "* Length: ";
|
||||
|
@ -167,11 +171,13 @@ int main( int argc, char **argv )
|
|||
tstr.str( line );
|
||||
|
||||
tstr >> length;
|
||||
|
||||
if( !tstr.fail() && length > 0.0 )
|
||||
ok = true;
|
||||
}
|
||||
|
||||
ok = false;
|
||||
|
||||
while( !ok )
|
||||
{
|
||||
cout << "* Board offset: ";
|
||||
|
@ -183,11 +189,13 @@ int main( int argc, char **argv )
|
|||
tstr.str( line );
|
||||
|
||||
tstr >> extraZ;
|
||||
|
||||
if( !tstr.fail() && extraZ >= 0.0 )
|
||||
ok = true;
|
||||
}
|
||||
|
||||
ok = false;
|
||||
|
||||
while( ( axial || orientation == 'h' ) && !ok )
|
||||
{
|
||||
cout << "* Wire diameter: ";
|
||||
|
@ -199,6 +207,7 @@ int main( int argc, char **argv )
|
|||
tstr.str( line );
|
||||
|
||||
tstr >> wireDia;
|
||||
|
||||
if( !tstr.fail() && wireDia > 0.0 )
|
||||
{
|
||||
if( wireDia < dia )
|
||||
|
@ -210,14 +219,9 @@ int main( int argc, char **argv )
|
|||
|
||||
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;
|
||||
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, "" );
|
||||
|
@ -225,13 +229,12 @@ int main( int argc, char **argv )
|
|||
}
|
||||
|
||||
|
||||
void make_vcyl( bool inch, bool axial, double dia, double length,
|
||||
double z, double wireDia )
|
||||
void make_vcyl( bool inch, bool axial, double dia, double length, double z, double wireDia )
|
||||
{
|
||||
bool ok = false;
|
||||
bool left = false;
|
||||
bool ok = false;
|
||||
bool left = false;
|
||||
stringstream tstr;
|
||||
string line;
|
||||
string line;
|
||||
|
||||
double pitch = 0.0;
|
||||
|
||||
|
@ -246,9 +249,10 @@ void make_vcyl( bool inch, bool axial, double dia, double length,
|
|||
tstr.str( line );
|
||||
|
||||
tstr >> pitch;
|
||||
|
||||
if( !tstr.fail() && pitch > 0.0 )
|
||||
{
|
||||
if( (pitch - wireDia) <= (dia / 2.0) )
|
||||
if( ( pitch - wireDia ) <= ( dia / 2.0 ) )
|
||||
{
|
||||
cout << "* WARNING: Pitch must be > dia/2 + wireDia\n";
|
||||
}
|
||||
|
@ -260,6 +264,7 @@ void make_vcyl( bool inch, bool axial, double dia, double length,
|
|||
}
|
||||
|
||||
ok = false;
|
||||
|
||||
while( axial && !ok )
|
||||
{
|
||||
cout << "* Pin side (L,R): ";
|
||||
|
@ -270,10 +275,12 @@ void make_vcyl( bool inch, bool axial, double dia, double length,
|
|||
if( !line.compare( "l" ) || !line.compare( "L" ) )
|
||||
{
|
||||
left = true;
|
||||
ok = true;
|
||||
ok = true;
|
||||
}
|
||||
else if( !line.compare( "r" ) || !line.compare( "R" ) )
|
||||
{
|
||||
ok = true;
|
||||
}
|
||||
}
|
||||
|
||||
line.clear();
|
||||
|
@ -304,14 +311,14 @@ void make_vcyl( bool inch, bool axial, double dia, double length,
|
|||
|
||||
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) );
|
||||
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) );
|
||||
fprintf( fp, "# wire dia: %d THOU\n", (int) ( wireDia * 1000 ) );
|
||||
fprintf( fp, "# pitch: %d THOU\n", (int) ( pitch * 1000 ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -331,8 +338,7 @@ void make_vcyl( bool inch, bool axial, double dia, double length,
|
|||
|
||||
if( !axial )
|
||||
{
|
||||
fprintf( fp, "\"CYLV_%s_RAD\" \"D%.3f_H%.3f_Z%.3f\" ", inch ? "IN" : "MM",
|
||||
dia, length, z );
|
||||
fprintf( fp, "\"CYLV_%s_RAD\" \"D%.3f_H%.3f_Z%.3f\" ", inch ? "IN" : "MM", dia, length, z );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -341,7 +347,7 @@ void make_vcyl( bool inch, bool axial, double dia, double length,
|
|||
}
|
||||
|
||||
if( inch )
|
||||
fprintf( fp, "THOU %d\n", (int) ((length + z) * 1000) );
|
||||
fprintf( fp, "THOU %d\n", (int) ( ( length + z ) * 1000 ) );
|
||||
else
|
||||
fprintf( fp, "MM %.3f\n", length + z );
|
||||
|
||||
|
@ -350,7 +356,7 @@ void make_vcyl( bool inch, bool axial, double dia, double length,
|
|||
fprintf( fp, "0 0 0 0\n" );
|
||||
|
||||
if( inch )
|
||||
fprintf( fp, "0 %d 0 360\n", (int) (dia * 500) );
|
||||
fprintf( fp, "0 %d 0 360\n", (int) ( dia * 500 ) );
|
||||
else
|
||||
fprintf( fp, "0 %.3f 0 360\n", dia / 2.0 );
|
||||
|
||||
|
@ -369,8 +375,8 @@ void make_vcyl( bool inch, bool axial, double dia, double length,
|
|||
|
||||
if( inch )
|
||||
{
|
||||
dia *= 1000.0;
|
||||
pitch *= 1000.0;
|
||||
dia *= 1000.0;
|
||||
pitch *= 1000.0;
|
||||
wireDia *= 1000.0;
|
||||
}
|
||||
|
||||
|
@ -393,7 +399,9 @@ void make_vcyl( bool inch, bool axial, double dia, double length,
|
|||
{
|
||||
li = '1';
|
||||
fullAng = -360.0;
|
||||
for( int i = 0; i < 4; ++i ) px[i] = -px[i];
|
||||
|
||||
for( int i = 0; i < 4; ++i )
|
||||
px[i] = -px[i];
|
||||
}
|
||||
|
||||
|
||||
|
@ -403,8 +411,7 @@ void make_vcyl( bool inch, bool axial, double dia, double length,
|
|||
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 %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
|
||||
|
@ -412,27 +419,25 @@ void make_vcyl( bool inch, bool axial, double dia, double length,
|
|||
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 %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 );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void make_hcyl( 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 )
|
||||
{
|
||||
stringstream tstr;
|
||||
string line;
|
||||
string line;
|
||||
|
||||
double pitch = 0.0;
|
||||
double lead = 0.0; // lead length for radial leads
|
||||
double lead = 0.0; // lead length for radial leads
|
||||
|
||||
bool ok = false;
|
||||
|
||||
while( !ok )
|
||||
{
|
||||
if( axial )
|
||||
|
@ -447,11 +452,12 @@ void make_hcyl( bool inch, bool axial, double dia, double length,
|
|||
tstr.str( line );
|
||||
|
||||
tstr >> pitch;
|
||||
|
||||
if( !tstr.fail() && pitch > 0.0 )
|
||||
{
|
||||
if( axial )
|
||||
{
|
||||
if( (pitch - wireDia) <= length )
|
||||
if( ( pitch - wireDia ) <= length )
|
||||
{
|
||||
cout << "* WARNING: Axial pitch must be > length + wireDia\n";
|
||||
}
|
||||
|
@ -462,7 +468,7 @@ void make_hcyl( bool inch, bool axial, double dia, double length,
|
|||
}
|
||||
else
|
||||
{
|
||||
if( (pitch + wireDia) >= dia )
|
||||
if( ( pitch + wireDia ) >= dia )
|
||||
{
|
||||
cout << "* WARNING: Radial pitch must be < dia - wireDia\n";
|
||||
}
|
||||
|
@ -479,6 +485,7 @@ void make_hcyl( bool inch, bool axial, double dia, double length,
|
|||
}
|
||||
|
||||
ok = false;
|
||||
|
||||
while( !axial && !ok )
|
||||
{
|
||||
cout << "* Lead length: ";
|
||||
|
@ -490,6 +497,7 @@ void make_hcyl( bool inch, bool axial, double dia, double length,
|
|||
tstr.str( line );
|
||||
|
||||
tstr >> lead;
|
||||
|
||||
if( !tstr.fail() && lead > 0.0 )
|
||||
{
|
||||
if( lead < wireDia )
|
||||
|
@ -500,6 +508,7 @@ void make_hcyl( bool inch, bool axial, double dia, double length,
|
|||
}
|
||||
|
||||
line.clear();
|
||||
|
||||
while( line.empty() || line.find( ".idf" ) == string::npos )
|
||||
{
|
||||
cout << "* File name (*.idf): ";
|
||||
|
@ -524,13 +533,14 @@ void make_hcyl( bool inch, bool axial, double dia, double length,
|
|||
|
||||
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) );
|
||||
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) );
|
||||
fprintf( fp, "# lead: %d THOU\n", (int) ( lead * 1000 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -539,6 +549,7 @@ void make_hcyl( bool inch, bool axial, double dia, double 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 );
|
||||
}
|
||||
|
@ -547,8 +558,8 @@ void make_hcyl( bool inch, bool axial, double dia, double length,
|
|||
|
||||
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 );
|
||||
fprintf( fp, "\"CYLH_%s_AXI\" \"D%.3f_H%.3f_Z%.3f_WD%.3f_P%.3f\" ", inch ? "IN" : "MM", dia,
|
||||
length, z, wireDia, pitch );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -558,7 +569,7 @@ void make_hcyl( bool inch, bool axial, double dia, double length,
|
|||
|
||||
if( inch )
|
||||
{
|
||||
fprintf( fp, "THOU %d\n", (int) ((dia + z) * 1000) );
|
||||
fprintf( fp, "THOU %d\n", (int) ( ( dia + z ) * 1000 ) );
|
||||
dia *= 1000.0;
|
||||
length *= 1000.0;
|
||||
wireDia *= 1000.0;
|
||||
|
@ -578,12 +589,10 @@ void make_hcyl( bool inch, bool axial, double dia, double length,
|
|||
|
||||
fprintf( fp, ".END_ELECTRICAL\n" );
|
||||
fclose( fp );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void writeAxialCyl( FILE* fp, bool inch, double dia, double length,
|
||||
double wireDia, double pitch )
|
||||
|
||||
void writeAxialCyl( FILE* fp, bool inch, double dia, double length, double wireDia, double pitch )
|
||||
{
|
||||
double x1, y1;
|
||||
double x2, y2;
|
||||
|
@ -625,23 +634,20 @@ void writeAxialCyl( FILE* fp, bool inch, double dia, double length,
|
|||
fprintf( fp, "0 %.3f %.3f 0\n", -x1, y1 );
|
||||
fprintf( fp, "0 %.3f %.3f 0\n", x1, y1 );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void writeRadialCyl( FILE* fp, bool inch, double dia, double length,
|
||||
double wireDia, double pitch, double lead )
|
||||
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
|
||||
// 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;
|
||||
x2 = ( pitch + wireDia ) / 2.0;
|
||||
x3 = x2 - wireDia;
|
||||
|
||||
if( inch )
|
||||
|
@ -676,6 +682,4 @@ void writeRadialCyl( FILE* fp, bool inch, double dia, double length,
|
|||
fprintf( fp, "0 %.3f %.3f 0\n", x1, y1 );
|
||||
fprintf( fp, "0 %.3f %.3f 0\n", -x1, y1 );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2014-2017 Cirilo Bernardo
|
||||
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2020-2021 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
|
||||
|
@ -32,8 +32,9 @@
|
|||
using namespace std;
|
||||
using namespace IDF3;
|
||||
|
||||
// fetch a line from the given input file and trim the ends
|
||||
bool IDF3::FetchIDFLine( std::istream& aModel, std::string& aLine, bool& isComment, std::streampos& aFilePos )
|
||||
|
||||
bool IDF3::FetchIDFLine( std::istream& aModel, std::string& aLine, bool& isComment,
|
||||
std::streampos& aFilePos )
|
||||
{
|
||||
aLine = "";
|
||||
aFilePos = aModel.tellg();
|
||||
|
@ -68,9 +69,8 @@ bool IDF3::FetchIDFLine( std::istream& aModel, std::string& aLine, bool& isComme
|
|||
}
|
||||
|
||||
|
||||
// extract an IDF string and move the index to point to the character after the substring
|
||||
bool IDF3::GetIDFString( const std::string& aLine, std::string& aIDFString,
|
||||
bool& hasQuotes, int& aIndex )
|
||||
bool IDF3::GetIDFString( const std::string& aLine, std::string& aIDFString, bool& hasQuotes,
|
||||
int& aIndex )
|
||||
{
|
||||
// 1. drop all leading spaces
|
||||
// 2. if the first character is '"', read until the next '"',
|
||||
|
@ -97,6 +97,7 @@ bool IDF3::GetIDFString( const std::string& aLine, std::string& aIDFString,
|
|||
{
|
||||
hasQuotes = true;
|
||||
++idx;
|
||||
|
||||
while( idx < len && aLine[idx] != '"' )
|
||||
ostr << aLine[idx++];
|
||||
|
||||
|
@ -145,7 +146,6 @@ bool IDF3::CompareToken( const char* aTokenString, const std::string& aInputStri
|
|||
}
|
||||
|
||||
|
||||
// parse a string for an IDF3::KEY_OWNER
|
||||
bool IDF3::ParseOwner( const std::string& aToken, IDF3::KEY_OWNER& aOwner )
|
||||
{
|
||||
if( CompareToken( "UNOWNED", aToken ) )
|
||||
|
@ -209,35 +209,36 @@ bool IDF3::WriteLayersText( std::ostream& aBoardFile, IDF3::IDF_LAYER aLayer )
|
|||
{
|
||||
switch( aLayer )
|
||||
{
|
||||
case LYR_TOP:
|
||||
aBoardFile << "TOP";
|
||||
break;
|
||||
case LYR_TOP:
|
||||
aBoardFile << "TOP";
|
||||
break;
|
||||
|
||||
case LYR_BOTTOM:
|
||||
aBoardFile << "BOTTOM";
|
||||
break;
|
||||
case LYR_BOTTOM:
|
||||
aBoardFile << "BOTTOM";
|
||||
break;
|
||||
|
||||
case LYR_BOTH:
|
||||
aBoardFile << "BOTH";
|
||||
break;
|
||||
case LYR_BOTH:
|
||||
aBoardFile << "BOTH";
|
||||
break;
|
||||
|
||||
case LYR_INNER:
|
||||
aBoardFile << "INNER";
|
||||
break;
|
||||
case LYR_INNER:
|
||||
aBoardFile << "INNER";
|
||||
break;
|
||||
|
||||
case LYR_ALL:
|
||||
aBoardFile << "ALL";
|
||||
break;
|
||||
case LYR_ALL:
|
||||
aBoardFile << "ALL";
|
||||
break;
|
||||
|
||||
default:
|
||||
do{
|
||||
std::ostringstream ostr;
|
||||
ostr << "invalid IDF layer: " << aLayer;
|
||||
default:
|
||||
do
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
ostr << "invalid IDF layer: " << aLayer;
|
||||
|
||||
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
|
||||
} while( 0 );
|
||||
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
|
||||
} while( 0 );
|
||||
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
return !aBoardFile.fail();
|
||||
|
@ -248,20 +249,20 @@ std::string IDF3::GetPlacementString( IDF3::IDF_PLACEMENT aPlacement )
|
|||
{
|
||||
switch( aPlacement )
|
||||
{
|
||||
case PS_UNPLACED:
|
||||
return "UNPLACED";
|
||||
case PS_UNPLACED:
|
||||
return "UNPLACED";
|
||||
|
||||
case PS_PLACED:
|
||||
return "PLACED";
|
||||
case PS_PLACED:
|
||||
return "PLACED";
|
||||
|
||||
case PS_MCAD:
|
||||
return "MCAD";
|
||||
case PS_MCAD:
|
||||
return "MCAD";
|
||||
|
||||
case PS_ECAD:
|
||||
return "ECAD";
|
||||
case PS_ECAD:
|
||||
return "ECAD";
|
||||
|
||||
default:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
std::ostringstream ostr;
|
||||
|
@ -275,23 +276,23 @@ std::string IDF3::GetLayerString( IDF3::IDF_LAYER aLayer )
|
|||
{
|
||||
switch( aLayer )
|
||||
{
|
||||
case LYR_TOP:
|
||||
return "TOP";
|
||||
case LYR_TOP:
|
||||
return "TOP";
|
||||
|
||||
case LYR_BOTTOM:
|
||||
return "BOTTOM";
|
||||
case LYR_BOTTOM:
|
||||
return "BOTTOM";
|
||||
|
||||
case LYR_BOTH:
|
||||
return "BOTH";
|
||||
case LYR_BOTH:
|
||||
return "BOTH";
|
||||
|
||||
case LYR_INNER:
|
||||
return "INNER";
|
||||
case LYR_INNER:
|
||||
return "INNER";
|
||||
|
||||
case LYR_ALL:
|
||||
return "ALL";
|
||||
case LYR_ALL:
|
||||
return "ALL";
|
||||
|
||||
default:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
std::ostringstream ostr;
|
||||
|
@ -300,21 +301,22 @@ std::string IDF3::GetLayerString( IDF3::IDF_LAYER aLayer )
|
|||
return ostr.str();
|
||||
}
|
||||
|
||||
|
||||
std::string IDF3::GetOwnerString( IDF3::KEY_OWNER aOwner )
|
||||
{
|
||||
switch( aOwner )
|
||||
{
|
||||
case IDF3::UNOWNED:
|
||||
return "UNOWNED";
|
||||
case IDF3::UNOWNED:
|
||||
return "UNOWNED";
|
||||
|
||||
case IDF3::MCAD:
|
||||
return "MCAD";
|
||||
case IDF3::MCAD:
|
||||
return "MCAD";
|
||||
|
||||
case IDF3::ECAD:
|
||||
return "ECAD";
|
||||
case IDF3::ECAD:
|
||||
return "ECAD";
|
||||
|
||||
default:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ostringstream ostr;
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2014-2017 Cirilo Bernardo
|
||||
* Copyright (C) 2014-2017 Cirilo Bernardo
|
||||
* Copyright (C) 2021 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
|
||||
|
@ -30,17 +31,18 @@
|
|||
#include <idf_common.h>
|
||||
|
||||
/**
|
||||
* Macro TO_UTF8
|
||||
* converts a wxString to a UTF8 encoded C string for all wxWidgets build modes.
|
||||
* Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
|
||||
*
|
||||
* wxstring is a wxString, not a wxT() or _(). The scope of the return value
|
||||
* is very limited and volatile, but can be used with printf() style functions well.
|
||||
*
|
||||
* NOTE: Taken from KiCad include/macros.h
|
||||
*/
|
||||
#define TO_UTF8( wxstring ) ( (const char*) (wxstring).utf8_str() )
|
||||
|
||||
/**
|
||||
* function FROM_UTF8
|
||||
* converts a UTF8 encoded C string to a wxString for all wxWidgets build modes.
|
||||
* Convert a UTF8 encoded C string to a wxString for all wxWidgets build modes.
|
||||
*
|
||||
* NOTE: Taken from KiCad include/macros.h
|
||||
*/
|
||||
static inline wxString FROM_UTF8( const char* cstring )
|
||||
|
@ -70,102 +72,89 @@ namespace IDF3
|
|||
{
|
||||
|
||||
/**
|
||||
* Function FetchIDFLine
|
||||
* retrieves a single line from an IDF file and performs minimal processing. If a comment symbol
|
||||
* is encountered then it is removed and a single leading space is removed if present; all trailing
|
||||
* spaces are removed. If the line is not a comment then all leading and trailing spaces are stripped.
|
||||
* Retrieve a single line from an IDF file and performs minimal processing.
|
||||
*
|
||||
* @param aModel is an open IDFv3 file
|
||||
* @param aLine (output) is the line retrieved from the file
|
||||
* @param isComment (output) is set to true if the line is a comment
|
||||
* @param aFilePos (output) is set to the beginning of the line in case the file needs to be rewound
|
||||
* If a comment symbol is encountered then it is removed and a single leading space is removed
|
||||
* if present; all trailing spaces are removed. If the line is not a comment then all leading
|
||||
* and trailing spaces are stripped.
|
||||
*
|
||||
* @return bool: true if a line was read and was not empty; otherwise false
|
||||
* @param[in] aModel is an open IDFv3 file.
|
||||
* @param[out] aLine is the line retrieved from the file.
|
||||
* @param[out] isComment is set to true if the line is a comment.
|
||||
* @param[out] aFilePosis set to the beginning of the line in case the file needs to be rewound.
|
||||
* @return true if a line was read and was not empty; otherwise false.
|
||||
*/
|
||||
bool FetchIDFLine( std::istream& aModel, std::string& aLine, bool& isComment, std::streampos& aFilePos );
|
||||
bool FetchIDFLine( std::istream& aModel, std::string& aLine, bool& isComment,
|
||||
std::streampos& aFilePos );
|
||||
|
||||
|
||||
/**
|
||||
* Function GetIDFString
|
||||
* parses a line retrieved via FetchIDFLine() and returns the first IDF string found from the starting
|
||||
* point aIndex
|
||||
* Parse a line retrieved via FetchIDFLine() and returns the first IDF string found from the
|
||||
* starting point aIndex.
|
||||
*
|
||||
* @param aLine is the line to parse
|
||||
* @param aIDFString (output) is the IDF string retrieved
|
||||
* @param hasQuotes (output) is true if the string was in quotation marks
|
||||
* @param aIndex (input/output) is the index into the input line
|
||||
*
|
||||
* @return bool: true if a string was retrieved, otherwise false
|
||||
* @param[in] aLine is the line to parse.
|
||||
* @param[out] aIDFString is the IDF string retrieved.
|
||||
* @param[out] hasQuotes is true if the string was in quotation marks.
|
||||
* @param[in,out] aIndex is the index into the input line.
|
||||
* @return true if a string was retrieved, otherwise false.
|
||||
*/
|
||||
bool GetIDFString( const std::string& aLine, std::string& aIDFString,
|
||||
bool& hasQuotes, int& aIndex );
|
||||
bool GetIDFString( const std::string& aLine, std::string& aIDFString, bool& hasQuotes,
|
||||
int& aIndex );
|
||||
|
||||
/**
|
||||
* Function CompareToken
|
||||
* performs a case-insensitive comparison of a token string and an input string
|
||||
* Perform a case-insensitive comparison of a token string and an input string.
|
||||
*
|
||||
* @param aToken is an IDF token such as ".HEADER"
|
||||
* @param aInputString is a string typically retrieved via GetIDFString
|
||||
*
|
||||
* @return bool: true if the token and input string match
|
||||
* @param aToken is an IDF token such as ".HEADER".
|
||||
* @param aInputString is a string typically retrieved via GetIDFString.
|
||||
* @return true if the token and input string match.
|
||||
*/
|
||||
bool CompareToken( const char* aTokenString, const std::string& aInputString );
|
||||
|
||||
|
||||
/**
|
||||
* Function ParseOwner
|
||||
* parses the input string for a valid IDF Owner type
|
||||
* Parse the input string for a valid IDF Owner type.
|
||||
*
|
||||
* @param aToken is the string to be parsed
|
||||
* @param aOwner (output) is the IDF Owner class
|
||||
*
|
||||
* @return bool: true if a valid OWNER was found, otherwise false
|
||||
* @param[in] aToken is the string to be parsed.
|
||||
* @param[out] aOwner is the IDF Owner class.
|
||||
* @return true if a valid OWNER was found, otherwise false.
|
||||
*/
|
||||
bool ParseOwner( const std::string& aToken, IDF3::KEY_OWNER& aOwner );
|
||||
|
||||
|
||||
/**
|
||||
* Function ParseIDFLayer
|
||||
* parses an input string for a valid IDF layer specification
|
||||
* Parse an input string for a valid IDF layer specification.
|
||||
*
|
||||
* @param aToken is the string to be parsed
|
||||
* @param aLayer (output) is the IDF Layer type or group
|
||||
*
|
||||
* @return bool: true if a valid IDF Layer type was found, otherwise false
|
||||
* @param[in] aToken is the string to be parsed.
|
||||
* @param[out] aLayer is the IDF Layer type or group.
|
||||
* @return true if a valid IDF Layer type was found, otherwise false.
|
||||
*/
|
||||
bool ParseIDFLayer( const std::string& aToken, IDF3::IDF_LAYER& aLayer );
|
||||
|
||||
|
||||
/**
|
||||
* Function WriteLayersText
|
||||
* writes out text corresponding to the given IDF Layer type
|
||||
* Write out text corresponding to the given IDF Layer type.
|
||||
*
|
||||
* @param aBoardFile is an IDFv3 file open for output
|
||||
* @param aLayer is the IDF Layer type
|
||||
*
|
||||
* @return bool: true if the data was successfully written, otherwise false
|
||||
* @param[in] aBoardFile is an IDFv3 file open for output.
|
||||
* @param aLayer is the IDF Layer type.
|
||||
* @return true if the data was successfully written, otherwise false
|
||||
*/
|
||||
bool WriteLayersText( std::ostream& aBoardFile, IDF3::IDF_LAYER aLayer );
|
||||
|
||||
|
||||
/**
|
||||
* Function GetPlacementString
|
||||
* returns a string representing the given IDF Placement type
|
||||
* Return a string representing the given IDF Placement type.
|
||||
*
|
||||
* @param aPlacement is the IDF placement type to encode as a string
|
||||
*
|
||||
* @return string: the string representation of aPlacement
|
||||
* @param aPlacement is the IDF placement type to encode as a string.
|
||||
* @return the string representation of aPlacement.
|
||||
*/
|
||||
std::string GetPlacementString( IDF3::IDF_PLACEMENT aPlacement );
|
||||
|
||||
|
||||
/**
|
||||
* Function GetLayerString
|
||||
* returns a string representing the given IDF Layer type
|
||||
* Return a string representing the given IDF Layer type.
|
||||
*
|
||||
* @param aLayer is the IDF layer type to encode as a string
|
||||
*
|
||||
* @return string: the string representation of aLayer
|
||||
* @param aLayer is the IDF layer type to encode as a string.
|
||||
* @return the string representation of aLayer.
|
||||
*/
|
||||
std::string GetLayerString( IDF3::IDF_LAYER aLayer );
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2014 Cirilo Bernardo
|
||||
* Copyright (C) 2014 Cirilo Bernardo
|
||||
* Copyright (C) 2021 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
|
||||
|
@ -33,13 +34,11 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
void writeLeaded( FILE* fp, double width, double length,
|
||||
double wireDia, double pitch, bool inch );
|
||||
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 );
|
||||
void writeLeadless( FILE* fp, double width, double length, double chamfer, bool inch );
|
||||
|
||||
int main( int argc, char **argv )
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
// IDF implicitly requires the C locale
|
||||
setlocale( LC_ALL, "C" );
|
||||
|
@ -64,20 +63,21 @@ int main( int argc, char **argv )
|
|||
cout << " ** only required for leaded components\n\n";
|
||||
}
|
||||
|
||||
bool inch = false; // default mm
|
||||
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;
|
||||
bool leaded = false;
|
||||
bool ok = false;
|
||||
|
||||
stringstream tstr;
|
||||
string line;
|
||||
string line;
|
||||
|
||||
line.clear();
|
||||
|
||||
while( line.compare( "mm" ) && line.compare( "in" ) )
|
||||
{
|
||||
cout << "* Units (mm,in): ";
|
||||
|
@ -89,6 +89,7 @@ int main( int argc, char **argv )
|
|||
inch = true;
|
||||
|
||||
ok = false;
|
||||
|
||||
while( !ok )
|
||||
{
|
||||
cout << "* Width: ";
|
||||
|
@ -100,11 +101,13 @@ int main( int argc, char **argv )
|
|||
tstr.str( line );
|
||||
|
||||
tstr >> width;
|
||||
|
||||
if( !tstr.fail() && width >= 0.001 )
|
||||
ok = true;
|
||||
}
|
||||
|
||||
ok = false;
|
||||
|
||||
while( !ok )
|
||||
{
|
||||
cout << "* Length: ";
|
||||
|
@ -116,11 +119,13 @@ int main( int argc, char **argv )
|
|||
tstr.str( line );
|
||||
|
||||
tstr >> length;
|
||||
|
||||
if( !tstr.fail() && length > 0.0 )
|
||||
ok = true;
|
||||
}
|
||||
|
||||
ok = false;
|
||||
|
||||
while( !ok )
|
||||
{
|
||||
cout << "* Height: ";
|
||||
|
@ -132,11 +137,13 @@ int main( int argc, char **argv )
|
|||
tstr.str( line );
|
||||
|
||||
tstr >> height;
|
||||
|
||||
if( !tstr.fail() && height >= 0.001 )
|
||||
ok = true;
|
||||
}
|
||||
|
||||
ok = false;
|
||||
|
||||
while( !ok )
|
||||
{
|
||||
cout << "* Chamfer (0 for none): ";
|
||||
|
@ -148,6 +155,7 @@ int main( int argc, char **argv )
|
|||
tstr.str( line );
|
||||
|
||||
tstr >> chamfer;
|
||||
|
||||
if( !tstr.fail() && chamfer >= 0.0 )
|
||||
{
|
||||
if( chamfer > width / 3.0 || chamfer > length / 3.0 )
|
||||
|
@ -160,6 +168,7 @@ int main( int argc, char **argv )
|
|||
if( chamfer < 1e-6 )
|
||||
{
|
||||
ok = false;
|
||||
|
||||
while( !ok )
|
||||
{
|
||||
cout << "* Leaded: Y, N: ";
|
||||
|
@ -181,6 +190,7 @@ int main( int argc, char **argv )
|
|||
}
|
||||
|
||||
ok = false;
|
||||
|
||||
while( leaded && !ok )
|
||||
{
|
||||
cout << "* Wire dia.: ";
|
||||
|
@ -192,6 +202,7 @@ int main( int argc, char **argv )
|
|||
tstr.str( line );
|
||||
|
||||
tstr >> wireDia;
|
||||
|
||||
if( !tstr.fail() && wireDia >= 0.001 )
|
||||
{
|
||||
if( wireDia >= length )
|
||||
|
@ -202,6 +213,7 @@ int main( int argc, char **argv )
|
|||
}
|
||||
|
||||
ok = false;
|
||||
|
||||
while( leaded && !ok )
|
||||
{
|
||||
cout << "* Pitch: ";
|
||||
|
@ -213,6 +225,7 @@ int main( int argc, char **argv )
|
|||
tstr.str( line );
|
||||
|
||||
tstr >> pitch;
|
||||
|
||||
if( !tstr.fail() && pitch >= 0.001 )
|
||||
{
|
||||
if( pitch <= ( length + wireDia ) / 2.0 )
|
||||
|
@ -223,6 +236,7 @@ int main( int argc, char **argv )
|
|||
}
|
||||
|
||||
line.clear();
|
||||
|
||||
while( line.empty() || line.find( ".idf" ) == string::npos )
|
||||
{
|
||||
cout << "* File name (*.idf): ";
|
||||
|
@ -266,8 +280,8 @@ int main( int argc, char **argv )
|
|||
}
|
||||
|
||||
fprintf( fp, ".ELECTRICAL\n" );
|
||||
fprintf( fp, "\"RECT%sIN\" \"W%d_L%d_H%d", leaded ? "L" : "",
|
||||
(int) width, (int) length, (int) height );
|
||||
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 );
|
||||
|
@ -293,8 +307,8 @@ int main( int argc, char **argv )
|
|||
}
|
||||
|
||||
fprintf( fp, ".ELECTRICAL\n" );
|
||||
fprintf( fp, "\"RECT%sMM\" \"W%.3f_L%.3f_H%.3f_", leaded ? "L" : "",
|
||||
width, length, height );
|
||||
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 );
|
||||
|
@ -318,8 +332,7 @@ int main( int argc, char **argv )
|
|||
}
|
||||
|
||||
|
||||
void writeLeaded( FILE* fp, double width, double length,
|
||||
double wireDia, double pitch, bool inch )
|
||||
void writeLeaded( FILE* fp, double width, double length, double wireDia, double pitch, bool inch )
|
||||
{
|
||||
if( inch )
|
||||
{
|
||||
|
@ -365,12 +378,10 @@ void writeLeaded( FILE* fp, double width, double length,
|
|||
fprintf( fp, "0 %.3f %.3f 0\n", x1, -y1 );
|
||||
fprintf( fp, "0 %.3f %.3f 180\n", x1, y1 );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void writeLeadless( FILE* fp, double width, double length,
|
||||
double chamfer, bool inch )
|
||||
|
||||
void writeLeadless( FILE* fp, double width, double length, double chamfer, bool inch )
|
||||
{
|
||||
if( chamfer < 0.001 )
|
||||
{
|
||||
|
@ -428,6 +439,4 @@ void writeLeadless( FILE* fp, double width, double length,
|
|||
fprintf( fp, "0 %.3f %.3f 0\n", x, -y );
|
||||
fprintf( fp, "0 %.3f %.3f 0\n", x, y );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* file: vrml_layer.cpp
|
||||
*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* Copyright (C) 2013-2017 Cirilo Bernardo
|
||||
*
|
||||
|
@ -100,13 +101,13 @@ int VRML_LAYER::calcNSides( double aRadius, double aAngle )
|
|||
if( csides < 2 * maxSeg )
|
||||
csides /= 2;
|
||||
else
|
||||
csides = (((double) csides) * minSegLength / maxSegLength );
|
||||
csides = ( ( (double) csides ) * minSegLength / maxSegLength );
|
||||
}
|
||||
|
||||
if( csides < 3 )
|
||||
csides = 3;
|
||||
|
||||
if( (csides & 1) == 0 )
|
||||
if( ( csides & 1 ) == 0 )
|
||||
csides += 1;
|
||||
|
||||
return csides;
|
||||
|
@ -147,7 +148,7 @@ static void CALLBACK vrml_tess_err( GLenum errorID, void* user_data )
|
|||
|
||||
|
||||
static void CALLBACK vrml_tess_combine( GLdouble coords[3], VERTEX_3D* vertex_data[4],
|
||||
GLfloat weight[4], void** outData, void* user_data )
|
||||
GLfloat weight[4], void** outData, void* user_data )
|
||||
{
|
||||
VRML_LAYER* lp = (VRML_LAYER*) user_data;
|
||||
|
||||
|
@ -232,6 +233,7 @@ void VRML_LAYER::GetArcParams( int& aMaxSeg, double& aMinLength, double& aMaxLen
|
|||
aMaxLength = maxSegLength;
|
||||
}
|
||||
|
||||
|
||||
bool VRML_LAYER::SetArcParams( int aMaxSeg, double aMinLength, double aMaxLength )
|
||||
{
|
||||
if( aMaxSeg < 8 )
|
||||
|
@ -247,7 +249,6 @@ bool VRML_LAYER::SetArcParams( int aMaxSeg, double aMinLength, double aMaxLength
|
|||
}
|
||||
|
||||
|
||||
// clear all data
|
||||
void VRML_LAYER::Clear( void )
|
||||
{
|
||||
int i;
|
||||
|
@ -275,7 +276,6 @@ void VRML_LAYER::Clear( void )
|
|||
}
|
||||
|
||||
|
||||
// clear ephemeral data in between invocations of the tesselation routine
|
||||
void VRML_LAYER::clearTmp( void )
|
||||
{
|
||||
unsigned int i;
|
||||
|
@ -315,9 +315,7 @@ void VRML_LAYER::clearTmp( void )
|
|||
}
|
||||
|
||||
|
||||
// create a new contour to be populated; returns an index
|
||||
// into the contour list or -1 if there are problems
|
||||
int VRML_LAYER::NewContour( bool aPlatedHole )
|
||||
int VRML_LAYER::NewContour( bool aPlatedHole )
|
||||
{
|
||||
if( fix )
|
||||
return -1;
|
||||
|
@ -333,9 +331,6 @@ int VRML_LAYER::NewContour( bool aPlatedHole )
|
|||
}
|
||||
|
||||
|
||||
// adds a vertex to the existing list and places its index in
|
||||
// an existing contour; returns true if OK,
|
||||
// false otherwise (indexed contour does not exist)
|
||||
bool VRML_LAYER::AddVertex( int aContourID, double aXpos, double aYpos )
|
||||
{
|
||||
if( fix )
|
||||
|
@ -372,8 +367,6 @@ bool VRML_LAYER::AddVertex( int aContourID, double aXpos, double aYpos )
|
|||
}
|
||||
|
||||
|
||||
// ensure the winding of a contour with respect to the normal (0, 0, 1);
|
||||
// set 'hole' to true to ensure a hole (clockwise winding)
|
||||
bool VRML_LAYER::EnsureWinding( int aContourID, bool aHoleFlag )
|
||||
{
|
||||
if( aContourID < 0 || (unsigned int) aContourID >= contours.size() )
|
||||
|
@ -408,8 +401,7 @@ bool VRML_LAYER::EnsureWinding( int aContourID, bool aHoleFlag )
|
|||
}
|
||||
|
||||
|
||||
bool VRML_LAYER::AppendCircle( double aXpos, double aYpos,
|
||||
double aRadius, int aContourID,
|
||||
bool VRML_LAYER::AppendCircle( double aXpos, double aYpos, double aRadius, int aContourID,
|
||||
bool aHoleFlag )
|
||||
{
|
||||
if( aContourID < 0 || (unsigned int) aContourID >= contours.size() )
|
||||
|
@ -465,10 +457,8 @@ bool VRML_LAYER::AppendCircle( double aXpos, double aYpos,
|
|||
}
|
||||
|
||||
|
||||
// adds a circle to the existing list; if 'hole' is true the contour is
|
||||
// a hole. Returns true if OK.
|
||||
bool VRML_LAYER::AddCircle( double aXpos, double aYpos, double aRadius,
|
||||
bool aHoleFlag, bool aPlatedHole )
|
||||
bool VRML_LAYER::AddCircle( double aXpos, double aYpos, double aRadius, bool aHoleFlag,
|
||||
bool aPlatedHole )
|
||||
{
|
||||
int pad;
|
||||
|
||||
|
@ -487,10 +477,7 @@ bool VRML_LAYER::AddCircle( double aXpos, double aYpos, double aRadius,
|
|||
}
|
||||
|
||||
|
||||
// adds a slotted pad with orientation given by angle; if 'hole' is true the
|
||||
// contour is a hole. Returns true if OK.
|
||||
bool VRML_LAYER::AddSlot( double aCenterX, double aCenterY,
|
||||
double aSlotLength, double aSlotWidth,
|
||||
bool VRML_LAYER::AddSlot( double aCenterX, double aCenterY, double aSlotLength, double aSlotWidth,
|
||||
double aAngle, bool aHoleFlag, bool aPlatedHole )
|
||||
{
|
||||
aAngle *= M_PI / 180.0;
|
||||
|
@ -577,7 +564,7 @@ bool VRML_LAYER::AddSlot( double aCenterX, double aCenterY,
|
|||
|
||||
|
||||
bool VRML_LAYER::AddPolygon( const std::vector< wxRealPoint >& aPolySet, double aCenterX,
|
||||
double aCenterY, double aAngle )
|
||||
double aCenterY, double aAngle )
|
||||
{
|
||||
int pad = NewContour( false );
|
||||
|
||||
|
@ -639,7 +626,6 @@ bool VRML_LAYER::AppendArc( double aCenterX, double aCenterY, double aRadius,
|
|||
}
|
||||
|
||||
|
||||
// adds an arc with the given center, start point, pen width, and angle (degrees).
|
||||
bool VRML_LAYER::AddArc( double aCenterX, double aCenterY, double aStartX, double aStartY,
|
||||
double aArcWidth, double aAngle, bool aHoleFlag, bool aPlatedHole )
|
||||
{
|
||||
|
@ -754,8 +740,6 @@ bool VRML_LAYER::AddArc( double aCenterX, double aCenterY, double aStartX, doubl
|
|||
}
|
||||
|
||||
|
||||
// tesselates the contours in preparation for a 3D output;
|
||||
// returns true if all was fine, false otherwise
|
||||
bool VRML_LAYER::Tesselate( VRML_LAYER* holes, bool aHolesOnly )
|
||||
{
|
||||
if( !tess )
|
||||
|
@ -1001,7 +985,6 @@ bool VRML_LAYER::pushOutline( VRML_LAYER* holes )
|
|||
}
|
||||
|
||||
|
||||
// writes out the vertex list for a planar feature
|
||||
bool VRML_LAYER::WriteVertices( double aZcoord, std::ostream& aOutFile, int aPrecision )
|
||||
{
|
||||
if( ordmap.size() < 3 )
|
||||
|
@ -1045,10 +1028,8 @@ bool VRML_LAYER::WriteVertices( double aZcoord, std::ostream& aOutFile, int aPre
|
|||
}
|
||||
|
||||
|
||||
// writes out the vertex list for a 3D feature; top and bottom are the
|
||||
// Z values for the top and bottom; top must be > bottom
|
||||
bool VRML_LAYER::Write3DVertices( double aTopZ, double aBottomZ,
|
||||
std::ostream& aOutFile, int aPrecision )
|
||||
bool VRML_LAYER::Write3DVertices( double aTopZ, double aBottomZ, std::ostream& aOutFile,
|
||||
int aPrecision )
|
||||
{
|
||||
if( ordmap.size() < 3 )
|
||||
{
|
||||
|
@ -1132,9 +1113,6 @@ bool VRML_LAYER::Write3DVertices( double aTopZ, double aBottomZ,
|
|||
}
|
||||
|
||||
|
||||
// writes out the index list;
|
||||
// 'top' indicates the vertex ordering and should be
|
||||
// true for a polygon visible from above the PCB
|
||||
bool VRML_LAYER::WriteIndices( bool aTopFlag, std::ostream& aOutFile )
|
||||
{
|
||||
if( triplets.empty() )
|
||||
|
@ -1182,7 +1160,6 @@ bool VRML_LAYER::WriteIndices( bool aTopFlag, std::ostream& aOutFile )
|
|||
}
|
||||
|
||||
|
||||
// writes out the index list for a 3D feature
|
||||
bool VRML_LAYER::Write3DIndices( std::ostream& aOutFile, bool aIncludePlatedHoles )
|
||||
{
|
||||
if( outline.empty() )
|
||||
|
@ -1229,14 +1206,17 @@ bool VRML_LAYER::Write3DIndices( std::ostream& aOutFile, bool aIncludePlatedHole
|
|||
|
||||
while( tbeg != tend )
|
||||
{
|
||||
if( (i++ & 7) == 4 )
|
||||
if( ( i++ & 7 ) == 4 )
|
||||
{
|
||||
i = 1;
|
||||
aOutFile << ",\n" << (tbeg->i2 + idx2) << ", " << (tbeg->i1 + idx2) << ", " << (tbeg->i3 + idx2) << ", -1";
|
||||
aOutFile << ",\n"
|
||||
<< ( tbeg->i2 + idx2 ) << ", " << ( tbeg->i1 + idx2 ) << ", "
|
||||
<< ( tbeg->i3 + idx2 ) << ", -1";
|
||||
}
|
||||
else
|
||||
{
|
||||
aOutFile << ", " << (tbeg->i2 + idx2) << ", " << (tbeg->i1 + idx2) << ", " << (tbeg->i3 + idx2) << ", -1";
|
||||
aOutFile << ", " << ( tbeg->i2 + idx2 ) << ", " << ( tbeg->i1 + idx2 ) << ", "
|
||||
<< ( tbeg->i3 + idx2 ) << ", -1";
|
||||
}
|
||||
|
||||
++tbeg;
|
||||
|
@ -1245,7 +1225,6 @@ bool VRML_LAYER::Write3DIndices( std::ostream& aOutFile, bool aIncludePlatedHole
|
|||
else
|
||||
mark = ' ';
|
||||
|
||||
|
||||
// print out indices for the walls joining top to bottom
|
||||
int lastPoint;
|
||||
int curPoint;
|
||||
|
@ -1258,6 +1237,7 @@ bool VRML_LAYER::Write3DIndices( std::ostream& aOutFile, bool aIncludePlatedHole
|
|||
std::list<int>::const_iterator cend;
|
||||
|
||||
i = 2;
|
||||
|
||||
while( obeg != oend )
|
||||
{
|
||||
cp = *obeg;
|
||||
|
@ -1288,16 +1268,20 @@ bool VRML_LAYER::Write3DIndices( std::ostream& aOutFile, bool aIncludePlatedHole
|
|||
|
||||
if( !holes_only )
|
||||
{
|
||||
if( (i++ & 3) == 2 )
|
||||
if( ( i++ & 3 ) == 2 )
|
||||
{
|
||||
i = 1;
|
||||
aOutFile << mark << "\n" << curPoint << ", " << lastPoint << ", " << curPoint + idx2;
|
||||
aOutFile << ", -1, " << curPoint + idx2 << ", " << lastPoint << ", " << lastPoint + idx2 << ", -1";
|
||||
aOutFile << mark << "\n"
|
||||
<< curPoint << ", " << lastPoint << ", " << curPoint + idx2;
|
||||
aOutFile << ", -1, " << curPoint + idx2 << ", " << lastPoint << ", "
|
||||
<< lastPoint + idx2 << ", -1";
|
||||
}
|
||||
else
|
||||
{
|
||||
aOutFile << mark << " " << curPoint << ", " << lastPoint << ", " << curPoint + idx2;
|
||||
aOutFile << ", -1, " << curPoint + idx2 << ", " << lastPoint << ", " << lastPoint + idx2 << ", -1";
|
||||
aOutFile << mark << " " << curPoint << ", " << lastPoint << ", "
|
||||
<< curPoint + idx2;
|
||||
aOutFile << ", -1, " << curPoint + idx2 << ", " << lastPoint << ", "
|
||||
<< lastPoint + idx2 << ", -1";
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1305,13 +1289,17 @@ bool VRML_LAYER::Write3DIndices( std::ostream& aOutFile, bool aIncludePlatedHole
|
|||
if( (i++ & 3) == 2 )
|
||||
{
|
||||
i = 1;
|
||||
aOutFile << mark << "\n" << curPoint << ", " << curPoint + idx2 << ", " << lastPoint;
|
||||
aOutFile << ", -1, " << curPoint + idx2 << ", " << lastPoint + idx2 << ", " << lastPoint << ", -1";
|
||||
aOutFile << mark << "\n"
|
||||
<< curPoint << ", " << curPoint + idx2 << ", " << lastPoint;
|
||||
aOutFile << ", -1, " << curPoint + idx2 << ", " << lastPoint + idx2 << ", "
|
||||
<< lastPoint << ", -1";
|
||||
}
|
||||
else
|
||||
{
|
||||
aOutFile << mark << " " << curPoint << ", " << curPoint + idx2 << ", " << lastPoint;
|
||||
aOutFile << ", -1, " << curPoint + idx2 << ", " << lastPoint + idx2 << ", " << lastPoint << ", -1";
|
||||
aOutFile << mark << " " << curPoint << ", " << curPoint + idx2 << ", "
|
||||
<< lastPoint;
|
||||
aOutFile << ", -1, " << curPoint + idx2 << ", " << lastPoint + idx2 << ", "
|
||||
<< lastPoint << ", -1";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1328,28 +1316,32 @@ bool VRML_LAYER::Write3DIndices( std::ostream& aOutFile, bool aIncludePlatedHole
|
|||
|
||||
if( !holes_only )
|
||||
{
|
||||
if( (i++ & 3) == 2 )
|
||||
if( ( i++ & 3 ) == 2 )
|
||||
{
|
||||
aOutFile << ",\n" << curPoint << ", " << lastPoint << ", " << curPoint + idx2;
|
||||
aOutFile << ", -1, " << curPoint + idx2 << ", " << lastPoint << ", " << lastPoint + idx2 << ", -1";
|
||||
aOutFile << ", -1, " << curPoint + idx2 << ", " << lastPoint << ", "
|
||||
<< lastPoint + idx2 << ", -1";
|
||||
}
|
||||
else
|
||||
{
|
||||
aOutFile << ", " << curPoint << ", " << lastPoint << ", " << curPoint + idx2;
|
||||
aOutFile << ", -1, " << curPoint + idx2 << ", " << lastPoint << ", " << lastPoint + idx2 << ", -1";
|
||||
aOutFile << ", -1, " << curPoint + idx2 << ", " << lastPoint << ", "
|
||||
<< lastPoint + idx2 << ", -1";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( (i++ & 3) == 2 )
|
||||
if( ( i++ & 3 ) == 2 )
|
||||
{
|
||||
aOutFile << ",\n" << curPoint << ", " << curPoint + idx2 << ", " << lastPoint;
|
||||
aOutFile << ", -1, " << curPoint + idx2 << ", " << lastPoint + idx2 << ", " << lastPoint << ", -1";
|
||||
aOutFile << ", -1, " << curPoint + idx2 << ", " << lastPoint + idx2 << ", "
|
||||
<< lastPoint << ", -1";
|
||||
}
|
||||
else
|
||||
{
|
||||
aOutFile << ", " << curPoint << ", " << curPoint + idx2 << ", " << lastPoint;
|
||||
aOutFile << ", -1, " << curPoint + idx2 << ", " << lastPoint + idx2 << ", " << lastPoint << ", -1";
|
||||
aOutFile << ", -1, " << curPoint + idx2 << ", " << lastPoint + idx2 << ", "
|
||||
<< lastPoint << ", -1";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1361,7 +1353,6 @@ bool VRML_LAYER::Write3DIndices( std::ostream& aOutFile, bool aIncludePlatedHole
|
|||
}
|
||||
|
||||
|
||||
// add a triangular facet (triplet) to the output index list
|
||||
bool VRML_LAYER::addTriplet( VERTEX_3D* p0, VERTEX_3D* p1, VERTEX_3D* p2 )
|
||||
{
|
||||
double dx0 = p1->x - p0->x;
|
||||
|
@ -1400,7 +1391,6 @@ bool VRML_LAYER::addTriplet( VERTEX_3D* p0, VERTEX_3D* p1, VERTEX_3D* p2 )
|
|||
}
|
||||
|
||||
|
||||
// add an extra vertex (to be called only by the COMBINE callback)
|
||||
VERTEX_3D* VRML_LAYER::AddExtraVertex( double aXpos, double aYpos, bool aPlatedHole )
|
||||
{
|
||||
VERTEX_3D* vertex = new VERTEX_3D;
|
||||
|
@ -1420,7 +1410,6 @@ VERTEX_3D* VRML_LAYER::AddExtraVertex( double aXpos, double aYpos, bool aPlatedH
|
|||
}
|
||||
|
||||
|
||||
// start a GL command list
|
||||
void VRML_LAYER::glStart( GLenum cmd )
|
||||
{
|
||||
glcmd = cmd;
|
||||
|
@ -1430,7 +1419,6 @@ void VRML_LAYER::glStart( GLenum cmd )
|
|||
}
|
||||
|
||||
|
||||
// process a vertex
|
||||
void VRML_LAYER::glPushVertex( VERTEX_3D* vertex )
|
||||
{
|
||||
if( vertex->o < 0 )
|
||||
|
@ -1443,51 +1431,51 @@ void VRML_LAYER::glPushVertex( VERTEX_3D* vertex )
|
|||
}
|
||||
|
||||
|
||||
// end a GL command list
|
||||
void VRML_LAYER::glEnd( void )
|
||||
{
|
||||
switch( glcmd )
|
||||
{
|
||||
case GL_LINE_LOOP:
|
||||
{
|
||||
// add the loop to the list of outlines
|
||||
std::list<int>* loop = new std::list<int>;
|
||||
|
||||
double firstX = 0.0;
|
||||
double firstY = 0.0;
|
||||
double lastX = 0.0;
|
||||
double lastY = 0.0;
|
||||
double curX, curY;
|
||||
double area = 0.0;
|
||||
|
||||
if( vlist.size() > 0 )
|
||||
{
|
||||
// add the loop to the list of outlines
|
||||
std::list<int>* loop = new std::list<int>;
|
||||
|
||||
double firstX = 0.0;
|
||||
double firstY = 0.0;
|
||||
double lastX = 0.0;
|
||||
double lastY = 0.0;
|
||||
double curX, curY;
|
||||
double area = 0.0;
|
||||
|
||||
if( vlist.size() > 0 )
|
||||
{
|
||||
loop->push_back( vlist[0]->o );
|
||||
firstX = vlist[0]->x;
|
||||
firstY = vlist[0]->y;
|
||||
lastX = firstX;
|
||||
lastY = firstY;
|
||||
}
|
||||
|
||||
for( size_t i = 1; i < vlist.size(); ++i )
|
||||
{
|
||||
loop->push_back( vlist[i]->o );
|
||||
curX = vlist[i]->x;
|
||||
curY = vlist[i]->y;
|
||||
area += ( curX - lastX ) * ( curY + lastY );
|
||||
lastX = curX;
|
||||
lastY = curY;
|
||||
}
|
||||
|
||||
area += ( firstX - lastX ) * ( firstY + lastY );
|
||||
|
||||
outline.push_back( loop );
|
||||
|
||||
if( area <= 0.0 )
|
||||
solid.push_back( true );
|
||||
else
|
||||
solid.push_back( false );
|
||||
loop->push_back( vlist[0]->o );
|
||||
firstX = vlist[0]->x;
|
||||
firstY = vlist[0]->y;
|
||||
lastX = firstX;
|
||||
lastY = firstY;
|
||||
}
|
||||
|
||||
for( size_t i = 1; i < vlist.size(); ++i )
|
||||
{
|
||||
loop->push_back( vlist[i]->o );
|
||||
curX = vlist[i]->x;
|
||||
curY = vlist[i]->y;
|
||||
area += ( curX - lastX ) * ( curY + lastY );
|
||||
lastX = curX;
|
||||
lastY = curY;
|
||||
}
|
||||
|
||||
area += ( firstX - lastX ) * ( firstY + lastY );
|
||||
|
||||
outline.push_back( loop );
|
||||
|
||||
if( area <= 0.0 )
|
||||
solid.push_back( true );
|
||||
else
|
||||
solid.push_back( false );
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case GL_TRIANGLE_FAN:
|
||||
|
@ -1513,7 +1501,6 @@ void VRML_LAYER::glEnd( void )
|
|||
}
|
||||
|
||||
|
||||
// set the error message
|
||||
void VRML_LAYER::SetGLError( GLenum errorID )
|
||||
{
|
||||
const char * msg = (const char*)gluErrorString( errorID );
|
||||
|
@ -1533,7 +1520,6 @@ void VRML_LAYER::SetGLError( GLenum errorID )
|
|||
}
|
||||
|
||||
|
||||
// process a GL_TRIANGLE_FAN list
|
||||
void VRML_LAYER::processFan( void )
|
||||
{
|
||||
if( vlist.size() < 3 )
|
||||
|
@ -1551,7 +1537,6 @@ void VRML_LAYER::processFan( void )
|
|||
}
|
||||
|
||||
|
||||
// process a GL_TRIANGLE_STRIP list
|
||||
void VRML_LAYER::processStrip( void )
|
||||
{
|
||||
// note: (source: http://www.opengl.org/wiki/Primitive)
|
||||
|
@ -1584,7 +1569,6 @@ void VRML_LAYER::processStrip( void )
|
|||
}
|
||||
|
||||
|
||||
// process a GL_TRIANGLES list
|
||||
void VRML_LAYER::processTri( void )
|
||||
{
|
||||
// notes:
|
||||
|
@ -1624,7 +1608,6 @@ int VRML_LAYER::checkNContours( bool holes )
|
|||
}
|
||||
|
||||
|
||||
// push the internally held vertices
|
||||
void VRML_LAYER::pushVertices( bool holes )
|
||||
{
|
||||
// push the internally held vertices
|
||||
|
@ -1705,17 +1688,12 @@ VERTEX_3D* VRML_LAYER::getVertexByIndex( int aPointIndex, VRML_LAYER* holes )
|
|||
}
|
||||
|
||||
|
||||
// retrieve the total number of vertices
|
||||
int VRML_LAYER::GetSize( void )
|
||||
{
|
||||
return vertices.size();
|
||||
}
|
||||
|
||||
|
||||
// Inserts all contours into the given tesselator; this results in the
|
||||
// renumbering of all vertices from 'start'. Returns the end number.
|
||||
// Take care when using this call since tesselators cannot work on
|
||||
// the internal data concurrently
|
||||
int VRML_LAYER::Import( int start, GLUtesselator* aTesselator )
|
||||
{
|
||||
if( start < 0 )
|
||||
|
@ -1772,7 +1750,6 @@ int VRML_LAYER::Import( int start, GLUtesselator* aTesselator )
|
|||
}
|
||||
|
||||
|
||||
// return the vertex identified by index
|
||||
VERTEX_3D* VRML_LAYER::GetVertexByIndex( int aPointIndex )
|
||||
{
|
||||
int i0 = vertices[0]->i;
|
||||
|
@ -1787,7 +1764,6 @@ VERTEX_3D* VRML_LAYER::GetVertexByIndex( int aPointIndex )
|
|||
}
|
||||
|
||||
|
||||
// return the error string
|
||||
const std::string& VRML_LAYER::GetError( void )
|
||||
{
|
||||
return error;
|
||||
|
@ -1803,8 +1779,8 @@ void VRML_LAYER::SetVertexOffsets( double aXoffset, double aYoffset )
|
|||
|
||||
|
||||
bool VRML_LAYER::Get3DTriangles( std::vector< double >& aVertexList,
|
||||
std::vector< int > &aIndexPlane, std::vector< int > &aIndexSide,
|
||||
double aTopZ, double aBotZ )
|
||||
std::vector< int > &aIndexPlane, std::vector< int > &aIndexSide,
|
||||
double aTopZ, double aBotZ )
|
||||
{
|
||||
aVertexList.clear();
|
||||
aIndexPlane.clear();
|
||||
|
@ -1897,6 +1873,7 @@ bool VRML_LAYER::Get3DTriangles( std::vector< double >& aVertexList,
|
|||
std::list< int >::const_iterator cend;
|
||||
|
||||
i = 2;
|
||||
|
||||
while( obeg != oend )
|
||||
{
|
||||
cp = *obeg;
|
||||
|
@ -1977,7 +1954,7 @@ bool VRML_LAYER::Get3DTriangles( std::vector< double >& aVertexList,
|
|||
|
||||
|
||||
bool VRML_LAYER::Get2DTriangles( std::vector< double >& aVertexList,
|
||||
std::vector< int > &aIndexPlane, double aHeight, bool aTopPlane )
|
||||
std::vector< int > &aIndexPlane, double aHeight, bool aTopPlane )
|
||||
{
|
||||
aVertexList.clear();
|
||||
aIndexPlane.clear();
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2013-2017 Cirilo Bernardo
|
||||
* Copyright (C) 2013-2017 Cirilo Bernardo
|
||||
* Copyright (C) 2021 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
|
||||
|
@ -28,8 +29,7 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
* Classes and structures to support the tesselation of a
|
||||
* PCB for VRML output.
|
||||
* Classes and structures to support the tesselation of a PCB for VRML output.
|
||||
*/
|
||||
|
||||
#ifndef VRML_LAYER_H
|
||||
|
@ -92,6 +92,333 @@ struct TRIPLET_3D
|
|||
|
||||
class VRML_LAYER
|
||||
{
|
||||
public:
|
||||
VRML_LAYER();
|
||||
virtual ~VRML_LAYER();
|
||||
|
||||
/**
|
||||
* Retrieve the parameters used in calculating the number of vertices in an arc.
|
||||
*
|
||||
* @param aMaxSeg is the maximum number of segments for an arc with cords of length aMinLength.
|
||||
* @param aMinLength is the minimum length of cords in an arc.
|
||||
* @param aMaxLength is the maximum length of cords in an arc.
|
||||
*/
|
||||
void GetArcParams( int& aMaxSeg, double& aMinLength, double& aMaxLength );
|
||||
|
||||
/**
|
||||
* Set the parameters used in calculating the number of vertices in an arc.
|
||||
*
|
||||
* The default settings are reasonable for rendering for unit lengths of 1mm.
|
||||
*
|
||||
* @param aMaxSeg is the maximum number of segments for an arc with cords of length aMinLength.
|
||||
* @param aMinLength is the minimum length of cords in an arc.
|
||||
* @param aMaxLength is the maximum length of cords in an arc.
|
||||
* @return true if the parameters were accepted.
|
||||
*/
|
||||
bool SetArcParams( int aMaxSeg, double aMinLength, double aMaxLength );
|
||||
|
||||
/**
|
||||
* Reset the parameters used in calculating the number of vertices in an arc to default values.
|
||||
*/
|
||||
void ResetArcParams();
|
||||
|
||||
/**
|
||||
* Rrase all data except for arc parameters.
|
||||
*/
|
||||
void Clear( void );
|
||||
|
||||
/**
|
||||
* @return the total number of vertices indexed.
|
||||
*/
|
||||
int GetSize( void );
|
||||
|
||||
/**
|
||||
* @return the number of stored contours.
|
||||
*/
|
||||
int GetNContours( void )
|
||||
{
|
||||
return contours.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new list of vertices and returns an index to the list.
|
||||
*
|
||||
* @param aPlatedHole is true if the new contour will represent a plated hole.
|
||||
* @return index to the list or -1 if the operation failed.
|
||||
*/
|
||||
int NewContour( bool aPlatedHole = false );
|
||||
|
||||
/**
|
||||
* Add a point to the requested contour.
|
||||
*
|
||||
* @param aContour is an index previously returned by a call to NewContour().
|
||||
* @param aXpos is the X coordinate of the vertex.
|
||||
* @param aYpos is the Y coordinate of the vertex.
|
||||
* @return true if the vertex was added.
|
||||
*/
|
||||
bool AddVertex( int aContourID, double aXpos, double aYpos );
|
||||
|
||||
/**
|
||||
* Check the winding of a contour and ensures that it is a hole or a solid depending on the
|
||||
* value of @param hole.
|
||||
*
|
||||
* @param aContour is an index to a contour as returned by NewContour().
|
||||
* @param aHoleFlag determines if the contour must be a hole.
|
||||
* @return true if the operation succeeded.
|
||||
*/
|
||||
bool EnsureWinding( int aContourID, bool aHoleFlag );
|
||||
|
||||
/**
|
||||
* Add a circular contour to the specified (empty) contour.
|
||||
*
|
||||
* @param aXpos is the X coordinate of the hole center.
|
||||
* @param aYpos is the Y coordinate of the hole center.
|
||||
* @param aRadius is the radius of the hole.
|
||||
* @param aContourID is the contour index.
|
||||
* @param aHoleFlag determines if the contour to be created is a cutout.
|
||||
* @return true if the new contour was successfully created.
|
||||
*/
|
||||
bool AppendCircle( double aXpos, double aYpos, double aRadius, int aContourID,
|
||||
bool aHoleFlag = false );
|
||||
|
||||
/**
|
||||
* Create a circular contour and adds it to the internal list.
|
||||
*
|
||||
* @param aXpos is the X coordinate of the hole center.
|
||||
* @param aYpos is the Y coordinate of the hole center.
|
||||
* @param aRadius is the radius of the hole.
|
||||
* @param aHoleFlag determines if the contour to be created is a cutout.
|
||||
* @param aPlatedHole is true if this is a plated hole.
|
||||
* @return true if the new contour was successfully created.
|
||||
*/
|
||||
bool AddCircle( double aXpos, double aYpos, double aRadius, bool aHoleFlag = false,
|
||||
bool aPlatedHole = false );
|
||||
|
||||
/**
|
||||
* Create and add a slot feature to the list of contours.
|
||||
*
|
||||
* @param aCenterX is the X coordinate of the slot's center.
|
||||
* @param aCenterY is the Y coordinate of the slot's center.
|
||||
* @param aSlotLength is the length of the slot along the major axis.
|
||||
* @param aSlotWidth is the width of the slot along the minor axis.
|
||||
* @param aAngle (degrees) is the orientation of the slot.
|
||||
* @param aHoleFlag determines whether the slot is a hole or a solid.
|
||||
* @param aPlatedHole is true if this is a plated slot.
|
||||
* @return true if the slot was successfully created.
|
||||
*/
|
||||
bool AddSlot( double aCenterX, double aCenterY, double aSlotLength, double aSlotWidth,
|
||||
double aAngle, bool aHoleFlag = false, bool aPlatedHole = false );
|
||||
|
||||
/**
|
||||
* Add an arc to the specified contour.
|
||||
*
|
||||
* @param aCenterX is the X coordinate of the arc's center.
|
||||
* @param aCenterY is the Y coordinate of the arc's center.
|
||||
* @param aRadius is the radius of the arc.
|
||||
* @param aStartAngle (degrees) is the starting angle of the arc.
|
||||
* @param aAngle (degrees) is the measure of the arc.
|
||||
* @param aContourID is the contour's index.
|
||||
* @return true if the slot was successfully created.
|
||||
*/
|
||||
bool AppendArc( double aCenterX, double aCenterY, double aRadius, double aStartAngle,
|
||||
double aAngle, int aContourID );
|
||||
|
||||
/**
|
||||
* Create a slotted arc and adds it to the internal list of contours.
|
||||
*
|
||||
* @param aCenterX is the X coordinate of the arc's center.
|
||||
* @param aCenterY is the Y coordinate of the arc's center.
|
||||
* @param aStartX is the X coordinate of the starting point.
|
||||
* @param aStartY is the Y coordinate of the starting point.
|
||||
* @param aArcWidth is the width of the arc.
|
||||
* @param aAngle is the included angle (degrees).
|
||||
* @param aHoleFlag determines whether the arc is to be a hole or a solid.
|
||||
* @param aPlatedHole is true if this is a plated slotted arc.
|
||||
* @return true if the feature was successfully created.
|
||||
*/
|
||||
bool AddArc( double aCenterX, double aCenterY, double aStartX, double aStartY,
|
||||
double aArcWidth, double aAngle, bool aHoleFlag = false,
|
||||
bool aPlatedHole = false );
|
||||
|
||||
/**
|
||||
* Create an arbitrary polygon and adds it to the list of contours.
|
||||
*
|
||||
* @param aPolySet is the set of polygon points.
|
||||
* @param aCenterX is the X coordinate of the polygon's center.
|
||||
* @param aCenterY is the Y coordinate of the polygon's center.
|
||||
* @param aAngle is the rotation angle (degrees) of the pad.
|
||||
*/
|
||||
bool AddPolygon( const std::vector< wxRealPoint >& aPolySet, double aCenterX, double aCenterY,
|
||||
double aAngle );
|
||||
|
||||
/**
|
||||
* Create a list of outline vertices as well as the vertex sets required to render the surface.
|
||||
*
|
||||
* @param holes is an optional pointer to cutouts to be imposed on the surface.
|
||||
* @param aHolesOnly is true if the outline contains only holes.
|
||||
* @return true if the operation succeeded.
|
||||
*/
|
||||
bool Tesselate( VRML_LAYER* holes = NULL, bool aHolesOnly = false );
|
||||
|
||||
/**
|
||||
* Write out the list of vertices required to render a planar surface.
|
||||
*
|
||||
* @param aZcoord is the Z coordinate of the plane.
|
||||
* @param aOutFile is the file to write to.
|
||||
* @param aPrecision is the precision of the output coordinates.
|
||||
* @return true if the operation succeeded.
|
||||
*/
|
||||
bool WriteVertices( double aZcoord, std::ostream& aOutFile, int aPrecision );
|
||||
|
||||
/**
|
||||
* Write out the list of vertices required to render an extruded solid.
|
||||
*
|
||||
* @param aTopZ is the Z coordinate of the top plane.
|
||||
* @param aBottomZ is the Z coordinate of the bottom plane.
|
||||
* @param aOutFile is the file to write to.
|
||||
* @param aPrecision is the precision of the output coordinates.
|
||||
* @return true if the operation succeeded.
|
||||
*/
|
||||
bool Write3DVertices( double aTopZ, double aBottomZ, std::ostream& aOutFile, int aPrecision );
|
||||
|
||||
/**
|
||||
* Write out the vertex sets required to render a planar surface.
|
||||
*
|
||||
* @param aTopFlag is true if the surface is to be visible from above; if false the surface
|
||||
* will be visible from below.
|
||||
* @param aOutFile is the file to write to.
|
||||
* @return true if the operation succeeded.
|
||||
*/
|
||||
bool WriteIndices( bool aTopFlag, std::ostream& aOutFile );
|
||||
|
||||
/**
|
||||
* Write out the vertex sets required to render an extruded solid.
|
||||
*
|
||||
* @param aOutFile is the file to write to.
|
||||
* @param aIncludePlatedHoles is true if holes marked as plated should be rendered. Default
|
||||
* is false since the user will usually render these holes in a
|
||||
* different color.
|
||||
* @return true if the operation succeeded.
|
||||
*/
|
||||
bool Write3DIndices( std::ostream& aOutFile, bool aIncludePlatedHoles = false );
|
||||
|
||||
/**
|
||||
* Add an extra vertex as required by the GLU tesselator.
|
||||
*
|
||||
* @param aXpos is the X coordinate of the newly created point.
|
||||
* @param aYpos is the Y coordinate of the newly created point.
|
||||
* @param aPlatedHole is true if this point is part of a plated hole.
|
||||
* @return is the new vertex or NULL if a vertex could not be created.
|
||||
*/
|
||||
VERTEX_3D* AddExtraVertex( double aXpos, double aYpos, bool aPlatedHole );
|
||||
|
||||
/**
|
||||
* Invoked by the GLU tesselator callback to notify this object of the type of GL command
|
||||
* which is applicable to the upcoming vertex list.
|
||||
*
|
||||
* @param cmd is the GL command.
|
||||
*/
|
||||
void glStart( GLenum cmd );
|
||||
|
||||
/**
|
||||
* Invoked by the GLU tesselator callback; the supplied vertex is added to the internal list
|
||||
* of vertices awaiting processing upon execution of glEnd()
|
||||
*
|
||||
* @param vertex is a vertex forming part of the GL command as previously set by glStart.
|
||||
*/
|
||||
void glPushVertex( VERTEX_3D* vertex );
|
||||
|
||||
/**
|
||||
* Invoked by the GLU tesselator callback to notify this object that the vertex list is
|
||||
* complete and ready for processing.
|
||||
*/
|
||||
void glEnd( void );
|
||||
|
||||
/**
|
||||
* Set the error message according to the specified OpenGL error.
|
||||
*/
|
||||
void SetGLError( GLenum error_id );
|
||||
|
||||
/**
|
||||
* Inserts all contours into the given tesselator.
|
||||
*
|
||||
* This results in the renumbering of all vertices from \a start. Take care when using
|
||||
* this call since tesselators cannot work on the internal data concurrently.
|
||||
*
|
||||
* @param start is the starting number for vertex indices.
|
||||
* @param tess is a pointer to a GLU Tesselator object.
|
||||
* @return the number of vertices exported.
|
||||
*/
|
||||
int Import( int start, GLUtesselator* aTesselator );
|
||||
|
||||
/**
|
||||
* Return a pointer to the requested vertex or NULL if no such vertex exists.
|
||||
*
|
||||
* @param aPointIndex is a vertex index.
|
||||
* @return the requested vertex or NULL
|
||||
*/
|
||||
VERTEX_3D* GetVertexByIndex( int aPointIndex );
|
||||
|
||||
/**
|
||||
* @return the error message related to the last failed operation.
|
||||
*/
|
||||
const std::string& GetError( void );
|
||||
|
||||
void SetVertexOffsets( double aXoffset, double aYoffset );
|
||||
|
||||
/**
|
||||
* Allocate and populate the 3D vertex and index lists with triangular vertices which may
|
||||
* be used for rendering a volume.
|
||||
*
|
||||
* @param aVertexList will store the vertices.
|
||||
* @param aIndexPlane will store the indices for the top + bottom planes.
|
||||
* @param aIndexSide will store the indices for the vertical wall.
|
||||
* @param aTopZ is the top plane of the model.
|
||||
* @param aBotZ is the bottom plane of the model.
|
||||
*/
|
||||
bool Get3DTriangles( std::vector< double >& aVertexList, std::vector< int >& aIndexPlane,
|
||||
std::vector< int >& aIndexSide, double aTopZ, double aBotZ );
|
||||
|
||||
/**
|
||||
* Allocate and populate the 3D vertex and index lists with triangular vertices which may
|
||||
* be used for rendering a plane.
|
||||
*
|
||||
* @param aVertexList will store the vertices.
|
||||
* @param aIndexPlane will store the indices for the plane.
|
||||
* @param aHeight is the plane of the model.
|
||||
* @param aTopPlane is true if the plane is a top plane (false = reverse indices).
|
||||
*/
|
||||
bool Get2DTriangles( std::vector< double >& aVertexList, std::vector< int > &aIndexPlane,
|
||||
double aHeight, bool aTopPlane );
|
||||
|
||||
|
||||
private:
|
||||
void clearTmp( void ); // clear ephemeral data used by the tesselation routine
|
||||
|
||||
// add a triangular facet (triplet) to the output index list
|
||||
bool addTriplet( VERTEX_3D* p0, VERTEX_3D* p1, VERTEX_3D* p2 );
|
||||
|
||||
// retrieve a vertex given its index; the vertex may be contained in the
|
||||
// vertices vector, extra_verts vector, or foreign VRML_LAYER object
|
||||
VERTEX_3D* getVertexByIndex( int aPointIndex, VRML_LAYER* holes );
|
||||
|
||||
void processFan( void ); // process a GL_TRIANGLE_FAN list
|
||||
void processStrip( void ); // process a GL_TRIANGLE_STRIP list
|
||||
void processTri( void ); // process a GL_TRIANGLES list
|
||||
|
||||
void pushVertices( bool holes ); // push the internal vertices
|
||||
bool pushOutline( VRML_LAYER* holes ); // push the outline vertices
|
||||
|
||||
// calculate number of sides on an arc (angle is in radians)
|
||||
int calcNSides( double aRadius, double aAngle );
|
||||
|
||||
// returns the number of solid or hole contours
|
||||
int checkNContours( bool holes );
|
||||
|
||||
public:
|
||||
/// set to true when a fault is encountered during tesselation
|
||||
bool Fault;
|
||||
|
||||
private:
|
||||
// Arc parameters
|
||||
int maxArcSeg; // maximum number of arc segments in a small circle
|
||||
|
@ -123,391 +450,8 @@ private:
|
|||
VRML_LAYER* pholes; // pointer to another layer object used for tesselation;
|
||||
// this object is normally expected to hold only holes
|
||||
|
||||
GLUtesselator* tess; // local instance of the GLU tesselator
|
||||
|
||||
GLenum glcmd; // current GL command type ( fan, triangle, tri-strip, loop )
|
||||
|
||||
void clearTmp( void ); // clear ephemeral data used by the tesselation routine
|
||||
|
||||
// add a triangular facet (triplet) to the output index list
|
||||
bool addTriplet( VERTEX_3D* p0, VERTEX_3D* p1, VERTEX_3D* p2 );
|
||||
|
||||
// retrieve a vertex given its index; the vertex may be contained in the
|
||||
// vertices vector, extra_verts vector, or foreign VRML_LAYER object
|
||||
VERTEX_3D* getVertexByIndex( int aPointIndex, VRML_LAYER* holes );
|
||||
|
||||
void processFan( void ); // process a GL_TRIANGLE_FAN list
|
||||
void processStrip( void ); // process a GL_TRIANGLE_STRIP list
|
||||
void processTri( void ); // process a GL_TRIANGLES list
|
||||
|
||||
void pushVertices( bool holes ); // push the internal vertices
|
||||
bool pushOutline( VRML_LAYER* holes ); // push the outline vertices
|
||||
|
||||
// calculate number of sides on an arc (angle is in radians)
|
||||
int calcNSides( double aRadius, double aAngle );
|
||||
|
||||
// returns the number of solid or hole contours
|
||||
int checkNContours( bool holes );
|
||||
|
||||
public:
|
||||
/// set to true when a fault is encountered during tesselation
|
||||
bool Fault;
|
||||
|
||||
VRML_LAYER();
|
||||
virtual ~VRML_LAYER();
|
||||
|
||||
/**
|
||||
* Function GetArcParams
|
||||
* retrieves the parameters used in calculating the number of vertices in an arc
|
||||
*
|
||||
* @param aMaxSeg is the maximum number of segments for an arc with cords of length aMinLength
|
||||
* @param aMinLength is the minimum length of cords in an arc
|
||||
* @param aMaxLength is the maximum length of cords in an arc
|
||||
*/
|
||||
void GetArcParams( int& aMaxSeg, double& aMinLength, double& aMaxLength );
|
||||
|
||||
/**
|
||||
* Function SetArcParams
|
||||
* sets the parameters used in calculating the number of vertices in an arc.
|
||||
* The default settings are reasonable for rendering for unit lengths of 1mm
|
||||
*
|
||||
* @param aMaxSeg is the maximum number of segments for an arc with cords of length aMinLength
|
||||
* @param aMinLength is the minimum length of cords in an arc
|
||||
* @param aMaxLength is the maximum length of cords in an arc
|
||||
*
|
||||
* @return bool: true if the parameters were accepted
|
||||
*/
|
||||
bool SetArcParams( int aMaxSeg, double aMinLength, double aMaxLength );
|
||||
|
||||
/**
|
||||
* Resets the parameters used in calculating the number of vertices in an arc
|
||||
* to default values
|
||||
*/
|
||||
void ResetArcParams();
|
||||
|
||||
/**
|
||||
* Function Clear
|
||||
* erases all data except for arc parameters.
|
||||
*/
|
||||
void Clear( void );
|
||||
|
||||
/**
|
||||
* Function GetSize
|
||||
* returns the total number of vertices indexed
|
||||
*/
|
||||
int GetSize( void );
|
||||
|
||||
/**
|
||||
* Function GetNConours
|
||||
* returns the number of stored contours
|
||||
*/
|
||||
int GetNContours( void )
|
||||
{
|
||||
return contours.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Function NewContour
|
||||
* creates a new list of vertices and returns an index to the list
|
||||
*
|
||||
* @param aPlatedHole is true if the new contour will represent a plated hole
|
||||
*
|
||||
* @return int: index to the list or -1 if the operation failed
|
||||
*/
|
||||
int NewContour( bool aPlatedHole = false );
|
||||
|
||||
/**
|
||||
* Function AddVertex
|
||||
* adds a point to the requested contour
|
||||
*
|
||||
* @param aContour is an index previously returned by a call to NewContour()
|
||||
* @param aXpos is the X coordinate of the vertex
|
||||
* @param aYpos is the Y coordinate of the vertex
|
||||
*
|
||||
* @return bool: true if the vertex was added
|
||||
*/
|
||||
bool AddVertex( int aContourID, double aXpos, double aYpos );
|
||||
|
||||
/**
|
||||
* Function EnsureWinding
|
||||
* checks the winding of a contour and ensures that it is a hole or
|
||||
* a solid depending on the value of @param hole
|
||||
*
|
||||
* @param aContour is an index to a contour as returned by NewContour()
|
||||
* @param aHoleFlag determines if the contour must be a hole
|
||||
*
|
||||
* @return bool: true if the operation succeeded
|
||||
*/
|
||||
bool EnsureWinding( int aContourID, bool aHoleFlag );
|
||||
|
||||
/**
|
||||
* Function AppendCircle
|
||||
* adds a circular contour to the specified (empty) contour
|
||||
*
|
||||
* @param aXpos is the X coordinate of the hole center
|
||||
* @param aYpos is the Y coordinate of the hole center
|
||||
* @param aRadius is the radius of the hole
|
||||
* @param aContourID is the contour index
|
||||
* @param aHoleFlag determines if the contour to be created is a cutout
|
||||
*
|
||||
* @return bool: true if the new contour was successfully created
|
||||
*/
|
||||
bool AppendCircle( double aXpos, double aYpos, double aRadius,
|
||||
int aContourID, bool aHoleFlag = false );
|
||||
|
||||
/**
|
||||
* Function AddCircle
|
||||
* creates a circular contour and adds it to the internal list
|
||||
*
|
||||
* @param aXpos is the X coordinate of the hole center
|
||||
* @param aYpos is the Y coordinate of the hole center
|
||||
* @param aRadius is the radius of the hole
|
||||
* @param aHoleFlag determines if the contour to be created is a cutout
|
||||
* @param aPlatedHole is true if this is a plated hole
|
||||
*
|
||||
* @return bool: true if the new contour was successfully created
|
||||
*/
|
||||
bool AddCircle( double aXpos, double aYpos, double aRadius,
|
||||
bool aHoleFlag = false, bool aPlatedHole = false );
|
||||
|
||||
/**
|
||||
* Function AddSlot
|
||||
* creates and adds a slot feature to the list of contours
|
||||
*
|
||||
* @param aCenterX is the X coordinate of the slot's center
|
||||
* @param aCenterY is the Y coordinate of the slot's center
|
||||
* @param aSlotLength is the length of the slot along the major axis
|
||||
* @param aSlotWidth is the width of the slot along the minor axis
|
||||
* @param aAngle (degrees) is the orientation of the slot
|
||||
* @param aHoleFlag determines whether the slot is a hole or a solid
|
||||
* @param aPlatedHole is true if this is a plated slot
|
||||
*
|
||||
* @return bool: true if the slot was successfully created
|
||||
*/
|
||||
bool AddSlot( double aCenterX, double aCenterY, double aSlotLength, double aSlotWidth,
|
||||
double aAngle, bool aHoleFlag = false, bool aPlatedHole = false );
|
||||
|
||||
/**
|
||||
* Function AppendArc
|
||||
* adds an arc to the specified contour
|
||||
*
|
||||
* @param aCenterX is the X coordinate of the arc's center
|
||||
* @param aCenterY is the Y coordinate of the arc's center
|
||||
* @param aRadius is the radius of the arc
|
||||
* @param aStartAngle (degrees) is the starting angle of the arc
|
||||
* @param aAngle (degrees) is the measure of the arc
|
||||
* @param aContourID is the contour's index
|
||||
*
|
||||
* @return bool: true if the slot was successfully created
|
||||
*/
|
||||
bool AppendArc( double aCenterX, double aCenterY, double aRadius,
|
||||
double aStartAngle, double aAngle, int aContourID );
|
||||
|
||||
/**
|
||||
* Function AddArc
|
||||
* creates a slotted arc and adds it to the internal list of contours
|
||||
*
|
||||
* @param aCenterX is the X coordinate of the arc's center
|
||||
* @param aCenterY is the Y coordinate of the arc's center
|
||||
* @param aStartX is the X coordinate of the starting point
|
||||
* @param aStartY is the Y coordinate of the starting point
|
||||
* @param aArcWidth is the width of the arc
|
||||
* @param aAngle is the included angle (degrees)
|
||||
* @param aHoleFlag determines whether the arc is to be a hole or a solid
|
||||
* @param aPlatedHole is true if this is a plated slotted arc
|
||||
*
|
||||
* @return bool: true if the feature was successfully created
|
||||
*/
|
||||
bool AddArc( double aCenterX, double aCenterY,
|
||||
double aStartX, double aStartY,
|
||||
double aArcWidth, double aAngle,
|
||||
bool aHoleFlag = false, bool aPlatedHole = false );
|
||||
|
||||
/**
|
||||
* Function AddPolygon
|
||||
* creates an arbitrary polygon and adds it to the list of contours
|
||||
*
|
||||
* @param aPolySet is the set of polygon points
|
||||
* @param aCenterX is the X coordinate of the polygon's center
|
||||
* @param aCenterY is the Y coordinate of the polygon's center
|
||||
* @param aAngle is the rotation angle (degrees) of the pad
|
||||
*/
|
||||
bool AddPolygon( const std::vector< wxRealPoint >& aPolySet,
|
||||
double aCenterX, double aCenterY, double aAngle );
|
||||
|
||||
/**
|
||||
* Function Tesselate
|
||||
* creates a list of outline vertices as well as the
|
||||
* vertex sets required to render the surface.
|
||||
*
|
||||
* @param holes is an optional pointer to cutouts to be imposed on the
|
||||
* surface.
|
||||
* @param aHolesOnly is true if the outline contains only holes
|
||||
*
|
||||
* @return bool: true if the operation succeeded
|
||||
*/
|
||||
bool Tesselate( VRML_LAYER* holes = NULL, bool aHolesOnly = false );
|
||||
|
||||
/**
|
||||
* Function WriteVertices
|
||||
* writes out the list of vertices required to render a
|
||||
* planar surface.
|
||||
*
|
||||
* @param aZcoord is the Z coordinate of the plane
|
||||
* @param aOutFile is the file to write to
|
||||
* @param aPrecision is the precision of the output coordinates
|
||||
*
|
||||
* @return bool: true if the operation succeeded
|
||||
*/
|
||||
bool WriteVertices( double aZcoord, std::ostream& aOutFile, int aPrecision );
|
||||
|
||||
/**
|
||||
* Function Write3DVertices
|
||||
* writes out the list of vertices required to render an extruded solid
|
||||
*
|
||||
* @param aTopZ is the Z coordinate of the top plane
|
||||
* @param aBottomZ is the Z coordinate of the bottom plane
|
||||
* @param aOutFile is the file to write to
|
||||
* @param aPrecision is the precision of the output coordinates
|
||||
*
|
||||
* @return bool: true if the operation succeeded
|
||||
*/
|
||||
bool Write3DVertices( double aTopZ, double aBottomZ, std::ostream& aOutFile, int aPrecision );
|
||||
|
||||
/**
|
||||
* Function WriteIndices
|
||||
* writes out the vertex sets required to render a planar
|
||||
* surface.
|
||||
*
|
||||
* @param aTopFlag is true if the surface is to be visible from above;
|
||||
* if false the surface will be visible from below.
|
||||
* @param aOutFile is the file to write to
|
||||
*
|
||||
* @return bool: true if the operation succeeded
|
||||
*/
|
||||
bool WriteIndices( bool aTopFlag, std::ostream& aOutFile );
|
||||
|
||||
/**
|
||||
* Function Write3DIndices
|
||||
* writes out the vertex sets required to render an extruded solid
|
||||
*
|
||||
* @param aOutFile is the file to write to
|
||||
* @param aIncludePlatedHoles is true if holes marked as plated should
|
||||
* be rendered. Default is false since the user will usually
|
||||
* render these holes in a different color
|
||||
*
|
||||
* @return bool: true if the operation succeeded
|
||||
*/
|
||||
bool Write3DIndices( std::ostream& aOutFile, bool aIncludePlatedHoles = false );
|
||||
|
||||
/**
|
||||
* Function AddExtraVertex
|
||||
* adds an extra vertex as required by the GLU tesselator.
|
||||
*
|
||||
* @param aXpos is the X coordinate of the newly created point
|
||||
* @param aYpos is the Y coordinate of the newly created point
|
||||
* @param aPlatedHole is true if this point is part of a plated hole
|
||||
*
|
||||
* @return VERTEX_3D*: is the new vertex or NULL if a vertex
|
||||
* could not be created.
|
||||
*/
|
||||
VERTEX_3D* AddExtraVertex( double aXpos, double aYpos, bool aPlatedHole );
|
||||
|
||||
/**
|
||||
* Function glStart
|
||||
* is invoked by the GLU tesselator callback to notify this object
|
||||
* of the type of GL command which is applicable to the upcoming
|
||||
* vertex list.
|
||||
*
|
||||
* @param cmd is the GL command
|
||||
*/
|
||||
void glStart( GLenum cmd );
|
||||
|
||||
/**
|
||||
* Function glPushVertex
|
||||
* is invoked by the GLU tesselator callback; the supplied vertex is
|
||||
* added to the internal list of vertices awaiting processing upon
|
||||
* execution of glEnd()
|
||||
*
|
||||
* @param vertex is a vertex forming part of the GL command as previously
|
||||
* set by glStart
|
||||
*/
|
||||
void glPushVertex( VERTEX_3D* vertex );
|
||||
|
||||
/**
|
||||
* Function glEnd
|
||||
* is invoked by the GLU tesselator callback to notify this object
|
||||
* that the vertex list is complete and ready for processing
|
||||
*/
|
||||
void glEnd( void );
|
||||
|
||||
/**
|
||||
* Function SetGLError
|
||||
* sets the error message according to the specified OpenGL error
|
||||
*/
|
||||
void SetGLError( GLenum error_id );
|
||||
|
||||
/**
|
||||
* Function Import
|
||||
* inserts all contours into the given tesselator; this
|
||||
* results in the renumbering of all vertices from @param start.
|
||||
* Take care when using this call since tesselators cannot work on
|
||||
* the internal data concurrently.
|
||||
*
|
||||
* @param start is the starting number for vertex indices
|
||||
* @param tess is a pointer to a GLU Tesselator object
|
||||
*
|
||||
* @return int: the number of vertices exported
|
||||
*/
|
||||
int Import( int start, GLUtesselator* aTesselator );
|
||||
|
||||
/**
|
||||
* Function GetVertexByIndex
|
||||
* returns a pointer to the requested vertex or
|
||||
* NULL if no such vertex exists.
|
||||
*
|
||||
* @param aPointIndex is a vertex index
|
||||
*
|
||||
* @return VERTEX_3D*: the requested vertex or NULL
|
||||
*/
|
||||
VERTEX_3D* GetVertexByIndex( int aPointIndex );
|
||||
|
||||
/*
|
||||
* Function GetError
|
||||
* Returns the error message related to the last failed operation
|
||||
*/
|
||||
const std::string& GetError( void );
|
||||
|
||||
void SetVertexOffsets( double aXoffset, double aYoffset );
|
||||
|
||||
/**
|
||||
* Function Get3DTriangles
|
||||
* Allocates and populates the 3D vertex and index lists with
|
||||
* triangular vertices which may be used for rendering a volume
|
||||
*
|
||||
* @param aVertexList will store the vertices
|
||||
* @param aIndexPlane will store the indices for the top + bottom planes
|
||||
* @param aIndexSide will store the indices for the vertical wall
|
||||
* @param aTopZ is the top plane of the model
|
||||
* @param aBotZ is the bottom plane of the model
|
||||
*/
|
||||
bool Get3DTriangles( std::vector< double >& aVertexList,
|
||||
std::vector< int > &aIndexPlane, std::vector< int > &aIndexSide,
|
||||
double aTopZ, double aBotZ );
|
||||
|
||||
/**
|
||||
* Function Get2DTriangles
|
||||
* Allocates and populates the 3D vertex and index lists with
|
||||
* triangular vertices which may be used for rendering a plane
|
||||
*
|
||||
* @param aVertexList will store the vertices
|
||||
* @param aIndexPlane will store the indices for the plane
|
||||
* @param aHeight is the plane of the model
|
||||
* @param aTopPlane is true if the plane is a top plane (false = reverse indices)
|
||||
*/
|
||||
bool Get2DTriangles( std::vector< double >& aVertexList,
|
||||
std::vector< int > &aIndexPlane, double aHeight, bool aTopPlane );
|
||||
|
||||
GLUtesselator* tess; // local instance of the GLU tesselator
|
||||
GLenum glcmd; // current GL command type ( fan, triangle, tri-strip, loop )
|
||||
};
|
||||
|
||||
#endif // VRML_LAYER_H
|
||||
|
|
Loading…
Reference in New Issue