KiCad PCB EDA Suite
Loading...
Searching...
No Matches
create_3Dgraphic_brd_items.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) 2015-2016 Mario Luzeiro <[email protected]>
5 * Copyright (C) 2023 CERN
6 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, you may find one here:
20 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21 * or you may search the http://www.gnu.org website for the version 2 license,
22 * or you may write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 */
25
32#include "../3d_rendering/raytracing/shapes2D/ring_2d.h"
33#include "../3d_rendering/raytracing/shapes2D/filled_circle_2d.h"
34#include "../3d_rendering/raytracing/shapes2D/round_segment_2d.h"
35#include "../3d_rendering/raytracing/shapes2D/triangle_2d.h"
36#include <board_adapter.h>
37#include <board.h>
38#include <footprint.h>
39#include <pad.h>
40#include <pcb_text.h>
41#include <pcb_textbox.h>
42#include <pcb_table.h>
43#include <pcb_painter.h> // for PCB_RENDER_SETTINGS
44#include <zone.h>
46#include <trigo.h>
50#include <geometry/shape_rect.h>
52#include <utility>
53#include <vector>
54#include <wx/log.h>
55#include <macros.h>
56#include <callback_gal.h>
57
58
59#define TO_3DU( x ) ( ( x ) * m_biuTo3Dunits )
60
61#define TO_SFVEC2F( vec ) SFVEC2F( TO_3DU( vec.x ), TO_3DU( -vec.y ) )
62
63
64void addFILLED_CIRCLE_2D( CONTAINER_2D_BASE* aContainer, const SFVEC2F& aCenter, float aRadius,
65 const BOARD_ITEM& aBoardItem )
66{
67 if( aRadius > 0.0f )
68 aContainer->Add( new FILLED_CIRCLE_2D( aCenter, aRadius, aBoardItem ) );
69}
70
71
72void addRING_2D( CONTAINER_2D_BASE* aContainer, const SFVEC2F& aCenter, float aInnerRadius,
73 float aOuterRadius, const BOARD_ITEM& aBoardItem )
74{
75 if( aOuterRadius > aInnerRadius && aInnerRadius > 0.0f )
76 aContainer->Add( new RING_2D( aCenter, aInnerRadius, aOuterRadius, aBoardItem ) );
77}
78
79
80void addROUND_SEGMENT_2D( CONTAINER_2D_BASE* aContainer, const SFVEC2F& aStart, const SFVEC2F& aEnd,
81 float aWidth, const BOARD_ITEM& aBoardItem )
82{
83 if( Is_segment_a_circle( aStart, aEnd ) )
84 {
85 // Cannot add segments that have the same start and end point
86 addFILLED_CIRCLE_2D( aContainer, aStart, aWidth / 2, aBoardItem );
87 return;
88 }
89
90 if( aWidth > 0.0f )
91 aContainer->Add( new ROUND_SEGMENT_2D( aStart, aEnd, aWidth, aBoardItem ) );
92}
93
94
95void BOARD_ADAPTER::addText( const EDA_TEXT* aText, CONTAINER_2D_BASE* aContainer,
96 const BOARD_ITEM* aOwner )
97{
99 TEXT_ATTRIBUTES attrs = aText->GetAttributes();
100 float penWidth_3DU = TO_3DU( aText->GetEffectiveTextPenWidth() );
101 KIFONT::FONT* font = aText->GetFont();
102 wxString shownText = aText->GetShownText( true );
103
104 if( !font )
105 font = KIFONT::FONT::GetFont( wxEmptyString, aText->IsBold(), aText->IsItalic() );
106
107 if( aOwner && aOwner->IsKnockout() )
108 {
109 SHAPE_POLY_SET finalPoly;
110 const PCB_TEXT* pcbText = static_cast<const PCB_TEXT*>( aOwner );
111
112 pcbText->TransformTextToPolySet( finalPoly, 0, aOwner->GetMaxError(), ERROR_INSIDE );
113
114 // Do not call finalPoly.Fracture() here: ConvertPolygonToTriangles() call it
115 // if needed, and Fracture() called twice can create bad results and is useless
116 ConvertPolygonToTriangles( finalPoly, *aContainer, m_biuTo3Dunits, *aOwner );
117 }
118 else
119 {
120 CALLBACK_GAL callback_gal( empty_opts,
121 // Stroke callback
122 [&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2 )
123 {
124 addROUND_SEGMENT_2D( aContainer, TO_SFVEC2F( aPt1 ), TO_SFVEC2F( aPt2 ),
125 penWidth_3DU, *aOwner );
126 },
127 // Triangulation callback
128 [&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2, const VECTOR2I& aPt3 )
129 {
130 aContainer->Add( new TRIANGLE_2D( TO_SFVEC2F( aPt1 ), TO_SFVEC2F( aPt2 ),
131 TO_SFVEC2F( aPt3 ), *aOwner ) );
132 } );
133
134 attrs.m_Angle = aText->GetDrawRotation();
135
136 if( auto* cache = aText->GetRenderCache( font, shownText ) )
137 {
138 callback_gal.DrawGlyphs( *cache );
139 }
140 else
141 {
142 font->Draw( &callback_gal, shownText, aText->GetDrawPos(), attrs,
143 aOwner->GetFontMetrics() );
144 }
145 }
146}
147
148
150 const BOARD_ITEM* aOwner )
151{
152 addText( aDimension, aContainer, aDimension );
153
154 const int linewidth = aDimension->GetLineThickness();
155
156 for( const std::shared_ptr<SHAPE>& shape : aDimension->GetShapes() )
157 {
158 switch( shape->Type() )
159 {
160 case SH_SEGMENT:
161 {
162 const SEG& seg = static_cast<const SHAPE_SEGMENT*>( shape.get() )->GetSeg();
163
164 addROUND_SEGMENT_2D( aContainer, TO_SFVEC2F( seg.A ), TO_SFVEC2F( seg.B ),
165 TO_3DU( linewidth ), *aOwner );
166 break;
167 }
168
169 case SH_CIRCLE:
170 {
171 int radius = static_cast<const SHAPE_CIRCLE*>( shape.get() )->GetRadius();
172 float innerR3DU = TO_3DU( radius ) - TO_3DU( aDimension->GetLineThickness() ) / 2.0f;
173 float outerR3DU = TO_3DU( radius ) + TO_3DU( aDimension->GetLineThickness() ) / 2.0f;
174
175 addRING_2D( aContainer, TO_SFVEC2F( shape->Centre() ), innerR3DU, outerR3DU, *aOwner );
176
177 break;
178 }
179
180 default:
181 break;
182 }
183 }
184}
185
186
188 PCB_LAYER_ID aLayerId,
189 const std::bitset<LAYER_3D_END>& aFlags )
190{
192
193 for( PCB_FIELD* field : aFootprint->GetFields() )
194 {
195 if( !aFlags.test( LAYER_FP_TEXT ) )
196 continue;
197
198 if( field->IsReference() && !aFlags.test( LAYER_FP_REFERENCES ) )
199 continue;
200
201 if( field->IsValue() && !aFlags.test( LAYER_FP_VALUES ) )
202 continue;
203
204 if( field->GetLayer() == aLayerId && field->IsVisible() )
205 addText( field, aContainer, field );
206 }
207
208 for( BOARD_ITEM* item : aFootprint->GraphicalItems() )
209 {
210 switch( item->Type() )
211 {
212 case PCB_TEXT_T:
213 {
214 PCB_TEXT* text = static_cast<PCB_TEXT*>( item );
215
216 if( !aFlags.test( LAYER_FP_TEXT ) )
217 continue;
218
219 if( text->GetText() == wxT( "${REFERENCE}" ) && !aFlags.test( LAYER_FP_REFERENCES ) )
220 continue;
221
222 if( text->GetText() == wxT( "${VALUE}" ) && !aFlags.test( LAYER_FP_VALUES ) )
223 continue;
224
225 if( text->GetLayer() == aLayerId )
226 addText( text, aContainer, text );
227
228 break;
229 }
230
231 case PCB_TEXTBOX_T:
232 {
233 PCB_TEXTBOX* textbox = static_cast<PCB_TEXTBOX*>( item );
234
235 if( textbox->GetLayer() == aLayerId )
236 addShape( textbox, aContainer, aFootprint );
237
238 break;
239 }
240
241 case PCB_TABLE_T:
242 {
243 PCB_TABLE* table = static_cast<PCB_TABLE*>( item );
244
245 if( table->GetLayer() == aLayerId )
246 addTable( table, aContainer, aFootprint );
247
248 break;
249 }
250
252 case PCB_DIM_CENTER_T:
254 case PCB_DIM_RADIAL_T:
255 case PCB_DIM_LEADER_T:
256 {
257 PCB_DIMENSION_BASE* dimension = static_cast<PCB_DIMENSION_BASE*>( item );
258
259 if( dimension->GetLayer() == aLayerId )
260 addShape( dimension, aContainer, aFootprint );
261
262 break;
263 }
264
265 case PCB_SHAPE_T:
266 {
267 PCB_SHAPE* shape = static_cast<PCB_SHAPE*>( item );
268
269 if( shape->IsOnLayer( aLayerId ) )
270 addShape( shape, aContainer, aFootprint, aLayerId );
271
272 break;
273 }
274
275 default:
276 break;
277 }
278 }
279}
280
281
283 PCB_LAYER_ID aLayer, int aMargin )
284{
285 SFVEC2F start3DU = TO_SFVEC2F( aTrack->GetStart() );
286 SFVEC2F end3DU = TO_SFVEC2F( aTrack->GetEnd() );
287
288 switch( aTrack->Type() )
289 {
290 case PCB_VIA_T:
291 {
292 const PCB_VIA* via = static_cast<const PCB_VIA*>( aTrack );
293 float width3DU = TO_3DU( via->GetWidth( aLayer ) + aMargin * 2 );
294
295 addFILLED_CIRCLE_2D( aDstContainer, start3DU, width3DU / 2.0, *aTrack );
296 break;
297 }
298
299 case PCB_ARC_T:
300 {
301 const PCB_ARC* arc = static_cast<const PCB_ARC*>( aTrack );
302
303 if( arc->IsDegenerated() )
304 {
305 // Draw this very small arc like a track segment (a PCB_TRACE_T)
306 PCB_TRACK track( arc->GetParent() );
307 track.SetStart( arc->GetStart() );
308 track.SetEnd( arc->GetEnd() );
309 track.SetWidth( arc->GetWidth() );
310 track.SetLayer( arc->GetLayer() );
311
312 createTrackWithMargin( &track, aDstContainer, aLayer, aMargin );
313 return;
314 }
315
316 VECTOR2I center( arc->GetCenter() );
317 EDA_ANGLE arc_angle = arc->GetAngle();
318 double radius = arc->GetRadius();
319 int arcsegcount = GetArcToSegmentCount( KiROUND( radius ), arc->GetMaxError(), arc_angle );
320 int circlesegcount;
321
322 // Avoid arcs that cannot be drawn
323 if( radius < std::numeric_limits<double>::min() || arc_angle.IsZero() )
324 break;
325
326 // We need a circle to segment count. However, the arc angle can be small, and the
327 // radius very big. so we calculate a reasonable value for circlesegcount.
328 if( arcsegcount <= 1 ) // The arc will be approximated by a segment
329 {
330 circlesegcount = 1;
331 }
332 else
333 {
334 circlesegcount = KiROUND( arcsegcount * 360.0 / std::abs( arc_angle.AsDegrees() ) );
335 circlesegcount = std::clamp( circlesegcount, 1, 128 );
336 }
337
338 createArcSegments( center, arc->GetStart(), arc_angle, circlesegcount,
339 arc->GetWidth() + aMargin * 2, aDstContainer, *arc );
340 break;
341 }
342
343 case PCB_TRACE_T: // Track is a usual straight segment
344 {
345 float width3DU = TO_3DU( aTrack->GetWidth() + aMargin * 2 );
346 addROUND_SEGMENT_2D( aDstContainer, start3DU, end3DU, width3DU, *aTrack );
347 break;
348 }
349
350 default:
351 break;
352 }
353}
354
355
357 PCB_LAYER_ID aLayer, const VECTOR2I& aMargin ) const
358{
359 SHAPE_POLY_SET poly;
360 VECTOR2I clearance = aMargin;
361
362 // Our shape-based builder can't handle negative or differing x:y clearance values (the
363 // former are common for solder paste while the later get generated when a relative paste
364 // margin is used with an oblong pad). So we apply this huge hack and fake a larger pad to
365 // run the general-purpose polygon builder on.
366 // Of course being a hack it falls down when dealing with custom shape pads (where the size
367 // is only the size of the anchor), so for those we punt and just use aMargin.x.
368
369 if( ( clearance.x < 0 || clearance.x != clearance.y ) && aPad->GetShape( aLayer ) != PAD_SHAPE::CUSTOM )
370 {
371 VECTOR2I dummySize = VECTOR2I( aPad->GetSize( aLayer ) ) + clearance + clearance;
372
373 if( dummySize.x <= 0 || dummySize.y <= 0 )
374 return;
375
376 PAD dummy( *aPad );
377 dummy.SetSize( aLayer, VECTOR2I( dummySize.x, dummySize.y ) );
378 dummy.TransformShapeToPolygon( poly, aLayer, 0, aPad->GetMaxError(), ERROR_INSIDE );
379 clearance = { 0, 0 };
380 }
381 else if( aPad->GetShape( aLayer ) == PAD_SHAPE::CUSTOM )
382 {
383 // A custom pad can have many complex subshape items. To avoid issues, use its
384 // final polygon shape, not its basic shape set. One cannot apply the clearance
385 // to each subshape: it does no work
386 aPad->TransformShapeToPolygon( poly, aLayer, 0, aPad->GetMaxError() );
387 }
388 else
389 {
390 auto padShapes = std::static_pointer_cast<SHAPE_COMPOUND>( aPad->GetEffectiveShape( aLayer ) );
391
392 for( const SHAPE* shape : padShapes->Shapes() )
393 {
394 switch( shape->Type() )
395 {
396 case SH_SEGMENT:
397 {
398 const SHAPE_SEGMENT* seg = static_cast<const SHAPE_SEGMENT*>( shape );
399
400 addROUND_SEGMENT_2D( aContainer,
401 TO_SFVEC2F( seg->GetSeg().A ),
402 TO_SFVEC2F( seg->GetSeg().B ),
403 TO_3DU( seg->GetWidth() + clearance.x * 2 ),
404 *aPad );
405 break;
406 }
407
408 case SH_CIRCLE:
409 {
410 const SHAPE_CIRCLE* circle = static_cast<const SHAPE_CIRCLE*>( shape );
411
412 addFILLED_CIRCLE_2D( aContainer,
415 *aPad );
416 break;
417 }
418
419 case SH_RECT:
420 {
421 const SHAPE_RECT* rect = static_cast<const SHAPE_RECT*>( shape );
422
423 poly.NewOutline();
424 poly.Append( rect->GetPosition() );
425 poly.Append( rect->GetPosition().x + rect->GetSize().x, rect->GetPosition().y );
426 poly.Append( rect->GetPosition() + rect->GetSize() );
427 poly.Append( rect->GetPosition().x, rect->GetPosition().y + rect->GetSize().y );
428 break;
429 }
430
431 case SH_SIMPLE:
432 poly.AddOutline( static_cast<const SHAPE_SIMPLE*>( shape )->Vertices() );
433 break;
434
435 case SH_POLY_SET:
436 poly.Append( *static_cast<const SHAPE_POLY_SET*>( shape ) );
437 break;
438
439 case SH_ARC:
440 {
441 const SHAPE_ARC* arc = static_cast<const SHAPE_ARC*>( shape );
443
444 for( int i = 0; i < l.SegmentCount(); i++ )
445 {
446 SHAPE_SEGMENT seg( l.Segment( i ).A, l.Segment( i ).B, arc->GetWidth() );
447
448 addROUND_SEGMENT_2D( aContainer,
449 TO_SFVEC2F( seg.GetSeg().A ),
450 TO_SFVEC2F( seg.GetSeg().B ),
451 TO_3DU( arc->GetWidth() + clearance.x * 2 ),
452 *aPad );
453 }
454
455 break;
456 }
457
458 default:
459 UNIMPLEMENTED_FOR( SHAPE_TYPE_asString( shape->Type() ) );
460 break;
461 }
462 }
463 }
464
465 if( !poly.IsEmpty() )
466 {
467 if( clearance.x )
468 poly.Inflate( clearance.x, CORNER_STRATEGY::ROUND_ALL_CORNERS, aPad->GetMaxError() );
469
470 // Add the PAD polygon
471 ConvertPolygonToTriangles( poly, *aContainer, m_biuTo3Dunits, *aPad );
472 }
473}
474
475
477 int aInflateValue )
478{
479 if( !aPad->HasHole() )
480 {
481 wxLogTrace( m_logTrace, wxT( "BOARD_ADAPTER::createPadWithHole - found an invalid pad" ) );
482 return;
483 }
484
485 std::shared_ptr<SHAPE_SEGMENT> slot = aPad->GetEffectiveHoleShape();
486
487 addROUND_SEGMENT_2D( aDstContainer,
488 TO_SFVEC2F( slot->GetSeg().A ),
489 TO_SFVEC2F( slot->GetSeg().B ),
490 TO_3DU( slot->GetWidth() + aInflateValue * 2 ),
491 *aPad );
492}
493
494
495void BOARD_ADAPTER::addPads( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aContainer,
496 PCB_LAYER_ID aLayerId )
497{
498 for( PAD* pad : aFootprint->Pads() )
499 {
500 if( !pad->IsOnLayer( aLayerId ) )
501 continue;
502
503 if( IsCopperLayer( aLayerId ) )
504 {
505 // Skip pad annulus when there isn't one (note: this is more discerning than
506 // pad->IsOnLayer(), which doesn't check for NPTH pads with holes that consume
507 // the entire pad).
508 if( !pad->IsOnCopperLayer() )
509 continue;
510
511 // Skip pad annulus when not connected on this layer (if removing is enabled)
512 if( !pad->FlashLayer( aLayerId ) )
513 continue;
514 }
515
516 VECTOR2I margin( 0, 0 );
517
518 switch( aLayerId )
519 {
520 case F_Mask:
521 case B_Mask:
522 margin.x += pad->GetSolderMaskExpansion( aLayerId );
523 margin.y += pad->GetSolderMaskExpansion( aLayerId );
524 break;
525
526 case F_Paste:
527 case B_Paste:
528 margin += pad->GetSolderPasteMargin( aLayerId );
529 break;
530
531 default:
532 break;
533 }
534
535 createPadWithMargin( pad, aContainer, aLayerId, margin );
536 }
537}
538
539
540// based on TransformArcToPolygon function from
541// common/convert_basic_shapes_to_polygon.cpp
542void BOARD_ADAPTER::createArcSegments( const VECTOR2I& aCentre, const VECTOR2I& aStart,
543 const EDA_ANGLE& aArcAngle, int aCircleToSegmentsCount,
544 int aWidth, CONTAINER_2D_BASE* aContainer,
545 const BOARD_ITEM& aOwner )
546{
547 // Don't attempt to render degenerate shapes
548 if( aWidth == 0 )
549 return;
550
551 VECTOR2I arc_start, arc_end;
552 EDA_ANGLE arcAngle( aArcAngle );
553 EDA_ANGLE delta = ANGLE_360 / aCircleToSegmentsCount; // rotate angle
554
555 arc_end = arc_start = aStart;
556
557 if( arcAngle != ANGLE_360 )
558 RotatePoint( arc_end, aCentre, -arcAngle );
559
560 if( arcAngle < ANGLE_0 )
561 {
562 std::swap( arc_start, arc_end );
563 arcAngle = -arcAngle;
564 }
565
566 // Compute the ends of segments and creates poly
567 VECTOR2I curr_end = arc_start;
568 VECTOR2I curr_start = arc_start;
569
570 for( EDA_ANGLE ii = delta; ii < arcAngle; ii += delta )
571 {
572 curr_end = arc_start;
573 RotatePoint( curr_end, aCentre, -ii );
574
575 addROUND_SEGMENT_2D( aContainer, TO_SFVEC2F( curr_start ), TO_SFVEC2F( curr_end ),
576 TO_3DU( aWidth ), aOwner );
577
578 curr_start = curr_end;
579 }
580
581 if( curr_end != arc_end )
582 {
583 addROUND_SEGMENT_2D( aContainer, TO_SFVEC2F( curr_end ), TO_SFVEC2F( arc_end ),
584 TO_3DU( aWidth ), aOwner );
585 }
586}
587
588
589void BOARD_ADAPTER::addShape( const PCB_SHAPE* aShape, CONTAINER_2D_BASE* aContainer,
590 const BOARD_ITEM* aOwner, PCB_LAYER_ID aLayer )
591{
592 LINE_STYLE lineStyle = aShape->GetStroke().GetLineStyle();
593 int linewidth = aShape->GetWidth();
594 int margin = 0;
595 bool isSolidFill = aShape->IsSolidFill();
596 bool isHatchedFill = aShape->IsHatchedFill();
597
598 if( IsSolderMaskLayer( aLayer )
599 && aShape->HasSolderMask()
600 && IsExternalCopperLayer( aShape->GetLayer() ) )
601 {
602 margin = aShape->GetSolderMaskExpansion();
603 linewidth += margin * 2;
604 lineStyle = LINE_STYLE::SOLID;
605
606 if( isHatchedFill )
607 {
608 isSolidFill = true;
609 isHatchedFill = false;
610 }
611 }
612
613 float linewidth3DU = TO_3DU( linewidth );
614
615 if( lineStyle <= LINE_STYLE::FIRST_TYPE )
616 {
617 switch( aShape->GetShape() )
618 {
619 case SHAPE_T::CIRCLE:
620 {
621 SFVEC2F center3DU = TO_SFVEC2F( aShape->GetCenter() );
622 float innerR3DU = TO_3DU( aShape->GetRadius() ) - linewidth3DU / 2.0;
623 float outerR3DU = TO_3DU( aShape->GetRadius() ) + linewidth3DU / 2.0;
624
625 if( isSolidFill || innerR3DU <= 0.0 )
626 addFILLED_CIRCLE_2D( aContainer, center3DU, outerR3DU, *aOwner );
627 else
628 addRING_2D( aContainer, center3DU, innerR3DU, outerR3DU, *aOwner );
629
630 break;
631 }
632
633 case SHAPE_T::RECTANGLE:
634 if( isSolidFill )
635 {
636 SHAPE_POLY_SET polyList;
637
638 aShape->TransformShapeToPolySet( polyList, UNDEFINED_LAYER, 0, aShape->GetMaxError(),
639 ERROR_INSIDE );
640
641 polyList.Simplify();
642
643 if( margin != 0 )
644 {
645 polyList.Inflate( margin, CORNER_STRATEGY::ROUND_ALL_CORNERS, aShape->GetMaxError() );
646 }
647
648 ConvertPolygonToTriangles( polyList, *aContainer, m_biuTo3Dunits, *aOwner );
649 }
650 else
651 {
652 std::vector<VECTOR2I> pts = aShape->GetRectCorners();
653
654 addROUND_SEGMENT_2D( aContainer, TO_SFVEC2F( pts[0] ), TO_SFVEC2F( pts[1] ),
655 linewidth3DU, *aOwner );
656 addROUND_SEGMENT_2D( aContainer, TO_SFVEC2F( pts[1] ), TO_SFVEC2F( pts[2] ),
657 linewidth3DU, *aOwner );
658 addROUND_SEGMENT_2D( aContainer, TO_SFVEC2F( pts[2] ), TO_SFVEC2F( pts[3] ),
659 linewidth3DU, *aOwner );
660 addROUND_SEGMENT_2D( aContainer, TO_SFVEC2F( pts[3] ), TO_SFVEC2F( pts[0] ),
661 linewidth3DU, *aOwner );
662 }
663 break;
664
665 case SHAPE_T::ARC:
666 {
667 unsigned int segCount = GetCircleSegmentCount( aShape->GetBoundingBox().GetSizeMax() );
668
669 createArcSegments( aShape->GetCenter(), aShape->GetStart(), aShape->GetArcAngle(),
670 segCount, linewidth, aContainer, *aOwner );
671 break;
672 }
673
674 case SHAPE_T::SEGMENT:
675 addROUND_SEGMENT_2D( aContainer, TO_SFVEC2F( aShape->GetStart() ),
676 TO_SFVEC2F( aShape->GetEnd() ), linewidth3DU, *aOwner );
677 break;
678
679 case SHAPE_T::BEZIER:
680 {
681 SHAPE_POLY_SET polyList;
682
683 aShape->TransformShapeToPolygon( polyList, UNDEFINED_LAYER, 0, aShape->GetMaxError(),
684 ERROR_INSIDE );
685
686 // Some polygons can be a bit complex (especially when coming from a
687 // picture of a text converted to a polygon
688 // So call Simplify before calling ConvertPolygonToTriangles, just in case.
689 polyList.Simplify();
690
691 if( polyList.IsEmpty() ) // Just for caution
692 break;
693
694 if( margin != 0 )
695 {
696 CORNER_STRATEGY cornerStr = margin >= 0 ? CORNER_STRATEGY::ROUND_ALL_CORNERS
697 : CORNER_STRATEGY::ALLOW_ACUTE_CORNERS;
698
699 polyList.Inflate( margin, cornerStr, aShape->GetMaxError() );
700 }
701
702 ConvertPolygonToTriangles( polyList, *aContainer, m_biuTo3Dunits, *aOwner );
703 break;
704 }
705
706 case SHAPE_T::POLY:
707 {
708 if( isSolidFill )
709 {
710 SHAPE_POLY_SET polyList;
711
712 aShape->TransformShapeToPolygon( polyList, UNDEFINED_LAYER, 0, aShape->GetMaxError(),
713 ERROR_INSIDE );
714
715 // Some polygons can be a bit complex (especially when coming from a
716 // picture of a text converted to a polygon
717 // So call Simplify before calling ConvertPolygonToTriangles, just in case.
718 polyList.Simplify();
719
720 if( polyList.IsEmpty() ) // Just for caution
721 break;
722
723 if( margin != 0 )
724 {
725 CORNER_STRATEGY cornerStr = margin >= 0 ? CORNER_STRATEGY::ROUND_ALL_CORNERS
726 : CORNER_STRATEGY::ALLOW_ACUTE_CORNERS;
727
728 polyList.Inflate( margin, cornerStr, aShape->GetMaxError() );
729 }
730
731 ConvertPolygonToTriangles( polyList, *aContainer, m_biuTo3Dunits, *aOwner );
732 }
733 else
734 {
735 std::vector<VECTOR2I> pts = aShape->GetCorners();
736
737 for( int i = 0; i < pts.size() - 1; i++ )
738 {
739 addROUND_SEGMENT_2D( aContainer, TO_SFVEC2F( pts[i] ), TO_SFVEC2F( pts[i + 1] ), linewidth3DU,
740 *aOwner );
741 }
742
743 addROUND_SEGMENT_2D( aContainer, TO_SFVEC2F( pts[pts.size() - 1] ), TO_SFVEC2F( pts[0] ), linewidth3DU,
744 *aOwner );
745 }
746 break;
747 }
748
749 default:
750 wxFAIL_MSG( wxT( "BOARD_ADAPTER::addShape no implementation for " )
751 + aShape->SHAPE_T_asString() );
752 break;
753 }
754 }
755 else
756 {
757 std::vector<SHAPE*> shapes = aShape->MakeEffectiveShapes( true );
758 SFVEC2F a3DU;
759 SFVEC2F b3DU;
760
761 const PCB_PLOT_PARAMS& plotParams = aShape->GetBoard()->GetPlotOptions();
762 KIGFX::PCB_RENDER_SETTINGS renderSettings;
763
764 renderSettings.SetDashLengthRatio( plotParams.GetDashedLineDashRatio() );
765 renderSettings.SetGapLengthRatio( plotParams.GetDashedLineGapRatio() );
766
767 for( SHAPE* shape : shapes )
768 {
769 STROKE_PARAMS::Stroke( shape, lineStyle, aShape->GetWidth(), &renderSettings,
770 [&]( const VECTOR2I& a, const VECTOR2I& b )
771 {
772 addROUND_SEGMENT_2D( aContainer, TO_SFVEC2F( a ), TO_SFVEC2F( b ),
773 linewidth3DU, *aOwner );
774 } );
775 }
776
777 for( SHAPE* shape : shapes )
778 delete shape;
779 }
780
781 if( isHatchedFill )
782 ConvertPolygonToTriangles( aShape->GetHatching(), *aContainer, m_biuTo3Dunits, *aOwner );
783}
784
785
786void BOARD_ADAPTER::addShape( const PCB_TEXTBOX* aTextBox, CONTAINER_2D_BASE* aContainer,
787 const BOARD_ITEM* aOwner )
788{
789 addText( aTextBox, aContainer, aOwner );
790
791 if( !aTextBox->IsBorderEnabled() )
792 return;
793
794 // We cannot use PCB_TEXTBOX::TransformShapeToPolygon because it convert the textbox
795 // as filled polygon even if there's no background colour.
796 // So for polygon, we use PCB_SHAPE::TransformShapeToPolygon
797
798 if( aTextBox->GetShape() == SHAPE_T::RECTANGLE )
799 {
800 addShape( static_cast<const PCB_SHAPE*>( aTextBox ), aContainer, aOwner, UNDEFINED_LAYER );
801 }
802 else
803 {
804 SHAPE_POLY_SET polyList;
805
806 aTextBox->PCB_SHAPE::TransformShapeToPolygon( polyList, UNDEFINED_LAYER, 0, aTextBox->GetMaxError(),
807 ERROR_INSIDE );
808
809 ConvertPolygonToTriangles( polyList, *aContainer, m_biuTo3Dunits, *aOwner );
810 }
811}
812
813
814void BOARD_ADAPTER::addTable( const PCB_TABLE* aTable, CONTAINER_2D_BASE* aContainer,
815 const BOARD_ITEM* aOwner )
816{
817 aTable->DrawBorders(
818 [&]( const VECTOR2I& ptA, const VECTOR2I& ptB, const STROKE_PARAMS& stroke )
819 {
820 addROUND_SEGMENT_2D( aContainer, TO_SFVEC2F( ptA ), TO_SFVEC2F( ptB ),
821 TO_3DU( stroke.GetWidth() ), *aOwner );
822 } );
823
824 for( PCB_TABLECELL* cell : aTable->GetCells() )
825 {
826 if( cell->GetColSpan() > 0 && cell->GetRowSpan() > 0 )
827 addText( cell, aContainer, aOwner );
828 }
829}
830
831
833 PCB_LAYER_ID aLayerId )
834{
835 // This convert the poly in outline and holes
836 ConvertPolygonToTriangles( *aZone->GetFilledPolysList( aLayerId ), *aContainer, m_biuTo3Dunits, *aZone );
837}
838
839
841 CONTAINER_2D_BASE* aContainer, int aWidth )
842{
843 if( aPad->GetShape( aLayer ) == PAD_SHAPE::CIRCLE ) // Draw a ring
844 {
845 const SFVEC2F center3DU = TO_SFVEC2F( aPad->ShapePos( aLayer ) );
846 const int radius = aPad->GetSize( aLayer ).x / 2;
847 const float inner_radius3DU = TO_3DU( radius - aWidth / 2.0 );
848 const float outer_radius3DU = TO_3DU( radius + aWidth / 2.0 );
849
850 addRING_2D( aContainer, center3DU, inner_radius3DU, outer_radius3DU, *aPad );
851 }
852 else
853 {
854 // For other shapes, add outlines as thick segments in polygon buffer
855 const std::shared_ptr<SHAPE_POLY_SET>& corners = aPad->GetEffectivePolygon( aLayer, ERROR_INSIDE );
856 const SHAPE_LINE_CHAIN& path = corners->COutline( 0 );
857
858 for( int j = 0; j < path.PointCount(); j++ )
859 {
860 SFVEC2F start3DU = TO_SFVEC2F( path.CPoint( j ) );
861 SFVEC2F end3DU = TO_SFVEC2F( path.CPoint( j + 1 ) );
862
863 addROUND_SEGMENT_2D( aContainer, start3DU, end3DU, TO_3DU( aWidth ), *aPad );
864 }
865 }
866}
@ ERROR_INSIDE
Definition: approximation.h:34
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition: box2.h:990
void addPads(const FOOTPRINT *aFootprint, CONTAINER_2D_BASE *aDstContainer, PCB_LAYER_ID aLayerId)
void createTrackWithMargin(const PCB_TRACK *aTrack, CONTAINER_2D_BASE *aDstContainer, PCB_LAYER_ID aLayer, int aMargin=0)
void addSolidAreasShapes(const ZONE *aZone, CONTAINER_2D_BASE *aDstContainer, PCB_LAYER_ID aLayerId)
void addFootprintShapes(const FOOTPRINT *aFootprint, CONTAINER_2D_BASE *aDstContainer, PCB_LAYER_ID aLayerId, const std::bitset< LAYER_3D_END > &aVisibilityFlags)
void createArcSegments(const VECTOR2I &aCentre, const VECTOR2I &aStart, const EDA_ANGLE &aArcAngle, int aCircleToSegmentsCount, int aWidth, CONTAINER_2D_BASE *aContainer, const BOARD_ITEM &aOwner)
void createPadWithMargin(const PAD *aPad, CONTAINER_2D_BASE *aDstContainer, PCB_LAYER_ID aLayer, const VECTOR2I &aMargin) const
void createPadWithHole(const PAD *aPad, CONTAINER_2D_BASE *aDstContainer, int aInflateValue)
void buildPadOutlineAsSegments(const PAD *aPad, PCB_LAYER_ID aLayer, CONTAINER_2D_BASE *aDstContainer, int aWidth)
void addTable(const PCB_TABLE *aTable, CONTAINER_2D_BASE *aContainer, const BOARD_ITEM *aOwner)
unsigned int GetCircleSegmentCount(float aDiameter3DU) const
void addShape(const PCB_SHAPE *aShape, CONTAINER_2D_BASE *aContainer, const BOARD_ITEM *aOwner, PCB_LAYER_ID aLayer)
double m_biuTo3Dunits
Scale factor to convert board internal units to 3D units normalized between -1.0 and 1....
void addText(const EDA_TEXT *aText, CONTAINER_2D_BASE *aDstContainer, const BOARD_ITEM *aOwner)
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:79
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:232
virtual bool IsKnockout() const
Definition: board_item.h:319
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:280
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
Definition: board_item.cpp:79
const KIFONT::METRICS & GetFontMetrics() const
Definition: board_item.cpp:132
BOARD_ITEM_CONTAINER * GetParent() const
Definition: board_item.h:210
int GetMaxError() const
Definition: board_item.cpp:138
const PCB_PLOT_PARAMS & GetPlotOptions() const
Definition: board.h:745
constexpr int GetSizeMax() const
Definition: box2.h:235
void Add(OBJECT_2D *aObject)
Definition: container_2d.h:44
double AsDegrees() const
Definition: eda_angle.h:116
bool IsZero() const
Definition: eda_angle.h:136
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:110
EDA_ANGLE GetArcAngle() const
Definition: eda_shape.cpp:1080
const SHAPE_POLY_SET & GetHatching() const
Definition: eda_shape.h:148
virtual std::vector< SHAPE * > MakeEffectiveShapes(bool aEdgeOnly=false) const
Make a set of SHAPE objects representing the EDA_SHAPE.
Definition: eda_shape.h:379
int GetRadius() const
Definition: eda_shape.cpp:1005
SHAPE_T GetShape() const
Definition: eda_shape.h:168
bool IsHatchedFill() const
Definition: eda_shape.h:124
bool IsSolidFill() const
Definition: eda_shape.h:117
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
Definition: eda_shape.h:215
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
Definition: eda_shape.h:173
std::vector< VECTOR2I > GetRectCorners() const
Definition: eda_shape.cpp:1599
wxString SHAPE_T_asString() const
Definition: eda_shape.cpp:343
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition: eda_text.h:79
bool IsItalic() const
Definition: eda_text.h:166
KIFONT::FONT * GetFont() const
Definition: eda_text.h:244
std::vector< std::unique_ptr< KIFONT::GLYPH > > * GetRenderCache(const KIFONT::FONT *aFont, const wxString &forResolvedText, const VECTOR2I &aOffset={ 0, 0 }) const
Definition: eda_text.cpp:676
virtual EDA_ANGLE GetDrawRotation() const
Definition: eda_text.h:374
virtual VECTOR2I GetDrawPos() const
Definition: eda_text.h:375
const TEXT_ATTRIBUTES & GetAttributes() const
Definition: eda_text.h:228
int GetEffectiveTextPenWidth(int aDefaultPenWidth=0) const
The EffectiveTextPenWidth uses the text thickness if > 1 or aDefaultPenWidth.
Definition: eda_text.cpp:465
bool IsBold() const
Definition: eda_text.h:181
virtual wxString GetShownText(bool aAllowExtraText, int aDepth=0) const
Return the string actually shown after processing of the base text.
Definition: eda_text.h:108
std::deque< PAD * > & Pads()
Definition: footprint.h:209
void GetFields(std::vector< PCB_FIELD * > &aVector, bool aVisibleOnly) const
Populate a std::vector with PCB_TEXTs.
Definition: footprint.cpp:638
DRAWINGS & GraphicalItems()
Definition: footprint.h:212
FONT is an abstract base class for both outline and stroke fonts.
Definition: font.h:131
static FONT * GetFont(const wxString &aFontName=wxEmptyString, bool aBold=false, bool aItalic=false, const std::vector< wxString > *aEmbeddedFiles=nullptr, bool aForDrawingSheet=false)
Definition: font.cpp:147
void Draw(KIGFX::GAL *aGal, const wxString &aText, const VECTOR2I &aPosition, const VECTOR2I &aCursor, const TEXT_ATTRIBUTES &aAttributes, const METRICS &aFontMetrics) const
Draw a string.
Definition: font.cpp:250
PCB specific render settings.
Definition: pcb_painter.h:80
void SetGapLengthRatio(double aRatio)
void SetDashLengthRatio(double aRatio)
Definition: pad.h:54
virtual std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer, FLASHING flashPTHPads=FLASHING::DEFAULT) const override
Some pad shapes can be complex (rounded/chamfered rectangle), even without considering custom shapes.
Definition: pad.cpp:537
PAD_SHAPE GetShape(PCB_LAYER_ID aLayer) const
Definition: pad.h:195
void TransformShapeToPolygon(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aMaxError, ERROR_LOC aErrorLoc=ERROR_INSIDE, bool ignoreLineWidth=false) const override
Convert the pad shape to a closed polygon.
Definition: pad.cpp:2018
const std::shared_ptr< SHAPE_POLY_SET > & GetEffectivePolygon(PCB_LAYER_ID aLayer, ERROR_LOC aErrorLoc=ERROR_INSIDE) const
Definition: pad.cpp:525
bool HasHole() const override
Definition: pad.h:106
VECTOR2I ShapePos(PCB_LAYER_ID aLayer) const
Definition: pad.cpp:1068
std::shared_ptr< SHAPE_SEGMENT > GetEffectiveHoleShape() const override
Return a SHAPE_SEGMENT object representing the pad's hole.
Definition: pad.cpp:598
const VECTOR2I & GetSize(PCB_LAYER_ID aLayer) const
Definition: pad.h:264
bool IsDegenerated(int aThreshold=5) const
Definition: pcb_track.cpp:2176
double GetRadius() const
Definition: pcb_track.cpp:2141
EDA_ANGLE GetAngle() const
Definition: pcb_track.cpp:2148
virtual VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
Definition: pcb_track.h:352
Abstract dimension API.
int GetLineThickness() const
const std::vector< std::shared_ptr< SHAPE > > & GetShapes() const
Parameters and options when plotting/printing a board.
double GetDashedLineGapRatio() const
double GetDashedLineDashRatio() const
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition: pcb_shape.h:121
VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
Definition: pcb_shape.h:81
int GetWidth() const override
Definition: pcb_shape.cpp:385
bool HasSolderMask() const
Definition: pcb_shape.h:195
int GetSolderMaskExpansion() const
Definition: pcb_shape.cpp:185
virtual std::vector< VECTOR2I > GetCorners() const
Return 4 corners for a rectangle or rotated rectangle (stored as a poly).
Definition: pcb_shape.cpp:443
void TransformShapeToPolySet(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc) const override
Convert the item shape to a polyset.
Definition: pcb_shape.cpp:838
void TransformShapeToPolygon(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false) const override
Convert the shape to a closed polygon.
Definition: pcb_shape.cpp:829
STROKE_PARAMS GetStroke() const override
Definition: pcb_shape.h:91
bool IsOnLayer(PCB_LAYER_ID aLayer) const override
Test to see if this object is on the given layer.
Definition: pcb_shape.cpp:212
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
Definition: pcb_shape.h:71
std::vector< PCB_TABLECELL * > GetCells() const
Definition: pcb_table.h:154
void DrawBorders(const std::function< void(const VECTOR2I &aPt1, const VECTOR2I &aPt2, const STROKE_PARAMS &aStroke)> &aCallback) const
Definition: pcb_table.cpp:317
bool IsBorderEnabled() const
Disables the border, this is done by changing the stroke internally.
void TransformTextToPolySet(SHAPE_POLY_SET &aBuffer, int aClearance, int aMaxError, ERROR_LOC aErrorLoc) const
Function TransformTextToPolySet Convert the text to a polygonSet describing the actual character stro...
Definition: pcb_text.cpp:565
void SetEnd(const VECTOR2I &aEnd)
Definition: pcb_track.h:148
void SetStart(const VECTOR2I &aStart)
Definition: pcb_track.h:151
const VECTOR2I & GetStart() const
Definition: pcb_track.h:152
const VECTOR2I & GetEnd() const
Definition: pcb_track.h:149
virtual void SetWidth(int aWidth)
Definition: pcb_track.h:145
virtual int GetWidth() const
Definition: pcb_track.h:146
Definition: seg.h:42
VECTOR2I A
Definition: seg.h:49
VECTOR2I B
Definition: seg.h:50
const SHAPE_LINE_CHAIN ConvertToPolyline(int aMaxError=DefaultAccuracyForPCB(), int *aActualError=nullptr) const
Construct a SHAPE_LINE_CHAIN of segments from a given arc.
Definition: shape_arc.cpp:900
int GetWidth() const
Definition: shape_arc.h:210
int GetRadius() const
Definition: shape_circle.h:118
const VECTOR2I GetCenter() const
Definition: shape_circle.h:123
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
SEG Segment(int aIndex) const
Return a copy of the aIndex-th segment in the line chain.
int SegmentCount() const
Return the number of segments in this line chain.
Represent a set of closed polygons.
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new outline to the set and returns its index.
bool IsEmpty() const
Return true if the set is empty (no polygons at all)
void Inflate(int aAmount, CORNER_STRATEGY aCornerStrategy, int aMaxError, bool aSimplify=false)
Perform outline inflation/deflation.
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline)
void Simplify()
Simplify the polyset (merges overlapping polys, eliminates degeneracy/self-intersections)
int NewOutline()
Creates a new empty polygon in the set and returns its index.
const VECTOR2I & GetPosition() const
Definition: shape_rect.h:160
const VECTOR2I GetSize() const
Definition: shape_rect.h:168
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
const SHAPE_LINE_CHAIN & Vertices() const
Return the list of vertices defining this simple polygon.
Definition: shape_simple.h:124
An abstract shape on 2D plane.
Definition: shape.h:126
Simple container to manage line stroke parameters.
Definition: stroke_params.h:94
int GetWidth() const
LINE_STYLE GetLineStyle() const
static void Stroke(const SHAPE *aShape, LINE_STYLE aLineStyle, int aWidth, const KIGFX::RENDER_SETTINGS *aRenderSettings, const std::function< void(const VECTOR2I &a, const VECTOR2I &b)> &aStroker)
Handle a list of polygons defining a copper zone.
Definition: zone.h:74
const std::shared_ptr< SHAPE_POLY_SET > & GetFilledPolysList(PCB_LAYER_ID aLayer) const
Definition: zone.h:600
CORNER_STRATEGY
define how inflate transform build inflated polygon
#define TO_3DU(x)
void addFILLED_CIRCLE_2D(CONTAINER_2D_BASE *aContainer, const SFVEC2F &aCenter, float aRadius, const BOARD_ITEM &aBoardItem)
#define TO_SFVEC2F(vec)
void addROUND_SEGMENT_2D(CONTAINER_2D_BASE *aContainer, const SFVEC2F &aStart, const SFVEC2F &aEnd, float aWidth, const BOARD_ITEM &aBoardItem)
void addRING_2D(CONTAINER_2D_BASE *aContainer, const SFVEC2F &aCenter, float aInnerRadius, float aOuterRadius, const BOARD_ITEM &aBoardItem)
static constexpr EDA_ANGLE ANGLE_0
Definition: eda_angle.h:411
static constexpr EDA_ANGLE ANGLE_360
Definition: eda_angle.h:417
a few functions useful in geometry calculations.
int GetArcToSegmentCount(int aRadius, int aErrorMax, const EDA_ANGLE &aArcAngle)
static const wxChar * m_logTrace
Trace mask used to enable or disable debug output for this class.
bool IsSolderMaskLayer(int aLayer)
Definition: layer_ids.h:735
bool IsCopperLayer(int aLayerId)
Test whether a layer is a copper layer.
Definition: layer_ids.h:665
@ LAYER_FP_REFERENCES
Show footprints references (when texts are visible).
Definition: layer_ids.h:265
@ LAYER_FP_TEXT
Definition: layer_ids.h:239
@ LAYER_FP_VALUES
Show footprints values (when texts are visible).
Definition: layer_ids.h:262
bool IsExternalCopperLayer(int aLayerId)
Test whether a layer is an external (F_Cu or B_Cu) copper layer.
Definition: layer_ids.h:676
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:60
@ F_Paste
Definition: layer_ids.h:104
@ B_Mask
Definition: layer_ids.h:98
@ F_Mask
Definition: layer_ids.h:97
@ B_Paste
Definition: layer_ids.h:105
@ UNDEFINED_LAYER
Definition: layer_ids.h:61
This file contains miscellaneous commonly used macros and functions.
#define UNIMPLEMENTED_FOR(type)
Definition: macros.h:96
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition: eda_angle.h:400
bool Is_segment_a_circle(const SFVEC2F &aStart, const SFVEC2F &aEnd)
Check if segment start and end is very close to each other.
@ 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_SEGMENT
line segment
Definition: shape.h:48
@ SH_ARC
circular arc
Definition: shape.h:54
static wxString SHAPE_TYPE_asString(SHAPE_TYPE a)
Definition: shape.h:59
std::vector< FAB_LAYER_COLOR > dummy
LINE_STYLE
Dashed line types.
Definition: stroke_params.h:46
VECTOR2I center
int radius
SHAPE_CIRCLE circle(c.m_circle_center, c.m_circle_radius)
int clearance
int delta
void ConvertPolygonToTriangles(const SHAPE_POLY_SET &aPolyList, CONTAINER_2D_BASE &aDstContainer, float aBiuTo3dUnitsScale, const BOARD_ITEM &aBoardItem)
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
Definition: trigo.cpp:229
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
Definition: typeinfo.h:88
@ PCB_DIM_ORTHOGONAL_T
class PCB_DIM_ORTHOGONAL, a linear dimension constrained to x/y
Definition: typeinfo.h:105
@ PCB_DIM_LEADER_T
class PCB_DIM_LEADER, a leader dimension (graphic item)
Definition: typeinfo.h:102
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:97
@ PCB_DIM_CENTER_T
class PCB_DIM_CENTER, a center point marking (graphic item)
Definition: typeinfo.h:103
@ PCB_TEXTBOX_T
class PCB_TEXTBOX, wrapped text on a layer
Definition: typeinfo.h:93
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
Definition: typeinfo.h:92
@ PCB_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
Definition: typeinfo.h:101
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
Definition: typeinfo.h:98
@ PCB_TABLE_T
class PCB_TABLE, table of PCB_TABLECELLs
Definition: typeinfo.h:94
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:96
@ PCB_DIM_RADIAL_T
class PCB_DIM_RADIAL, a radius or diameter dimension
Definition: typeinfo.h:104
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:695
glm::vec2 SFVEC2F
Definition: xv3d_types.h:42