Browse Source

API: Add initial definitions for dimensions

pcb_db
Jon Evans 11 months ago
parent
commit
49d5e64428
  1. 89
      api/proto/board/board_types.proto
  2. 7
      api/proto/common/types/base_types.proto
  3. 16
      pcbnew/api/api_handler_pcb.cpp
  4. 36
      pcbnew/api/api_pcb_enums.cpp
  5. 47
      pcbnew/pcb_dimension.cpp
  6. 3
      pcbnew/pcb_dimension.h
  7. 231
      qa/data/pcbnew/api_kitchen_sink.kicad_pcb
  8. 6
      qa/tests/api/test_api_enums.cpp
  9. 58
      qa/tests/api/test_api_proto.cpp

89
api/proto/board/board_types.proto

@ -599,9 +599,89 @@ message Zone
kiapi.common.types.LockedState locked = 12;
}
// An aligned dimension is drawn parallel to the line segment between the start and end points
message AlignedDimensionAttributes
{
kiapi.common.types.Vector2 start = 1;
kiapi.common.types.Vector2 end = 2;
// Perpendicular distance from dimension endpoints to crossbar
kiapi.common.types.Distance height = 3;
// Length of extension lines past the crossbar
kiapi.common.types.Distance extension_height = 4;
}
// An orthogonal dimension is drawn parallel to the X or Y axis of the coordinate system
message OrthogonalDimensionAttributes
{
kiapi.common.types.Vector2 start = 1;
kiapi.common.types.Vector2 end = 2;
// Perpendicular distance from dimension endpoints to crossbar
kiapi.common.types.Distance height = 3;
// Length of extension lines past the crossbar
kiapi.common.types.Distance extension_height = 4;
// Which axis the dimension is parallel to
kiapi.common.types.AxisAlignment alignment = 5;
}
message RadialDimensionAttributes
{
// The center of the dimensioned circle or arc
kiapi.common.types.Vector2 center = 1;
// A point on the radius of the circle or arc
kiapi.common.types.Vector2 radius_point = 2;
// The distance from radius_point to draw the first segment of the leader line.
// The second segment is drawn from the end of the first segment to the text position.
kiapi.common.types.Distance leader_length = 3;
}
// The style of the optional frame applied to dimension text
enum DimensionTextBorderStyle
{
DTBS_UNKNOWN = 0;
DTBS_NONE = 1;
DTBS_RECTANGLE = 2;
DTBS_CIRCLE = 3;
DTBS_ROUNDRECT = 4;
}
message LeaderDimensionAttributes
{
kiapi.common.types.Vector2 start = 1;
kiapi.common.types.Vector2 end = 2;
DimensionTextBorderStyle border_style = 3;
}
message CenterDimensionAttributes
{
kiapi.common.types.Vector2 center = 1;
// A point on the end of one of the four radial spokes drawn from the center point
kiapi.common.types.Vector2 end = 2;
}
// A dimension in KiCad is a special type of text object.
// To know the visual appearance of the dimension as rendered by KiCad, use GetTextAsShapes
message Dimension
{
// TODO
kiapi.common.types.KIID id = 1;
kiapi.common.types.LockedState locked = 2;
BoardLayer layer = 3;
kiapi.common.types.Text text = 4;
oneof dimension_style {
AlignedDimensionAttributes aligned = 5;
OrthogonalDimensionAttributes orthogonal = 6;
RadialDimensionAttributes radial = 7;
LeaderDimensionAttributes leader = 8;
CenterDimensionAttributes center = 9;
}
}
message ReferenceImage
@ -626,12 +706,6 @@ message Field
BoardText text = 3;
}
message Model3D
{
// TODO
}
enum FootprintMountingStyle
{
FMS_UNKNOWN = 0;
@ -640,7 +714,6 @@ enum FootprintMountingStyle
FMS_UNSPECIFIED = 3;
}
message FootprintAttributes
{
string description = 1;

7
api/proto/common/types/base_types.proto

@ -431,3 +431,10 @@ message TitleBlockInfo
string comment8 = 12;
string comment9 = 13;
}
enum AxisAlignment
{
AA_UNKNOWN = 0;
AA_X_AXIS = 1;
AA_Y_AXIS = 2;
}

16
pcbnew/api/api_handler_pcb.cpp

@ -274,6 +274,22 @@ HANDLER_RESULT<ItemRequestStatus> API_HANDLER_PCB::handleCreateUpdateItemsIntern
continue;
}
if( type == PCB_DIMENSION_T )
{
board::types::Dimension dimension;
anyItem.UnpackTo( &dimension );
switch( dimension.dimension_style_case() )
{
case board::types::Dimension::kAligned: type = PCB_DIM_ALIGNED_T; break;
case board::types::Dimension::kOrthogonal: type = PCB_DIM_ORTHOGONAL_T; break;
case board::types::Dimension::kRadial: type = PCB_DIM_RADIAL_T; break;
case board::types::Dimension::kLeader: type = PCB_DIM_LEADER_T; break;
case board::types::Dimension::kCenter: type = PCB_DIM_CENTER_T; break;
case board::types::Dimension::DIMENSION_STYLE_NOT_SET: break;
}
}
HANDLER_RESULT<std::unique_ptr<BOARD_ITEM>> creationResult =
createItemForType( *type, container );

36
pcbnew/api/api_pcb_enums.cpp

@ -24,6 +24,7 @@
#include <wx/wx.h>
#include <padstack.h>
#include <pcb_dimension.h>
#include <pcb_track.h>
#include <zones.h>
#include <zone_settings.h>
@ -441,4 +442,39 @@ TEARDROP_TYPE FromProtoEnum( types::TeardropType aValue )
}
}
template<>
types::DimensionTextBorderStyle ToProtoEnum( DIM_TEXT_BORDER aValue )
{
switch( aValue )
{
case DIM_TEXT_BORDER::NONE: return types::DimensionTextBorderStyle::DTBS_NONE;
case DIM_TEXT_BORDER::RECTANGLE: return types::DimensionTextBorderStyle::DTBS_RECTANGLE;
case DIM_TEXT_BORDER::CIRCLE: return types::DimensionTextBorderStyle::DTBS_CIRCLE;
case DIM_TEXT_BORDER::ROUNDRECT: return types::DimensionTextBorderStyle::DTBS_ROUNDRECT;
default:
wxCHECK_MSG( false, types::DimensionTextBorderStyle::DTBS_UNKNOWN,
"Unhandled case in ToProtoEnum<DIM_TEXT_BORDER>");
}
}
template<>
DIM_TEXT_BORDER FromProtoEnum( types::DimensionTextBorderStyle aValue )
{
switch( aValue )
{
case types::DimensionTextBorderStyle::DTBS_NONE: return DIM_TEXT_BORDER::NONE;
case types::DimensionTextBorderStyle::DTBS_RECTANGLE: return DIM_TEXT_BORDER::RECTANGLE;
case types::DimensionTextBorderStyle::DTBS_CIRCLE: return DIM_TEXT_BORDER::CIRCLE;
case types::DimensionTextBorderStyle::DTBS_ROUNDRECT: return DIM_TEXT_BORDER::ROUNDRECT;
default:
wxCHECK_MSG( false, DIM_TEXT_BORDER::NONE,
"Unhandled case in FromProtoEnum<types::DimensionTextBorderStyle>" );
}
}
// Adding something new here? Add it to test_api_enums.cpp!

47
pcbnew/pcb_dimension.cpp

@ -39,6 +39,9 @@
#include <settings/color_settings.h>
#include <settings/settings_manager.h>
#include <trigo.h>
#include <api/api_enums.h>
#include <api/api_utils.h>
#include <api/board/board_types.pb.h>
static const int INWARD_ARROW_LENGTH_TO_HEAD_RATIO = 2;
@ -250,6 +253,50 @@ double PCB_DIMENSION_BASE::Similarity( const BOARD_ITEM& aOther ) const
}
void PCB_DIMENSION_BASE::Serialize( google::protobuf::Any &aContainer ) const
{
using namespace kiapi::common;
kiapi::board::types::Dimension dimension;
dimension.mutable_id()->set_value( m_Uuid.AsStdString() );
dimension.set_layer( ToProtoEnum<PCB_LAYER_ID, kiapi::board::types::BoardLayer>( GetLayer() ) );
dimension.set_locked( IsLocked() ? types::LockedState::LS_LOCKED
: types::LockedState::LS_UNLOCKED );
google::protobuf::Any any;
EDA_TEXT::Serialize( any );
any.UnpackTo( dimension.mutable_text() );
types::Text* text = dimension.mutable_text();
PackVector2( *text->mutable_position(), GetPosition() );
aContainer.PackFrom( dimension );
}
bool PCB_DIMENSION_BASE::Deserialize( const google::protobuf::Any &aContainer )
{
using namespace kiapi::common;
kiapi::board::types::Dimension dimension;
if( !aContainer.UnpackTo( &dimension ) )
return false;
SetLayer( FromProtoEnum<PCB_LAYER_ID, kiapi::board::types::BoardLayer>( dimension.layer() ) );
const_cast<KIID&>( m_Uuid ) = KIID( dimension.id().value() );
SetLocked( dimension.locked() == types::LockedState::LS_LOCKED );
google::protobuf::Any any;
any.PackFrom( dimension.text() );
EDA_TEXT::Deserialize( any );
const types::Text& text = dimension.text();
SetPosition( UnpackVector2( text.position() ) );
return true;
}
void PCB_DIMENSION_BASE::drawAnArrow( VECTOR2I startPoint, EDA_ANGLE anAngle, int aLength )
{
if( aLength )

3
pcbnew/pcb_dimension.h

@ -120,6 +120,9 @@ class PCB_DIMENSION_BASE : public PCB_TEXT
public:
PCB_DIMENSION_BASE( BOARD_ITEM* aParent, KICAD_T aType = PCB_DIMENSION_T );
void Serialize( google::protobuf::Any &aContainer ) const override;
bool Deserialize( const google::protobuf::Any &aContainer ) override;
/**
* The dimension's origin is the first feature point for the dimension. Every dimension has
* one or more feature points, so every dimension has at least an origin.

231
qa/data/pcbnew/api_kitchen_sink.kicad_pcb

@ -1,5 +1,5 @@
(kicad_pcb
(version 20241030)
(version 20241129)
(generator "pcbnew")
(generator_version "8.99")
(general
@ -10,22 +10,22 @@
(layers
(0 "F.Cu" signal)
(2 "B.Cu" signal)
(9 "F.Adhes" user)
(11 "B.Adhes" user)
(9 "F.Adhes" user "F.Adhesive")
(11 "B.Adhes" user "B.Adhesive")
(13 "F.Paste" user)
(15 "B.Paste" user)
(5 "F.SilkS" user)
(7 "B.SilkS" user)
(5 "F.SilkS" user "F.Silkscreen")
(7 "B.SilkS" user "B.Silkscreen")
(1 "F.Mask" user)
(3 "B.Mask" user)
(17 "Dwgs.User" user)
(19 "Cmts.User" user)
(21 "Eco1.User" user)
(23 "Eco2.User" user)
(17 "Dwgs.User" user "User.Drawings")
(19 "Cmts.User" user "User.Comments")
(21 "Eco1.User" user "User.Eco1")
(23 "Eco2.User" user "User.Eco2")
(25 "Edge.Cuts" user)
(27 "Margin" user)
(31 "F.CrtYd" user)
(29 "B.CrtYd" user)
(31 "F.CrtYd" user "F.Courtyard")
(29 "B.CrtYd" user "B.Courtyard")
(35 "F.Fab" user)
(33 "B.Fab" user)
(39 "User.1" signal)
@ -468,7 +468,7 @@
(width 0.05)
(type solid)
)
(fill none)
(fill no)
(layer "Edge.Cuts")
(uuid "052086a7-98a9-4ea1-bdee-ad673fb3a26c")
)
@ -481,7 +481,7 @@
(width 0.05)
(type solid)
)
(fill none)
(fill no)
(layer "Edge.Cuts")
(uuid "98ab137c-f925-4075-af50-4ac8fe13c14d")
)
@ -492,7 +492,7 @@
(width 0.05)
(type default)
)
(fill none)
(fill no)
(layer "Edge.Cuts")
(uuid "b27945e5-32fe-454b-ad80-b75cae1194e1")
)
@ -503,7 +503,7 @@
(width 0.05)
(type default)
)
(fill none)
(fill no)
(layer "Edge.Cuts")
(uuid "e1699138-73b7-4cfd-aec1-5bee869795d9")
)
@ -514,7 +514,7 @@
(width 1.87)
(type solid)
)
(fill none)
(fill no)
(layer "B.Fab")
(uuid "01315513-10cc-4984-96ac-98682589967a")
)
@ -525,7 +525,7 @@
(width 0.1)
(type dash_dot_dot)
)
(fill none)
(fill no)
(layer "B.Fab")
(uuid "2e68cc14-52eb-4276-b39c-c502b042bc91")
)
@ -543,12 +543,12 @@
(gr_circle
(center 106.5 48.5)
(end 108.5 49)
(locked yes)
(stroke
(width 0.177)
(type default)
)
(fill none)
(fill no)
(locked yes)
(layer "B.Fab")
(uuid "b5d27e62-c3ee-43b4-a859-5e626272bf9c")
)
@ -559,7 +559,7 @@
(width 0)
(type solid)
)
(fill solid)
(fill yes)
(layer "B.Fab")
(uuid "cb2af193-349d-4651-a0c1-5d028759a9f3")
)
@ -615,6 +615,197 @@
(type dot)
)
)
(dimension
(type aligned)
(layer "F.SilkS")
(uuid "0bc42083-d926-4194-a819-d6be9c0115b7")
(pts
(xy 119.75 76.25) (xy 119.75 82.5)
)
(height -5.5)
(format
(prefix "")
(suffix "")
(units 1)
(units_format 1)
(precision 1)
)
(style
(thickness 0.1)
(arrow_length 1.27)
(text_position_mode 2)
(arrow_direction outward)
(extension_height 0.58642)
(extension_offset 0.5)
)
(gr_text "246.1 mils"
(at 126 79 0)
(layer "F.SilkS")
(uuid "0bc42083-d926-4194-a819-d6be9c0115b7")
(effects
(font
(size 1 1)
(thickness 0.1)
)
)
)
)
(dimension
(type aligned)
(layer "F.SilkS")
(uuid "53a9c653-d0ab-4671-bb3c-e68323561710")
(pts
(xy 119.75 76.25) (xy 93.25 78.75)
)
(height 2.5229)
(format
(prefix "")
(suffix "")
(units 3)
(units_format 1)
(precision 4)
)
(style
(thickness 0.1)
(arrow_length 1.27)
(text_position_mode 2)
(arrow_direction outward)
(extension_height 0.58642)
(extension_offset 0.5)
(keep_text_aligned yes)
)
(gr_text "26.6177 mm"
(at 106.159728 75 5.38931176)
(layer "F.SilkS")
(uuid "53a9c653-d0ab-4671-bb3c-e68323561710")
(effects
(font
(size 1 1)
(thickness 0.1)
)
)
)
)
(dimension
(type leader)
(layer "F.SilkS")
(uuid "7d932562-7662-47a4-b0f3-f405d4e7fd17")
(pts
(xy 109.5 89) (xy 113.25 85.75)
)
(format
(prefix "")
(suffix "")
(units 0)
(units_format 0)
(precision 4)
(override_value "Leader")
)
(style
(thickness 0.1)
(arrow_length 1.27)
(text_position_mode 0)
(text_frame 1)
(extension_offset 0.5)
)
(gr_text "Leader"
(at 119 85.75 0)
(layer "F.SilkS")
(uuid "7d932562-7662-47a4-b0f3-f405d4e7fd17")
(effects
(font
(size 1 1)
(thickness 0.1)
)
)
)
)
(dimension
(type center)
(layer "F.SilkS")
(uuid "6c3890f3-95ec-403d-a195-7e14eaa0059b")
(pts
(xy 106.5 90.75) (xy 106.5 87.25)
)
(style
(thickness 0.1)
(arrow_length 1.27)
(text_position_mode 0)
(extension_offset 0.5)
(keep_text_aligned yes)
)
)
(dimension
(type radial)
(layer "F.SilkS")
(uuid "32a22a4a-ae09-4c8c-9323-a332622fcb7d")
(pts
(xy 115 93.5) (xy 113.25 94.75)
)
(leader_length 3.81)
(format
(prefix "R ")
(suffix "")
(units 3)
(units_format 1)
(precision 4)
)
(style
(thickness 0.1)
(arrow_length 1.27)
(text_position_mode 0)
(extension_offset 0.5)
(keep_text_aligned yes)
)
(gr_text "R 2.1506 mm"
(at 97.449675 96.964518 0)
(layer "F.SilkS")
(uuid "32a22a4a-ae09-4c8c-9323-a332622fcb7d")
(effects
(font
(size 1 1)
(thickness 0.1)
)
)
)
)
(dimension
(type orthogonal)
(layer "F.Cu")
(uuid "11ccce8d-b920-43bc-a797-25f3df207d00")
(pts
(xy 93.25 78.75) (xy 119.75 76.25)
)
(height 3.75)
(orientation 0)
(format
(prefix "")
(suffix "")
(units 3)
(units_format 1)
(precision 4)
)
(style
(thickness 0.2)
(arrow_length 1.27)
(text_position_mode 0)
(arrow_direction outward)
(extension_height 0.58642)
(extension_offset 0.5)
(keep_text_aligned yes)
)
(gr_text "26.5000 mm"
(at 106.5 80.7 0)
(layer "F.Cu")
(uuid "11ccce8d-b920-43bc-a797-25f3df207d00")
(effects
(font
(size 1.5 1.5)
(thickness 0.3)
)
)
)
)
(segment
(start 88.3 63.2)
(end 90.65 60.85)

6
qa/tests/api/test_api_enums.cpp

@ -34,6 +34,7 @@
// Board-specific
#include <padstack.h>
#include <pcb_dimension.h>
#include <pcb_track.h>
#include <zones.h>
#include <zone_settings.h>
@ -213,4 +214,9 @@ BOOST_AUTO_TEST_CASE( TeardropType )
testEnums<TEARDROP_TYPE, kiapi::board::types::TeardropType>();
}
BOOST_AUTO_TEST_CASE( DimensionTextBorderStyle )
{
testEnums<DIM_TEXT_BORDER, kiapi::board::types::DimensionTextBorderStyle>();
}
BOOST_AUTO_TEST_SUITE_END()

58
qa/tests/api/test_api_proto.cpp

@ -29,6 +29,7 @@
#include <board.h>
#include <footprint.h>
#include <pcb_dimension.h>
#include <pcb_track.h>
#include <zone.h>
@ -46,8 +47,8 @@ struct PROTO_TEST_FIXTURE
};
template<typename ProtoClass, typename KiCadClass>
void testProtoFromKiCadObject( KiCadClass* aInput )
template<typename ProtoClass, typename KiCadClass, typename ParentClass>
void testProtoFromKiCadObject( KiCadClass* aInput, ParentClass* aParent )
{
BOOST_TEST_CONTEXT( aInput->GetFriendlyName() << ": " << aInput->m_Uuid.AsStdString() )
{
@ -61,6 +62,8 @@ void testProtoFromKiCadObject( KiCadClass* aInput )
"Any message did not unpack into the requested type" );
KiCadClass output( *static_cast<KiCadClass*>( aInput->Clone() ) );
// Not yet
//KiCadClass output( aParent );
bool deserializeResult = false;
BOOST_REQUIRE_NO_THROW( deserializeResult = output.Deserialize( any ) );
@ -94,15 +97,15 @@ BOOST_FIXTURE_TEST_CASE( BoardTypes, PROTO_TEST_FIXTURE )
switch( track->Type() )
{
case PCB_TRACE_T:
testProtoFromKiCadObject<kiapi::board::types::Track>( track );
testProtoFromKiCadObject<kiapi::board::types::Track>( track, m_board.get() );
break;
case PCB_ARC_T:
testProtoFromKiCadObject<kiapi::board::types::Arc>( track );
testProtoFromKiCadObject<kiapi::board::types::Arc>( track, m_board.get() );
break;
case PCB_VIA_T:
testProtoFromKiCadObject<kiapi::board::types::Via>( track );
testProtoFromKiCadObject<kiapi::board::types::Via>( track, m_board.get() );
break;
default:
@ -111,16 +114,46 @@ BOOST_FIXTURE_TEST_CASE( BoardTypes, PROTO_TEST_FIXTURE )
}
for( FOOTPRINT* footprint : m_board->Footprints() )
testProtoFromKiCadObject<kiapi::board::types::FootprintInstance>( footprint );
testProtoFromKiCadObject<kiapi::board::types::FootprintInstance>( footprint, m_board.get() );
for( ZONE* zone : m_board->Zones() )
testProtoFromKiCadObject<kiapi::board::types::Zone>( zone );
testProtoFromKiCadObject<kiapi::board::types::Zone>( zone, m_board.get() );
// TODO(JE) Shapes
for( BOARD_ITEM* item : m_board->Drawings() )
{
switch( item->Type() )
{
case PCB_DIM_ALIGNED_T:
testProtoFromKiCadObject<kiapi::board::types::Dimension>(
static_cast<PCB_DIM_ALIGNED*>( item ), m_board.get() );
break;
// TODO(JE) Text
case PCB_DIM_ORTHOGONAL_T:
testProtoFromKiCadObject<kiapi::board::types::Dimension>(
static_cast<PCB_DIM_ORTHOGONAL*>( item ), m_board.get() );
break;
// TODO(JE) Dimensions
case PCB_DIM_CENTER_T:
testProtoFromKiCadObject<kiapi::board::types::Dimension>(
static_cast<PCB_DIM_CENTER*>( item ), m_board.get() );
break;
case PCB_DIM_LEADER_T:
testProtoFromKiCadObject<kiapi::board::types::Dimension>(
static_cast<PCB_DIM_LEADER*>( item ), m_board.get() );
break;
case PCB_DIM_RADIAL_T:
testProtoFromKiCadObject<kiapi::board::types::Dimension>(
static_cast<PCB_DIM_RADIAL*>( item ), m_board.get() );
break;
default: break;
}
// TODO(JE) Shapes
// TODO(JE) Text
}
}
@ -133,7 +166,8 @@ BOOST_FIXTURE_TEST_CASE( Padstacks, PROTO_TEST_FIXTURE )
switch( track->Type() )
{
case PCB_VIA_T:
testProtoFromKiCadObject<kiapi::board::types::Via>( static_cast<PCB_VIA*>( track ) );
testProtoFromKiCadObject<kiapi::board::types::Via>( static_cast<PCB_VIA*>( track ),
m_board.get() );
break;
default:
@ -142,7 +176,7 @@ BOOST_FIXTURE_TEST_CASE( Padstacks, PROTO_TEST_FIXTURE )
}
for( FOOTPRINT* footprint : m_board->Footprints() )
testProtoFromKiCadObject<kiapi::board::types::FootprintInstance>( footprint );
testProtoFromKiCadObject<kiapi::board::types::FootprintInstance>( footprint, m_board.get() );
}
BOOST_AUTO_TEST_SUITE_END()
Loading…
Cancel
Save