/* * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright The KiCad Developers, see AUTHORS.txt for contributors. * Author: SYSUEric . * * 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 . */ #include #include "odb_component.h" #include "odb_util.h" #include "hash_eda.h" #include "pcb_io_odbpp.h" ODB_COMPONENT& COMPONENTS_MANAGER::AddComponent( const FOOTPRINT* aFp, const EDA_DATA::PACKAGE& aPkg ) { auto& comp = m_compList.emplace_back( m_compList.size(), aPkg.m_index ); comp.m_center = ODB::AddXY( aFp->GetPosition() ); EDA_ANGLE angle = aFp->GetOrientation(); if( angle != ANGLE_0 ) { // odb Rotation is expressed in degrees and is always clockwise. // while kicad EDA_ANGLE is anticlockwise. angle = ANGLE_360 - angle; comp.m_rot = ODB::Double2String( angle.Normalize().AsDegrees() ); } if( aFp->IsFlipped() ) { comp.m_mirror = wxT( "M" ); } comp.m_comp_name = aFp->GetReference().ToAscii(); comp.m_part_name = wxString::Format( "%s_%s", aFp->GetFPID().GetFullLibraryName(), aFp->GetFPID().GetLibItemName().wx_str() ); // ODB++ cannot handle spaces in these fields ODB::RemoveWhitespace( comp.m_comp_name ); ODB::RemoveWhitespace( comp.m_part_name ); if( comp.m_comp_name.IsEmpty() ) { // The spec requires a component name; some ODB++ parsers can't handle it being empty comp.m_comp_name = wxString::Format( "UNNAMED%zu", m_compList.size() ); } for( PCB_FIELD* field : aFp->GetFields() ) { if( field->GetId() == FIELD_T::REFERENCE ) continue; wxString key = field->GetName(); ODB::RemoveWhitespace( key ); comp.m_prp[key] = wxString::Format( "'%s'", field->GetText() ); } if( aFp->IsDNP() ) { AddSystemAttribute( comp, ODB_ATTR::NO_POP{ true } ); } if( aFp->GetAttributes() & FP_SMD ) { AddSystemAttribute( comp, ODB_ATTR::COMP_MOUNT_TYPE::MT_SMD ); } else if( aFp->GetAttributes() & FP_THROUGH_HOLE ) { AddSystemAttribute( comp, ODB_ATTR::COMP_MOUNT_TYPE::THT ); } else { AddSystemAttribute( comp, ODB_ATTR::COMP_MOUNT_TYPE::OTHER ); } return comp; } void COMPONENTS_MANAGER::Write( std::ostream& ost ) const { ost << "UNITS=" << PCB_IO_ODBPP::m_unitsStr << std::endl; WriteAttributes( ost ); for( const auto& comp : m_compList ) { comp.Write( ost ); } } void ODB_COMPONENT::Write( std::ostream& ost ) const { ost << "# CMP " << m_index << std::endl; ost << "CMP " << m_pkg_ref << " " << m_center.first << " " << m_center.second << " " << m_rot << " " << m_mirror << " " << m_comp_name << " " << m_part_name; WriteAttributes( ost ); ost << std::endl; for( const auto& [key, value] : m_prp ) { ost << "PRP " << key << " " << value << std::endl; } for( const auto& toep : m_toeprints ) { toep.Write( ost ); } ost << "#" << std::endl; } void ODB_COMPONENT::TOEPRINT::Write( std::ostream& ost ) const { ost << "TOP " << m_pin_num << " " << m_center.first << " " << m_center.second << " " << m_rot << " " << m_mirror << " " << m_net_num << " " << m_subnet_num << " " << m_toeprint_name << std::endl; }