7
mirror of https://gitlab.com/kicad/code/kicad.git synced 2025-04-21 11:11:41 +00:00

API: Add serialization for netclasses

Fixes https://gitlab.com/kicad/code/kicad/-/issues/18609
This commit is contained in:
Jon Evans 2024-12-30 23:29:13 -05:00
parent aa2be7dd5a
commit 2c56e9826a
8 changed files with 252 additions and 3 deletions

View File

@ -35,6 +35,22 @@ message NetClassesResponse
}
message SetNetClasses
{
repeated kiapi.common.project.NetClass net_classes = 1;
// Whether to merge or replace the existing netclasses with the contents of this message
// Note that this only happens at the level of netclass name: for example, if merge_mode is set to
// MMM_MERGE, the design has netclasses ["Default", "HV"], and this message has netclasses
// ["Default", "LV"], the resulting set will be ["Default", "HV", "LV"] -- the Default netclass
// will have its properties replaced with those in this message, the "LV" netclass will be added,
// and the "HV" netclass will be left alone. If merge_mode is set to MMM_REPLACE, the "HV" class
// will be erased. Note that there must always be a "Default" netclass, so it will not be erased
// even if merge_mode is MMM_REPLACE and there is no "Default" class specified in this message.
kiapi.common.types.MapMergeMode merge_mode = 3;
}
message ExpandTextVariables
{
kiapi.common.types.DocumentSpecifier document = 1;

View File

@ -26,12 +26,48 @@ syntax = "proto3";
package kiapi.common.project;
import "common/types/base_types.proto";
import "common/types/enums.proto";
import "board/board_types.proto";
message NetClassBoardSettings
{
optional kiapi.common.types.Distance clearance = 1;
optional kiapi.common.types.Distance track_width = 2;
optional kiapi.common.types.Distance diff_pair_track_width = 3;
optional kiapi.common.types.Distance diff_pair_gap = 4;
optional kiapi.common.types.Distance diff_pair_via_gap = 5;
// The default padstack to use for vias belonging to this netclass
// Currently KiCad only supports specifying the drill diameter and annular size on all layers for
// netclass via stacks. Complex padstacks and other via features cannot be specified here.
optional kiapi.board.types.PadStack via_stack = 6;
// The default padstack to use for microvias belonging to this netclass
// Currently KiCad only supports specifying the drill diameter and annular size on all layers for
// netclass via stacks. Complex padstacks and other via features cannot be specified here.
optional kiapi.board.types.PadStack microvia_stack = 7;
optional kiapi.common.types.Color color = 8;
}
message NetClassSchematicSettings
{
optional kiapi.common.types.Distance wire_width = 1;
optional kiapi.common.types.Distance bus_width = 2;
optional kiapi.common.types.Color color = 3;
optional kiapi.common.types.StrokeLineStyle line_style = 4;
}
message NetClass
{
// The name of the netclass (the literal string "Default" for the default netclass)
string name = 1;
optional int32 priority = 2;
optional NetClassBoardSettings board = 3;
optional NetClassSchematicSettings schematic = 4;
}
message TextVariables

View File

@ -45,6 +45,7 @@ API_HANDLER_COMMON::API_HANDLER_COMMON() :
{
registerHandler<commands::GetVersion, GetVersionResponse>( &API_HANDLER_COMMON::handleGetVersion );
registerHandler<GetNetClasses, NetClassesResponse>( &API_HANDLER_COMMON::handleGetNetClasses );
registerHandler<SetNetClasses, Empty>( &API_HANDLER_COMMON::handleSetNetClasses );
registerHandler<Ping, Empty>( &API_HANDLER_COMMON::handlePing );
registerHandler<GetTextExtents, types::Box2>( &API_HANDLER_COMMON::handleGetTextExtents );
registerHandler<GetTextAsShapes, GetTextAsShapesResponse>(
@ -85,15 +86,57 @@ HANDLER_RESULT<NetClassesResponse> API_HANDLER_COMMON::handleGetNetClasses(
std::shared_ptr<NET_SETTINGS>& netSettings =
Pgm().GetSettingsManager().Prj().GetProjectFile().m_NetSettings;
for( const auto& [name, netClass] : netSettings->GetNetclasses() )
google::protobuf::Any any;
netSettings->GetDefaultNetclass()->Serialize( any );
any.UnpackTo( reply.add_net_classes() );
for( const auto& netClass : netSettings->GetNetclasses() | std::views::values )
{
reply.add_net_classes()->set_name( name.ToStdString() );
netClass->Serialize( any );
any.UnpackTo( reply.add_net_classes() );
}
return reply;
}
HANDLER_RESULT<Empty> API_HANDLER_COMMON::handleSetNetClasses(
const HANDLER_CONTEXT<SetNetClasses>& aCtx )
{
std::shared_ptr<NET_SETTINGS>& netSettings =
Pgm().GetSettingsManager().Prj().GetProjectFile().m_NetSettings;
if( aCtx.Request.merge_mode() == MapMergeMode::MMM_REPLACE )
netSettings->ClearNetclasses();
auto netClasses = netSettings->GetNetclasses();
google::protobuf::Any any;
for( const auto& ncProto : aCtx.Request.net_classes() )
{
any.PackFrom( ncProto );
wxString name = wxString::FromUTF8( ncProto.name() );
if( name == wxT( "Default" ) )
{
netSettings->GetDefaultNetclass()->Deserialize( any );
}
else
{
if( !netClasses.contains( name ) )
netClasses.insert( { name, std::make_shared<NETCLASS>( name, false ) } );
netClasses[name]->Deserialize( any );
}
}
netSettings->SetNetclasses( netClasses );
return Empty();
}
HANDLER_RESULT<Empty> API_HANDLER_COMMON::handlePing( const HANDLER_CONTEXT<Ping>& aCtx )
{
return Empty();

View File

@ -212,4 +212,24 @@ KICOMMON_API SHAPE_POLY_SET UnpackPolySet( const types::PolySet& aInput )
return sps;
}
KICOMMON_API void PackColor( types::Color& aOutput, const KIGFX::COLOR4D& aInput )
{
aOutput.set_r( aInput.r );
aOutput.set_g( aInput.g );
aOutput.set_b( aInput.b );
aOutput.set_a( aInput.a );
}
KICOMMON_API KIGFX::COLOR4D UnpackColor( const types::Color& aInput )
{
double r = std::clamp( aInput.r(), 0.0, 1.0 );
double g = std::clamp( aInput.g(), 0.0, 1.0 );
double b = std::clamp( aInput.b(), 0.0, 1.0 );
double a = std::clamp( aInput.a(), 0.0, 1.0 );
return KIGFX::COLOR4D( r, g, b, a );
}
} // namespace kiapi::common

View File

@ -27,6 +27,9 @@
#include <netclass.h>
#include <macros.h>
#include <base_units.h>
#include <api/api_enums.h>
#include <api/api_utils.h>
#include <api/common/types/project_settings.pb.h>
// This will get mapped to "kicad_default" in the specctra_export.
const char NETCLASS::Default[] = "Default";
@ -126,6 +129,125 @@ bool NETCLASS::operator==( const NETCLASS& other ) const
}
void NETCLASS::Serialize( google::protobuf::Any &aContainer ) const
{
using namespace kiapi::common;
project::NetClass nc;
nc.set_name( m_Name.ToUTF8() );
nc.set_priority( m_Priority );
project::NetClassBoardSettings* board = nc.mutable_board();
if( m_Clearance )
board->mutable_clearance()->set_value_nm( *m_Clearance );
if( m_TrackWidth )
board->mutable_track_width()->set_value_nm( *m_TrackWidth );
if( m_diffPairWidth )
board->mutable_diff_pair_track_width()->set_value_nm( *m_diffPairWidth );
if( m_diffPairGap )
board->mutable_diff_pair_gap()->set_value_nm( *m_diffPairGap );
if( m_diffPairViaGap )
board->mutable_diff_pair_via_gap()->set_value_nm( *m_diffPairViaGap );
if( m_ViaDia )
{
kiapi::board::types::PadStackLayer* layer = board->mutable_via_stack()->add_copper_layers();
layer->set_shape( kiapi::board::types::PSS_CIRCLE );
layer->set_layer( kiapi::board::types::BoardLayer::BL_F_Cu );
PackVector2( *layer->mutable_size(), { *m_ViaDia, *m_ViaDia } );
}
if( m_ViaDrill )
{
PackVector2( *board->mutable_via_stack()->mutable_drill()->mutable_diameter(),
{ *m_ViaDrill, *m_ViaDrill } );
}
if( m_pcbColor != COLOR4D::UNSPECIFIED )
PackColor( *board->mutable_color(), m_pcbColor );
project::NetClassSchematicSettings* schematic = nc.mutable_schematic();
if( m_wireWidth )
schematic->mutable_wire_width()->set_value_nm( *m_wireWidth );
if( m_busWidth )
schematic->mutable_bus_width()->set_value_nm( *m_busWidth );
if( m_schematicColor != COLOR4D::UNSPECIFIED )
PackColor( *schematic->mutable_color(), m_schematicColor );
if( m_lineStyle )
{
// TODO(JE) resolve issues with moving to kicommon
// schematic->set_line_style( ToProtoEnum<LINE_STYLE, types::StrokeLineStyle>(
// static_cast<LINE_STYLE>( *m_lineStyle ) ) );
}
aContainer.PackFrom( nc );
}
bool NETCLASS::Deserialize( const google::protobuf::Any &aContainer )
{
using namespace kiapi::common;
project::NetClass nc;
if( !aContainer.UnpackTo( &nc ) )
return false;
m_Name = wxString::FromUTF8( nc.name() );
m_Priority = nc.priority();
if( nc.board().has_clearance() )
m_Clearance = nc.board().clearance().value_nm();
if( nc.board().has_track_width() )
m_TrackWidth = nc.board().track_width().value_nm();
if( nc.board().has_diff_pair_track_width() )
m_diffPairWidth = nc.board().diff_pair_track_width().value_nm();
if( nc.board().has_diff_pair_gap() )
m_diffPairGap = nc.board().diff_pair_gap().value_nm();
if( nc.board().has_diff_pair_via_gap() )
m_diffPairViaGap = nc.board().diff_pair_via_gap().value_nm();
if( nc.board().has_via_stack() )
{
if( nc.board().via_stack().copper_layers_size() > 0 )
m_ViaDia = nc.board().via_stack().copper_layers().at( 0 ).size().x_nm();
if( nc.board().via_stack().has_drill() )
m_ViaDrill = nc.board().via_stack().drill().diameter().x_nm();
}
if( nc.board().has_color() )
m_pcbColor = UnpackColor( nc.board().color() );
if( nc.schematic().has_wire_width() )
m_wireWidth = nc.schematic().wire_width().value_nm();
if( nc.schematic().has_bus_width() )
m_busWidth = nc.schematic().bus_width().value_nm();
if( nc.schematic().has_color() )
m_schematicColor = UnpackColor( nc.schematic().color() );
// TODO(JE) resolve issues with moving to kicommon
// if( nc.schematic().has_line_style() )
// m_lineStyle = static_cast<int>( FromProtoEnum<LINE_STYLE>( nc.schematic().line_style() ) );
return true;
}
const std::vector<NETCLASS*>& NETCLASS::GetConstituentNetclasses() const
{
return m_constituents;

View File

@ -44,6 +44,9 @@ private:
HANDLER_RESULT<commands::NetClassesResponse> handleGetNetClasses(
const HANDLER_CONTEXT<commands::GetNetClasses>& aCtx );
HANDLER_RESULT<Empty> handleSetNetClasses(
const HANDLER_CONTEXT<commands::SetNetClasses>& aCtx );
HANDLER_RESULT<Empty> handlePing( const HANDLER_CONTEXT<commands::Ping>& aCtx );
HANDLER_RESULT<types::Box2> handleGetTextExtents(

View File

@ -31,6 +31,7 @@
#include <geometry/shape_line_chain.h>
#include <math/vector2d.h>
#include <math/vector3.h>
#include <gal/color4d.h>
class SHAPE_LINE_CHAIN;
@ -72,6 +73,10 @@ KICOMMON_API void PackPolySet( types::PolySet& aOutput, const SHAPE_POLY_SET& aI
KICOMMON_API SHAPE_POLY_SET UnpackPolySet( const types::PolySet& aInput );
KICOMMON_API void PackColor( types::Color& aOutput, const KIGFX::COLOR4D& aInput );
KICOMMON_API KIGFX::COLOR4D UnpackColor( const types::Color& aInput );
} // namespace kiapi::common
#endif //KICAD_API_UTILS_H

View File

@ -32,6 +32,7 @@
#include <kicommon.h>
#include <macros_swig.h>
#include <stroke_params.h>
#include <api/serializable.h>
using KIGFX::COLOR4D;
@ -40,7 +41,7 @@ DECL_SET_FOR_SWIG( STRINGSET, wxString )
/**
* A collection of nets and the parameters used to route or test these nets.
*/
class KICOMMON_API NETCLASS
class KICOMMON_API NETCLASS : public SERIALIZABLE
{
public:
static const char Default[]; ///< the name of the default NETCLASS
@ -62,6 +63,9 @@ public:
return wxT( "NETCLASS" );
}
void Serialize( google::protobuf::Any &aContainer ) const override;
bool Deserialize( const google::protobuf::Any &aContainer ) override;
/// @brief Resets all parent fields to point to this netclass
void ResetParents();