/**
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 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 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see .
*/
#ifndef PCB_IO_IPC2581_H_
#define PCB_IO_IPC2581_H_
#include
#include
#include
#include
#include // PCB_LAYER_ID
#include
#include
#include
#include
#include
class BOARD;
class BOARD_ITEM;
class EDA_TEXT;
class FOOTPRINT;
class PROGRESS_REPORTER;
class NETINFO_ITEM;
class PAD;
class PCB_SHAPE;
class PCB_VIA;
class PCB_TEXT;
class PROGRESS_REPORTER;
class SHAPE_POLY_SET;
class SHAPE_SEGMENT;
class PCB_IO_IPC2581 : public PCB_IO
{
public:
PCB_IO_IPC2581() : PCB_IO( wxS( "IPC-2581" ) )
{
m_total_bytes = 0;
m_scale = 1.0;
m_sigfig = 3;
m_version = 'B';
m_enterpriseNode = nullptr;
m_board = nullptr;
m_props = nullptr;
m_shape_user_node = nullptr;
m_shape_std_node = nullptr;
m_line_node = nullptr;
m_last_padstack = nullptr;
m_progress_reporter = nullptr;
m_xml_doc = nullptr;
m_xml_root = nullptr;
}
~PCB_IO_IPC2581() override;
// BOARD* LoadBoard( const wxString& aFileName, BOARD* aAppendToMe,
// const STRING_UTF8_MAP* aProperties = nullptr,
// PROJECT* aProject = nullptr ) override;
void SaveBoard( const wxString& aFileName, BOARD* aBoard,
const STRING_UTF8_MAP* aProperties = nullptr ) override;
const IO_BASE::IO_FILE_DESC GetBoardFileDesc() const override
{
return IO_BASE::IO_FILE_DESC( wxEmptyString, {}, {}, false, false, true );
}
const IO_BASE::IO_FILE_DESC GetLibraryDesc() const override
{
// No library description for this plugin
return IO_BASE::IO_FILE_DESC( wxEmptyString, {} );
}
std::vector GetImportedCachedLibraryFootprints() override;
long long GetLibraryTimestamp( const wxString& aLibraryPath ) const override
{
return 0;
}
// Reading currently disabled
bool CanReadBoard( const wxString& aFileName ) const override
{
return false;
}
// Reading currently disabled
bool CanReadFootprint( const wxString& aFileName ) const override
{
return false;
}
// Reading currently disabled
bool CanReadLibrary( const wxString& aFileName ) const override
{
return false;
}
private:
/**
* Frees the memory allocated for the loaded footprints in #m_loaded_footprints.
*/
void clearLoadedFootprints();
/**
* Creates the XML header for IPC-2581
*/
wxXmlNode* generateXmlHeader();
/**
* Creates the Content section of the XML file. This holds the overview of
* the rest of the board data. Includes references to the step, bom, and layers
* as well as the content dictionaries
*/
wxXmlNode* generateContentSection();
/**
* Creates the logistical data header. This section defines the organization and person
* creating the file. Can be used for contact information and config management
*/
wxXmlNode* generateLogisticSection();
/**
* Creates the history section. This section defines the history of the file, the revision
* number, and the date of the revision as well as software used to create the file. Optionally,
* the data could include information about the git revision and tag
*/
wxXmlNode* generateHistorySection();
/**
* Creates the BOM section. This section defines the BOM data for the board. This includes
* the part number, manufacturer, and distributor information for each component on the board.
*/
wxXmlNode* generateBOMSection( wxXmlNode* aEcadNode );
/**
* Creates the ECAD section. This describes the layout, layers, and design as well as
* component placement and netlist information
*/
wxXmlNode* generateEcadSection();
/**
* Creates the Approved Vendor List section. If the user chooses, this will associate
* BOM items with vendor numbers and names.
*/
wxXmlNode* generateAvlSection();
void generateCadLayers( wxXmlNode* aCadLayerNode );
void generateDrillLayers( wxXmlNode* aCadLayerNode );
void generateStepSection( wxXmlNode* aCadNode );
void generateProfile( wxXmlNode* aStepNode );
void generateLogicalNets( wxXmlNode* aStepNode );
void generatePhyNetGroup( wxXmlNode* aStepNode );
void generateLayerFeatures( wxXmlNode* aStepNode );
void generateLayerSetDrill( wxXmlNode* aStepNode );
void generateLayerSetNet( wxXmlNode* aLayerNode, PCB_LAYER_ID aLayer, std::vector& aItems );
wxXmlNode* generateContentStackup( wxXmlNode* aContentNode );
void generateComponents( wxXmlNode* aStepNode );
void addCadHeader( wxXmlNode* aEcadNode );
wxXmlNode* addPackage( wxXmlNode* aStepNode, FOOTPRINT* aFootprint );
void addPad( wxXmlNode* aContentNode, const PAD* aPad, PCB_LAYER_ID aLayer );
void addVia( wxXmlNode* aContentNode, const PCB_VIA* aVia, PCB_LAYER_ID aLayer );
void addPadStack( wxXmlNode* aContentNode, const PAD* aPad );
void addPadStack( wxXmlNode* aContentNode, const PCB_VIA* aVia );
void addLocationNode( wxXmlNode* aContentNode, double aX, double aY );
void addLocationNode( wxXmlNode* aContentNode, const PAD& aPad, bool aRelative );
void addLocationNode( wxXmlNode* aContentNode, const PCB_SHAPE& aShape );
void addShape( wxXmlNode* aContentNode, const PCB_SHAPE& aShape );
void addShape( wxXmlNode* aContentNode, const PAD& aPad, PCB_LAYER_ID aLayer );
void addSlotCavity( wxXmlNode* aContentNode, const PAD& aPad, const wxString& aName );
void addKnockoutText( wxXmlNode* aContentNode, PCB_TEXT* aText );
void addText( wxXmlNode* aContentNode, EDA_TEXT* aShape, const KIFONT::METRICS& aFontMetrics );
void addLineDesc( wxXmlNode* aNode, int aWidth, LINE_STYLE aDashType, bool aForce = false );
void addFillDesc( wxXmlNode* aNode, FILL_T aFillType, bool aForce = false );
bool addPolygonNode( wxXmlNode* aParentNode, const SHAPE_POLY_SET::POLYGON& aPolygon,
FILL_T aFillType = FILL_T::FILLED_SHAPE, int aWidth = 0,
LINE_STYLE aDashType = LINE_STYLE::SOLID );
bool addPolygonCutouts( wxXmlNode* aParentNode, const SHAPE_POLY_SET::POLYGON& aPolygon );
bool addOutlineNode( wxXmlNode* aParentNode, const SHAPE_POLY_SET& aPolySet, int aWidth = 0,
LINE_STYLE aDashType = LINE_STYLE::SOLID );
bool addContourNode( wxXmlNode* aParentNode, const SHAPE_POLY_SET& aPolySet, int aOutline = 0,
FILL_T aFillType = FILL_T::FILLED_SHAPE, int aWidth = 0,
LINE_STYLE aDashType = LINE_STYLE::SOLID );
size_t lineHash( int aWidth, LINE_STYLE aDashType );
size_t shapeHash( const PCB_SHAPE& aShape );
wxString genString( const wxString& aStr, const char* aPrefix = nullptr ) const;
wxString genLayerString( PCB_LAYER_ID aLayer, const char* aPrefix ) const;
wxString genLayersString( PCB_LAYER_ID aTop, PCB_LAYER_ID aBottom, const char* aPrefix ) const;
wxString floatVal( double aVal );
wxString pinName( const PAD* aPad ) const;
wxString componentName( FOOTPRINT* aFootprint );
void addXY( wxXmlNode* aNode, const VECTOR2I& aVec, const char* aXName = nullptr,
const char* aYName = nullptr );
void addAttribute( wxXmlNode* aNode, const wxString& aName, const wxString& aValue );
wxXmlNode* insertNode( wxXmlNode* aParent, const wxString& aName );
wxXmlNode* appendNode( wxXmlNode* aParent, const wxString& aName );
void appendNode( wxXmlNode* aParent, wxXmlNode* aNode );
void insertNode( wxXmlNode* aParent, wxXmlNode* aNode );
void insertNodeAfter( wxXmlNode* aPrev, wxXmlNode* aNode );
void addLayerAttributes( wxXmlNode* aNode, PCB_LAYER_ID aLayer );
bool isValidLayerFor2581( PCB_LAYER_ID aLayer );
private:
size_t m_total_bytes; // m_loaded_footprints;
const STRING_UTF8_MAP* m_props;
std::map m_user_shape_dict; // m_std_shape_dict; // m_line_dict; // m_padstack_dict; // m_padstacks; //
m_footprint_dict; //_##)
std::map
m_footprint_refdes_dict; //
m_footprint_refdes_reverse_dict; //
m_OEMRef_dict; //>>
m_net_pin_dict; //
m_layer_name_map; //, std::vector>
m_drill_layers; //, std::vector>
m_slot_holes; // m_acceptable_chars; //