KiCad PCB EDA Suite
Loading...
Searching...
No Matches
graphic_edit.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 The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * 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, see <https://www.gnu.org/licenses/>.
18 */
19
20#include <tools/graphic_edit.h>
21
22#include <board_item.h>
23#include <pcb_shape.h>
24
25#include <cmath>
26
27
28const PCB_SHAPE* GraphicEditShape( const EDA_ITEM* aItem )
29{
30 if( !aItem || aItem->Type() != PCB_SHAPE_T )
31 return nullptr;
32
33 const PCB_SHAPE* shape = static_cast<const PCB_SHAPE*>( aItem );
34
35 switch( shape->GetShape() )
36 {
38 case SHAPE_T::ARC:
39 case SHAPE_T::CIRCLE:
40 case SHAPE_T::RECTANGLE: return shape;
41 default: return nullptr;
42 }
43}
44
45
46bool IsGraphicExtendSource( const PCB_SHAPE& aShape )
47{
48 return aShape.GetShape() == SHAPE_T::SEGMENT || aShape.GetShape() == SHAPE_T::ARC;
49}
50
51
52bool IsGraphicTrimSource( const PCB_SHAPE& aShape )
53{
54 return GraphicEditShape( &aShape ) != nullptr;
55}
56
57
58const PCB_SHAPE* GraphicEditSource( const BOARD_ITEM& aSource, bool ( *aAccepts )( const PCB_SHAPE& ),
59 GRAPHIC_EDIT_RESULT& aResult )
60{
61 const PCB_SHAPE* source = GraphicEditShape( &aSource );
62
63 if( !source || !aAccepts( *source ) )
64 {
66 return nullptr;
67 }
68
69 if( source->IsLocked() )
70 {
72 return nullptr;
73 }
74
75 return source;
76}
77
78
79const PCB_SHAPE* GraphicEditBoundary( const BOARD_ITEM* aBoundary, const PCB_SHAPE& aSource )
80{
81 const PCB_SHAPE* boundary = GraphicEditShape( aBoundary );
82
83 if( !boundary || boundary == &aSource || boundary->GetLayer() != aSource.GetLayer() )
84 return nullptr;
85
86 return boundary;
87}
88
89
91{
92 return SHAPE_ARC( aShape.GetStart(), aShape.GetArcMid(), aShape.GetEnd(), 0 );
93}
94
95
97{
98 double sweep = std::abs( aArc.GetCentralAngle().AsDegrees() );
99
100 return aArc.GetRadius() > 0.0 && aArc.GetRadius() <= MAX_GRAPHIC_EDIT_ARC_RADIUS
101 && sweep >= GRAPHIC_EDIT_ANGLE_EPSILON && sweep < 360.0 - GRAPHIC_EDIT_ANGLE_EPSILON;
102}
103
104
105bool GraphicEditCoincident( const VECTOR2I& aA, const VECTOR2I& aB )
106{
107 // 2 is the furthest apart a rounding step either way can put them.
108 return aA.SquaredDistance( aB ) <= 2;
109}
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition board_item.h:84
bool IsLocked() const override
double AsDegrees() const
Definition eda_angle.h:116
A base class for most all the KiCad significant classes used in schematics and boards.
Definition eda_item.h:98
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:110
SHAPE_T GetShape() const
Definition eda_shape.h:175
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
Definition eda_shape.h:325
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
Definition eda_shape.h:275
VECTOR2I GetArcMid() const
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
Definition pcb_shape.h:68
EDA_ANGLE GetCentralAngle() const
Get the "central angle" of the arc - this is the angle at the point of the "pie slice".
double GetRadius() const
constexpr extended_type SquaredDistance(const VECTOR2< T > &aVector) const
Compute the squared distance between two vectors.
Definition vector2d.h:557
@ SEGMENT
Definition eda_shape.h:56
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
Definition eda_shape.h:57
SHAPE_ARC GraphicEditArc(const PCB_SHAPE &aShape)
bool IsGraphicEditArcUsable(const SHAPE_ARC &aArc)
False for radii and sweeps the planners refuse. Check before planning an arc.
bool IsGraphicTrimSource(const PCB_SHAPE &aShape)
Trim also takes the closed shapes, which it opens up.
const PCB_SHAPE * GraphicEditBoundary(const BOARD_ITEM *aBoundary, const PCB_SHAPE &aSource)
A boundary usable against aSource. Null if it is the source, off-layer or unusable.
const PCB_SHAPE * GraphicEditSource(const BOARD_ITEM &aSource, bool(*aAccepts)(const PCB_SHAPE &), GRAPHIC_EDIT_RESULT &aResult)
The shape to edit, or null with the reason in aResult. aAccepts decides the kinds.
bool GraphicEditCoincident(const VECTOR2I &aA, const VECTOR2I &aB)
Points built by different routes land a rounding step apart.
bool IsGraphicExtendSource(const PCB_SHAPE &aShape)
Extend needs two ends to work with.
const PCB_SHAPE * GraphicEditShape(const EDA_ITEM *aItem)
Any graphical shape a planner or a boundary search might use. Anything else gives null.
constexpr int MAX_GRAPHIC_EDIT_ARC_RADIUS
Larger arcs overflow the boundary search box.
constexpr double GRAPHIC_EDIT_ANGLE_EPSILON
Sweeps this near zero or a full turn are ambiguous.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition eda_angle.h:411
GRAPHIC_EDIT_REFUSAL m_Refusal
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
Definition typeinfo.h:80
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683