7
mirror of https://gitlab.com/kicad/code/kicad.git synced 2025-04-18 18:29:17 +00:00

API: Add serialization of FP_3DMODEL

This commit is contained in:
Jon Evans 2024-11-24 15:53:02 -05:00
parent 5323c8587a
commit c0d43c0c0c
5 changed files with 100 additions and 24 deletions
api/proto
common/api
include/api
pcbnew

View File

@ -706,6 +706,24 @@ message FootprintDesignRuleOverrides
ZoneConnectionStyle zone_connection = 4;
}
message Footprint3DModel
{
string filename = 1;
// Scaling factor along each axis
kiapi.common.types.Vector3D scale = 2;
// Rotation around each axis, in degrees
kiapi.common.types.Vector3D rotation = 3;
// Offset from footprint center
kiapi.common.types.Vector3D offset = 4;
bool visible = 5;
double opacity = 6;
}
// A footprint definition (i.e. what would be in a library)
message Footprint
{

View File

@ -191,6 +191,13 @@ message Vector3
int64 z_nm = 3;
}
message Vector3D
{
double x_nm = 1;
double y_nm = 2;
double z_nm = 3;
}
message Box2
{
kiapi.common.types.Vector2 position = 1;

View File

@ -80,6 +80,20 @@ VECTOR2I UnpackVector2( const types::Vector2& aInput )
}
void PackVector3D( types::Vector3D& aOutput, const VECTOR3D& aInput )
{
aOutput.set_x_nm( aInput.x );
aOutput.set_y_nm( aInput.y );
aOutput.set_z_nm( aInput.z );
}
VECTOR3D UnpackVector3D( const types::Vector3D& aInput )
{
return VECTOR3D( aInput.x_nm(), aInput.y_nm(), aInput.z_nm() );
}
void PackBox2( types::Box2& aOutput, const BOX2I& aInput )
{
PackVector2( *aOutput.mutable_position(), aInput.GetOrigin() );

View File

@ -30,6 +30,7 @@
#include <layer_ids.h>
#include <geometry/shape_line_chain.h>
#include <math/vector2d.h>
#include <math/vector3.h>
class SHAPE_LINE_CHAIN;
@ -46,6 +47,10 @@ void PackVector2( types::Vector2& aOutput, const VECTOR2I& aInput );
VECTOR2I UnpackVector2( const types::Vector2& aInput );
void PackVector3D( types::Vector3D& aOutput, const VECTOR3D& aInput );
VECTOR3D UnpackVector3D( const types::Vector3D& aInput );
void PackBox2( types::Box2& aOutput, const BOX2I& aInput );
BOX2I UnpackBox2( const types::Box2& aInput );

View File

@ -270,13 +270,14 @@ FOOTPRINT::~FOOTPRINT()
void FOOTPRINT::Serialize( google::protobuf::Any &aContainer ) const
{
kiapi::board::types::FootprintInstance footprint;
using namespace kiapi::board;
types::FootprintInstance footprint;
footprint.mutable_id()->set_value( m_Uuid.AsStdString() );
footprint.mutable_position()->set_x_nm( GetPosition().x );
footprint.mutable_position()->set_y_nm( GetPosition().y );
footprint.mutable_orientation()->set_value_degrees( GetOrientationDegrees() );
footprint.set_layer( ToProtoEnum<PCB_LAYER_ID, kiapi::board::types::BoardLayer>( GetLayer() ) );
footprint.set_layer( ToProtoEnum<PCB_LAYER_ID, types::BoardLayer>( GetLayer() ) );
footprint.set_locked( IsLocked() ? kiapi::common::types::LockedState::LS_LOCKED
: kiapi::common::types::LockedState::LS_UNLOCKED );
@ -290,7 +291,7 @@ void FOOTPRINT::Serialize( google::protobuf::Any &aContainer ) const
GetField( DESCRIPTION_FIELD )->Serialize( buf );
buf.UnpackTo( footprint.mutable_description_field() );
kiapi::board::types::FootprintAttributes* attrs = footprint.mutable_attributes();
types::FootprintAttributes* attrs = footprint.mutable_attributes();
attrs->set_not_in_schematic( IsBoardOnly() );
attrs->set_exclude_from_position_files( IsExcludedFromPosFiles() );
@ -298,7 +299,7 @@ void FOOTPRINT::Serialize( google::protobuf::Any &aContainer ) const
attrs->set_exempt_from_courtyard_requirement( AllowMissingCourtyard() );
attrs->set_do_not_populate( IsDNP() );
kiapi::board::types::Footprint* def = footprint.mutable_definition();
types::Footprint* def = footprint.mutable_definition();
def->mutable_id()->CopyFrom( kiapi::common::LibIdToProto( GetFPID() ) );
// anchor?
@ -307,7 +308,7 @@ void FOOTPRINT::Serialize( google::protobuf::Any &aContainer ) const
// TODO: serialize library mandatory fields
kiapi::board::types::FootprintDesignRuleOverrides* overrides = def->mutable_overrides();
types::FootprintDesignRuleOverrides* overrides = def->mutable_overrides();
if( GetLocalClearance().has_value() )
overrides->mutable_copper_clearance()->set_value_nm( *GetLocalClearance() );
@ -322,12 +323,11 @@ void FOOTPRINT::Serialize( google::protobuf::Any &aContainer ) const
overrides->mutable_solder_paste()->mutable_solder_paste_margin_ratio()->set_value( *GetLocalSolderPasteMarginRatio() );
overrides->set_zone_connection(
ToProtoEnum<ZONE_CONNECTION,
kiapi::board::types::ZoneConnectionStyle>( GetLocalZoneConnection() ) );
ToProtoEnum<ZONE_CONNECTION, types::ZoneConnectionStyle>( GetLocalZoneConnection() ) );
for( const wxString& group : GetNetTiePadGroups() )
{
kiapi::board::types::NetTieDefinition* netTie = def->add_net_ties();
types::NetTieDefinition* netTie = def->add_net_ties();
wxStringTokenizer tokenizer( group, " " );
while( tokenizer.HasMoreTokens() )
@ -335,10 +335,7 @@ void FOOTPRINT::Serialize( google::protobuf::Any &aContainer ) const
}
for( PCB_LAYER_ID layer : GetPrivateLayers().Seq() )
{
def->add_private_layers(
ToProtoEnum<PCB_LAYER_ID, kiapi::board::types::BoardLayer>( layer ) );
}
def->add_private_layers( ToProtoEnum<PCB_LAYER_ID, types::BoardLayer>( layer ) );
for( const PCB_FIELD* item : Fields() )
{
@ -367,7 +364,18 @@ void FOOTPRINT::Serialize( google::protobuf::Any &aContainer ) const
item->Serialize( *itemMsg );
}
// TODO: 3D models
for( const FP_3DMODEL& model : Models() )
{
google::protobuf::Any* itemMsg = def->add_items();
types::Footprint3DModel modelMsg;
modelMsg.set_filename( model.m_Filename.ToUTF8() );
kiapi::common::PackVector3D( *modelMsg.mutable_scale(), model.m_Scale );
kiapi::common::PackVector3D( *modelMsg.mutable_rotation(), model.m_Rotation );
kiapi::common::PackVector3D( *modelMsg.mutable_offset(), model.m_Offset );
modelMsg.set_visible( model.m_Show );
modelMsg.set_opacity( model.m_Opacity );
itemMsg->PackFrom( modelMsg );
}
aContainer.PackFrom( footprint );
}
@ -375,7 +383,8 @@ void FOOTPRINT::Serialize( google::protobuf::Any &aContainer ) const
bool FOOTPRINT::Deserialize( const google::protobuf::Any &aContainer )
{
kiapi::board::types::FootprintInstance footprint;
using namespace kiapi::board;
types::FootprintInstance footprint;
if( !aContainer.UnpackTo( &footprint ) )
return false;
@ -383,11 +392,11 @@ bool FOOTPRINT::Deserialize( const google::protobuf::Any &aContainer )
const_cast<KIID&>( m_Uuid ) = KIID( footprint.id().value() );
SetPosition( VECTOR2I( footprint.position().x_nm(), footprint.position().y_nm() ) );
SetOrientationDegrees( footprint.orientation().value_degrees() );
SetLayer( FromProtoEnum<PCB_LAYER_ID, kiapi::board::types::BoardLayer>( footprint.layer() ) );
SetLayer( FromProtoEnum<PCB_LAYER_ID, types::BoardLayer>( footprint.layer() ) );
SetLocked( footprint.locked() == kiapi::common::types::LockedState::LS_LOCKED );
google::protobuf::Any buf;
kiapi::board::types::Field mandatoryField;
types::Field mandatoryField;
if( footprint.has_reference_field() )
{
@ -433,7 +442,7 @@ bool FOOTPRINT::Deserialize( const google::protobuf::Any &aContainer )
SetLibDescription( footprint.definition().attributes().description() );
SetKeywords( footprint.definition().attributes().keywords() );
const kiapi::board::types::FootprintDesignRuleOverrides& overrides = footprint.overrides();
const types::FootprintDesignRuleOverrides& overrides = footprint.overrides();
if( overrides.has_copper_clearance() )
SetLocalClearance( overrides.copper_clearance().value_nm() );
@ -447,7 +456,7 @@ bool FOOTPRINT::Deserialize( const google::protobuf::Any &aContainer )
if( overrides.has_solder_paste() )
{
const kiapi::board::types::SolderPasteOverrides& pasteSettings = overrides.solder_paste();
const types::SolderPasteOverrides& pasteSettings = overrides.solder_paste();
if( pasteSettings.has_solder_paste_margin() )
SetLocalSolderPasteMargin( pasteSettings.solder_paste_margin().value_nm() );
@ -462,7 +471,7 @@ bool FOOTPRINT::Deserialize( const google::protobuf::Any &aContainer )
SetLocalZoneConnection( FromProtoEnum<ZONE_CONNECTION>( overrides.zone_connection() ) );
for( const kiapi::board::types::NetTieDefinition& netTieMsg : footprint.definition().net_ties() )
for( const types::NetTieDefinition& netTieMsg : footprint.definition().net_ties() )
{
wxString group;
@ -477,8 +486,8 @@ bool FOOTPRINT::Deserialize( const google::protobuf::Any &aContainer )
for( int layerMsg : footprint.definition().private_layers() )
{
auto layer = static_cast<kiapi::board::types::BoardLayer>( layerMsg );
privateLayers.set( FromProtoEnum<PCB_LAYER_ID, kiapi::board::types::BoardLayer>( layer ) );
auto layer = static_cast<types::BoardLayer>( layerMsg );
privateLayers.set( FromProtoEnum<PCB_LAYER_ID, types::BoardLayer>( layer ) );
}
SetPrivateLayers( privateLayers );
@ -501,7 +510,32 @@ bool FOOTPRINT::Deserialize( const google::protobuf::Any &aContainer )
std::optional<KICAD_T> type = kiapi::common::TypeNameFromAny( itemMsg );
if( !type )
continue;
{
// Bit of a hack here, but eventually 3D models should be promoted to a first-class
// object, at which point they can get their own serialization
if( itemMsg.type_url() == "type.googleapis.com/kiapi.board.types.Footprint3DModel" )
{
types::Footprint3DModel modelMsg;
if( !itemMsg.UnpackTo( &modelMsg ) )
continue;
FP_3DMODEL model;
model.m_Filename = wxString::FromUTF8( modelMsg.filename() );
model.m_Show = modelMsg.visible();
model.m_Opacity = modelMsg.opacity();
model.m_Scale = kiapi::common::UnpackVector3D( modelMsg.scale() );
model.m_Rotation = kiapi::common::UnpackVector3D( modelMsg.rotation() );
model.m_Offset = kiapi::common::UnpackVector3D( modelMsg.offset() );
Models().push_back( model );
}
else
{
continue;
}
}
std::unique_ptr<BOARD_ITEM> item = CreateItemForType( *type, this );
@ -509,8 +543,6 @@ bool FOOTPRINT::Deserialize( const google::protobuf::Any &aContainer )
Add( item.release(), ADD_MODE::APPEND );
}
// TODO: 3D models
return true;
}