32#include "../3d_rendering/raytracing/shapes2D/ring_2d.h"
33#include "../3d_rendering/raytracing/shapes2D/filled_circle_2d.h"
34#include "../3d_rendering/raytracing/shapes2D/round_segment_2d.h"
35#include "../3d_rendering/raytracing/shapes2D/triangle_2d.h"
60#define TO_3DU( x ) ( ( x ) * m_biuTo3Dunits )
62#define TO_SFVEC2F( vec ) SFVEC2F( TO_3DU( vec.x ), TO_3DU( -vec.y ) )
74 float aOuterRadius,
const BOARD_ITEM& aBoardItem )
76 if( aOuterRadius > aInnerRadius && aInnerRadius > 0.0f )
77 aContainer->
Add(
new RING_2D( aCenter, aInnerRadius, aOuterRadius, aBoardItem ) );
126 penWidth_3DU, *aOwner );
146 addText( aDimension, aContainer, aDimension );
150 for(
const std::shared_ptr<SHAPE>& shape : aDimension->
GetShapes() )
152 switch( shape->Type() )
156 const SEG& seg =
static_cast<const SHAPE_SEGMENT*
>( shape.get() )->GetSeg();
159 TO_3DU( linewidth ), *aOwner );
165 int radius =
static_cast<const SHAPE_CIRCLE*
>( shape.get() )->GetRadius();
183 const std::bitset<LAYER_3D_END>& aVisibilityFlags )
189 if( field->GetLayer() == aLayerId && field->IsVisible() )
195 else if( field->IsValue() && !aVisibilityFlags.test(
LAYER_FP_VALUES ) )
198 addText( field, aContainer, field );
204 switch( item->Type() )
210 if(
text->GetLayer() == aLayerId &&
text->IsVisible() )
216 else if(
text->GetText() == wxT(
"${VALUE}" ) && !aVisibilityFlags.test(
LAYER_FP_VALUES ) )
229 if( textbox->
GetLayer() == aLayerId )
230 addShape( textbox, aContainer, aFootprint );
240 addTable( table, aContainer, aFootprint );
253 if( dimension->
GetLayer() == aLayerId )
254 addShape( dimension, aContainer, aFootprint );
264 addShape( shape, aContainer, aFootprint );
281 const float radius3DU =
TO_3DU( ( aTrack->
GetWidth() / 2.0 ) + aMargin );
292 switch( aTrack->
Type() )
322 if( radius < std::numeric_limits<double>::min() || arc_angle.
IsZero() )
327 if( arcsegcount <= 1 )
334 circlesegcount =
alg::clamp( 1, circlesegcount, 128 );
338 aDstContainer, *arc );
368 if( ( clearance.
x < 0 || clearance.
x != clearance.
y )
369 && aPad->
GetShape() != PAD_SHAPE::CUSTOM )
373 if( dummySize.
x <= 0 || dummySize.
y <= 0 )
379 clearance = { 0, 0 };
382 dummy.SetParentGroup(
nullptr );
384 else if( aPad->
GetShape() == PAD_SHAPE::CUSTOM )
393 auto padShapes = std::static_pointer_cast<SHAPE_COMPOUND>( aPad->
GetEffectiveShape() );
395 for(
const SHAPE* shape : padShapes->Shapes() )
397 switch( shape->Type() )
471 poly.
Inflate( clearance.
x, CORNER_STRATEGY::ROUND_ALL_CORNERS, maxError );
484 wxLogTrace(
m_logTrace, wxT(
"BOARD_ADAPTER::createPadWithHole - found an invalid pad" ) );
493 TO_3DU( slot->GetWidth() + aInflateValue * 2 ),
499 PCB_LAYER_ID aLayerId,
bool aSkipPlatedPads,
bool aSkipNonPlatedPads )
503 if( !
pad->IsOnLayer( aLayerId ) )
511 if( !
pad->IsOnCopperLayer() )
515 if( !
pad->FlashLayer( aLayerId ) )
524 if( aSkipPlatedPads &&
pad->FlashLayer(
F_Mask ) )
527 if( aSkipNonPlatedPads && !
pad->FlashLayer(
F_Mask ) )
533 if( aSkipPlatedPads &&
pad->FlashLayer(
B_Mask ) )
536 if( aSkipNonPlatedPads && !
pad->FlashLayer(
B_Mask ) )
543 margin.
x +=
pad->GetSolderMaskExpansion();
544 margin.
y +=
pad->GetSolderMaskExpansion();
549 margin +=
pad->GetSolderPasteMargin();
564 const EDA_ANGLE& aArcAngle,
int aCircleToSegmentsCount,
576 arc_end = arc_start = aStart;
583 std::swap( arc_start, arc_end );
584 arcAngle = -arcAngle;
593 curr_end = arc_start;
597 TO_3DU( aWidth ), aOwner );
599 curr_start = curr_end;
602 if( curr_end != arc_end )
605 TO_3DU( aWidth ), aOwner );
617 if( lineStyle <= LINE_STYLE::FIRST_TYPE )
621 case SHAPE_T::CIRCLE:
627 if( aShape->
IsFilled() || innerR3DU <= 0.0 )
630 addRING_2D( aContainer, center3DU, innerR3DU, outerR3DU, *aOwner );
635 case SHAPE_T::RECTANGLE:
652 linewidth3DU, *aOwner );
654 linewidth3DU, *aOwner );
656 linewidth3DU, *aOwner );
658 linewidth3DU, *aOwner );
667 segCount, aShape->
GetWidth(), aContainer, *aOwner );
671 case SHAPE_T::SEGMENT:
676 case SHAPE_T::BEZIER:
697 wxFAIL_MSG( wxT(
"BOARD_ADAPTER::addShape no implementation for " )
714 for(
SHAPE* shape : shapes )
719 addROUND_SEGMENT_2D( aContainer, TO_SFVEC2F( a ), TO_SFVEC2F( b ),
720 linewidth3DU, *aOwner );
724 for(
SHAPE* shape : shapes )
733 addText( aTextBox, aContainer, aOwner );
742 if( aTextBox->
GetShape() == SHAPE_T::RECTANGLE )
750 aTextBox->PCB_SHAPE::TransformShapeToPolygon( polyList,
UNDEFINED_LAYER, 0,
765 addText( cell, aContainer, aOwner );
781 if( aPad->
GetShape() == PAD_SHAPE::CIRCLE )
784 const int radius = aPad->
GetSize().
x / 2;
785 const float inner_radius3DU =
TO_3DU( radius - aWidth / 2.0 );
786 const float outer_radius3DU =
TO_3DU( radius + aWidth / 2.0 );
788 addRING_2D( aContainer, center3DU, inner_radius3DU, outer_radius3DU, *aPad );
796 for(
int j = 0; j <
path.PointCount(); j++ )
constexpr int ARC_HIGH_DEF
void addSolidAreasShapes(const ZONE *aZone, CONTAINER_2D_BASE *aDstContainer, PCB_LAYER_ID aLayerId)
void addFootprintShapes(const FOOTPRINT *aFootprint, CONTAINER_2D_BASE *aDstContainer, PCB_LAYER_ID aLayerId, const std::bitset< LAYER_3D_END > &aVisibilityFlags)
void createArcSegments(const VECTOR2I &aCentre, const VECTOR2I &aStart, const EDA_ANGLE &aArcAngle, int aCircleToSegmentsCount, int aWidth, CONTAINER_2D_BASE *aContainer, const BOARD_ITEM &aOwner)
void createPadWithMargin(const PAD *aPad, CONTAINER_2D_BASE *aDstContainer, PCB_LAYER_ID aLayer, const VECTOR2I &aMargin) const
void addPads(const FOOTPRINT *aFootprint, CONTAINER_2D_BASE *aDstContainer, PCB_LAYER_ID aLayerId, bool aSkipPlatedPads, bool aSkipNonPlatedPads)
const BOARD * GetBoard() const noexcept
void createPadWithHole(const PAD *aPad, CONTAINER_2D_BASE *aDstContainer, int aInflateValue)
void buildPadOutlineAsSegments(const PAD *aPad, CONTAINER_2D_BASE *aDstContainer, int aWidth)
void addShape(const PCB_SHAPE *aShape, CONTAINER_2D_BASE *aContainer, const BOARD_ITEM *aOwner)
void createTrack(const PCB_TRACK *aTrack, CONTAINER_2D_BASE *aDstContainer)
void addTable(const PCB_TABLE *aTable, CONTAINER_2D_BASE *aContainer, const BOARD_ITEM *aOwner)
unsigned int GetCircleSegmentCount(float aDiameter3DU) const
void createViaWithMargin(const PCB_TRACK *aTrack, CONTAINER_2D_BASE *aDstContainer, int aMargin)
double m_biuTo3Dunits
Scale factor to convert board internal units to 3D units normalized between -1.0 and 1....
void addText(const EDA_TEXT *aText, CONTAINER_2D_BASE *aDstContainer, const BOARD_ITEM *aOwner)
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
virtual bool IsKnockout() const
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
const KIFONT::METRICS & GetFontMetrics() const
BOARD_ITEM_CONTAINER * GetParent() const
const PCB_PLOT_PARAMS & GetPlotOptions() const
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
void Add(OBJECT_2D *aObject)
KICAD_T Type() const
Returns the type of object.
EDA_ANGLE GetArcAngle() const
virtual std::vector< SHAPE * > MakeEffectiveShapes(bool aEdgeOnly=false) const
Make a set of SHAPE objects representing the EDA_SHAPE.
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
std::vector< VECTOR2I > GetRectCorners() const
wxString SHAPE_T_asString() const
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
KIFONT::FONT * GetFont() const
virtual EDA_ANGLE GetDrawRotation() const
virtual VECTOR2I GetDrawPos() const
const TEXT_ATTRIBUTES & GetAttributes() const
int GetEffectiveTextPenWidth(int aDefaultPenWidth=0) const
The EffectiveTextPenWidth uses the text thickness if > 1 or aDefaultPenWidth.
virtual wxString GetShownText(bool aAllowExtraText, int aDepth=0) const
Return the string actually shown after processing of the base text.
FONT is an abstract base class for both outline and stroke fonts.
static FONT * GetFont(const wxString &aFontName=wxEmptyString, bool aBold=false, bool aItalic=false, const std::vector< wxString > *aEmbeddedFiles=nullptr, bool aForDrawingSheet=false)
void Draw(KIGFX::GAL *aGal, const wxString &aText, const VECTOR2I &aPosition, const VECTOR2I &aCursor, const TEXT_ATTRIBUTES &aAttributes, const METRICS &aFontMetrics) const
Draw a string.
PCB specific render settings.
void SetGapLengthRatio(double aRatio)
void SetDashLengthRatio(double aRatio)
VECTOR2I ShapePos() const
void TransformShapeToPolygon(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aMaxError, ERROR_LOC aErrorLoc=ERROR_INSIDE, bool ignoreLineWidth=false) const override
Convert the pad shape to a closed polygon.
const std::shared_ptr< SHAPE_POLY_SET > & GetEffectivePolygon(ERROR_LOC aErrorLoc=ERROR_INSIDE) const
PAD_SHAPE GetShape() const
virtual std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, FLASHING flashPTHPads=FLASHING::DEFAULT) const override
Some pad shapes can be complex (rounded/chamfered rectangle), even without considering custom shapes.
bool HasHole() const override
std::shared_ptr< SHAPE_SEGMENT > GetEffectiveHoleShape() const override
Return a SHAPE_SEGMENT object representing the pad's hole.
const VECTOR2I & GetSize() const
bool IsDegenerated(int aThreshold=5) const
EDA_ANGLE GetAngle() const
virtual VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
int GetLineThickness() const
const std::vector< std::shared_ptr< SHAPE > > & GetShapes() const
Parameters and options when plotting/printing a board.
double GetDashedLineGapRatio() const
double GetDashedLineDashRatio() const
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
int GetWidth() const override
void TransformShapeToPolygon(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false) const override
Convert the shape to a closed polygon.
STROKE_PARAMS GetStroke() const override
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
std::vector< PCB_TABLECELL * > GetCells() const
bool IsBorderEnabled() const
Disables the border, this is done by changing the stroke internally.
void TransformTextToPolySet(SHAPE_POLY_SET &aBuffer, int aClearance, int aMaxError, ERROR_LOC aErrorLoc) const
Function TransformTextToPolySet Convert the text to a polygonSet describing the actual character stro...
void SetEnd(const VECTOR2I &aEnd)
void SetStart(const VECTOR2I &aStart)
const VECTOR2I & GetStart() const
const VECTOR2I & GetEnd() const
virtual void SetWidth(int aWidth)
virtual int GetWidth() const
const SHAPE_LINE_CHAIN ConvertToPolyline(double aAccuracy=DefaultAccuracyForPCB(), double *aEffectiveAccuracy=nullptr) const
Construct a SHAPE_LINE_CHAIN of segments from a given arc.
const VECTOR2I GetCenter() const
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
SEG Segment(int aIndex) const
Return a copy of the aIndex-th segment in the line chain.
int SegmentCount() const
Return the number of segments in this line chain.
Represent a set of closed polygons.
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new outline to the set and returns its index.
bool IsEmpty() const
Return true if the set is empty (no polygons at all)
void Inflate(int aAmount, CORNER_STRATEGY aCornerStrategy, int aMaxError, bool aSimplify=false)
Perform outline inflation/deflation.
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline)
void Simplify(POLYGON_MODE aFastMode)
Simplify the polyset (merges overlapping polys, eliminates degeneracy/self-intersections) For aFastMo...
int NewOutline()
Creates a new empty polygon in the set and returns its index.
const VECTOR2I & GetPosition() const
const VECTOR2I GetSize() const
const SEG & GetSeg() const
Represent a simple polygon consisting of a zero-thickness closed chain of connected line segments.
const SHAPE_LINE_CHAIN & Vertices() const
Return the list of vertices defining this simple polygon.
An abstract shape on 2D plane.
LINE_STYLE GetLineStyle() const
static void Stroke(const SHAPE *aShape, LINE_STYLE aLineStyle, int aWidth, const KIGFX::RENDER_SETTINGS *aRenderSettings, const std::function< void(const VECTOR2I &a, const VECTOR2I &b)> &aStroker)
Handle a list of polygons defining a copper zone.
const std::shared_ptr< SHAPE_POLY_SET > & GetFilledPolysList(PCB_LAYER_ID aLayer) const
void addFILLED_CIRCLE_2D(CONTAINER_2D_BASE *aContainer, const SFVEC2F &aCenter, float aRadius, const BOARD_ITEM &aBoardItem)
void addROUND_SEGMENT_2D(CONTAINER_2D_BASE *aContainer, const SFVEC2F &aStart, const SFVEC2F &aEnd, float aWidth, const BOARD_ITEM &aBoardItem)
void addRING_2D(CONTAINER_2D_BASE *aContainer, const SFVEC2F &aCenter, float aInnerRadius, float aOuterRadius, const BOARD_ITEM &aBoardItem)
static constexpr EDA_ANGLE ANGLE_0
static constexpr EDA_ANGLE ANGLE_360
a few functions useful in geometry calculations.
int GetArcToSegmentCount(int aRadius, int aErrorMax, const EDA_ANGLE &aArcAngle)
static const wxChar * m_logTrace
Trace mask used to enable or disable debug output for this class.
bool IsCopperLayer(int aLayerId)
Tests whether a layer is a copper layer.
@ LAYER_FP_REFERENCES
show footprints references (when texts are visible)
@ LAYER_FP_VALUES
show footprints values (when texts are visible)
PCB_LAYER_ID
A quick note on layer IDs:
This file contains miscellaneous commonly used macros and functions.
#define UNIMPLEMENTED_FOR(type)
T clamp(T min, T value, T max)
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
bool Is_segment_a_circle(const SFVEC2F &aStart, const SFVEC2F &aEnd)
Check if segment start and end is very close to each other.
@ SH_POLY_SET
set of polygons (with holes, etc.)
@ SH_RECT
axis-aligned rectangle
@ SH_SIMPLE
simple polygon
static wxString SHAPE_TYPE_asString(SHAPE_TYPE a)
std::vector< FAB_LAYER_COLOR > dummy
LINE_STYLE
Dashed line types.
void ConvertPolygonToTriangles(const SHAPE_POLY_SET &aPolyList, CONTAINER_2D_BASE &aDstContainer, float aBiuTo3dUnitsScale, const BOARD_ITEM &aBoardItem)
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
@ PCB_DIM_ORTHOGONAL_T
class PCB_DIM_ORTHOGONAL, a linear dimension constrained to x/y
@ PCB_DIM_LEADER_T
class PCB_DIM_LEADER, a leader dimension (graphic item)
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
@ PCB_DIM_CENTER_T
class PCB_DIM_CENTER, a center point marking (graphic item)
@ PCB_TEXTBOX_T
class PCB_TEXTBOX, wrapped text on a layer
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
@ PCB_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
@ PCB_TABLE_T
class PCB_TABLE, table of PCB_TABLECELLs
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
@ PCB_DIM_RADIAL_T
class PCB_DIM_RADIAL, a radius or diameter dimension
constexpr ret_type KiROUND(fp_type v, bool aQuiet=false)
Round a floating point number to an integer using "round halfway cases away from zero".
VECTOR2< int32_t > VECTOR2I