summaryrefslogtreecommitdiff
path: root/pcbnew/router/router_preview_item.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'pcbnew/router/router_preview_item.cpp')
-rw-r--r--pcbnew/router/router_preview_item.cpp343
1 files changed, 343 insertions, 0 deletions
diff --git a/pcbnew/router/router_preview_item.cpp b/pcbnew/router/router_preview_item.cpp
new file mode 100644
index 0000000..c490ae4
--- /dev/null
+++ b/pcbnew/router/router_preview_item.cpp
@@ -0,0 +1,343 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <deque>
+#include <gal/color4d.h>
+
+#include <geometry/shape_rect.h>
+#include <geometry/shape_convex.h>
+
+#include "class_track.h"
+#include <pcb_painter.h>
+#include <colors.h>
+
+#include "router_preview_item.h"
+
+#include "pns_line.h"
+#include "pns_segment.h"
+#include "pns_via.h"
+
+using namespace KIGFX;
+
+ROUTER_PREVIEW_ITEM::ROUTER_PREVIEW_ITEM( const PNS_ITEM* aItem, VIEW_GROUP* aParent ) :
+ EDA_ITEM( NOT_USED )
+{
+ m_parent = aParent;
+
+ m_shape = NULL;
+ m_clearance = -1;
+ m_originLayer = m_layer = ITEM_GAL_LAYER( GP_OVERLAY );
+
+ // initialize variables, overwritten by Update( aItem ), if aItem != NULL
+ m_router = NULL;
+ m_type = PR_SHAPE;
+ m_style = 0;
+ m_width = 0;
+ m_depth = 0;
+
+ if( aItem )
+ Update( aItem );
+}
+
+
+ROUTER_PREVIEW_ITEM::~ROUTER_PREVIEW_ITEM()
+{
+ delete m_shape;
+}
+
+
+void ROUTER_PREVIEW_ITEM::Update( const PNS_ITEM* aItem )
+{
+ m_originLayer = aItem->Layers().Start();
+
+ if( aItem->OfKind( PNS_ITEM::LINE ) )
+ {
+ const PNS_LINE* l = static_cast<const PNS_LINE*>( aItem );
+
+ if( !l->SegmentCount() )
+ return;
+ }
+
+ assert( m_originLayer >= 0 );
+
+ m_layer = m_originLayer;
+ m_color = getLayerColor( m_originLayer );
+ m_color.a = 0.8;
+ m_depth = BaseOverlayDepth - aItem->Layers().Start();
+ m_shape = aItem->Shape()->Clone();
+
+ switch( aItem->Kind() )
+ {
+ case PNS_ITEM::LINE:
+ m_type = PR_SHAPE;
+ m_width = ( (PNS_LINE*) aItem )->Width();
+ break;
+
+ case PNS_ITEM::SEGMENT:
+ {
+ PNS_SEGMENT* seg = (PNS_SEGMENT*) aItem;
+ m_type = PR_SHAPE;
+ m_width = seg->Width();
+ break;
+ }
+
+ case PNS_ITEM::VIA:
+ m_originLayer = m_layer = ITEM_GAL_LAYER( VIAS_VISIBLE );
+ m_type = PR_SHAPE;
+ m_width = 0;
+ m_color = COLOR4D( 0.7, 0.7, 0.7, 0.8 );
+ m_depth = ViaOverlayDepth;
+ break;
+
+ case PNS_ITEM::SOLID:
+ m_type = PR_SHAPE;
+ m_width = 0;
+ break;
+
+ default:
+ break;
+ }
+
+ if( aItem->Marker() & MK_VIOLATION )
+ m_color = COLOR4D( 0, 1, 0, 1 );
+
+ if( aItem->Marker() & MK_HEAD )
+ m_color.Brighten( 0.7 );
+
+ ViewSetVisible( true );
+ ViewUpdate( GEOMETRY | APPEARANCE );
+}
+
+
+const BOX2I ROUTER_PREVIEW_ITEM::ViewBBox() const
+{
+ BOX2I bbox;
+
+ switch( m_type )
+ {
+ case PR_SHAPE:
+ bbox = m_shape->BBox();
+ bbox.Inflate( m_width / 2 );
+ return bbox;
+
+ case PR_POINT:
+ bbox = BOX2I ( m_pos - VECTOR2I( 100000, 100000 ), VECTOR2I( 200000, 200000 ) );
+ return bbox;
+
+ default:
+ break;
+ }
+
+ return bbox;
+}
+
+
+void ROUTER_PREVIEW_ITEM::drawLineChain( const SHAPE_LINE_CHAIN& aL, KIGFX::GAL* aGal ) const
+{
+ for( int s = 0; s < aL.SegmentCount(); s++ )
+ aGal->DrawLine( aL.CSegment( s ).A, aL.CSegment( s ).B );
+
+ if( aL.IsClosed() )
+ aGal->DrawLine( aL.CSegment( -1 ).B, aL.CSegment( 0 ).A );
+}
+
+
+void ROUTER_PREVIEW_ITEM::ViewDraw( int aLayer, KIGFX::GAL* aGal ) const
+{
+ //col.Brighten(0.7);
+ aGal->SetLayerDepth( m_depth );
+
+ if( m_type == PR_SHAPE )
+ {
+ if( !m_shape )
+ return;
+
+ aGal->SetLineWidth( m_width );
+ aGal->SetStrokeColor( m_color );
+ aGal->SetFillColor( m_color );
+ aGal->SetIsStroke( m_width ? true : false );
+ aGal->SetIsFill( true );
+
+ switch( m_shape->Type() )
+ {
+ case SH_LINE_CHAIN:
+ {
+ const SHAPE_LINE_CHAIN* l = (const SHAPE_LINE_CHAIN*) m_shape;
+ drawLineChain( *l, aGal );
+ break;
+ }
+
+ case SH_SEGMENT:
+ {
+ const SHAPE_SEGMENT* s = (const SHAPE_SEGMENT*) m_shape;
+ aGal->DrawSegment( s->GetSeg().A, s->GetSeg().B, s->GetWidth() );
+
+ if( m_clearance > 0 )
+ {
+ aGal->SetLayerDepth( ClearanceOverlayDepth );
+ aGal->SetStrokeColor( COLOR4D( DARKDARKGRAY ) );
+ aGal->SetFillColor( COLOR4D( DARKDARKGRAY ) );
+ aGal->DrawSegment( s->GetSeg().A, s->GetSeg().B, s->GetWidth() + 2 * m_clearance );
+ }
+
+ break;
+ }
+
+ case SH_CIRCLE:
+ {
+ const SHAPE_CIRCLE* c = (const SHAPE_CIRCLE*) m_shape;
+ aGal->DrawCircle( c->GetCenter(), c->GetRadius() );
+
+ if( m_clearance > 0 )
+ {
+ aGal->SetLayerDepth( ClearanceOverlayDepth );
+ aGal->SetFillColor( COLOR4D( DARKDARKGRAY ) );
+ aGal->SetIsStroke( false );
+ aGal->DrawCircle( c->GetCenter(), c->GetRadius() + m_clearance );
+ }
+
+ break;
+ }
+
+ case SH_RECT:
+ {
+ const SHAPE_RECT* r = (const SHAPE_RECT*) m_shape;
+ aGal->DrawRectangle( r->GetPosition(), r->GetPosition() + r->GetSize() );
+
+ if( m_clearance > 0 )
+ {
+ aGal->SetLayerDepth( ClearanceOverlayDepth );
+ VECTOR2I p0( r->GetPosition() ), s( r->GetSize() );
+ aGal->SetStrokeColor( COLOR4D( DARKDARKGRAY ) );
+ aGal->SetIsStroke( true );
+ aGal->SetLineWidth( 2 * m_clearance );
+ aGal->DrawLine( p0, VECTOR2I( p0.x + s.x, p0.y ) );
+ aGal->DrawLine( p0, VECTOR2I( p0.x, p0.y + s.y ) );
+ aGal->DrawLine( p0 + s , VECTOR2I( p0.x + s.x, p0.y ) );
+ aGal->DrawLine( p0 + s, VECTOR2I( p0.x, p0.y + s.y ) );
+ }
+
+ break;
+ }
+
+ case SH_CONVEX:
+ {
+ const SHAPE_CONVEX* c = (const SHAPE_CONVEX*) m_shape;
+ std::deque<VECTOR2D> polygon = std::deque<VECTOR2D>();
+ for( int i = 0; i < c->PointCount(); i++ )
+ {
+ polygon.push_back( c->CDPoint( i ) );
+ }
+ aGal->DrawPolygon( polygon );
+
+ if( m_clearance > 0 )
+ {
+ aGal->SetLayerDepth( ClearanceOverlayDepth );
+ aGal->SetStrokeColor( COLOR4D( DARKDARKGRAY ) );
+ aGal->SetIsStroke( true );
+ aGal->SetLineWidth( 2 * m_clearance );
+ // need the implicit last segment to be explicit for DrawPolyline
+ polygon.push_back( c->CDPoint( 0 ) );
+ aGal->DrawPolyline( polygon );
+ }
+ break;
+ }
+
+ case SH_POLY_SET:
+ case SH_COMPOUND:
+ break; // Not yet in use
+ }
+ }
+}
+
+
+void ROUTER_PREVIEW_ITEM::Line( const SHAPE_LINE_CHAIN& aLine, int aWidth, int aStyle )
+{
+ m_originLayer = m_layer = 0;
+ m_width = aWidth;
+ m_color = assignColor( aStyle );
+ m_type = PR_SHAPE;
+ m_depth = -1024; // TODO gal->GetMinDepth()
+ m_shape = aLine.Clone();
+
+ ViewSetVisible( true );
+ ViewUpdate( GEOMETRY | APPEARANCE );
+}
+
+
+void ROUTER_PREVIEW_ITEM::Point( const VECTOR2I& aPos, int aStyle )
+{
+}
+
+
+void ROUTER_PREVIEW_ITEM::Box( const BOX2I& aBox, int aStyle )
+{
+}
+
+
+const COLOR4D ROUTER_PREVIEW_ITEM::getLayerColor( int aLayer ) const
+{
+ PCB_RENDER_SETTINGS* settings =
+ static_cast<PCB_RENDER_SETTINGS*>( m_parent->GetView()->GetPainter()->GetSettings() );
+
+ return settings->GetLayerColor( aLayer );
+}
+
+
+const COLOR4D ROUTER_PREVIEW_ITEM::assignColor( int aStyle ) const
+{
+ COLOR4D color;
+
+ switch( aStyle )
+ {
+ case 0:
+ color = COLOR4D( 0, 1, 0, 1 ); break;
+
+ case 1:
+ color = COLOR4D( 1, 0, 0, 1 ); break;
+
+ case 2:
+ color = COLOR4D( 1, 1, 0, 1 ); break;
+
+ case 3:
+ color = COLOR4D( 0, 0, 1, 1 ); break;
+
+ case 4:
+ color = COLOR4D( 1, 1, 1, 1 ); break;
+
+ case 5:
+ color = COLOR4D( 1, 1, 0, 1 ); break;
+
+ case 6:
+ color = COLOR4D( 0, 1, 1, 1 ); break;
+
+ case 32:
+ color = COLOR4D( 0, 0, 1, 1 ); break;
+
+ default:
+ color = COLOR4D( 0.4, 0.4, 0.4, 1 ); break;
+ }
+
+ return color;
+}
+
+const int ROUTER_PREVIEW_ITEM::ClearanceOverlayDepth = -300;
+const int ROUTER_PREVIEW_ITEM::BaseOverlayDepth = -310;
+const int ROUTER_PREVIEW_ITEM::ViaOverlayDepth = -346;