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

API: Add GetBoundingBox and Box2

This commit is contained in:
Jon Evans 2024-11-19 22:09:00 -05:00
parent f97f79426a
commit 033fb4fc8f
7 changed files with 94 additions and 12 deletions

View File

@ -123,7 +123,7 @@ message RefillZones
* Utilities
*/
// returns kiapi.common.commands.BoundingBoxResponse
// returns kiapi.common.types.Box2
message GetTextExtents
{
// A temporary text item to calculate the bounding box for

View File

@ -261,17 +261,29 @@ message DeleteItemsResponse
repeated ItemDeletionResult deleted_items = 3;
}
message GetItemBoundingBox
enum BoundingBoxMode
{
BBM_UNKNOWN = 0;
BBM_ITEM_ONLY = 1;
BBM_ITEM_AND_CHILD_TEXT = 2;
}
message GetBoundingBox
{
kiapi.common.types.ItemHeader header = 1;
kiapi.common.types.KIID id = 2;
repeated kiapi.common.types.KIID items = 2;
// Some item types can have independently-movable text as children (e.g. footprints)
// This mode controls whether or not these are included in the box
BoundingBoxMode mode = 3;
}
message BoundingBoxResponse
message GetBoundingBoxResponse
{
kiapi.common.types.Vector2 position = 1;
kiapi.common.types.Vector2 size = 2;
repeated kiapi.common.types.KIID items = 1;
repeated kiapi.common.types.Box2 boxes = 2;
}
// Tests if a certain point falls within tolerance of an item's geometry

View File

@ -191,6 +191,12 @@ message Vector3
int64 z_nm = 3;
}
message Box2
{
kiapi.common.types.Vector2 position = 1;
kiapi.common.types.Vector2 size = 2;
}
// Describes a quantity of distance (size, length, etc). All coordinates are in nanometers.
message Distance
{

View File

@ -66,18 +66,32 @@ types::LibraryIdentifier LibIdToProto( const LIB_ID& aId )
}
void PackVector2( kiapi::common::types::Vector2& aOutput, const VECTOR2I aInput )
void PackVector2( types::Vector2& aOutput, const VECTOR2I& aInput )
{
aOutput.set_x_nm( aInput.x );
aOutput.set_y_nm( aInput.y );
}
VECTOR2I UnpackVector2( const types::Vector2& aInput )
{
return VECTOR2I( aInput.x_nm(), aInput.y_nm() );
}
void PackBox2( types::Box2& aOutput, const BOX2I& aInput )
{
PackVector2( *aOutput.mutable_position(), aInput.GetOrigin() );
PackVector2( *aOutput.mutable_size(), aInput.GetSize() );
}
BOX2I UnpackBox2( const types::Box2& aInput )
{
return BOX2I( UnpackVector2( aInput.position() ), UnpackVector2( aInput.size() ) );
}
void PackPolyLine( kiapi::common::types::PolyLine& aOutput, const SHAPE_LINE_CHAIN& aSlc )
{
for( int vertex = 0; vertex < aSlc.PointCount(); vertex = aSlc.NextShape( vertex ) )

View File

@ -42,10 +42,14 @@ LIB_ID LibIdFromProto( const types::LibraryIdentifier& aId );
types::LibraryIdentifier LibIdToProto( const LIB_ID& aId );
void PackVector2( kiapi::common::types::Vector2& aOutput, const VECTOR2I aInput );
void PackVector2( types::Vector2& aOutput, const VECTOR2I& aInput );
VECTOR2I UnpackVector2( const types::Vector2& aInput );
void PackBox2( types::Box2& aOutput, const BOX2I& aInput );
BOX2I UnpackBox2( const types::Box2& aInput );
void PackPolyLine( kiapi::common::types::PolyLine& aOutput, const SHAPE_LINE_CHAIN& aSlc );
SHAPE_LINE_CHAIN UnpackPolyLine( const kiapi::common::types::PolyLine& aInput );

View File

@ -63,7 +63,9 @@ API_HANDLER_PCB::API_HANDLER_PCB( PCB_EDIT_FRAME* aFrame ) :
registerHandler<GetBoardStackup, BoardStackupResponse>( &API_HANDLER_PCB::handleGetStackup );
registerHandler<GetGraphicsDefaults, GraphicsDefaultsResponse>(
&API_HANDLER_PCB::handleGetGraphicsDefaults );
registerHandler<GetTextExtents, BoundingBoxResponse>(
registerHandler<GetBoundingBox, GetBoundingBoxResponse>(
&API_HANDLER_PCB::handleGetBoundingBox );
registerHandler<GetTextExtents, types::Box2>(
&API_HANDLER_PCB::handleGetTextExtents );
registerHandler<GetPadShapeAsPolygon, PadShapeAsPolygonResponse>(
&API_HANDLER_PCB::handleGetPadShapeAsPolygon );
@ -571,7 +573,48 @@ HANDLER_RESULT<GraphicsDefaultsResponse> API_HANDLER_PCB::handleGetGraphicsDefau
}
HANDLER_RESULT<commands::BoundingBoxResponse> API_HANDLER_PCB::handleGetTextExtents(
HANDLER_RESULT<GetBoundingBoxResponse> API_HANDLER_PCB::handleGetBoundingBox( GetBoundingBox& aMsg,
const HANDLER_CONTEXT& aCtx )
{
if( std::optional<ApiResponseStatus> busy = checkForBusy() )
return tl::unexpected( *busy );
if( !validateItemHeaderDocument( aMsg.header() ) )
{
ApiResponseStatus e;
// No message needed for AS_UNHANDLED; this is an internal flag for the API server
e.set_status( ApiStatusCode::AS_UNHANDLED );
return tl::unexpected( e );
}
GetBoundingBoxResponse response;
bool includeText = aMsg.mode() == BoundingBoxMode::BBM_ITEM_AND_CHILD_TEXT;
for( const types::KIID& idMsg : aMsg.items() )
{
KIID id( idMsg.value() );
std::optional<BOARD_ITEM*> optItem = getItemById( id );
if( !optItem )
continue;
BOARD_ITEM* item = *optItem;
BOX2I bbox;
if( item->Type() == PCB_FOOTPRINT_T )
bbox = static_cast<FOOTPRINT*>( item )->GetBoundingBox( includeText );
else
bbox = item->GetBoundingBox();
response.add_items()->set_value( idMsg.value() );
PackBox2( *response.add_boxes(), bbox );
}
return response;
}
HANDLER_RESULT<types::Box2> API_HANDLER_PCB::handleGetTextExtents(
GetTextExtents& aMsg,
const HANDLER_CONTEXT& aCtx )
{
@ -588,7 +631,7 @@ HANDLER_RESULT<commands::BoundingBoxResponse> API_HANDLER_PCB::handleGetTextExte
return tl::unexpected( e );
}
commands::BoundingBoxResponse response;
types::Box2 response;
BOX2I bbox = text.GetTextBox();
EDA_ANGLE angle = text.GetTextAngle();

View File

@ -72,7 +72,10 @@ private:
HANDLER_RESULT<GraphicsDefaultsResponse> handleGetGraphicsDefaults( GetGraphicsDefaults& aMsg,
const HANDLER_CONTEXT& aCtx );
HANDLER_RESULT<commands::BoundingBoxResponse> handleGetTextExtents( GetTextExtents& aMsg,
HANDLER_RESULT<commands::GetBoundingBoxResponse> handleGetBoundingBox( commands::GetBoundingBox& aMsg,
const HANDLER_CONTEXT& aCtx );
HANDLER_RESULT<types::Box2> handleGetTextExtents( GetTextExtents& aMsg,
const HANDLER_CONTEXT& aCtx );
HANDLER_RESULT<PadShapeAsPolygonResponse> handleGetPadShapeAsPolygon( GetPadShapeAsPolygon& aMsg,