/* * This program source code file is part of KiCad, a free EDA CAD application. * * 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 * 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_OUTLINES_H #define IDF_OUTLINES_H #include #include #include #include /* * NOTES ON OUTLINE TYPES: * * BOARD_OUTLINE (PANEL_OUTLINE) * .BOARD_OUTLINE [OWNER] * [thickness] * [outlines] * * OTHER_OUTLINE * .OTHER_OUTLINE [OWNER] * [outline identifier] [thickness] [board side: Top/Bot] * [outline] * * ROUTE_OUTLINE * .ROUTE_OUTLINE [OWNER] * [layers] * [outline] * * PLACE_OUTLINE * .PLACE_OUTLINE [OWNER] * [board side: Top/Bot/Both] [height] * [outline] * * ROUTE_KEEPOUT * .ROUTE_KEEPOUT [OWNER] * [layers] * [outline] * * VIA_KEEPOUT * .VIA_KEEPOUT [OWNER] * [outline] * * PLACE_KEEPOUT * .PLACE_KEEPOUT [OWNER] * [board side: Top/Bot/Both] [height] * [outline] * * Placement Group * .PLACE_REGION [OWNER] * [side: Top/Bot/Both ] [component group name] * [outline] * * Component Outline: * .ELECTRICAL/.MECHANICAL * [GEOM] [PART] [UNIT] [HEIGHT] * [outline] * [PROP] [prop name] [prop value] */ class IDF3_BOARD; /** * IDFv3 BOARD OUTLINE data and is the basis of other IDFv3 outline objects. */ class BOARD_OUTLINE { public: BOARD_OUTLINE(); virtual ~BOARD_OUTLINE(); /** * Function SetUnit * sets the native unit of the outline; except for component outlines this must * be the same as the native unit of the parent IDF_BOARD object * * @param aUnit is the native unit (UNIT_MM or UNIT_THOU) */ virtual bool SetUnit( IDF3::IDF_UNIT aUnit ); /** * Return the native unit type of the outline. * * @return IDF_UNIT is the native unit (UNIT_MM or UNIT_THOU). */ virtual IDF3::IDF_UNIT GetUnit( void ); /** * Set the thickness or height of the outline (mm). * * @param aThickness is the thickness or height of the outline in mm. */ virtual bool SetThickness( double aThickness ); /** * @return the thickness or height of an outline (mm). */ virtual double GetThickness( void ); /** * Free memory and reinitializes all internal data except for the parent pointer. * * @return true if OK, false on ownership violations. */ virtual bool Clear( void ); /** * @return the type of outline according to the IDFv3 classification. */ IDF3::OUTLINE_TYPE GetOutlineType( void ); /** * @return the parent IDF_BOARD object. */ IDF3_BOARD* GetParent( void ); /** * Add the specified outline to this object. * * @param aOutline is a valid IDF outline. * @return true if the outline was added; false if the outline already existed or an * ownership violation occurs. */ bool AddOutline( IDF_OUTLINE* aOutline ); /** * Remove the given outline, subject to IDF ownership rules, * if it is owned by this object. * * The outline pointer remains valid and it is the user's responsibility to delete the * object. The first outline in the list will never be deleted unless it is the sole * remaining outline; this is to ensure that a board outline is not removed while the * cutouts remain. * * @param aOutline is a pointer to the outline to remove from the list. * @return true if the outline was found and removed; false if the outline was not found * or an ownership violation occurs. */ bool DelOutline( IDF_OUTLINE* aOutline ); /** * Delete the outline specified by the given index, subject to IDF ownership rules. * * The outline data is destroyed. The first outline in the list will never be deleted * unless it is the sole remaining outline; this is to ensure that a board outline is * not removed while the cutouts remain. * * @param aIndex is an index to the outline to delete * @return true if the outline was found and deleted; false if the outline was not found * or an ownership violation or indexation error occurs. */ bool DelOutline( size_t aIndex ); /** * Return outlines list. * * It is up to the user to respect the IDFv3 specification and avoid changes to this * list which are in violation of the specification. */ const std::list< IDF_OUTLINE* >*const GetOutlines( void ); /** * @return the number of items in the internal outline list. */ size_t OutlinesSize( void ); /** * Return a pointer to the outline as specified by aIndex. * * If the index is out of bounds NULL is returned and the error message is set. It is the * responsibility of the user to observe IDF ownership rules. */ IDF_OUTLINE* GetOutline( size_t aIndex ); /** * @return the ownership status of the outline (ECAD, MCAD, UNOWNED). */ IDF3::KEY_OWNER GetOwner( void ); /** * Set the ownership status of the outline subject to IDF ownership rules. * * @return true if the ownership was changed and false if a specification violation occurred. */ bool SetOwner( IDF3::KEY_OWNER aOwner ); /** * @return true if this type of outline only supports a single outline. All outlines except * for BOARD_OUTLINE are single. */ bool IsSingle( void ); /** * Clear internal data except for the parent pointer. */ void ClearOutlines( void ); /** * Add a comment to the outline data. * * This function is not subject to IDF ownership rules. */ void AddComment( const std::string& aComment ); /** * @return the number of comments in the internal list. */ size_t CommentsSize( void ); /** * @return the internal list of comments. */ std::list< std::string >* GetComments( void ); /** * @return indexed comment or NULL if the index is out of bounds. */ const std::string* GetComment( size_t aIndex ); /** * Deletes a comment based on the given index. * * @return true if a comment was deleted, false if the index is out of bounds. */ bool DeleteComment( size_t aIndex ); /** * Deletes all comments. */ void ClearComments( void ); const std::string& GetError( void ) { return errormsg; } protected: // Read outline data from a BOARD or LIBRARY file's outline section void readOutlines( std::istream& aBoardFile, IDF3::IDF_VERSION aIdfVersion ); // Write comments to a BOARD or LIBRARY file (must not be within a SECTION as per IDFv3 spec) bool writeComments( std::ostream& aBoardFile ); // Write the outline owner to a BOARD file bool writeOwner( std::ostream& aBoardFile ); // Write the data of a single outline object void writeOutline( std::ostream& aBoardFile, IDF_OUTLINE* aOutline, size_t aIndex ); // Iterate through the outlines and write out all data void writeOutlines( std::ostream& aBoardFile ); // write outline data (no headers) // Clear internal list of outlines void clearOutlines( void ); /** * Set the parent IDF_BOARD object. */ void setParent( IDF3_BOARD* aParent ); // Shadow routines used by friends to bypass ownership checks bool addOutline( IDF_OUTLINE* aOutline ); virtual bool setThickness( double aThickness ); virtual void clear( void ); /** * Read data from a .BOARD_OUTLINE section. * * In case of an unrecoverable error an exception is thrown. On a successful * return the file pointer will be at the line following .END_BOARD_OUTLINE * * @param aBoardFile is an IDFv3 file opened for reading. * @param aHeader is the ".BOARD_OUTLINE" header line as read by FetchIDFLine. */ virtual void readData( std::istream& aBoardFile, const std::string& aHeader, IDF3::IDF_VERSION aIdfVersion ); /** * Write the comments and .BOARD_OUTLINE section to an IDFv3 file. * Throws exceptions. * * @param aBoardFile is an IDFv3 file opened for writing. */ virtual void writeData( std::ostream& aBoardFile ); std::string errormsg; std::list< IDF_OUTLINE* > outlines; // indicates the owner of this outline (MCAD, ECAD, UNOWNED). IDF3::KEY_OWNER owner; IDF3::OUTLINE_TYPE outlineType; // type of IDF outline bool single; // true if only a single outline is accepted std::list< std::string > comments; // associated comment list IDF3::IDF_UNIT unit; // outline's native unit (MM or THOU) IDF3_BOARD* parent; // BOARD which contains this outline double thickness; // Board/Extrude Thickness or Height (IDF spec) private: friend class IDF3_BOARD; }; /** * Miscellaneous extrusions on the board */ class OTHER_OUTLINE : public BOARD_OUTLINE { public: OTHER_OUTLINE( IDF3_BOARD* aParent ); /** * Function SetOutlineIdentifier * sets the Outline Identifier string of this OTHER_OUTLINE object * as per IDFv3 spec. */ virtual bool SetOutlineIdentifier( const std::string& aUniqueID ); /** * Function GetOutlineIdentifier * returns the object's Outline Identifier */ virtual const std::string& GetOutlineIdentifier( void ); /** * Function SetSide * sets the side which this outline is applicable to (TOP, BOTTOM). * * @return bool: true if the side was set, false if the side is invalid * or there is a violation of IDF ownership rules. */ virtual bool SetSide( IDF3::IDF_LAYER aSide ); /** * Function GetSide * returns the side which this outline is applicable to */ virtual IDF3::IDF_LAYER GetSide( void ); /** * Function Clear * deletes internal data except for the parent object */ virtual bool Clear( void ) override; private: /** * Read an OTHER_OUTLINE data from an IDFv3 file. * If an unrecoverable error occurs an exception is thrown. * * @param aBoardFile is an IDFv3 file open for reading. * @param aHeader is the .OTHER_OUTLINE header as read via FetchIDFLine. */ virtual void readData( std::istream& aBoardFile, const std::string& aHeader, IDF3::IDF_VERSION aIdfVersion ) override; /** * Write the OTHER_OUTLINE data to an open IDFv3 file. * * @param aBoardFile is an IDFv3 file open for writing. * @return true if the data was successfully written, otherwise false. */ virtual void writeData( std::ostream& aBoardFile ) override; friend class IDF3_BOARD; std::string uniqueID; // Outline Identifier (IDF spec) IDF3::IDF_LAYER side; // Board Side [TOP/BOTTOM ONLY] (IDF spec) }; /** * Routing areas on the board. */ class ROUTE_OUTLINE : public BOARD_OUTLINE { public: ROUTE_OUTLINE( IDF3_BOARD* aParent ); /** * Function SetLayers * sets the layer or group of layers this outline is applicable to. * This function is subject to IDF ownership rules; true is returned * on success, otherwise false is returned and the error message is set. */ virtual bool SetLayers( IDF3::IDF_LAYER aLayer ); /** * Function GetLayers * returns the layer or group of layers which this outline is applicable to */ virtual IDF3::IDF_LAYER GetLayers( void ); /** * Function Clear * deletes internal data except for the parent object */ virtual bool Clear( void ) override; private: friend class IDF3_BOARD; /** * Read ROUTE_OUTLINE data from an IDFv3 file. * If an unrecoverable error occurs an exception is thrown. * * @param aBoardFile is an open IDFv3 board file. * @param aHeader is the .ROUTE_OUTLINE header as returned by FetchIDFLine. */ virtual void readData( std::istream& aBoardFile, const std::string& aHeader, IDF3::IDF_VERSION aIdfVersion ) override; /** * Write the ROUTE_OUTLINE data to an open IDFv3 file. */ virtual void writeData( std::ostream& aBoardFile ) override; protected: IDF3::IDF_LAYER layers; // Routing layers (IDF spec) }; /** * Area on the board for placing components. */ class PLACE_OUTLINE : public BOARD_OUTLINE { public: PLACE_OUTLINE( IDF3_BOARD* aParent ); /** * Function SetSide * sets the side (TOP, BOTTOM, BOTH) which this outline applies to. * This function is subject to IDF ownership rules; true is returned * on success, otherwise false is returned and the error message is set. */ virtual bool SetSide( IDF3::IDF_LAYER aSide ); /** * Function GetSide * returns the side which this outline is applicable to */ virtual IDF3::IDF_LAYER GetSide( void ); /** * Function SetMaxHeight * sets the maximum height of a component within this outline. * This function is subject to IDF ownership rules; true is returned * on success, otherwise false is returned and the error message is set. */ virtual bool SetMaxHeight( double aHeight ); /** * Function GetMaxHeight * returns the maximum allowable height for a component in this region */ virtual double GetMaxHeight( void ); /** * Function Clear * deletes all internal data */ virtual bool Clear( void ) override; private: friend class IDF3_BOARD; /** * Read PLACE_OUTLINE data from an open IDFv3 file. * * If an unrecoverable error occurs an exception is thrown. * * @param aBoardFile is an IDFv3 file opened for reading. * @param aHeader is the .PLACE_OUTLINE header as returned by FetchIDFLine. */ virtual void readData( std::istream& aBoardFile, const std::string& aHeader, IDF3::IDF_VERSION aIdfVersion ) override; /** * Write the PLACE_OUTLINE data to an open IDFv3 file. * * @param aBoardFile is an IDFv3 file opened for writing. * @return true if the data was successfully written, otherwise false. */ virtual void writeData( std::ostream& aBoardFile ) override; protected: IDF3::IDF_LAYER side; // Board Side [TOP/BOTTOM/BOTH ONLY] (IDF spec) }; /** * Regions and layers where no electrical routing is permitted. */ class ROUTE_KO_OUTLINE : public ROUTE_OUTLINE { public: ROUTE_KO_OUTLINE( IDF3_BOARD* aParent ); }; /** * Region in which vias are prohibited. * * @note IDFv3 only considers thru-hole vias and makes no statement regarding behavior with * blind or buried vias. */ class VIA_KO_OUTLINE : public OTHER_OUTLINE { public: VIA_KO_OUTLINE( IDF3_BOARD* aParent ); }; /** * Regions and layers in which no component may be placed or on which a maximum component height * is in effect. */ class PLACE_KO_OUTLINE : public PLACE_OUTLINE { public: PLACE_KO_OUTLINE( IDF3_BOARD* aParent ); }; /** * Regions and layers in which user-specified features or components may be placed. */ class GROUP_OUTLINE : public BOARD_OUTLINE { public: GROUP_OUTLINE( IDF3_BOARD* aParent ); /** * Set the side which this outline applies to (TOP, BOTTOM, BOTH). * * This function is subject to IDF ownership rules; true is returned * on success, otherwise false is returned and the error message is set. */ virtual bool SetSide( IDF3::IDF_LAYER aSide ); /** * @return the side which this outline applies to. */ virtual IDF3::IDF_LAYER GetSide( void ); /** * Set the name of the group, subject to IDF ownership rules. * * This function is subject to IDF ownership rules; true is returned * on success, otherwise false is returned and the error message is set. */ virtual bool SetGroupName( std::string aGroupName ); /** * Return a reference to the (non-unique) group name. */ virtual const std::string& GetGroupName( void ); /** * Delete internal data, subject to IDF ownership rules. */ virtual bool Clear( void ) override; private: friend class IDF3_BOARD; /** * Read GROUP_OUTLINE data from an open IDFv3 file. * * If an unrecoverable error occurs an exception is thrown. * * @param aBoardFile is an open IDFv3 file. * @param aHeader is the .PLACE_REGION header as returned by FetchIDFLine. */ virtual void readData( std::istream& aBoardFile, const std::string& aHeader, IDF3::IDF_VERSION aIdfVersion ) override; /** * Write the data to a .PLACE_REGION section of an IDFv3 file. * * @param aBoardFile is an IDFv3 file open for writing. * @return true if the data is successfully written, otherwise false. */ virtual void writeData( std::ostream& aBoardFile ) override; IDF3::IDF_LAYER side; // Board Side [TOP/BOTTOM/BOTH ONLY] (IDF spec) std::string groupName; // non-unique string }; /** * A component's outline as stored in an IDF library file. */ class IDF3_COMP_OUTLINE : public BOARD_OUTLINE { public: IDF3_COMP_OUTLINE( IDF3_BOARD* aParent ); /** * Delete internal outline data. */ virtual bool Clear( void ) override; /** * Set the type of component outline (.ELECTRICAL or .MECHANICAL). * * @return true on success, otherwise false and the error message is set. */ bool SetComponentClass( IDF3::COMP_TYPE aCompClass ); /** * @return2 the class of component represented by this outline. */ IDF3::COMP_TYPE GetComponentClass( void ); /** * Set the Geometry Name (Package Name, IDFv3 spec) of the component outline. */ void SetGeomName( const std::string& aGeomName ); /** * @return the Geometry Name (Package Name) of the component outline. */ const std::string& GetGeomName( void ); /** * Set the Part Name (Part Number, IDFv3 spec) of the component outline. */ void SetPartName( const std::string& aPartName ); /** * Return the Part Name (Part Number) of the component outline. */ const std::string& GetPartName( void ); /** * @return the unique identifier for this component outline, this is equal to * GEOM_NAME + "_" + PART_NAME. */ const std::string& GetUID( void ); /** * Create a default outline with the given Geometry and Part names. * * This outline is a star with outer radius 5mm and inner radius 2.5mm. */ bool CreateDefaultOutline( const std::string &aGeom, const std::string &aPart ); // XXX: property manipulators private: friend class IDF3_BOARD; friend class IDF3_COMP_OUTLINE_DATA; void readProperties( std::istream& aLibFile ); bool writeProperties( std::ostream& aLibFile ); /** * Read a component outline from an open IDFv3 file. * * If an unrecoverable error occurs, an exception is thrown. * * @param aLibFile is an open IDFv3 Library file. * @param aHeader is the .ELECTRICAL or .MECHANICAL header as returned by FetchIDFLine. */ virtual void readData( std::istream& aLibFile, const std::string& aHeader, IDF3::IDF_VERSION aIdfVersion ) override; /** * Write comments and component outline data to an IDFv3 Library file. * * @param aLibFile is an IDFv3 library file open for writing. * @return true if the data was successfully written, otherwise false. */ virtual void writeData( std::ostream& aLibFile ) override; /** * Increment the internal reference counter to keep track of the number of * components referring to this outline. * * @return the number of current references to this component outline. */ int incrementRef( void ); /** * Decrement the internal reference counter to keep track of the number of * components referring to this outline. * * @return the number of remaining references or -1 if there were no references when the * function was invoked, in which case the error message is also set. */ int decrementRef( void ); std::string uid; // unique ID std::string geometry; // geometry name (IDF) std::string part; // part name (IDF) IDF3::COMP_TYPE compType; // component type int refNum; // number of components referring to this outline std::map< std::string, std::string > props; // properties list }; #endif // IDF_OUTLINES_H