111 const double maxWorldPerPx =
pcbIUScale.mmToIU( 3.0 ) / 16.0;
113 return aWorldScale > 0.0 ? std::min( 1.0 / aWorldScale, maxWorldPerPx ) : maxWorldPerPx;
121 const double discPx = 11.0;
122 const double marginPx = 3.0;
125 const double baseAngle = atan2( preferred.
y, preferred.
x );
127 const double shapeClear = ( discPx + marginPx ) * aWorldPerPx;
128 const double badgeClear = ( 2.0 * discPx + marginPx ) * aWorldPerPx;
131 static const double dirSpread[] = { 0, 30, -30, 60, -60, 90, -90, 120, -120, 150, -150, 180 };
132 static const double magSteps[] = { 1.0, 1.6, 2.3 };
134 std::vector<VECTOR2D> positions;
135 positions.reserve( aBadges.size() );
144 double d = std::numeric_limits<double>::max();
147 for(
const SEG& seg : badge.avoid )
148 d = std::min( d, seg.
Distance( p ) - shapeClear );
150 for(
const VECTOR2D& placed : positions )
151 d = std::min( d, ( placed - aPos ).EuclideanNorm() - badgeClear );
157 double bestScore = -std::numeric_limits<double>::max();
160 for(
double mag : magSteps )
162 for(
double spread : dirSpread )
164 double a = baseAngle + spread *
M_PI / 180.0;
175 if( score > bestScore )
186 positions.push_back( best );
234 const std::optional<VECTOR2I>& aAnchor )
282 COLOR4D underColor( 0.80, 0.42, 0.02, 0.9 );
283 COLOR4D wellColor( 0.18, 0.72, 0.30, 0.9 );
284 COLOR4D overColor( 0.92, 0.18, 0.18, 0.9 );
296 const double lineWidth =
pcbIUScale.mmToIU( 0.15 );
306 default:
return underColor;
356 if( pts.size() >= 2 )
367 bool showAll =
false;
373 return std::ranges::any_of( aConstraint->
GetMembers(),
394 auto constraintShown =
397 if( focusConstraint !=
niluuid )
398 return aConstraint->
m_Uuid == focusConstraint;
406 return referencesShape( aConstraint, focusShape );
411 std::set<KIID> erroredIds( diag.
errored.begin(), diag.
errored.end() );
424 return shape->GetBoundingBox().Centre();
431 auto appendShapeSegs = [&](
const PCB_SHAPE* aShape, std::vector<SEG>& aOut )
447 for(
int i = 0; i <= steps; ++i )
449 EDA_ANGLE a = start + sweep * ( double( i ) / steps );
453 aOut.emplace_back( prev, p );
465 for(
size_t i = 1; i < pts.size(); ++i )
466 aOut.emplace_back( pts[i - 1], pts[i] );
477 auto walkConstraints =
482 const std::vector<CONSTRAINT_MEMBER>& members = constraint->GetMembers();
484 if( members.empty() || !constraintShown( constraint ) )
487 bool errored = erroredIds.contains( constraint->m_Uuid );
488 bool conflicting = conflictingIds.contains( constraint->m_Uuid );
491 std::optional<VECTOR2I> pos = badgePosition( first );
498 if( errored || conflicting )
505 color = colorForState( it->second );
512 std::vector<SEG> avoid;
518 appendShapeSegs( shape, avoid );
523 { *pos, constraint->m_Uuid, constraint->GetConstraintType(), color, std::move( avoid ) } );
527 walkConstraints(
m_board->Constraints() );
530 walkConstraints( footprint->Constraints() );
536 const COLOR4D previewColor( 0.10, 0.85, 0.95, 0.9 );
542 outlineShape( shape, previewColor );
548 setStroke( previewColor );
559 { return aBadge.constraint == m_selected; } ) )
587 return it->second.get();
589 std::unique_ptr<BITMAP_BASE> base;
593 if( wxBitmap bmp =
KiBitmap(
id ); bmp.IsOk() )
595 base = std::make_unique<BITMAP_BASE>();
596 base->SetImage( bmp.ConvertToImage() );
600 return (
m_icons[aType] = std::move( base ) ).get();
606 uint8_t r = uint8_t( aColor.
r * 255.0 );
607 uint8_t g = uint8_t( aColor.
g * 255.0 );
608 uint8_t b = uint8_t( aColor.
b * 255.0 );
609 uint8_t a = uint8_t( aColor.
a * 255.0 );
611 uint32_t key = ( uint32_t( r ) << 24 ) | ( uint32_t( g ) << 16 ) | ( uint32_t( b ) << 8 ) | a;
614 return it->second.get();
623 for(
int y = 0; y <
S; ++y )
625 for(
int x = 0; x <
S; ++x )
627 double d = std::hypot( x + 0.5 -
center, y + 0.5 -
center );
628 double coverage = std::clamp(
radius - d + 0.5, 0.0, 1.0 );
630 img.SetRGB( x, y, r, g, b );
631 img.SetAlpha( x, y, uint8_t( a * coverage ) );
635 auto base = std::make_unique<BITMAP_BASE>();
636 base->SetImage( img );
638 return (
m_discs[key] = std::move( base ) ).get();
650 const double iconPx = 18.0;
651 const double bigIconPx = 26.0;
652 const double linePx = 1.5;
677 gal->
Scale(
VECTOR2D( aWidth / natural, aWidth / natural ) );
682 for(
size_t i = 0; i <
m_badges.size(); ++i )
691 double iconSize = ( selected ? bigIconPx : iconPx ) * worldPerPx;
692 double chipR = 0.62 * iconSize;
696 blit(
disc( badge.
color ), pos, 2.0 * chipR );
703 gal->
SetLineWidth(
static_cast<float>( linePx * worldPerPx ) );
704 gal->
DrawCircle( pos, chipR + 2.0 * linePx * worldPerPx );
707 blit( bitmap, pos, iconSize );
714 const double pxToWorld = 1.0 /
scale;
721 gal->
SetLineWidth(
static_cast<float>( linePx * pxToWorld ) );
constexpr EDA_IU_SCALE pcbIUScale
wxBitmap KiBitmap(BITMAPS aBitmap, int aHeightTag)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
BITMAPS
A list of all bitmap identifiers.
CONSTRAINT_STATE
The constraint state of a shape, for the diagnostics overlay tint.
@ OVER_CONSTRAINED
In a cluster the solver reports as conflicting.
@ UNDER_CONSTRAINED
In a cluster with remaining free degrees of freedom.
@ WELL_CONSTRAINED
In a fully-determined cluster (zero free DOF).
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
This class handle bitmap images in KiCad.
VECTOR2I GetSizePixels() const
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Information pertinent to a Pcbnew printed circuit board.
std::optional< VECTOR2I > m_previewAnchor
std::vector< CONSTRAINT_BADGE > m_badges
void ViewDraw(int aLayer, KIGFX::VIEW *aView) const override
Draw the parts of the object belonging to layer aLayer.
std::map< uint32_t, std::unique_ptr< BITMAP_BASE > > m_discs
BITMAP_BASE * disc(const KIGFX::COLOR4D &aColor) const
A filled disc of the given colour, built and cached on first use.
~CONSTRAINT_BADGE_ITEM() override
std::map< PCB_CONSTRAINT_TYPE, std::unique_ptr< BITMAP_BASE > > m_icons
std::vector< VECTOR2D > m_layout
BITMAP_BASE * icon(PCB_CONSTRAINT_TYPE aType) const
The badge icon for a constraint type, loaded and cached on first use (nullptr for UNDEFINED).
static double BadgeHitRadius()
Click hit radius in screen pixels.
bool SetPickPreview(const KIID &aElement, bool aWholeElement, const std::optional< VECTOR2I > &aAnchor)
Preview next constraint pick target while authoring a point based constraint aElement is shape or dim...
bool SetVisibilityMode(OVERLAY_MODE aMode)
Set the visibility mode (HOVER vs ALWAYS). Returns true if it changed.
void RefreshSelection()
Redraw from the last diagnosis without re-solving (for a selection-only change).
bool SetIsolated(const KIID &aConstraint)
Show only this constraint, or niluuid to show all. Returns true if it changed.
CONSTRAINT_OVERLAY(BOARD *aBoard, KIGFX::VIEW *aView)
CONSTRAINT_BADGE_ITEM m_badgeItem
~CONSTRAINT_OVERLAY() override
void ClearPickPreview()
Drop any pick preview.
BOARD_CONSTRAINT_DIAGNOSTICS m_lastDiag
std::vector< CONSTRAINT_BADGE > m_badges
std::optional< VECTOR2I > m_previewAnchor
static double BadgeWorldPerPixel(double aWorldScale)
World units per screen pixel for badge sizing, capped at far zoom-out.
void render()
Redraw the tint and badges from m_lastDiag (no re-solve).
void Clear()
Hide the overlay.
static VECTOR2D BadgeScreenOffset()
Screen-pixel offset from a badge's anchor to where its glyph draws and hit-tests, keeping the glyph c...
bool SetSelected(const KIID &aConstraint)
Mark a constraint as selected so its badge draws enlarged and ringed; pass niluuid to clear.
bool SetHoverShape(const KIID &aShape)
In HOVER mode, show only this shape's constraints; niluuid draws nothing.
static std::vector< VECTOR2D > LayoutBadges(const std::vector< CONSTRAINT_BADGE > &aBadges, double aWorldPerPx)
The on-screen draw position (world units) of each badge at the given scale: the anchor offset by Badg...
void Update(const BOARD_CONSTRAINT_DIAGNOSTICS &aDiag)
Redraw the tint and badges from aDiag (the caller owns the one board-wide solve).
EDA_ITEM(EDA_ITEM *parent, KICAD_T idType, bool isSCH_ITEM=false, bool isBOARD_ITEM=false)
EDA_ANGLE GetArcAngle() const
int GetEllipseMinorRadius() const
const VECTOR2I & GetEllipseCenter() const
EDA_ANGLE GetEllipseEndAngle() const
int GetEllipseMajorRadius() const
EDA_ANGLE GetEllipseRotation() const
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
EDA_ANGLE GetEllipseStartAngle() const
const std::vector< VECTOR2I > & GetBezierPoints() const
static const int POINT_SIZE
Single point size in pixels.
A color representation with 4 components: red, green, blue, alpha.
Abstract interface for drawing on a 2D-surface.
virtual void SetIsFill(bool aIsFillEnabled)
Enable/disable fill.
virtual void SetFillColor(const COLOR4D &aColor)
Set the fill color.
virtual void Translate(const VECTOR2D &aTranslation)
Translate the context.
virtual void DrawCircle(const VECTOR2D &aCenterPoint, double aRadius)
Draw a circle using world coordinates.
virtual void Restore()
Restore the context.
virtual void SetLineWidth(float aLineWidth)
Set the line width.
virtual void SetStrokeColor(const COLOR4D &aColor)
Set the stroke color.
virtual void SetIsStroke(bool aIsStrokeEnabled)
Enable/disable stroked outlines.
double GetWorldUnitLength() const
virtual void Scale(const VECTOR2D &aScale)
Scale the context.
virtual void DrawBitmap(const BITMAP_BASE &aBitmap, double alphaBlend=1.0)
Draw a bitmap image.
virtual void Save()
Save the context.
double GetWorldScale() const
Get the world scale.
Contains all the knowledge about how to draw graphical object onto any particular output device.
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
GAL * GetGAL() const
Return the GAL this view is using to draw graphical primitives.
A geometric constraint between board items (issue #2329).
const std::vector< CONSTRAINT_MEMBER > & GetMembers() const
VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
int Distance(const SEG &aSeg) const
Compute minimum Euclidean distance to segment aSeg.
SHAPE_LINE_CHAIN ConvertToPolyline(int aMaxError) const
Build a polyline approximation of the ellipse or arc.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
std::shared_ptr< KIGFX::VIEW_OVERLAY > m_overlay
VIEW_OVERLAY_HOLDER(KIGFX::VIEW *aView)
std::vector< CONSTRAINT_ANCHOR_POINT > ConstraintItemAnchors(const BOARD_ITEM *aItem)
The constraint anchors an item exposes.
std::optional< VECTOR2I > ConstraintAnchorPosition(BOARD *aBoard, const CONSTRAINT_MEMBER &aMember)
Current location of a constraint member's anchor (its shape's START/END/CENTER, or a dimension's feat...
OVERLAY_MODE
Draws the geometric-constraint diagnostics tint onto a GAL overlay (issue #2329): every constrained s...
static constexpr EDA_ANGLE ANGLE_0
static constexpr EDA_ANGLE ANGLE_360
@ LAYER_CONSTRAINT_UNDER
Under-constrained (free DOF remain).
@ LAYER_CONSTRAINT_OVER
Over-constrained / conflicting.
@ LAYER_CONSTRAINT_WELL
Fully constrained.
@ TARGET_OVERLAY
Items that may change while the view stays the same (noncached)
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
BITMAPS ConstraintTypeBitmap(PCB_CONSTRAINT_TYPE aType)
Badge icon for a constraint type; INVALID_BITMAP for UNDEFINED.
PCB_CONSTRAINT_TYPE
The geometric relationship a PCB_CONSTRAINT enforces between its members.
std::deque< PCB_CONSTRAINT * > CONSTRAINTS
Board-wide diagnostics for the constraint overlay and info bar.
std::map< KIID, CONSTRAINT_STATE > shapeStates
std::vector< KIID > errored
Invalid constraints (member missing, deleted, or of a kind incompatible with the type).
std::vector< KIID > conflicting
A selectable feature of a shape (a segment endpoint, arc centre, ...) and its location.
An on-canvas constraint badge.
One participant in a constraint: a referenced board item plus the feature of that item that participa...
KIID m_item
Referenced board item, usually a PCB_SHAPE.
@ NOT_USED
the 3d code uses this value
VECTOR2< int32_t > VECTOR2I
VECTOR2< double > VECTOR2D