KiCad PCB EDA Suite
Loading...
Searching...
No Matches
construction_geom.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
25
26#include <layer_ids.h>
30#include <view/view.h>
31
32using namespace KIGFX;
33
34
36 EDA_ITEM( nullptr, NOT_USED ), // Never added to a BOARD/SCHEMATIC so it needs no type
37 m_color( COLOR4D::WHITE ), m_persistentColor( COLOR4D::WHITE )
38{
39}
40
41
42void CONSTRUCTION_GEOM::AddDrawable( const DRAWABLE& aItem, bool aPersistent )
43{
44 m_drawables.push_back( { aItem, aPersistent } );
45}
46
48{
49 m_drawables.clear();
50}
51
53{
54 // We could be a bit more circumspect here, but much of the time the
55 // enxtended lines go across the whole screen anyway
56 BOX2I bbox;
57 bbox.SetMaximum();
58 return bbox;
59}
60
61void CONSTRUCTION_GEOM::ViewDraw( int aLayer, VIEW* aView ) const
62{
63 GAL& gal = *aView->GetGAL();
64
65 gal.SetIsFill( false );
66 gal.SetIsStroke( true );
67 gal.SetLineWidth( 1 );
68
69 const BOX2I viewport = BOX2ISafe( aView->GetViewport() );
70
71 // Prevents extremely short snap lines from inhibiting drawing
72 // These can happen due to rounding in intersections, etc.
73 // (usually it is length 1 IU)
74 const int minSnapLineLength = 10;
75 const bool haveSnapLine = m_snapLine && m_snapLine->Length() >= minSnapLineLength;
76
77 // Avoid fighting with the snap line
78 const auto drawLineIfNotAlsoSnapLine = [&]( const SEG& aLine )
79 {
80 if( !haveSnapLine || !aLine.ApproxCollinear( *m_snapLine, 1 ) )
81 {
82 gal.DrawLine( aLine.A, aLine.B );
83 }
84 };
85
86 // Draw all the items
87 for( const DRAWABLE_INFO& drawable : m_drawables )
88 {
89 gal.SetStrokeColor( drawable.IsPersistent ? m_persistentColor : m_color );
90
91 std::visit(
92 [&]( const auto& visited )
93 {
94 using ItemType = std::decay_t<decltype( visited )>;
95
96 if constexpr( std::is_same_v<ItemType, LINE> )
97 {
98 // Extend the segment to the viewport boundary
99 std::optional<SEG> segToBoundary =
100 KIGEOM::ClipLineToBox( visited, viewport );
101
102 if( segToBoundary )
103 {
104 drawLineIfNotAlsoSnapLine( *segToBoundary );
105 }
106 }
107 else if constexpr( std::is_same_v<ItemType, HALF_LINE> )
108 {
109 // Extend the ray to the viewport boundary
110 std::optional<SEG> segToBoundary =
111 KIGEOM::ClipHalfLineToBox( visited, viewport );
112
113 if( segToBoundary )
114 {
115 drawLineIfNotAlsoSnapLine( *segToBoundary );
116 }
117 }
118 else if constexpr( std::is_same_v<ItemType, SEG> )
119 {
120 drawLineIfNotAlsoSnapLine( visited );
121 }
122 else if constexpr( std::is_same_v<ItemType, CIRCLE> )
123 {
124 gal.DrawCircle( visited.Center, visited.Radius );
125 }
126 else if constexpr( std::is_same_v<ItemType, SHAPE_ARC> )
127 {
128 gal.DrawArc( visited.GetCenter(), visited.GetRadius(),
129 visited.GetStartAngle(), visited.GetCentralAngle() );
130 }
131 else if constexpr( std::is_same_v<ItemType, VECTOR2I> )
132 {
133 KIGFX::DrawCross( gal, visited, aView->ToWorld( 16 ) );
134 }
135 },
136 drawable.Item );
137 }
138
139 if( haveSnapLine )
140 {
142
143 const int dashSizeBasis = aView->ToWorld( 12 );
144 const int snapOriginMarkerSize = aView->ToWorld( 16 );
145 // Avoid clash with the snap marker if very close
146 const int omitStartMarkerIfWithinLength = aView->ToWorld( 8 );
147
148 // The line itself
149 KIGFX::DrawDashedLine( gal, *m_snapLine, dashSizeBasis );
150
151 // The line origin marker if the line is long enough
152 if( m_snapLine->A.Distance( m_snapLine->B ) > omitStartMarkerIfWithinLength )
153 {
154 KIGFX::DrawCross( gal, m_snapLine->A, snapOriginMarkerSize );
155 gal.DrawCircle( m_snapLine->A, snapOriginMarkerSize / 2 );
156 }
157 }
158}
159
160void CONSTRUCTION_GEOM::ViewGetLayers( int aLayers[], int& aCount ) const
161{
162 aLayers[0] = LAYER_GP_OVERLAY;
163 aCount = 1;
164}
constexpr BOX2I BOX2ISafe(const BOX2D &aInput)
Definition: box2.h:929
constexpr void SetMaximum()
Definition: box2.h:80
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:89
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
std::optional< SEG > m_snapLine
const BOX2I ViewBBox() const override
Return the bounding box of the item covering all its layers.
std::vector< DRAWABLE_INFO > m_drawables
void AddDrawable(const DRAWABLE &aItem, bool aIsPersistent)
std::variant< SEG, LINE, HALF_LINE, CIRCLE, SHAPE_ARC, VECTOR2I > DRAWABLE
void ViewGetLayers(int aLayers[], int &aCount) const override
Return the all the layers within the VIEW the object is painted on.
void ViewDraw(int aLayer, VIEW *aView) const override
Draw the parts of the object belonging to layer aLayer.
Abstract interface for drawing on a 2D-surface.
virtual void SetIsFill(bool aIsFillEnabled)
Enable/disable fill.
virtual void DrawCircle(const VECTOR2D &aCenterPoint, double aRadius)
Draw a circle using world coordinates.
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.
virtual void DrawLine(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint)
Draw a line.
virtual void DrawArc(const VECTOR2D &aCenterPoint, double aRadius, const EDA_ANGLE &aStartAngle, const EDA_ANGLE &aAngle)
Draw an arc.
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition: view.h:68
BOX2D GetViewport() const
Return the current viewport visible area rectangle.
Definition: view.cpp:547
GAL * GetGAL() const
Return the #GAL this view is using to draw graphical primitives.
Definition: view.h:203
VECTOR2D ToWorld(const VECTOR2D &aCoord, bool aAbsolute=true) const
Converts a screen space point/vector to a point/vector in world space coordinates.
Definition: view.cpp:484
Definition: seg.h:42
@ WHITE
Definition: color4d.h:48
ItemType
Utility functions for drawing compound items (i.e.
@ LAYER_GP_OVERLAY
general purpose overlay
Definition: layer_ids.h:219
std::optional< SEG > ClipHalfLineToBox(const HALF_LINE &aRay, const BOX2I &aBox)
Get the segment of a half-line that is inside a box, if any.
std::optional< SEG > ClipLineToBox(const LINE &aLine, const BOX2I &aBox)
Get the segment of a line that is inside a box, if any.
The Cairo implementation of the graphics abstraction layer.
Definition: color4d.cpp:247
void DrawCross(GAL &aGal, const VECTOR2I &aPosition, int aSize)
Draw a cross at a given position.
void DrawDashedLine(GAL &aGal, const SEG &aSeg, double aDashSize)
Draw a dashed line.
Utility functions for working with shapes.
@ NOT_USED
the 3d code uses this value
Definition: typeinfo.h:79