diff --git a/api/proto/board/board_commands.proto b/api/proto/board/board_commands.proto index a0b313b6ce..a7143d172a 100644 --- a/api/proto/board/board_commands.proto +++ b/api/proto/board/board_commands.proto @@ -130,6 +130,31 @@ message GetTextExtents kiapi.board.types.Text text = 1; } +// Computes the polygon representation of a pad, merging any custom shapes together. +// This representation will approximate curves as a series of segments. +message GetPadShapeAsPolygon +{ + // The board to process + kiapi.common.types.DocumentSpecifier board = 1; + + // A list of one or more pads to process + repeated kiapi.common.types.KIID pads = 2; + + // The layer to process + kiapi.board.types.BoardLayer layer = 3; +} + +// Returned from GetPadShapeAsPolygon. The pads and polygons repeated fields will have the same length +// and can be treated as a list of tuples. +message PadShapeAsPolygonResponse +{ + // The pads that were processed + repeated kiapi.common.types.KIID pads = 1; + + // The polygon representation of each pad + repeated kiapi.common.types.PolygonWithHoles polygons = 2; +} + //// Interactive commands //// // These commands begin an interactive operation in the editor. // They return a response immediately, but the editor will become busy diff --git a/pcbnew/api/api_handler_pcb.cpp b/pcbnew/api/api_handler_pcb.cpp index 0ce28e62e9..386c1a7831 100644 --- a/pcbnew/api/api_handler_pcb.cpp +++ b/pcbnew/api/api_handler_pcb.cpp @@ -63,8 +63,10 @@ API_HANDLER_PCB::API_HANDLER_PCB( PCB_EDIT_FRAME* aFrame ) : registerHandler( &API_HANDLER_PCB::handleGetStackup ); registerHandler( &API_HANDLER_PCB::handleGetGraphicsDefaults ); - registerHandler( + registerHandler( &API_HANDLER_PCB::handleGetTextExtents ); + registerHandler( + &API_HANDLER_PCB::handleGetPadShapeAsPolygon ); registerHandler( &API_HANDLER_PCB::handleInteractiveMoveItems ); registerHandler( &API_HANDLER_PCB::handleGetNets ); @@ -603,6 +605,41 @@ HANDLER_RESULT API_HANDLER_PCB::handleGetTextExte } +HANDLER_RESULT API_HANDLER_PCB::handleGetPadShapeAsPolygon( + GetPadShapeAsPolygon& aMsg, + const HANDLER_CONTEXT& aCtx ) +{ + HANDLER_RESULT documentValidation = validateDocument( aMsg.board() ); + + if( !documentValidation ) + return tl::unexpected( documentValidation.error() ); + + SHAPE_POLY_SET poly; + PadShapeAsPolygonResponse response; + PCB_LAYER_ID layer = FromProtoEnum( aMsg.layer() ); + + for( const types::KIID& padRequest : aMsg.pads() ) + { + KIID id( padRequest.value() ); + std::optional optPad = getItemById( id ); + + if( !optPad || ( *optPad )->Type() != PCB_PAD_T ) + continue; + + response.add_pads()->set_value( padRequest.value() ); + + PAD* pad = static_cast( *optPad ); + pad->TransformShapeToPolygon( poly, pad->Padstack().EffectiveLayerFor( layer ), 0, + ARC_HIGH_DEF, ERROR_INSIDE ); + + types::PolygonWithHoles* polyMsg = response.mutable_polygons()->Add(); + PackPolyLine( *polyMsg->mutable_outline(), poly.COutline( 0 ) ); + } + + return response; +} + + HANDLER_RESULT API_HANDLER_PCB::handleInteractiveMoveItems( InteractiveMoveItems& aMsg, const HANDLER_CONTEXT& aCtx ) { diff --git a/pcbnew/api/api_handler_pcb.h b/pcbnew/api/api_handler_pcb.h index 55d836f35d..8c48483a2c 100644 --- a/pcbnew/api/api_handler_pcb.h +++ b/pcbnew/api/api_handler_pcb.h @@ -75,6 +75,9 @@ private: HANDLER_RESULT handleGetTextExtents( GetTextExtents& aMsg, const HANDLER_CONTEXT& aCtx ); + HANDLER_RESULT handleGetPadShapeAsPolygon( GetPadShapeAsPolygon& aMsg, + const HANDLER_CONTEXT& aCtx ); + HANDLER_RESULT handleInteractiveMoveItems( InteractiveMoveItems& aMsg, const HANDLER_CONTEXT& aCtx );