KiCad PCB EDA Suite
router_preview_item.cpp
Go to the documentation of this file.
1 /*
2  * KiRouter - a push-and-(sometimes-)shove PCB router
3  *
4  * Copyright (C) 2013-2014 CERN
5  * Copyright (C) 2016 KiCad Developers, see AUTHORS.txt for contributors.
6  * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
7  *
8  * This program is free software: you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License as published by the
10  * Free Software Foundation, either version 3 of the License, or (at your
11  * option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with this program. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #include <deque>
23 #include <gal/color4d.h>
24 #include <view/view.h>
25 
26 #include <geometry/shape_rect.h>
27 #include <geometry/shape_simple.h>
28 #include "class_track.h"
29 #include <pcb_painter.h>
30 
31 #include "router_preview_item.h"
32 
33 #include "pns_arc.h"
34 #include "pns_line.h"
35 #include "pns_segment.h"
36 #include "pns_via.h"
37 
38 using namespace KIGFX;
39 
42 {
43  m_view = aView;
44 
45  m_shape = NULL;
46  m_clearance = -1;
48 
49  m_showTrackClearance = false;
50  m_showViaClearance = false;
51 
52  // initialize variables, overwritten by Update( aItem ), if aItem != NULL
53  m_router = NULL;
54  m_type = PR_SHAPE;
55  m_style = 0;
56  m_width = 0;
57  m_depth = 0;
58 
59  if( aItem )
60  Update( aItem );
61 }
62 
63 
65 {
66  delete m_shape;
67 }
68 
69 
71 {
72  m_originLayer = aItem->Layers().Start();
73 
74  if( aItem->OfKind( PNS::ITEM::LINE_T ) )
75  {
76  const PNS::LINE* l = static_cast<const PNS::LINE*>( aItem );
77 
78  if( !l->SegmentCount() )
79  return;
80  }
81 
82  assert( m_originLayer >= 0 );
83 
86  m_color.a = 0.8;
87  m_depth = BaseOverlayDepth - aItem->Layers().Start();
88  m_shape = aItem->Shape()->Clone();
89 
90  switch( aItem->Kind() )
91  {
92  case PNS::ITEM::LINE_T:
93  m_type = PR_SHAPE;
94  m_width = static_cast<const PNS::LINE*>( aItem )->Width();
95  break;
96 
97  case PNS::ITEM::ARC_T:
98  m_type = PR_SHAPE;
99  m_width = static_cast<const PNS::ARC*>( aItem )->Width();
100  break;
101 
103  m_type = PR_SHAPE;
104  m_width = static_cast<const PNS::SEGMENT*>( aItem )->Width();
105  break;
106 
107  case PNS::ITEM::VIA_T:
109  m_type = PR_SHAPE;
110  m_width = 0;
111  m_color = COLOR4D( 0.7, 0.7, 0.7, 0.8 );
113  break;
114 
115  case PNS::ITEM::SOLID_T:
116  m_type = PR_SHAPE;
117  m_width = 0;
118  break;
119 
120  default:
121  break;
122  }
123 
124  if( aItem->Marker() & PNS::MK_VIOLATION )
125  m_color = COLOR4D( 0, 1, 0, 1 );
126 }
127 
128 
130 {
131  BOX2I bbox;
132 
133  switch( m_type )
134  {
135  case PR_SHAPE:
136  if( m_shape )
137  {
138  bbox = m_shape->BBox();
139  bbox.Inflate( m_width / 2 );
140  }
141  return bbox;
142 
143  case PR_POINT:
144  bbox = BOX2I ( m_pos - VECTOR2I( 100000, 100000 ), VECTOR2I( 200000, 200000 ) );
145  return bbox;
146 
147  default:
148  break;
149  }
150 
151  return bbox;
152 }
153 
154 
156 {
157  gal->SetIsFill( false );
158 
159  for( int s = 0; s < aL.SegmentCount(); s++ )
160  gal->DrawLine( aL.CSegment( s ).A, aL.CSegment( s ).B );
161 
162  for( size_t s = 0; s < aL.ArcCount(); s++ )
163  {
164  auto arc = aL.CArcs()[s];
165 
166  auto start_angle = DEG2RAD( arc.GetStartAngle() );
167  auto angle = DEG2RAD( arc.GetCentralAngle() );
168 
169  gal->DrawArc( arc.GetCenter(), arc.GetRadius(), start_angle, start_angle + angle);
170  }
171 
172  if( aL.IsClosed() )
173  gal->DrawLine( aL.CSegment( -1 ).B, aL.CSegment( 0 ).A );
174 }
175 
176 
177 void ROUTER_PREVIEW_ITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
178 {
179  auto gal = aView->GetGAL();
180  //col.Brighten(0.7);
181 
182  if( m_type == PR_SHAPE )
183  {
184  if( !m_shape )
185  return;
186 
187  // N.B. The order of draw here is important
188  // Cairo doesn't current support z-ordering, so we need
189  // to draw the clearance first to ensure it is in the background
191  //TODO(snh) Add configuration option for the color/alpha here
192  gal->SetStrokeColor( COLOR4D( DARKDARKGRAY ).WithAlpha( 0.9 ) );
193  gal->SetFillColor( COLOR4D( DARKDARKGRAY ).WithAlpha( 0.7 ) );
194  gal->SetIsStroke( m_width ? true : false );
195  gal->SetIsFill( true );
196 
197  switch( m_shape->Type() )
198  {
199  case SH_LINE_CHAIN:
200  {
201  const SHAPE_LINE_CHAIN* l = (const SHAPE_LINE_CHAIN*) m_shape;
202 
203  if( m_showTrackClearance && m_clearance > 0 )
204  {
205  gal->SetLineWidth( m_width + 2 * m_clearance );
206  drawLineChain( *l, gal );
207  }
208 
209  gal->SetLayerDepth( m_depth );
210  gal->SetLineWidth( m_width );
211  gal->SetStrokeColor( m_color );
212  gal->SetFillColor( m_color );
213  drawLineChain( *l, gal );
214  break;
215  }
216 
217  case SH_SEGMENT:
218  {
219  const SHAPE_SEGMENT* s = (const SHAPE_SEGMENT*) m_shape;
220 
221  if( m_showTrackClearance && m_clearance > 0 )
222  {
223  gal->SetLineWidth( m_width + 2 * m_clearance );
224  gal->DrawSegment( s->GetSeg().A, s->GetSeg().B, s->GetWidth() + 2 * m_clearance );
225  }
226 
227  gal->SetLayerDepth( m_depth );
228  gal->SetLineWidth( m_width );
229  gal->SetStrokeColor( m_color );
230  gal->SetFillColor( m_color );
231  gal->DrawSegment( s->GetSeg().A, s->GetSeg().B, s->GetWidth() );
232  break;
233  }
234 
235  case SH_CIRCLE:
236  {
237  const SHAPE_CIRCLE* c = (const SHAPE_CIRCLE*) m_shape;
238  gal->SetStrokeColor( m_color );
239 
240  if( m_showViaClearance && m_clearance > 0 )
241  {
242  gal->SetIsStroke( false );
243  gal->DrawCircle( c->GetCenter(), c->GetRadius() + m_clearance );
244  }
245 
246  gal->SetLayerDepth( m_depth );
247  gal->SetIsStroke( m_width ? true : false );
248  gal->SetLineWidth( m_width );
249  gal->SetFillColor( m_color );
250  gal->DrawCircle( c->GetCenter(), c->GetRadius() );
251 
252  break;
253  }
254 
255  case SH_RECT:
256  {
257  const SHAPE_RECT* r = (const SHAPE_RECT*) m_shape;
258  gal->SetFillColor( m_color );
259 
260  if( m_clearance > 0 )
261  {
262  VECTOR2I p0( r->GetPosition() ), s( r->GetSize() );
263  gal->SetIsStroke( true );
264  gal->SetLineWidth( 2 * m_clearance );
265  gal->DrawLine( p0, VECTOR2I( p0.x + s.x, p0.y ) );
266  gal->DrawLine( p0, VECTOR2I( p0.x, p0.y + s.y ) );
267  gal->DrawLine( p0 + s , VECTOR2I( p0.x + s.x, p0.y ) );
268  gal->DrawLine( p0 + s, VECTOR2I( p0.x, p0.y + s.y ) );
269  }
270 
271  gal->SetLayerDepth( m_depth );
272  gal->SetIsStroke( m_width ? true : false );
273  gal->SetLineWidth( m_width );
274  gal->SetStrokeColor( m_color );
275  gal->DrawRectangle( r->GetPosition(), r->GetPosition() + r->GetSize() );
276 
277  break;
278  }
279 
280  case SH_SIMPLE:
281  {
282  const SHAPE_SIMPLE* c = (const SHAPE_SIMPLE*) m_shape;
283  std::deque<VECTOR2D> polygon = std::deque<VECTOR2D>();
284  for( int i = 0; i < c->PointCount(); i++ )
285  {
286  polygon.push_back( c->CDPoint( i ) );
287  }
288 
289  gal->SetFillColor( m_color );
290 
291  if( m_clearance > 0 )
292  {
293  gal->SetIsStroke( true );
294  gal->SetLineWidth( 2 * m_clearance );
295  // need the implicit last segment to be explicit for DrawPolyline
296  polygon.push_back( c->CDPoint( 0 ) );
297  gal->DrawPolyline( polygon );
298  }
299 
300  gal->SetLayerDepth( m_depth );
301  gal->SetIsStroke( m_width ? true : false );
302  gal->SetLineWidth( m_width );
303  gal->SetStrokeColor( m_color );
304  gal->DrawPolygon( polygon );
305  break;
306  }
307 
308  case SH_ARC:
309  {
310  const auto arc = static_cast<const SHAPE_ARC*>( m_shape );
311 
312  auto start_angle = DEG2RAD( arc->GetStartAngle() );
313  auto angle = DEG2RAD( arc->GetCentralAngle() );
314 
315  gal->SetIsFill( false );
316  gal->SetIsStroke( true );
317 
318  if( m_showTrackClearance && m_clearance > 0 )
319  {
320  gal->SetLineWidth( m_width + 2 * m_clearance );
321  gal->DrawArc( arc->GetCenter(), arc->GetRadius(), start_angle, start_angle + angle );
322  }
323 
324  gal->SetLayerDepth( m_depth );
325  gal->SetStrokeColor( m_color );
326  gal->SetFillColor( m_color );
327  gal->SetLineWidth( m_width );
328  gal->DrawArc( arc->GetCenter(), arc->GetRadius(), start_angle, start_angle + angle );
329  break;
330  }
331 
332  case SH_POLY_SET:
333  case SH_COMPOUND:
334  break; // Not yet in use
335  }
336  }
337 }
338 
339 
340 void ROUTER_PREVIEW_ITEM::Line( const SHAPE_LINE_CHAIN& aLine, int aWidth, int aStyle )
341 {
342  m_width = aWidth;
343  m_color = assignColor( aStyle );
344  m_type = PR_SHAPE;
345  m_depth = -1024; // TODO gal->GetMinDepth()
346  m_shape = aLine.Clone();
347 }
348 
349 
350 void ROUTER_PREVIEW_ITEM::Point( const VECTOR2I& aPos, int aStyle )
351 {
352 }
353 
354 
355 void ROUTER_PREVIEW_ITEM::Box( const BOX2I& aBox, int aStyle )
356 {
357 }
358 
359 
361 {
362  auto settings = static_cast<PCB_RENDER_SETTINGS*>( m_view->GetPainter()->GetSettings() );
363 
364  return settings->GetLayerColor( aLayer );
365 }
366 
367 
368 const COLOR4D ROUTER_PREVIEW_ITEM::assignColor( int aStyle ) const
369 {
370  COLOR4D color;
371 
372  switch( aStyle )
373  {
374  case 0:
375  color = COLOR4D( 0, 1, 0, 1 ); break;
376 
377  case 1:
378  color = COLOR4D( 1, 0, 0, 1 ); break;
379 
380  case 2:
381  color = COLOR4D( 1, 1, 0, 1 ); break;
382 
383  case 3:
384  color = COLOR4D( 0, 0, 1, 1 ); break;
385 
386  case 4:
387  color = COLOR4D( 1, 1, 1, 1 ); break;
388 
389  case 5:
390  color = COLOR4D( 1, 1, 0, 1 ); break;
391 
392  case 6:
393  color = COLOR4D( 0, 1, 1, 1 ); break;
394 
395  case 32:
396  color = COLOR4D( 0, 0, 1, 1 ); break;
397 
398  default:
399  color = COLOR4D( 0.4, 0.4, 0.4, 1 ); break;
400  }
401 
402  return color;
403 }
404 
405 const int ROUTER_PREVIEW_ITEM::ClearanceOverlayDepth = -VIEW::VIEW_MAX_LAYERS - 10;
406 const int ROUTER_PREVIEW_ITEM::BaseOverlayDepth = -VIEW::VIEW_MAX_LAYERS - 20;
407 const int ROUTER_PREVIEW_ITEM::ViaOverlayDepth = -VIEW::VIEW_MAX_LAYERS - 50;
set of polygons (with holes, etc.)
Definition: shape.h:51
ITEM.
Definition: pns_item.h:53
static const int ClearanceOverlayDepth
BOX2< VECTOR2I > BOX2I
Definition: box2.h:521
SHAPE_SIMPLE.
Definition: shape_simple.h:42
int GetRadius() const
Definition: shape_circle.h:83
Class CAIRO_GAL is the cairo implementation of the graphics abstraction layer.
Definition: color4d.cpp:131
int SegmentCount() const
Returns the number of segments in the line
Definition: pns_line.h:150
static const int BaseOverlayDepth
virtual void DrawArc(const VECTOR2D &aCenterPoint, double aRadius, double aStartAngle, double aEndAngle)
Draw an arc.
the 3d code uses this value
Definition: typeinfo.h:80
int color
Definition: DXF_plotter.cpp:61
SHAPE_TYPE Type() const
Function Type()
Definition: shape.h:85
GAL * GetGAL() const
Function GetGAL() Returns the GAL this view is using to draw graphical primitives.
Definition: view.h:180
void drawLineChain(const SHAPE_LINE_CHAIN &aL, KIGFX::GAL *aGal) const
const VECTOR2I GetCenter() const
Definition: shape_circle.h:88
size_t ArcCount() const
void Line(const SHAPE_LINE_CHAIN &aLine, int aWidth=0, int aStyle=0)
const std::vector< SHAPE_ARC > & CArcs() const
virtual void DrawLine(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint)
Draw a line.
VECTOR2< int > VECTOR2I
Definition: vector2d.h:594
virtual void SetLayerDepth(double aLayerDepth)
Set the depth of the layer (position on the z-axis)
virtual const BOX2I BBox(int aClearance=0) const =0
Function BBox()
PAINTER * GetPainter() const
Function GetPainter() Returns the painter object used by the view for drawing VIEW_ITEMS.
Definition: view.h:199
A single base class (TRACK) represents both tracks and vias, with subclasses for curved tracks (ARC) ...
const KIGFX::COLOR4D getLayerColor(int aLayer) const
const SEG & GetSeg() const
Definition: shape_segment.h:72
int Start() const
Definition: pns_layerset.h:83
const VECTOR2I GetSize() const
Function GetSize()
Definition: shape_rect.h:113
const VECTOR2D CDPoint(int aIndex) const
Function CDPoint()
Definition: shape_simple.h:112
double a
Alpha component.
Definition: color4d.h:305
#define NULL
virtual void SetIsFill(bool aIsFillEnabled)
Enable/disable fill.
virtual const SHAPE * Shape() const
Function Shape()
Definition: pns_item.h:214
const VECTOR2I & GetPosition() const
Function GetPosition()
Definition: shape_rect.h:103
void Update(const PNS::ITEM *aItem)
const KIGFX::COLOR4D assignColor(int aStyle) const
virtual SHAPE * Clone() const
Function Clone()
Definition: shape.h:96
compound shape, consisting of multiple simple shapes
Definition: shape.h:52
virtual void ViewDraw(int aLayer, KIGFX::VIEW *aView) const override
Function ViewDraw() Draws the parts of the object belonging to layer aLayer.
int SegmentCount() const
Function SegmentCount()
line chain (polyline)
Definition: shape.h:48
void Point(const VECTOR2I &aPos, int aStyle=0)
virtual RENDER_SETTINGS * GetSettings()=0
Function GetAdapter Returns pointer to current settings that are going to be used when drawing items.
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:301
simple polygon
Definition: shape.h:50
const SEG CSegment(int aIndex) const
Function CSegment()
double DEG2RAD(double deg)
Definition: trigo.h:214
SHAPE_LINE_CHAIN.
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
VECTOR2I A
Definition: seg.h:47
bool OfKind(int aKindMask) const
Function OfKind()
Definition: pns_item.h:133
int PointCount() const
Function PointCount()
Definition: shape_simple.h:85
currently selected items overlay
EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boards.
Definition: base_struct.h:163
line segment
Definition: shape.h:47
const BOX2I ViewBBox() const override
Function ViewBBox() returns the bounding box of the item covering all its layers.
PnsKind Kind() const
Function Kind()
Definition: pns_item.h:123
SHAPE * Clone() const override
Function Clone()
Definition: shape.h:45
bool IsClosed() const
Function IsClosed()
VIEW.
Definition: view.h:61
static const int ViaOverlayDepth
int GetWidth() const
Definition: shape_segment.h:82
circle
Definition: shape.h:49
void Box(const BOX2I &aBox, int aStyle=0)
ROUTER_PREVIEW_ITEM(const PNS::ITEM *aItem=NULL, KIGFX::VIEW *aView=NULL)
const LAYER_RANGE & Layers() const
Definition: pns_item.h:151
virtual int Marker() const
Definition: pns_item.h:221
axis-aligned rectangle
Definition: shape.h:46
Class GAL is the abstract interface for drawing on a 2D-surface.
COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:40
VECTOR2I B
Definition: seg.h:48