KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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-2023 KiCad Developers, see AUTHORS.txt for contributors.
6 * Author: Tomasz Wlostowski <[email protected]>
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
26#include <geometry/shape_rect.h>
28#include <pcb_painter.h>
29#include <trigo.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
38using namespace KIGFX;
39
40
43 m_view( aView ),
44 m_shape( nullptr ),
45 m_hole( nullptr )
46{
47 BOARD_ITEM* boardItem = aItem ? aItem->BoardItem() : nullptr;
48
49 // A PNS::SOLID for an edge-cut item must have 0 width for collision calculations, but when
50 // highlighting an edge we want to show it with its parent PCB_SHAPE's shape.
51 if( boardItem && boardItem->IsOnLayer( Edge_Cuts ) )
52 {
53 m_shape = boardItem->GetEffectiveShape()->Clone();
54 }
55 else if( aItem )
56 {
57 m_shape = aItem->Shape()->Clone();
58
59 if( aItem->Hole() )
60 m_hole = aItem->Hole()->Shape()->Clone();
61 }
62
63 m_clearance = -1;
65
66 m_showClearance = false;
67
68 // initialize variables, overwritten by Update( aItem ), if aItem != NULL
70 m_width = 0;
71 m_depth = 0;
72 m_isHeadTrace = false;
73
74 if( aItem )
75 Update( aItem );
76}
77
78
81{
82 m_view = aView;
83
84 m_shape = aShape.Clone();
85 m_hole = nullptr;
86
87 m_clearance = -1;
89
90 m_showClearance = false;
91
92 // initialize variables, overwritten by Update( aItem ), if aItem != NULL
94 m_width = 0;
95 m_depth = 0;
96 m_isHeadTrace = false;
97}
98
99
101{
102 delete m_shape;
103 delete m_hole;
104}
105
106
108{
109 m_originLayer = aItem->Layers().Start();
110
111 if( const PNS::LINE* l = dyn_cast<const PNS::LINE*>( aItem ) )
112 {
113 if( !l->SegmentCount() )
114 return;
115 }
116 else if( const PNS::VIA* v = dyn_cast<const PNS::VIA*>( aItem ) )
117 {
118 if( v->IsVirtual() )
119 return;
120 }
121
122 assert( m_originLayer >= 0 );
123
126 m_color.a = 0.8;
127 m_depth = BaseOverlayDepth - aItem->Layers().Start();
128
129 switch( aItem->Kind() )
130 {
133 m_width = static_cast<const PNS::LINE*>( aItem )->Width();
134 break;
135
136 case PNS::ITEM::ARC_T:
138 m_width = static_cast<const PNS::ARC*>( aItem )->Width();
139 break;
140
143 m_width = static_cast<const PNS::SEGMENT*>( aItem )->Width();
144 break;
145
146 case PNS::ITEM::VIA_T:
149 m_width = 0;
150 m_color = COLOR4D( 0.7, 0.7, 0.7, 0.8 );
152
153 delete m_shape;
154 m_shape = nullptr;
155
156 if( aItem->Shape() )
157 m_shape = aItem->Shape()->Clone();
158
159 delete m_hole;
160 m_hole = nullptr;
161
162 if( aItem->Hole() )
163 m_hole = aItem->Hole()->Shape()->Clone();
164
165 break;
166
169 m_width = 0;
170 break;
171
172 default:
173 break;
174 }
175
176 if( aItem->Marker() & PNS::MK_VIOLATION )
177 m_color = COLOR4D( 0, 1, 0, 1 );
178}
179
180
182{
183 BOX2I bbox;
184
185 switch( m_type )
186 {
187 case PR_SHAPE:
188 if( m_shape )
189 {
190 bbox = m_shape->BBox();
191 bbox.Inflate( m_width / 2 );
192 }
193
194 if( m_hole )
195 bbox.Merge( m_hole->BBox() );
196
197 return bbox;
198
199 case PR_POINT:
200 bbox = BOX2I ( m_pos - VECTOR2I( 100000, 100000 ), VECTOR2I( 200000, 200000 ) );
201 return bbox;
202
203 default:
204 break;
205 }
206
207 return bbox;
208}
209
210
212{
213 wxCHECK( aL, /* void */ );
214
215 gal->SetIsFill( false );
216
217 for( int s = 0; s < aL->GetSegmentCount(); s++ )
218 {
219 SEG seg = aL->GetSegment( s );
220
221 if( seg.A == seg.B )
222 {
223 gal->SetIsFill( true );
224 gal->SetIsStroke( false );
225 gal->DrawCircle( seg.A, gal->GetLineWidth() / 2 );
226 gal->SetIsFill( false );
227 gal->SetIsStroke( true );
228 }
229 else
230 {
231 gal->DrawLine( seg.A, seg.B );
232 }
233 }
234
235 const SHAPE_LINE_CHAIN* lineChain = dynamic_cast<const SHAPE_LINE_CHAIN*>( aL );
236
237 for( size_t s = 0; lineChain && s < lineChain->ArcCount(); s++ )
238 {
239 const SHAPE_ARC& arc = lineChain->CArcs()[s];
240 EDA_ANGLE start_angle = arc.GetStartAngle();
241 EDA_ANGLE angle = arc.GetCentralAngle();
242
243 gal->DrawArc( arc.GetCenter(), arc.GetRadius(), start_angle, angle);
244 }
245
246 if( aL->IsClosed() )
247 gal->DrawLine( aL->GetSegment( -1 ).B, aL->GetSegment( 0 ).A );
248}
249
250
251void ROUTER_PREVIEW_ITEM::drawShape( const SHAPE* aShape, KIGFX::GAL* gal ) const
252{
253 bool holeDrawn = false;
254
255 switch( aShape->Type() )
256 {
258 {
259 const SHAPE_LINE_CHAIN_BASE* l = (const SHAPE_LINE_CHAIN_BASE*) aShape;
260
261 if( m_showClearance && m_clearance > 0 )
262 {
263 gal->SetLineWidth( m_width + 2 * m_clearance );
264 drawLineChain( l, gal );
265 }
266
267 gal->SetLayerDepth( m_depth );
268 gal->SetLineWidth( m_width );
269 gal->SetStrokeColor( m_color );
270 gal->SetFillColor( m_color );
271 drawLineChain( l, gal );
272 break;
273 }
274
275 case SH_LINE_CHAIN:
276 {
277 const SHAPE_LINE_CHAIN* l = (const SHAPE_LINE_CHAIN*) aShape;
278 const int w = m_width;
279
280 if( m_showClearance && m_clearance > 0 )
281 {
282 gal->SetLineWidth( w + 2 * m_clearance );
283 drawLineChain( l, gal );
284 }
285
286 gal->SetLayerDepth( m_depth );
287 gal->SetLineWidth( w );
288 gal->SetStrokeColor( m_color );
289 gal->SetFillColor( m_color );
290 drawLineChain( l, gal );
291 break;
292 }
293
294 case SH_SEGMENT:
295 {
296 const SHAPE_SEGMENT* s = (const SHAPE_SEGMENT*) aShape;
297 const int w = s->GetWidth();
298
299 gal->SetIsStroke( false );
300
301 if( m_showClearance && m_clearance > 0 )
302 {
303 gal->SetLineWidth( w + 2 * m_clearance );
304 gal->DrawSegment( s->GetSeg().A, s->GetSeg().B, s->GetWidth() + 2 * m_clearance );
305 }
306
307 gal->SetLayerDepth( m_depth );
308 gal->SetLineWidth( w );
309 gal->SetFillColor( m_color );
310 gal->DrawSegment( s->GetSeg().A, s->GetSeg().B, s->GetWidth() );
311 break;
312 }
313
314 case SH_CIRCLE:
315 {
316 const SHAPE_CIRCLE* c = static_cast<const SHAPE_CIRCLE*>( aShape );
317 gal->SetStrokeColor( m_color );
318
319 if( m_showClearance && m_clearance > 0 )
320 {
321 gal->SetIsStroke( false );
322 gal->DrawCircle( c->GetCenter(), c->GetRadius() + m_clearance );
323 }
324
325 gal->SetLayerDepth( m_depth );
326
327 if( m_hole && dynamic_cast<SHAPE_CIRCLE*>( m_hole ) )
328 {
329 const SHAPE_CIRCLE* h = static_cast<const SHAPE_CIRCLE*>( m_hole );
330 int halfWidth = m_width / 2;
331
332 gal->SetIsStroke( true );
333 gal->SetIsFill( false );
334 gal->SetLineWidth( halfWidth + c->GetRadius() - h->GetRadius() );
335 gal->DrawCircle( c->GetCenter(), ( halfWidth + c->GetRadius() + h->GetRadius() ) / 2 );
336
337 holeDrawn = true;
338 }
339 else
340 {
341 gal->SetIsStroke( m_width ? true : false );
342 gal->SetLineWidth( m_width );
343 gal->SetFillColor( m_color );
344 gal->DrawCircle( c->GetCenter(), c->GetRadius() );
345 }
346
347 break;
348 }
349
350 case SH_RECT:
351 {
352 const SHAPE_RECT* r = (const SHAPE_RECT*) aShape;
353 gal->SetFillColor( m_color );
354
355 if( m_showClearance && m_clearance > 0 )
356 {
357 VECTOR2I p0( r->GetPosition() ), s( r->GetSize() );
358 gal->SetIsStroke( true );
359 gal->SetLineWidth( 2 * m_clearance );
360 gal->DrawLine( p0, VECTOR2I( p0.x + s.x, p0.y ) );
361 gal->DrawLine( p0, VECTOR2I( p0.x, p0.y + s.y ) );
362 gal->DrawLine( p0 + s , VECTOR2I( p0.x + s.x, p0.y ) );
363 gal->DrawLine( p0 + s, VECTOR2I( p0.x, p0.y + s.y ) );
364 }
365
366 gal->SetLayerDepth( m_depth );
367 gal->SetIsStroke( m_width ? true : false );
368 gal->SetLineWidth( m_width);
369 gal->SetStrokeColor( m_color );
370 gal->DrawRectangle( r->GetPosition(), r->GetPosition() + r->GetSize() );
371
372 break;
373 }
374
375 case SH_SIMPLE:
376 {
377 const SHAPE_SIMPLE* c = (const SHAPE_SIMPLE*) aShape;
378 std::deque<VECTOR2D> polygon = std::deque<VECTOR2D>();
379
380 for( int i = 0; i < c->PointCount(); i++ )
381 {
382 polygon.push_back( c->CDPoint( i ) );
383 }
384
385 gal->SetFillColor( m_color );
386
387 if( m_showClearance && m_clearance > 0 )
388 {
389 gal->SetIsStroke( true );
390 gal->SetLineWidth( 2 * m_clearance );
391
392 // need the implicit last segment to be explicit for DrawPolyline
393 polygon.push_back( c->CDPoint( 0 ) );
394 gal->DrawPolyline( polygon );
395 }
396
397 gal->SetLayerDepth( m_depth );
398 gal->SetIsStroke( m_width ? true : false );
399 gal->SetLineWidth( m_width );
400 gal->SetStrokeColor( m_color );
401 gal->DrawPolygon( polygon );
402 break;
403 }
404
405 case SH_ARC:
406 {
407 const SHAPE_ARC* arc = static_cast<const SHAPE_ARC*>( aShape );
408 const int w = arc->GetWidth();
409 EDA_ANGLE start_angle = arc->GetStartAngle();
410 EDA_ANGLE angle = arc->GetCentralAngle();
411
412 gal->SetIsFill( false );
413 gal->SetIsStroke( true );
414
415 if( m_showClearance && m_clearance > 0 )
416 {
417 gal->SetLineWidth( w + 2 * m_clearance );
418 gal->DrawArc( arc->GetCenter(), arc->GetRadius(), start_angle, angle );
419 }
420
421 gal->SetLayerDepth( m_depth );
422 gal->SetStrokeColor( m_color );
423 gal->SetFillColor( m_color );
424 gal->SetLineWidth( w );
425 gal->DrawArc( arc->GetCenter(), arc->GetRadius(), start_angle, angle );
426 break;
427 }
428
429 case SH_COMPOUND:
430 wxFAIL_MSG( wxT( "Router preview item: nested compound shapes not supported" ) );
431 break;
432
433 case SH_POLY_SET:
434 wxFAIL_MSG( wxT( "Router preview item: SHAPE_POLY_SET not supported" ) );
435 break;
436
437 case SH_NULL:
438 break;
439 }
440
441 if( m_hole && !holeDrawn )
442 {
443 gal->SetLayerDepth( m_depth );
444 gal->SetIsStroke( true );
445 gal->SetIsFill( false );
446 gal->SetStrokeColor( m_color );
447 gal->SetLineWidth( 1 );
448
449 SHAPE_CIRCLE* circle = dynamic_cast<SHAPE_CIRCLE*>( m_hole );
450 SHAPE_SEGMENT* slot = dynamic_cast<SHAPE_SEGMENT*>( m_hole );
451
452 if( circle )
453 gal->DrawCircle( circle->GetCenter(), circle->GetRadius() );
454 else if( slot )
455 gal->DrawSegment( slot->GetSeg().A, slot->GetSeg().B, slot->GetWidth() );
456 }
457}
458
459
460void ROUTER_PREVIEW_ITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
461{
462 GAL* gal = aView->GetGAL();
463 //col.Brighten(0.7);
464
465 if( m_type == PR_SHAPE )
466 {
467 if( !m_shape )
468 return;
469
470 // N.B. The order of draw here is important
471 // Cairo doesn't current support z-ordering, so we need
472 // to draw the clearance first to ensure it is in the background
474
475 //TODO(snh) Add configuration option for the color/alpha here
476 gal->SetStrokeColor( COLOR4D( DARKDARKGRAY ).WithAlpha( 0.9 ) );
477 gal->SetFillColor( COLOR4D( DARKDARKGRAY ).WithAlpha( 0.7 ) );
478 gal->SetIsStroke( m_width ? true : false );
479 gal->SetIsFill( true );
480
482 {
483 std::vector<const SHAPE*> subshapes;
484 m_shape->GetIndexableSubshapes( subshapes );
485
486 for( const SHAPE* shape : subshapes )
487 drawShape( shape, gal );
488 }
489 else
490 {
491 drawShape( m_shape, gal );
492 }
493 }
494}
495
496
498{
499 auto settings = static_cast<PCB_RENDER_SETTINGS*>( m_view->GetPainter()->GetSettings() );
500
501 COLOR4D color = settings->GetLayerColor( aLayer );
502
503 if( m_isHeadTrace )
504 {
505 return color.Saturate( 1.0 );
506 }
507
508 return color;
509}
510
511
513{
515
516 switch( aStyle )
517 {
518 case 0: color = COLOR4D( 0, 1, 0, 1 ); break;
519 case 1: color = COLOR4D( 1, 0, 0, 1 ); break;
520 case 2: color = COLOR4D( 1, 1, 0, 1 ); break;
521 case 3: color = COLOR4D( 0, 0, 1, 1 ); break;
522 case 4: color = COLOR4D( 1, 1, 1, 1 ); break;
523 case 5: color = COLOR4D( 1, 1, 0, 1 ); break;
524 case 6: color = COLOR4D( 0, 1, 1, 1 ); break;
525 case 32: color = COLOR4D( 0, 0, 1, 1 ); break;
526 default: color = COLOR4D( 0.4, 0.4, 0.4, 1 ); break;
527 }
528
529 return color;
530}
531
int color
Definition: DXF_plotter.cpp:58
BOX2< VECTOR2I > BOX2I
Definition: box2.h:853
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:77
virtual bool IsOnLayer(PCB_LAYER_ID aLayer) const
Test to see if this object is on the given layer.
Definition: board_item.h:269
virtual std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, FLASHING aFlash=FLASHING::DEFAULT) const
Some pad shapes can be complex (rounded/chamfered rectangle), even without considering custom shapes.
Definition: board_item.cpp:227
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:507
BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition: box2.h:589
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:85
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
double a
Alpha component.
Definition: color4d.h:379
Abstract interface for drawing on a 2D-surface.
virtual void DrawPolygon(const std::deque< VECTOR2D > &aPointList)
Draw a polygon.
virtual void SetLayerDepth(double aLayerDepth)
Set the depth of the layer (position on the z-axis)
virtual void SetIsFill(bool aIsFillEnabled)
Enable/disable fill.
virtual void DrawRectangle(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint)
Draw a rectangle.
virtual void SetFillColor(const COLOR4D &aColor)
Set the fill color.
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 DrawPolyline(const std::deque< VECTOR2D > &aPointList)
Draw a polyline.
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.
virtual void DrawSegment(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint, double aWidth)
Draw a rounded segment.
float GetLineWidth() const
Get the line width.
virtual RENDER_SETTINGS * GetSettings()=0
Return a pointer to current settings that are going to be used when drawing items.
PCB specific render settings.
Definition: pcb_painter.h:76
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition: view.h:69
GAL * GetGAL() const
Return the #GAL this view is using to draw graphical primitives.
Definition: view.h:195
static constexpr int VIEW_MAX_LAYERS
Rendering order modifier for layers that are marked as top layers.
Definition: view.h:727
PAINTER * GetPainter() const
Return the painter object used by the view for drawing #VIEW_ITEMS.
Definition: view.h:213
int Start() const
Definition: pns_layerset.h:82
const SHAPE * Shape() const override
Return the geometrical shape of the item.
Definition: pns_hole.h:69
Base class for PNS router board items.
Definition: pns_item.h:97
PnsKind Kind() const
Return the type (kind) of the item.
Definition: pns_item.h:166
virtual const SHAPE * Shape() const
Return the geometrical shape of the item.
Definition: pns_item.h:224
@ SEGMENT_T
Definition: pns_item.h:105
const LAYER_RANGE & Layers() const
Definition: pns_item.h:195
virtual HOLE * Hole() const
Definition: pns_item.h:272
virtual BOARD_ITEM * BoardItem() const
Definition: pns_item.h:190
virtual int Marker() const
Definition: pns_item.h:231
Represents a track on a PCB, connecting two non-trivial joints (that is, vias, pads,...
Definition: pns_line.h:61
const KIGFX::COLOR4D assignColor(int aStyle) const
ROUTER_PREVIEW_ITEM(const SHAPE &aShape, KIGFX::VIEW *aView=nullptr)
void Update(const PNS::ITEM *aItem)
const KIGFX::COLOR4D getLayerColor(int aLayer) const
static const int PathOverlayDepth
virtual void ViewDraw(int aLayer, KIGFX::VIEW *aView) const override
Draw the parts of the object belonging to layer aLayer.
static const int ClearanceOverlayDepth
static const int ViaOverlayDepth
static const int BaseOverlayDepth
void drawLineChain(const SHAPE_LINE_CHAIN_BASE *aL, KIGFX::GAL *aGal) const
const BOX2I ViewBBox() const override
Return the bounding box of the item covering all its layers.
void drawShape(const SHAPE *aShape, KIGFX::GAL *aGal) const
Definition: seg.h:42
VECTOR2I A
Definition: seg.h:49
VECTOR2I B
Definition: seg.h:50
EDA_ANGLE GetCentralAngle() const
Definition: shape_arc.cpp:449
int GetWidth() const
Definition: shape_arc.h:157
double GetRadius() const
Definition: shape_arc.cpp:465
EDA_ANGLE GetStartAngle() const
Definition: shape_arc.cpp:420
VECTOR2I GetCenter() const
Definition: shape_arc.cpp:434
virtual void GetIndexableSubshapes(std::vector< const SHAPE * > &aSubshapes) const
Definition: shape.h:115
virtual bool HasIndexableSubshapes() const
Definition: shape.h:108
SHAPE_TYPE Type() const
Return the type of the shape.
Definition: shape.h:98
int GetRadius() const
Definition: shape_circle.h:108
const VECTOR2I GetCenter() const
Definition: shape_circle.h:113
virtual size_t GetSegmentCount() const =0
virtual bool IsClosed() const =0
virtual const SEG GetSegment(int aIndex) const =0
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
const std::vector< SHAPE_ARC > & CArcs() const
size_t ArcCount() const
const VECTOR2I & GetPosition() const
Definition: shape_rect.h:127
const VECTOR2I GetSize() const
Definition: shape_rect.h:135
const SEG & GetSeg() const
int GetWidth() const
Represent a simple polygon consisting of a zero-thickness closed chain of connected line segments.
Definition: shape_simple.h:42
int PointCount() const
Return the number of points (vertices) in this polygon.
Definition: shape_simple.h:88
const VECTOR2D CDPoint(int aIndex) const
Return a given point as a vector with elements of type double.
Definition: shape_simple.h:113
An abstract shape on 2D plane.
Definition: shape.h:126
virtual SHAPE * Clone() const
Return a dynamically allocated copy of the shape.
Definition: shape.h:148
virtual const BOX2I BBox(int aClearance=0) const =0
Compute a bounding box of the shape, with a margin of aClearance a collision.
@ DARKDARKGRAY
Definition: color4d.h:45
@ LAYER_SELECT_OVERLAY
currently selected items overlay
Definition: layer_ids.h:220
@ LAYER_VIAS
Meta control for all vias opacity/visibility.
Definition: layer_ids.h:194
@ Edge_Cuts
Definition: layer_ids.h:114
The Cairo implementation of the graphics abstraction layer.
Definition: color4d.cpp:247
@ MK_VIOLATION
Definition: pns_item.h:43
@ SH_POLY_SET
set of polygons (with holes, etc.)
Definition: shape.h:52
@ SH_RECT
axis-aligned rectangle
Definition: shape.h:47
@ SH_CIRCLE
circle
Definition: shape.h:50
@ SH_SIMPLE
simple polygon
Definition: shape.h:51
@ SH_NULL
empty shape (no shape...),
Definition: shape.h:55
@ SH_SEGMENT
line segment
Definition: shape.h:48
@ SH_ARC
circular arc
Definition: shape.h:54
@ SH_POLY_SET_TRIANGLE
a single triangle belonging to a POLY_SET triangulation
Definition: shape.h:56
@ SH_LINE_CHAIN
line chain (polyline)
Definition: shape.h:49
@ SH_COMPOUND
compound shape, consisting of multiple simple shapes
Definition: shape.h:53
@ NOT_USED
the 3d code uses this value
Definition: typeinfo.h:79
VECTOR2< int > VECTOR2I
Definition: vector2d.h:588