2014-05-28 06:26:46 +00:00
|
|
|
/**
|
|
|
|
* @file idf_common.h
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
|
|
*
|
|
|
|
* Copyright (C) 2013-2014 Cirilo Bernardo
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, you may find one here:
|
|
|
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|
|
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
|
|
|
* or you may write to the Free Software Foundation, Inc.,
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef IDF_COMMON_H
|
|
|
|
#define IDF_COMMON_H
|
|
|
|
|
|
|
|
#include <list>
|
|
|
|
#include <fstream>
|
|
|
|
#include <exception>
|
|
|
|
#include <string>
|
|
|
|
|
|
|
|
#ifndef M_PI
|
|
|
|
#define M_PI 3.1415926535897932384626433832795028841
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef M_PI2
|
|
|
|
#define M_PI2 ( M_PI / 2.0 )
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef M_PI4
|
|
|
|
#define M_PI4 ( M_PI / 4.0 )
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// differences in angle smaller than MIN_ANG are considered equal
|
|
|
|
#define MIN_ANG (0.01)
|
|
|
|
|
|
|
|
class IDF_POINT;
|
|
|
|
class IDF_SEGMENT;
|
|
|
|
class IDF_DRILL_DATA;
|
|
|
|
class IDF_OUTLINE;
|
|
|
|
class IDF_LIB;
|
|
|
|
|
|
|
|
|
|
|
|
struct IDF_ERROR : std::exception
|
|
|
|
{
|
|
|
|
std::string message;
|
|
|
|
|
|
|
|
IDF_ERROR( const char* aSourceFile,
|
|
|
|
const char* aSourceMethod,
|
|
|
|
int aSourceLine,
|
|
|
|
const std::string& aMessage ) throw();
|
|
|
|
|
|
|
|
virtual ~IDF_ERROR() throw();
|
|
|
|
|
|
|
|
virtual const char* what() const throw();
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
namespace IDF3 {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ENUM FILE_STATE
|
|
|
|
* represents state values for the IDF parser's input
|
|
|
|
*/
|
|
|
|
enum FILE_STATE
|
|
|
|
{
|
|
|
|
FILE_START = 0, // no data has been read; expecting .HEADER
|
|
|
|
FILE_HEADER, // header has been read; expecting .BOARD_OUTLINE
|
|
|
|
FILE_OUTLINE, // board outline has been read; most sections can be accepted
|
|
|
|
FILE_PLACEMENT, // placement has been read; no further sections can be accepted
|
|
|
|
FILE_INVALID, // file is invalid
|
|
|
|
FILE_ERROR // other errors while processing the file
|
|
|
|
};
|
|
|
|
|
2014-06-01 16:55:53 +00:00
|
|
|
/**
|
|
|
|
* ENUM IDF_VERSION
|
|
|
|
* represents the supported IDF versions (3.0 and 2.0 ONLY)
|
|
|
|
*/
|
|
|
|
enum IDF_VERSION
|
|
|
|
{
|
|
|
|
IDF_V2 = 0, // version 2 has read support only; files written as IDFv3
|
|
|
|
IDF_V3 // version 3 has full read/write support
|
|
|
|
};
|
|
|
|
|
2014-05-28 06:26:46 +00:00
|
|
|
/**
|
|
|
|
* ENUM KEY_OWNER
|
|
|
|
* represents the type of CAD which has ownership an object
|
|
|
|
*/
|
|
|
|
enum KEY_OWNER
|
|
|
|
{
|
|
|
|
UNOWNED = 0, //< either MCAD or ECAD may modify a feature
|
|
|
|
MCAD, //< only MCAD may modify a feature
|
|
|
|
ECAD //< only ECAD may modify a feature
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ENUM KEY_HOLETYPE
|
|
|
|
* represents the purpose of an IDF hole
|
|
|
|
*/
|
|
|
|
enum KEY_HOLETYPE
|
|
|
|
{
|
|
|
|
PIN = 0, //< drill hole is for a pin
|
|
|
|
VIA, //< drill hole is for a via
|
|
|
|
MTG, //< drill hole is for mounting
|
|
|
|
TOOL, //< drill hole is for tooling
|
|
|
|
OTHER //< user has specified a custom type
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ENUM KEY_PLATING
|
|
|
|
* represents the plating condition of a hole
|
|
|
|
*/
|
|
|
|
enum KEY_PLATING
|
|
|
|
{
|
|
|
|
PTH = 0, //< Plate-Through Hole
|
|
|
|
NPTH //< Non-Plate-Through Hole
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ENUM KEY_REFDES
|
|
|
|
* represents a component's Reference Designator
|
|
|
|
*/
|
|
|
|
enum KEY_REFDES
|
|
|
|
{
|
|
|
|
BOARD = 0, //< feature is associated with the board
|
|
|
|
NOREFDES, //< feature is associated with a component with no RefDes
|
|
|
|
PANEL, //< feature is associated with an IDF panel
|
|
|
|
REFDES //< reference designator as assigned by the CAD software
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ENUM CAD_TYPE
|
|
|
|
* represents the class of CAD program which is opening or modifying a file
|
|
|
|
*/
|
|
|
|
enum CAD_TYPE
|
|
|
|
{
|
|
|
|
CAD_ELEC = 0, //< An Electrical CAD is opening/modifying the file
|
|
|
|
CAD_MECH, //< A Mechanical CAD is opening/modifying the file
|
|
|
|
CAD_INVALID
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ENUM IDF_LAYER
|
|
|
|
* represents the various IDF layer classes and groupings
|
|
|
|
*/
|
|
|
|
enum IDF_LAYER
|
|
|
|
{
|
|
|
|
LYR_TOP = 0,
|
|
|
|
LYR_BOTTOM,
|
|
|
|
LYR_BOTH,
|
|
|
|
LYR_INNER,
|
|
|
|
LYR_ALL,
|
|
|
|
LYR_INVALID
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ENUM OUTLINE_TYPE
|
|
|
|
* identifies the class of outline
|
|
|
|
*/
|
|
|
|
enum OUTLINE_TYPE
|
|
|
|
{
|
|
|
|
OTLN_BOARD = 0,
|
|
|
|
OTLN_OTHER,
|
|
|
|
OTLN_PLACE,
|
|
|
|
OTLN_ROUTE,
|
|
|
|
OTLN_PLACE_KEEPOUT,
|
|
|
|
OTLN_ROUTE_KEEPOUT,
|
|
|
|
OTLN_VIA_KEEPOUT,
|
|
|
|
OTLN_GROUP_PLACE,
|
|
|
|
OTLN_COMPONENT,
|
|
|
|
OTLN_INVALID
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ENUM COMP_TYPE
|
|
|
|
* identifies whether a component is a mechanical or electrical part
|
|
|
|
*/
|
|
|
|
enum COMP_TYPE
|
|
|
|
{
|
|
|
|
COMP_ELEC = 0, //< Component library object is an electrical part
|
|
|
|
COMP_MECH, //< Component library object is a mechanical part
|
|
|
|
COMP_INVALID
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ENUM IDF_UNIT
|
|
|
|
* represents the native unit of the board and of component outlines
|
|
|
|
*/
|
|
|
|
enum IDF_UNIT
|
|
|
|
{
|
|
|
|
UNIT_MM = 0, //< Units in the file are in millimeters
|
|
|
|
UNIT_THOU, //< Units in the file are in mils (aka thou)
|
2014-06-01 16:55:53 +00:00
|
|
|
UNIT_TNM, //< Deprecated Ten Nanometer Units from IDFv2
|
2014-05-28 06:26:46 +00:00
|
|
|
UNIT_INVALID
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ENUM IDF_PLACEMENT
|
|
|
|
* represents the placement status of a component
|
|
|
|
*/
|
|
|
|
enum IDF_PLACEMENT
|
|
|
|
{
|
|
|
|
PS_UNPLACED = 0, //< component location on the board has not been specified
|
|
|
|
PS_PLACED, //< component location has been specified and may be modified by ECAD or MCAD
|
|
|
|
PS_MCAD, //< component location has been specified and may only be modified by MCAD
|
|
|
|
PS_ECAD, //< component location has been specified and may only be modified by ECAD
|
|
|
|
PS_INVALID
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function CalcAngleRad
|
|
|
|
* calculates the angle (radians) between the horizon and the segment aStartPoint to aEndPoint
|
|
|
|
*
|
|
|
|
* @param aStartPoint is the start point of a line segment
|
|
|
|
* @param aEndPoint is the end point of a line segment
|
|
|
|
*
|
|
|
|
* @return double: the angle in radians
|
|
|
|
*/
|
|
|
|
double CalcAngleRad( const IDF_POINT& aStartPoint, const IDF_POINT& aEndPoint );
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function CalcAngleDeg
|
|
|
|
* calculates the angle (degrees) between the horizon and the segment aStartPoint to aEndPoint
|
|
|
|
*
|
|
|
|
* @param aStartPoint is the start point of a line segment
|
|
|
|
* @param aEndPoint is the end point of a line segment
|
|
|
|
*
|
|
|
|
* @return double: the angle in degrees
|
|
|
|
*/
|
|
|
|
double CalcAngleDeg( const IDF_POINT& aStartPoint, const IDF_POINT& aEndPoint );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function GetOutline
|
|
|
|
* takes contiguous elements from 'aLines' and stuffs them into 'aOutline'; elements put
|
|
|
|
* into the outline are deleted from aLines. This function is useful for sorting the jumbled
|
|
|
|
* mess of line segments and arcs which represent a board outline and cutouts in KiCad.
|
|
|
|
* The function will determine which segment element within aLines contains the leftmost
|
|
|
|
* point and retrieve the outline of which that segment is part.
|
|
|
|
*
|
|
|
|
* @param aLines (input/output) is a list of IDF segments which comprise an outline and
|
|
|
|
* cutouts.
|
|
|
|
* @param aOutline (output) is the ordered set of segments
|
|
|
|
*/
|
|
|
|
void GetOutline( std::list<IDF_SEGMENT*>& aLines,
|
|
|
|
IDF_OUTLINE& aOutline );
|
|
|
|
|
|
|
|
#ifdef DEBUG_IDF
|
|
|
|
// prints out segment information for debug purposes
|
|
|
|
void PrintSeg( IDF_SEGMENT* aSegment );
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Class IDF_NOTE
|
|
|
|
* represents an entry in the NOTE section of an IDF file
|
|
|
|
*/
|
|
|
|
class IDF_NOTE
|
|
|
|
{
|
2014-06-01 16:55:53 +00:00
|
|
|
friend class IDF3_BOARD;
|
2014-05-28 06:26:46 +00:00
|
|
|
private:
|
|
|
|
std::string text; // note text as per IDFv3
|
|
|
|
double xpos; // text X position as per IDFv3
|
|
|
|
double ypos; // text Y position as per IDFv3
|
|
|
|
double height; // text height as per IDFv3
|
|
|
|
double length; // text length as per IDFv3
|
|
|
|
|
|
|
|
/**
|
2014-06-01 16:55:53 +00:00
|
|
|
* Function readNote
|
2014-05-28 06:26:46 +00:00
|
|
|
* reads a note entry from an IDFv3 file
|
|
|
|
*
|
|
|
|
* @param aBoardFile is an open BOARD file; the file position must be set to the start of a NOTE entry
|
|
|
|
* @param aBoardState is the parser's current state value
|
|
|
|
* @param aBoardUnit is the BOARD file's native units (MM or THOU)
|
|
|
|
*
|
|
|
|
* @return bool: true if a note item was read, false otherwise. In case of unrecoverable errors
|
|
|
|
* an exception is thrown
|
|
|
|
*/
|
2014-06-01 16:55:53 +00:00
|
|
|
bool readNote( std::ifstream& aBoardFile, IDF3::FILE_STATE& aBoardState, IDF3::IDF_UNIT aBoardUnit );
|
2014-05-28 06:26:46 +00:00
|
|
|
|
|
|
|
/**
|
2014-06-01 16:55:53 +00:00
|
|
|
* Function writeNote
|
2014-05-28 06:26:46 +00:00
|
|
|
* writes a note entry to an IDFv3 file
|
|
|
|
*
|
|
|
|
* @param aBoardFile is an open BOARD file; the file position must be within a NOTE section
|
|
|
|
* @param aBoardUnit is the BOARD file's native units (MM or THOU)
|
|
|
|
*
|
|
|
|
* @return bool: true if the item was successfully written, false otherwise. In case of
|
|
|
|
* unrecoverable errors an exception is thrown
|
|
|
|
*/
|
2014-06-01 16:55:53 +00:00
|
|
|
bool writeNote( std::ofstream& aBoardFile, IDF3::IDF_UNIT aBoardUnit );
|
|
|
|
|
|
|
|
public:
|
|
|
|
IDF_NOTE();
|
2014-05-28 06:26:46 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Function SetText
|
|
|
|
* sets the text to be stored as a NOTE entry
|
|
|
|
*/
|
|
|
|
void SetText( const std::string& aText );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function SetPosition
|
|
|
|
* sets the position (mm) of the NOTE entry
|
|
|
|
*/
|
|
|
|
void SetPosition( double aXpos, double aYpos );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function SetSize
|
|
|
|
* sets the height and length (mm) of the NOTE entry
|
|
|
|
*/
|
|
|
|
void SetSize( double aHeight, double aLength );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function GetText
|
|
|
|
* returns the string stored in the note entry
|
|
|
|
*/
|
|
|
|
const std::string& GetText( void );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function GetText
|
|
|
|
* returns the position (mm) of the note entry
|
|
|
|
*/
|
|
|
|
void GetPosition( double& aXpos, double& aYpos );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function GetText
|
|
|
|
* returns the height and length (mm) of the note entry
|
|
|
|
*/
|
|
|
|
void GetSize( double& aHeight, double& aLength );
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @Class IDF_DRILL_DATA
|
|
|
|
* contains information describing a drilled hole and is responsible for
|
|
|
|
* writing this information to a file in compliance with the IDFv3 specification.
|
|
|
|
*/
|
|
|
|
class IDF_DRILL_DATA
|
|
|
|
{
|
2014-06-01 16:55:53 +00:00
|
|
|
friend class IDF3_BOARD;
|
|
|
|
friend class IDF3_COMPONENT;
|
2014-05-28 06:26:46 +00:00
|
|
|
private:
|
|
|
|
double dia;
|
|
|
|
double x;
|
|
|
|
double y;
|
|
|
|
IDF3::KEY_PLATING plating;
|
|
|
|
IDF3::KEY_REFDES kref;
|
|
|
|
IDF3::KEY_HOLETYPE khole;
|
|
|
|
std::string refdes;
|
|
|
|
std::string holetype;
|
|
|
|
IDF3::KEY_OWNER owner;
|
|
|
|
|
2014-06-01 16:55:53 +00:00
|
|
|
/**
|
|
|
|
* Function read
|
|
|
|
* read a drill entry from an IDFv3 file
|
|
|
|
*
|
|
|
|
* @param aBoardFile is an open IDFv3 file; the file position must be within the DRILLED_HOLES section
|
|
|
|
* @param aBoardUnit is the board file's native unit (MM or THOU)
|
|
|
|
* @param aBoardState is the state value of the parser
|
|
|
|
*
|
|
|
|
* @return bool: true if data was successfully read, otherwise false. In case of an
|
|
|
|
* unrecoverable error an exception is thrown
|
|
|
|
*/
|
|
|
|
bool read( std::ifstream& aBoardFile, IDF3::IDF_UNIT aBoardUnit, IDF3::FILE_STATE aBoardState,
|
|
|
|
IDF3::IDF_VERSION aIdfVersion );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function write
|
|
|
|
* writes a single line representing a hole within a .DRILLED_HOLES section
|
|
|
|
* In case of an unrecoverable error an exception is thrown.
|
|
|
|
*
|
|
|
|
* @param aBoardFile is an open BOARD file
|
|
|
|
* @param aBoardUnit is the native unit of the output file
|
|
|
|
*/
|
|
|
|
void write( std::ofstream& aBoardFile, IDF3::IDF_UNIT aBoardUnit );
|
|
|
|
|
2014-05-28 06:26:46 +00:00
|
|
|
public:
|
|
|
|
/**
|
|
|
|
* Constructor IDF_DRILL_DATA
|
|
|
|
* creates an empty drill entry which can be populated by the
|
2014-06-01 16:55:53 +00:00
|
|
|
* read() function
|
2014-05-28 06:26:46 +00:00
|
|
|
*/
|
|
|
|
IDF_DRILL_DATA();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructor IDF_DRILL_DATA
|
|
|
|
* creates a drill entry with information compliant with the
|
|
|
|
* IDFv3 specifications.
|
|
|
|
* @param aDrillDia : drill diameter
|
|
|
|
* @param aPosX : X coordinate of the drill center
|
|
|
|
* @param aPosY : Y coordinate of the drill center
|
|
|
|
* @param aPlating : flag, PTH or NPTH
|
|
|
|
* @param aRefDes : component Reference Designator
|
|
|
|
* @param aHoleType : purpose of hole
|
|
|
|
* @param aOwner : one of MCAD, ECAD, UNOWNED
|
|
|
|
*/
|
|
|
|
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 );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function Matches
|
|
|
|
* returns true if the given drill diameter and location
|
|
|
|
* matches the diameter and location of this IDF_DRILL_DATA object
|
|
|
|
*
|
|
|
|
* @param aDrillDia is the drill diameter (mm)
|
|
|
|
* @param aPosX is the X position (mm) of the drilled hole
|
|
|
|
* @param aPosY is the Y position (mm) of the drilled hole
|
|
|
|
*
|
|
|
|
* @return bool: true if the diameter and position match this object
|
|
|
|
*/
|
|
|
|
bool Matches( double aDrillDia, double aPosX, double aPosY );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function GettDrillDia
|
|
|
|
* returns the drill diameter in mm
|
|
|
|
*/
|
|
|
|
double GetDrillDia();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function GettDrillXPos
|
|
|
|
* returns the drill's X position in mm
|
|
|
|
*/
|
|
|
|
double GetDrillXPos();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function GettDrillYPos
|
|
|
|
* returns the drill's Y position in mm
|
|
|
|
*/
|
|
|
|
double GetDrillYPos();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function GetDrillPlating
|
|
|
|
* returns the plating value (PTH, NPTH)
|
|
|
|
*/
|
|
|
|
IDF3::KEY_PLATING GetDrillPlating();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function GetDrillRefDes
|
|
|
|
* returns the reference designator of the hole; this
|
|
|
|
* may be a component reference designator, BOARD, or
|
|
|
|
* NOREFDES as per IDFv3.
|
|
|
|
*/
|
|
|
|
const std::string& GetDrillRefDes();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function GetDrillHoleType
|
|
|
|
* returns the classification of the hole; this may be one of
|
|
|
|
* PIN, VIA, MTG, TOOL, or a user-specified string
|
|
|
|
*/
|
|
|
|
const std::string& GetDrillHoleType();
|
2014-06-01 16:55:53 +00:00
|
|
|
|
|
|
|
IDF3::KEY_OWNER GetDrillOwner( void )
|
|
|
|
{
|
|
|
|
return owner;
|
|
|
|
}
|
2014-05-28 06:26:46 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @Class IDF_POINT
|
|
|
|
* represents a point as used by the various IDF related classes
|
|
|
|
*/
|
|
|
|
class IDF_POINT
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
double x; // < X coordinate
|
|
|
|
double y; // < Y coordinate
|
|
|
|
|
|
|
|
IDF_POINT()
|
|
|
|
{
|
|
|
|
x = 0.0;
|
|
|
|
y = 0.0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function Matches()
|
|
|
|
* returns true if the given coordinate point is within the given radius
|
|
|
|
* of the point.
|
|
|
|
*
|
|
|
|
* @param aPoint : coordinates of the point being compared
|
|
|
|
* @param aRadius : radius (mm) within which the points are considered the same
|
|
|
|
*
|
|
|
|
* @return bool: true if this point matches the given point
|
|
|
|
*/
|
|
|
|
bool Matches( const IDF_POINT& aPoint, double aRadius = 1e-5 );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function CalcDistance()
|
|
|
|
* returns the Euclidean distance between this point and the given point
|
|
|
|
*
|
|
|
|
* @param aPoint : coordinates of the point whose distance is to be determined
|
|
|
|
*
|
|
|
|
* @return double: distance between this point and aPoint
|
|
|
|
*/
|
|
|
|
double CalcDistance( const IDF_POINT& aPoint ) const;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @Class IDF_SEGMENT
|
|
|
|
* represents a geometry segment as used in IDFv3 outlines; it may be any of
|
|
|
|
* an arc, line segment, or circle
|
|
|
|
*/
|
|
|
|
class IDF_SEGMENT
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
/**
|
|
|
|
* Function CalcCenterAndRadius()
|
|
|
|
* Calculates the center, radius, and angle between center and start point given the
|
|
|
|
* IDF compliant points and included angle.
|
|
|
|
*
|
|
|
|
* @var startPoint, @var endPoint, and @var angle must be set prior as per IDFv3
|
|
|
|
*/
|
|
|
|
void CalcCenterAndRadius( void );
|
|
|
|
|
|
|
|
public:
|
|
|
|
IDF_POINT startPoint; ///< starting point coordinates in mm
|
|
|
|
IDF_POINT endPoint; ///< end point coordinates in mm
|
|
|
|
IDF_POINT center; ///< center of an arc or circle; internally calculated and not to be set by the user
|
|
|
|
double angle; ///< included angle (degrees) according to IDFv3 specification
|
|
|
|
double offsetAngle; ///< angle between center and start of arc; internally calculated
|
|
|
|
double radius; ///< radius of the arc or circle; internally calculated
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructor IDF_SEGMENT
|
|
|
|
* initializes the internal variables
|
|
|
|
*/
|
|
|
|
IDF_SEGMENT();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function IDF_SEGMENT
|
|
|
|
* creates a straight segment
|
|
|
|
*/
|
|
|
|
IDF_SEGMENT( const IDF_POINT& aStartPoint, const IDF_POINT& aEndPoint );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructor IDF_SEGMENT
|
|
|
|
* creates a straight segment, arc, or circle depending on the angle
|
|
|
|
*
|
|
|
|
* @param aStartPoint : start point (center if using KiCad convention, otherwise IDF convention)
|
|
|
|
* @param aEndPoint : end point (start of arc if using KiCad convention, otherwise IDF convention)
|
|
|
|
* @param aAngle : included angle; the KiCad convention is equivalent to the IDF convention
|
|
|
|
* @param fromKicad : set true if we need to convert from KiCad to IDF convention
|
|
|
|
*/
|
|
|
|
IDF_SEGMENT( const IDF_POINT& aStartPoint,
|
|
|
|
const IDF_POINT& aEndPoint,
|
|
|
|
double aAngle,
|
|
|
|
bool aFromKicad );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function MatchesStart
|
|
|
|
* returns true if the given coordinate is within a radius 'rad'
|
|
|
|
* of the start point.
|
|
|
|
*
|
|
|
|
* @param aPoint : coordinates of the point (mm) being compared
|
|
|
|
* @param aRadius : radius (mm) within which the points are considered the same
|
|
|
|
*
|
|
|
|
* @return bool: true if the given point matches the start point of this segment
|
|
|
|
*/
|
|
|
|
bool MatchesStart( const IDF_POINT& aPoint, double aRadius = 1e-3 );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function MatchesEnd
|
|
|
|
* returns true if the given coordinate is within a radius 'rad'
|
|
|
|
* of the end point.
|
|
|
|
*
|
|
|
|
* @param aPoint : coordinates (mm) of the point being compared
|
|
|
|
* @param aRadius : radius (mm) within which the points are considered the same
|
|
|
|
*
|
|
|
|
* @return bool: true if the given point matches the end point of this segment
|
|
|
|
*/
|
|
|
|
bool MatchesEnd( const IDF_POINT& aPoint, double aRadius = 1e-3 );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function IsCircle
|
|
|
|
* returns true if this segment is a circle
|
|
|
|
*/
|
|
|
|
bool IsCircle( void );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function GetMinX()
|
|
|
|
* returns the minimum X coordinate of this segment
|
|
|
|
*/
|
|
|
|
double GetMinX( void );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function SwapEnds()
|
|
|
|
* Swaps the start and end points and alters internal
|
|
|
|
* variables as necessary for arcs
|
|
|
|
*/
|
|
|
|
void SwapEnds( void );
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @Class IDF_OUTLINE
|
|
|
|
* contains segment and winding information for an IDF outline
|
|
|
|
*/
|
|
|
|
class IDF_OUTLINE
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
double dir; // accumulator to help determine winding direction
|
|
|
|
std::list<IDF_SEGMENT*> outline; // sequential segments comprising an outline
|
|
|
|
|
|
|
|
public:
|
|
|
|
IDF_OUTLINE() { dir = 0.0; }
|
|
|
|
~IDF_OUTLINE() { Clear(); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function IsCCW
|
|
|
|
* returns true if the current list of points represents a counterclockwise winding
|
|
|
|
*/
|
|
|
|
bool IsCCW( void );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function IsCircle
|
|
|
|
* returns true if this outline is a circle
|
|
|
|
*/
|
|
|
|
bool IsCircle( void );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function Clear
|
|
|
|
* clears the internal list of outline segments
|
|
|
|
*/
|
|
|
|
void Clear( void )
|
|
|
|
{
|
|
|
|
dir = 0.0;
|
|
|
|
|
|
|
|
while( !outline.empty() )
|
|
|
|
{
|
|
|
|
delete outline.front();
|
|
|
|
outline.pop_front();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function size
|
|
|
|
* returns the size of the internal segment list
|
|
|
|
*/
|
|
|
|
size_t size( void )
|
|
|
|
{
|
|
|
|
return outline.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function empty
|
|
|
|
* returns true if the internal segment list is empty
|
|
|
|
*/
|
|
|
|
bool empty( void )
|
|
|
|
{
|
|
|
|
return outline.empty();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function front
|
|
|
|
* returns the front() iterator of the internal segment list
|
|
|
|
*/
|
|
|
|
IDF_SEGMENT*& front( void )
|
|
|
|
{
|
|
|
|
return outline.front();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function back
|
|
|
|
* returns the back() iterator of the internal segment list
|
|
|
|
*/
|
|
|
|
IDF_SEGMENT*& back( void )
|
|
|
|
{
|
|
|
|
return outline.back();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function begin
|
|
|
|
* returns the begin() iterator of the internal segment list
|
|
|
|
*/
|
|
|
|
std::list<IDF_SEGMENT*>::iterator begin( void )
|
|
|
|
{
|
|
|
|
return outline.begin();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function end
|
|
|
|
* returns the end() iterator of the internal segment list
|
|
|
|
*/
|
|
|
|
std::list<IDF_SEGMENT*>::iterator end( void )
|
|
|
|
{
|
|
|
|
return outline.end();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function push
|
|
|
|
* adds a segment to the internal segment list; segments must be added
|
|
|
|
* in order so that startPoint[N] == endPoint[N - 1]
|
|
|
|
*
|
|
|
|
* @param item is a pointer to the segment to add to the outline
|
|
|
|
*
|
|
|
|
* @return bool: true if the segment was added, otherwise false
|
|
|
|
* (outline restrictions have been violated)
|
|
|
|
*/
|
|
|
|
bool push( IDF_SEGMENT* item );
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif // IDF_COMMON_H
|