KiCad PCB EDA Suite
Loading...
Searching...
No Matches
api_sch_utils.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2024 Jon Evans <[email protected]>
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <algorithm>
22#include <trace_helpers.h>
23
24#include <sch_pin.h>
25#include <lib_symbol.h>
26#include <sch_symbol.h>
27#include <sch_bitmap.h>
28#include <sch_bus_entry.h>
29#include <sch_field.h>
30#include <sch_group.h>
31#include <sch_junction.h>
32#include <sch_label.h>
33#include <sch_line.h>
34#include <sch_no_connect.h>
35#include <sch_shape.h>
36#include <sch_sheet.h>
37#include <sch_screen.h>
38#include <sch_sheet_pin.h>
39#include <sch_table.h>
40#include <sch_tablecell.h>
41#include <sch_text.h>
42#include <sch_textbox.h>
43
44#include "api_sch_utils.h"
45
46#include <api/api_utils.h>
47
48
49using namespace kiapi::common;
50
51
52std::unique_ptr<EDA_ITEM> CreateItemForType( KICAD_T aType, EDA_ITEM* aContainer )
53{
54 SCH_ITEM* parentSchItem = dynamic_cast<SCH_ITEM*>( aContainer );
55
56 switch( aType )
57 {
58 case SCH_JUNCTION_T: return std::make_unique<SCH_JUNCTION>();
59 case SCH_NO_CONNECT_T: return std::make_unique<SCH_NO_CONNECT>();
60 case SCH_BUS_WIRE_ENTRY_T: return std::make_unique<SCH_BUS_WIRE_ENTRY>();
61 case SCH_BUS_BUS_ENTRY_T: return std::make_unique<SCH_BUS_BUS_ENTRY>();
62 case SCH_LINE_T: return std::make_unique<SCH_LINE>();
63 case SCH_SHAPE_T: return std::make_unique<SCH_SHAPE>();
64 case SCH_BITMAP_T: return std::make_unique<SCH_BITMAP>();
65 case SCH_TEXTBOX_T: return std::make_unique<SCH_TEXTBOX>();
66 case SCH_TEXT_T: return std::make_unique<SCH_TEXT>();
67 case SCH_TABLE_T: return std::make_unique<SCH_TABLE>();
68 case SCH_TABLECELL_T: return std::make_unique<SCH_TABLECELL>();
69 case SCH_LABEL_T: return std::make_unique<SCH_LABEL>();
70 case SCH_GLOBAL_LABEL_T: return std::make_unique<SCH_GLOBALLABEL>();
71 case SCH_HIER_LABEL_T: return std::make_unique<SCH_HIERLABEL>();
72 case SCH_DIRECTIVE_LABEL_T: return std::make_unique<SCH_DIRECTIVE_LABEL>();
73 case SCH_FIELD_T: return std::make_unique<SCH_FIELD>( parentSchItem );
74 case SCH_GROUP_T: return std::make_unique<SCH_GROUP>();
75 case SCH_SYMBOL_T: return std::make_unique<SCH_SYMBOL>();
76 case LIB_SYMBOL_T: return std::make_unique<LIB_SYMBOL>( wxEmptyString );
77 case SCH_SHEET_T:
78 {
79 if( aContainer && aContainer->Type() == SCH_SCREEN_T )
80 return std::make_unique<SCH_SHEET>( static_cast<SCH_SCREEN*>( aContainer ) );
81
82 return nullptr;
83 }
84
85
86 case SCH_SHEET_PIN_T:
87 if( aContainer && aContainer->Type() == SCH_SHEET_T )
88 return std::make_unique<SCH_SHEET_PIN>( static_cast<SCH_SHEET*>( aContainer ) );
89
90 return nullptr;
91
92 case SCH_PIN_T:
93 if( aContainer && aContainer->Type() == LIB_SYMBOL_T )
94 return std::make_unique<SCH_PIN>( static_cast<LIB_SYMBOL*>( aContainer ) );
95
96 return nullptr;
97
98 default:
99 return nullptr;
100 }
101}
102
103
104bool PackSymbol( kiapi::schematic::types::SchematicSymbolInstance* aOutput, const SCH_SYMBOL* aInput,
105 const SCH_SHEET_PATH& aPath )
106{
107 KIID_PATH path = aPath.Path();
108 SCH_SYMBOL_INSTANCE instance;
109
110 if( !aInput->GetInstance( instance, path ) )
111 {
112 wxLogTrace( traceApi, "error: instance data for symbol %s on %s is missing",
113 aInput->m_Uuid.AsString(), aPath.PathHumanReadable() );
114 return false;
115 }
116
117 google::protobuf::Any any;
118 aInput->Serialize( any );
119
120 if( !any.UnpackTo( aOutput ) )
121 return false;
122
123 PackSheetPath( *aOutput->mutable_path(), path );
124 aOutput->mutable_reference_field()->mutable_text()->set_text( instance.m_Reference.ToUTF8() );
125 aOutput->mutable_unit()->set_unit( instance.m_Unit );
126
127 kiapi::schematic::types::SchematicSymbol* def = aOutput->mutable_definition();
128
129 std::vector<const SCH_PIN*> pins = aInput->GetPins( &aPath );
130
131 std::ranges::sort( pins,
132 []( const SCH_PIN* a, const SCH_PIN* b )
133 {
134 return a->m_Uuid < b->m_Uuid;
135 } );
136
137 for( const SCH_PIN* pin : pins )
138 {
139 kiapi::schematic::types::SchematicSymbolChild* item = def->add_items();
140 item->mutable_unit()->set_unit( pin->GetUnit() );
141 item->mutable_body_style()->set_style( pin->GetBodyStyle() );
142 item->set_is_private( pin->IsPrivate() );
143 pin->Serialize( *item->mutable_item() );
144 }
145
146 kiapi::schematic::types::SchematicSymbolAttributes* attributes = aOutput->mutable_attributes();
147
148 attributes->set_exclude_from_simulation( instance.m_ExcludedFromSim );
149 attributes->set_exclude_from_bill_of_materials( instance.m_ExcludedFromBOM );
150 attributes->set_exclude_from_board( instance.m_ExcludedFromBoard );
151 attributes->set_exclude_from_position_files( instance.m_ExcludedFromPosFiles );
152 attributes->set_do_not_populate( instance.m_DNP );
153
154 for( const auto& [name, variantInfo] : instance.m_Variants )
155 {
156 kiapi::schematic::types::SchematicSymbolVariant* variant = aOutput->add_variants();
157 variant->set_name( name.ToUTF8() );
158 variant->set_description( variantInfo.m_Description.ToUTF8() );
159
160 attributes = variant->mutable_attributes();
161 attributes->set_exclude_from_simulation( variantInfo.m_ExcludedFromSim );
162 attributes->set_exclude_from_bill_of_materials( variantInfo.m_ExcludedFromBOM );
163 attributes->set_exclude_from_board( variantInfo.m_ExcludedFromBoard );
164 attributes->set_exclude_from_position_files( variantInfo.m_ExcludedFromPosFiles );
165 attributes->set_do_not_populate( variantInfo.m_DNP );
166
167 for( const auto& [key, value] : variantInfo.m_Fields )
168 ( *variant->mutable_fields() )[std::string( key.ToUTF8() )] = value.ToUTF8();
169 }
170
171 return true;
172}
173
174
175bool UnpackSymbol( SCH_SYMBOL* aOutput, const kiapi::schematic::types::SchematicSymbolInstance& aInput )
176{
177 using namespace kiapi::common::types;
178 using namespace kiapi::schematic::types;
179
180 google::protobuf::Any any;
181 any.PackFrom( aInput );
182
183 if( !aOutput->Deserialize( any ) )
184 return false;
185
186 SCH_SYMBOL_INSTANCE instance;
187 instance.m_Path = UnpackSheetPath( aInput.path() );
188 instance.m_Reference = wxString::FromUTF8( aInput.reference_field().text().text() );
189 instance.m_Unit = aInput.has_unit() ? aInput.unit().unit() : 1;
190
191 if( aInput.has_attributes() )
192 {
193 const SchematicSymbolAttributes& attrs = aInput.attributes();
194 instance.m_ExcludedFromSim = attrs.exclude_from_simulation();
195 instance.m_ExcludedFromBOM = attrs.exclude_from_bill_of_materials();
196 instance.m_ExcludedFromBoard = attrs.exclude_from_board();
197 instance.m_ExcludedFromPosFiles = attrs.exclude_from_position_files();
198 instance.m_DNP = attrs.do_not_populate();
199
200 aOutput->SetExcludedFromSim( attrs.exclude_from_simulation() );
201 aOutput->SetExcludedFromBOM( attrs.exclude_from_bill_of_materials() );
202 aOutput->SetExcludedFromBoard( attrs.exclude_from_board() );
203 aOutput->SetExcludedFromPosFiles( attrs.exclude_from_position_files() );
204 aOutput->SetDNP( attrs.do_not_populate() );
205 }
206
207 for( const SchematicSymbolVariant& variantProto : aInput.variants() )
208 {
209 SCH_SYMBOL_VARIANT variant( wxString::FromUTF8( variantProto.name() ) );
210 variant.m_Description = wxString::FromUTF8( variantProto.description() );
211
212 if( variantProto.has_attributes() )
213 {
214 const SchematicSymbolAttributes& vAttrs = variantProto.attributes();
215 variant.m_ExcludedFromSim = vAttrs.exclude_from_simulation();
216 variant.m_ExcludedFromBOM = vAttrs.exclude_from_bill_of_materials();
217 variant.m_ExcludedFromBoard = vAttrs.exclude_from_board();
218 variant.m_ExcludedFromPosFiles = vAttrs.exclude_from_position_files();
219 variant.m_DNP = vAttrs.do_not_populate();
220 }
221
222 for( const auto& [key, value] : variantProto.fields() )
223 variant.m_Fields[ wxString::FromUTF8( key ) ] = wxString::FromUTF8( value );
224
225 instance.m_Variants.emplace( variant.m_Name, std::move( variant ) );
226 }
227
228 aOutput->AddHierarchicalReference( instance );
229 return true;
230}
231
232
233bool PackSheet( kiapi::schematic::types::SheetSymbol* aOutput, const SCH_SHEET* aInput,
234 const SCH_SHEET_PATH& aPath )
235{
236 google::protobuf::Any any;
237 aInput->Serialize( any );
238
239 if( !any.UnpackTo( aOutput ) )
240 return false;
241
242 PackSheetPath( *aOutput->mutable_path(), aPath.Path() );
243 aOutput->set_page_number( aPath.GetPageNumber().ToUTF8() );
244
245 return true;
246}
247
248
249tl::expected<bool, ApiResponseStatus> UnpackSheet( SCH_SHEET* aOutput, const kiapi::schematic::types::SheetSymbol& aInput )
250{
251 google::protobuf::Any any;
252 any.PackFrom( aInput );
253
254 if( !aOutput->Deserialize( any ) )
255 {
256 ApiResponseStatus e;
257 e.set_status( ApiStatusCode::AS_BAD_REQUEST );
258 e.set_error_message( "could not unpack SCH_SHEET from SheetSymbol in request" );
259 return tl::unexpected( e );
260 }
261
262 KIID_PATH instancePath = UnpackSheetPath( aInput.path() );
263
264 if( !instancePath.empty() )
265 {
266 SCH_SHEET_INSTANCE instance;
267 instance.m_Path = instancePath;
268 instance.m_PageNumber = wxString::FromUTF8( aInput.page_number() );
269
270 aOutput->AddInstance( instance );
271 }
272
273 return true;
274}
const char * name
std::unique_ptr< EDA_ITEM > CreateItemForType(KICAD_T aType, EDA_ITEM *aContainer)
tl::expected< bool, ApiResponseStatus > UnpackSheet(SCH_SHEET *aOutput, const kiapi::schematic::types::SheetSymbol &aInput)
bool PackSheet(kiapi::schematic::types::SheetSymbol *aOutput, const SCH_SHEET *aInput, const SCH_SHEET_PATH &aPath)
bool PackSymbol(kiapi::schematic::types::SchematicSymbolInstance *aOutput, const SCH_SYMBOL *aInput, const SCH_SHEET_PATH &aPath)
bool UnpackSymbol(SCH_SYMBOL *aOutput, const kiapi::schematic::types::SchematicSymbolInstance &aInput)
A base class for most all the KiCad significant classes used in schematics and boards.
Definition eda_item.h:100
const KIID m_Uuid
Definition eda_item.h:528
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:112
wxString AsString() const
Definition kiid.cpp:244
Define a library symbol object.
Definition lib_symbol.h:83
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition sch_item.h:168
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
KIID_PATH Path() const
Get the sheet path as an KIID_PATH.
wxString GetPageNumber() const
wxString PathHumanReadable(bool aUseShortRootName=true, bool aStripTrailingSeparator=false, bool aEscapeSheetNames=false) const
Return the sheet path in a human readable form made from the sheet names.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition sch_sheet.h:48
void AddInstance(const SCH_SHEET_INSTANCE &aInstance)
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
Definition sch_sheet.cpp:86
Variant information for a schematic symbol.
Schematic symbol object.
Definition sch_symbol.h:76
virtual void SetDNP(bool aEnable, const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) override
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
void SetExcludedFromSim(bool aEnable, const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) override
Set or clear the exclude from simulation flag.
std::vector< const SCH_PIN * > GetPins(const SCH_SHEET_PATH *aSheet) const
Retrieve a list of the SCH_PINs for the given sheet path.
void AddHierarchicalReference(const KIID_PATH &aPath, const wxString &aRef, int aUnit)
Add a full hierarchical reference to this symbol.
void SetExcludedFromPosFiles(bool aEnable, const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) override
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
bool GetInstance(SCH_SYMBOL_INSTANCE &aInstance, const KIID_PATH &aSheetPath, bool aTestFromEnd=false) const
void SetExcludedFromBOM(bool aEnable, const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) override
Set or clear the exclude from schematic bill of materials flag.
void SetExcludedFromBoard(bool aEnable, const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) override
wxString m_Name
bool m_ExcludedFromBOM
std::map< wxString, wxString > m_Fields
bool m_ExcludedFromPosFiles
bool m_ExcludedFromSim
bool m_ExcludedFromBoard
wxString m_Description
A type-safe container of any type.
Definition ki_any.h:93
const wxChar *const traceApi
Flag to enable debug output related to the IPC API and its plugin system.
Definition api_utils.cpp:29
KICOMMON_API KIID_PATH UnpackSheetPath(const types::SheetPath &aInput)
KICOMMON_API void PackSheetPath(types::SheetPath &aOutput, const KIID_PATH &aInput)
Class to handle a set of SCH_ITEMs.
A simple container for sheet instance information.
A simple container for schematic symbol instance information.
std::map< wxString, SCH_SYMBOL_VARIANT > m_Variants
A list of symbol variants.
std::string path
KIBIS_PIN * pin
wxLogTrace helper definitions.
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition typeinfo.h:75
@ SCH_GROUP_T
Definition typeinfo.h:174
@ SCH_TABLE_T
Definition typeinfo.h:166
@ SCH_LINE_T
Definition typeinfo.h:164
@ LIB_SYMBOL_T
Definition typeinfo.h:149
@ SCH_NO_CONNECT_T
Definition typeinfo.h:161
@ SCH_SYMBOL_T
Definition typeinfo.h:173
@ SCH_TABLECELL_T
Definition typeinfo.h:167
@ SCH_FIELD_T
Definition typeinfo.h:151
@ SCH_DIRECTIVE_LABEL_T
Definition typeinfo.h:172
@ SCH_LABEL_T
Definition typeinfo.h:168
@ SCH_SHEET_T
Definition typeinfo.h:176
@ SCH_SHAPE_T
Definition typeinfo.h:150
@ SCH_HIER_LABEL_T
Definition typeinfo.h:170
@ SCH_BUS_BUS_ENTRY_T
Definition typeinfo.h:163
@ SCH_SCREEN_T
Definition typeinfo.h:203
@ SCH_SHEET_PIN_T
Definition typeinfo.h:175
@ SCH_TEXT_T
Definition typeinfo.h:152
@ SCH_BUS_WIRE_ENTRY_T
Definition typeinfo.h:162
@ SCH_BITMAP_T
Definition typeinfo.h:165
@ SCH_TEXTBOX_T
Definition typeinfo.h:153
@ SCH_GLOBAL_LABEL_T
Definition typeinfo.h:169
@ SCH_JUNCTION_T
Definition typeinfo.h:160
@ SCH_PIN_T
Definition typeinfo.h:154