diff options
Diffstat (limited to 'pcbnew/router/router_preview_item.cpp')
-rw-r--r-- | pcbnew/router/router_preview_item.cpp | 343 |
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; |