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 "class_track.h"
28 #include <pcb_painter.h>
29 
30 #include "router_preview_item.h"
31 
32 #include "../../include/geometry/shape_simple.h"
33 #include "pns_line.h"
34 #include "pns_segment.h"
35 #include "pns_via.h"
36 
37 using namespace KIGFX;
38 
41 {
42  m_view = aView;
43 
44  m_shape = NULL;
45  m_clearance = -1;
47 
48  m_showTrackClearance = false;
49  m_showViaClearance = false;
50 
51  // initialize variables, overwritten by Update( aItem ), if aItem != NULL
52  m_router = NULL;
53  m_type = PR_SHAPE;
54  m_style = 0;
55  m_width = 0;
56  m_depth = 0;
57 
58  if( aItem )
59  Update( aItem );
60 }
61 
62 
64 {
65  delete m_shape;
66 }
67 
68 
70 {
71  m_originLayer = aItem->Layers().Start();
72 
73  if( aItem->OfKind( PNS::ITEM::LINE_T ) )
74  {
75  const PNS::LINE* l = static_cast<const PNS::LINE*>( aItem );
76 
77  if( !l->SegmentCount() )
78  return;
79  }
80 
81  assert( m_originLayer >= 0 );
82 
85  m_color.a = 0.8;
86  m_depth = BaseOverlayDepth - aItem->Layers().Start();
87  m_shape = aItem->Shape()->Clone();
88 
89  switch( aItem->Kind() )
90  {
91  case PNS::ITEM::LINE_T:
92  m_type = PR_SHAPE;
93  m_width = ( (PNS::LINE*) aItem )->Width();
94  break;
95 
97  {
98  PNS::SEGMENT* seg = (PNS::SEGMENT*) aItem;
99  m_type = PR_SHAPE;
100  m_width = seg->Width();
101  break;
102  }
103 
104  case PNS::ITEM::VIA_T:
106  m_type = PR_SHAPE;
107  m_width = 0;
108  m_color = COLOR4D( 0.7, 0.7, 0.7, 0.8 );
110  break;
111 
112  case PNS::ITEM::SOLID_T:
113  m_type = PR_SHAPE;
114  m_width = 0;
115  break;
116 
117  default:
118  break;
119  }
120 
121  if( aItem->Marker() & PNS::MK_VIOLATION )
122  m_color = COLOR4D( 0, 1, 0, 1 );
123 }
124 
125 
127 {
128  BOX2I bbox;
129 
130  switch( m_type )
131  {
132  case PR_SHAPE:
133  if( m_shape )
134  {
135  bbox = m_shape->BBox();
136  bbox.Inflate( m_width / 2 );
137  }
138  return bbox;
139 
140  case PR_POINT:
141  bbox = BOX2I ( m_pos - VECTOR2I( 100000, 100000 ), VECTOR2I( 200000, 200000 ) );
142  return bbox;
143 
144  default:
145  break;
146  }
147 
148  return bbox;
149 }
150 
151 
153 {
154  for( int s = 0; s < aL.SegmentCount(); s++ )
155  gal->DrawLine( aL.CSegment( s ).A, aL.CSegment( s ).B );
156 
157  if( aL.IsClosed() )
158  gal->DrawLine( aL.CSegment( -1 ).B, aL.CSegment( 0 ).A );
159 }
160 
161 
162 void ROUTER_PREVIEW_ITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
163 {
164  auto gal = aView->GetGAL();
165  //col.Brighten(0.7);
166 
167  if( m_type == PR_SHAPE )
168  {
169  if( !m_shape )
170  return;
171 
172  // N.B. The order of draw here is important
173  // Cairo doesn't current support z-ordering, so we need
174  // to draw the clearance first to ensure it is in the background
176  gal->SetStrokeColor( COLOR4D( DARKDARKGRAY ) );
177  gal->SetFillColor( COLOR4D( DARKDARKGRAY ) );
178  gal->SetIsStroke( m_width ? true : false );
179  gal->SetIsFill( true );
180 
181  switch( m_shape->Type() )
182  {
183  case SH_LINE_CHAIN:
184  {
185  const SHAPE_LINE_CHAIN* l = (const SHAPE_LINE_CHAIN*) m_shape;
186 
187  if( m_showTrackClearance && m_clearance > 0 )
188  {
189  gal->SetLineWidth( m_width + 2 * m_clearance );
190  drawLineChain( *l, gal );
191  }
192 
193  gal->SetLayerDepth( m_depth );
194  gal->SetLineWidth( m_width );
195  gal->SetStrokeColor( m_color );
196  gal->SetFillColor( m_color );
197  drawLineChain( *l, gal );
198  break;
199  }
200 
201  case SH_SEGMENT:
202  {
203  const SHAPE_SEGMENT* s = (const SHAPE_SEGMENT*) m_shape;
204 
205  if( m_showTrackClearance && m_clearance > 0 )
206  {
207  gal->SetLineWidth( m_width + 2 * m_clearance );
208  gal->DrawSegment( s->GetSeg().A, s->GetSeg().B, s->GetWidth() + 2 * m_clearance );
209  }
210 
211  gal->SetLayerDepth( m_depth );
212  gal->SetLineWidth( m_width );
213  gal->SetStrokeColor( m_color );
214  gal->SetFillColor( m_color );
215  gal->DrawSegment( s->GetSeg().A, s->GetSeg().B, s->GetWidth() );
216  break;
217  }
218 
219  case SH_CIRCLE:
220  {
221  const SHAPE_CIRCLE* c = (const SHAPE_CIRCLE*) m_shape;
222  gal->SetStrokeColor( m_color );
223 
224  if( m_showViaClearance && m_clearance > 0 )
225  {
226  gal->SetIsStroke( false );
227  gal->DrawCircle( c->GetCenter(), c->GetRadius() + m_clearance );
228  }
229 
230  gal->SetLayerDepth( m_depth );
231  gal->SetIsStroke( m_width ? true : false );
232  gal->SetLineWidth( m_width );
233  gal->SetFillColor( m_color );
234  gal->DrawCircle( c->GetCenter(), c->GetRadius() );
235 
236  break;
237  }
238 
239  case SH_RECT:
240  {
241  const SHAPE_RECT* r = (const SHAPE_RECT*) m_shape;
242  gal->SetFillColor( m_color );
243 
244  if( m_clearance > 0 )
245  {
246  VECTOR2I p0( r->GetPosition() ), s( r->GetSize() );
247  gal->SetIsStroke( true );
248  gal->SetLineWidth( 2 * m_clearance );
249  gal->DrawLine( p0, VECTOR2I( p0.x + s.x, p0.y ) );
250  gal->DrawLine( p0, VECTOR2I( p0.x, p0.y + s.y ) );
251  gal->DrawLine( p0 + s , VECTOR2I( p0.x + s.x, p0.y ) );
252  gal->DrawLine( p0 + s, VECTOR2I( p0.x, p0.y + s.y ) );
253  }
254 
255  gal->SetLayerDepth( m_depth );
256  gal->SetIsStroke( m_width ? true : false );
257  gal->SetLineWidth( m_width );
258  gal->SetStrokeColor( m_color );
259  gal->DrawRectangle( r->GetPosition(), r->GetPosition() + r->GetSize() );
260 
261  break;
262  }
263 
264  case SH_SIMPLE:
265  {
266  const SHAPE_SIMPLE* c = (const SHAPE_SIMPLE*) m_shape;
267  std::deque<VECTOR2D> polygon = std::deque<VECTOR2D>();
268  for( int i = 0; i < c->PointCount(); i++ )
269  {
270  polygon.push_back( c->CDPoint( i ) );
271  }
272 
273  gal->SetFillColor( m_color );
274 
275  if( m_clearance > 0 )
276  {
277  gal->SetIsStroke( true );
278  gal->SetLineWidth( 2 * m_clearance );
279  // need the implicit last segment to be explicit for DrawPolyline
280  polygon.push_back( c->CDPoint( 0 ) );
281  gal->DrawPolyline( polygon );
282  }
283 
284  gal->SetLayerDepth( m_depth );
285  gal->SetIsStroke( m_width ? true : false );
286  gal->SetLineWidth( m_width );
287  gal->SetStrokeColor( m_color );
288  gal->DrawPolygon( polygon );
289  break;
290  }
291 
292  case SH_POLY_SET:
293  case SH_COMPOUND:
294  case SH_ARC:
295  break; // Not yet in use
296  }
297  }
298 }
299 
300 
301 void ROUTER_PREVIEW_ITEM::Line( const SHAPE_LINE_CHAIN& aLine, int aWidth, int aStyle )
302 {
303  m_width = aWidth;
304  m_color = assignColor( aStyle );
305  m_type = PR_SHAPE;
306  m_depth = -1024; // TODO gal->GetMinDepth()
307  m_shape = aLine.Clone();
308 }
309 
310 
311 void ROUTER_PREVIEW_ITEM::Point( const VECTOR2I& aPos, int aStyle )
312 {
313 }
314 
315 
316 void ROUTER_PREVIEW_ITEM::Box( const BOX2I& aBox, int aStyle )
317 {
318 }
319 
320 
322 {
323  auto settings = static_cast<PCB_RENDER_SETTINGS*>( m_view->GetPainter()->GetSettings() );
324 
325  return settings->GetLayerColor( aLayer );
326 }
327 
328 
329 const COLOR4D ROUTER_PREVIEW_ITEM::assignColor( int aStyle ) const
330 {
331  COLOR4D color;
332 
333  switch( aStyle )
334  {
335  case 0:
336  color = COLOR4D( 0, 1, 0, 1 ); break;
337 
338  case 1:
339  color = COLOR4D( 1, 0, 0, 1 ); break;
340 
341  case 2:
342  color = COLOR4D( 1, 1, 0, 1 ); break;
343 
344  case 3:
345  color = COLOR4D( 0, 0, 1, 1 ); break;
346 
347  case 4:
348  color = COLOR4D( 1, 1, 1, 1 ); break;
349 
350  case 5:
351  color = COLOR4D( 1, 1, 0, 1 ); break;
352 
353  case 6:
354  color = COLOR4D( 0, 1, 1, 1 ); break;
355 
356  case 32:
357  color = COLOR4D( 0, 0, 1, 1 ); break;
358 
359  default:
360  color = COLOR4D( 0.4, 0.4, 0.4, 1 ); break;
361  }
362 
363  return color;
364 }
365 
366 const int ROUTER_PREVIEW_ITEM::ClearanceOverlayDepth = -VIEW::VIEW_MAX_LAYERS - 10;
367 const int ROUTER_PREVIEW_ITEM::BaseOverlayDepth = -VIEW::VIEW_MAX_LAYERS - 20;
368 const int ROUTER_PREVIEW_ITEM::ViaOverlayDepth = -VIEW::VIEW_MAX_LAYERS - 50;
set of polygons (with holes, etc.)
Definition: shape.h:49
Class ITEM.
Definition: pns_item.h:53
static const int ClearanceOverlayDepth
BOX2< VECTOR2I > BOX2I
Definition: box2.h:520
Class SHAPE_SIMPLE.
Definition: shape_simple.h:42
const KIGFX::COLOR4D assignColor(int aStyle) const
const VECTOR2I GetCenter() const
Definition: shape_circle.h:84
Class CAIRO_GAL is the cairo implementation of the graphics abstraction layer.
Definition: class_module.h:58
const LAYER_RANGE & Layers() const
Function Layers()
Definition: pns_item.h:209
static const int BaseOverlayDepth
the 3d code uses this value
Definition: typeinfo.h:80
int color
Definition: DXF_plotter.cpp:62
int GetRadius() const
Definition: shape_circle.h:79
const VECTOR2D CDPoint(int aIndex) const
Function CDPoint()
Definition: shape_simple.h:126
virtual const SHAPE * Shape() const
Function Shape()
Definition: pns_item.h:298
const KIGFX::COLOR4D getLayerColor(int aLayer) const
void Line(const SHAPE_LINE_CHAIN &aLine, int aWidth=0, int aStyle=0)
virtual void DrawLine(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint)
Draw a line.
VECTOR2< int > VECTOR2I
Definition: vector2d.h:587
virtual int Marker() const
Definition: pns_item.h:313
const COLOR4D & GetLayerColor(int aLayer) const
Function GetLayerColor Returns the color used to draw a layer.
Definition: painter.h:219
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()
Functions relatives to tracks, vias and segments used to fill zones.
bool OfKind(int aKindMask) const
Function OfKind()
Definition: pns_item.h:132
virtual SHAPE * Clone() const
Function Clone()
Definition: shape.h:94
Class PCB_RENDER_SETTINGS Stores PCB specific render settings.
Definition: pcb_painter.h:62
const SEG CSegment(int aIndex) const
Function CSegment()
double a
Alpha component.
Definition: color4d.h:290
GAL * GetGAL() const
Function GetGAL() Returns the GAL this view is using to draw graphical primitives.
Definition: view.h:180
int SegmentCount() const
Returns the number of segments in the line
Definition: pns_line.h:129
void Update(const PNS::ITEM *aItem)
const VECTOR2I & GetPosition() const
Function GetPosition()
Definition: shape_rect.h:100
int GetWidth() const
Definition: shape_segment.h:80
compound shape, consisting of multiple simple shapes
Definition: shape.h:50
void drawLineChain(const SHAPE_LINE_CHAIN &aL, KIGFX::GAL *aGal) const
int Width() const
Definition: pns_segment.h:88
PAINTER * GetPainter() const
Function GetPainter() Returns the painter object used by the view for drawing VIEW_ITEMS.
Definition: view.h:199
int Start() const
Definition: pns_layerset.h:83
virtual void ViewDraw(int aLayer, KIGFX::VIEW *aView) const override
Function ViewDraw() Draws the parts of the object belonging to layer aLayer.
line chain (polyline)
Definition: shape.h:46
void Point(const VECTOR2I &aPos, int aStyle=0)
PnsKind Kind() const
Function Kind()
Definition: pns_item.h:122
virtual RENDER_SETTINGS * GetSettings()=0
Function GetSettings 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:300
simple polygon
Definition: shape.h:48
const SEG & GetSeg() const
Definition: shape_segment.h:70
SHAPE_TYPE Type() const
Function Type()
Definition: shape.h:83
Class SHAPE_LINE_CHAIN.
size_t i
Definition: json11.cpp:597
VECTOR2I A
Definition: seg.h:46
currently selected items overlay
int PointCount() const
Function PointCount()
Definition: shape_simple.h:85
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:154
line segment
Definition: shape.h:45
const BOX2I ViewBBox() const override
Function ViewBBox() returns the bounding box of the item covering all its layers. ...
bool IsClosed() const
Function IsClosed()
SHAPE * Clone() const override
Function Clone()
Definition: shape.h:43
Class VIEW.
Definition: view.h:61
static const int ViaOverlayDepth
const VECTOR2I GetSize() const
Function GetSize()
Definition: shape_rect.h:110
circle
Definition: shape.h:47
void Box(const BOX2I &aBox, int aStyle=0)
int SegmentCount() const
Function SegmentCount()
ROUTER_PREVIEW_ITEM(const PNS::ITEM *aItem=NULL, KIGFX::VIEW *aView=NULL)
axis-aligned rectangle
Definition: shape.h:44
Class GAL is the abstract interface for drawing on a 2D-surface.
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39
VECTOR2I B
Definition: seg.h:47