kicad-developers team mailing list archive
-
kicad-developers team
-
Mailing list archive
-
Message #09563
Re: HPGL
Hello,
this version observes the layer mask and works also with more then one
layer.
Regards, Andreas
=== modified file pcbnew/plot_board_layers.cpp
--- pcbnew/plot_board_layers.cpp 2013-02-06 15:21:37 +0000
+++ pcbnew/plot_board_layers.cpp 2013-02-11 21:22:05 +0000
@@ -408,7 +408,7 @@
// Plot tracks (not vias) :
for( TRACK* track = aBoard->m_Track; track; track = track->Next() )
{
- if( track->Type() == PCB_VIA_T )
+ if( track->Type() != PCB_TRACE_T )
continue;
if( (GetLayerMask( track->GetLayer() ) & aLayerMask) == 0 )
@@ -416,7 +416,295 @@
int width = track->GetWidth() + itemplotter.getFineWidthAdj();
aPlotter->SetColor( itemplotter.getColor( track->GetLayer() ) );
- aPlotter->ThickSegment( track->GetStart(), track->GetEnd(), width, plotMode );
+ wxPoint start, end, astart, aend, padpos, viapos;
+ float diag = 0.354; // half xy-short at 45 degrees
+
+ start = track->GetStart();
+ end = track->GetEnd();
+ if( aPlotOpt.GetFormat() == PLOT_FORMAT_HPGL ) // only for hpgl pen plotter
+ // shorten of the segment end, if it is connected to pad or via
+ {
+ wxSize hpadSize;
+ int hviaSize;
+ // search for connected segments, do nothing
+ // to do: short segments in pads must be deleted and the connected long segment is the working segment
+ // to do: break a segment, if it runs through a pad or via
+ for( TRACK* atrack = aBoard->m_Track; atrack; atrack = atrack->Next() )
+ {
+ if( atrack->Type() == PCB_VIA_T ) // not for via
+ continue;
+ if( (GetLayerMask( atrack->GetLayer() ) & aLayerMask) == 0 )
+ continue;
+ astart = atrack->GetStart();
+ aend = atrack->GetEnd();
+ if( start != astart && end != aend ) // only on foreign segments
+ {
+ if( start == astart || start == aend ) // segment start to other segment
+ {
+ // change start
+ }
+ if( end == astart || end == aend ) // segment end to other segment
+ {
+ // change end
+ }
+ }
+ }
+ // search for connected pads
+ for( MODULE* module = aBoard->m_Modules; module; module = module->Next() )
+ {
+ for ( D_PAD* apad = module->m_Pads; apad; apad = apad->Next() )
+ {
+ if( (apad->GetLayerMask() & aLayerMask) == 0 )
+ continue;
+ padpos = apad->ReturnShapePos();
+ if( plotMode == LINE ) // pad size in line mode is smaller the in filled mode
+ {
+ hpadSize.x = apad->GetSize().x / 2;
+ hpadSize.y = apad->GetSize().y / 2;
+ }
+ else
+ {
+ hpadSize.x = ( apad->GetSize().x - KiROUND( aPlotOpt.GetHPGLPenDiameter() *
+ IU_PER_MILS / aPlotOpt.GetScale() ) ) / 2;
+ hpadSize.y = ( apad->GetSize().y - KiROUND( aPlotOpt.GetHPGLPenDiameter() *
+ IU_PER_MILS / aPlotOpt.GetScale() ) ) / 2;
+ }
+ if( padpos == start ) // start on pad
+ {
+ if( start.x == end.x ) // vertical line
+ {
+ if( start.y > end.y ) // orientation
+ start.y -= hpadSize.y;
+ else
+ start.y += hpadSize.y;
+ }
+ else if( start.y == end.y ) // horizontal line
+ {
+ if( start.x > end.x ) // orientation
+ start.x -= hpadSize.x;
+ else
+ start.x += hpadSize.x;
+ }
+ else // diagonal line
+ {
+ if( apad->GetShape() == PAD_CIRCLE )
+ hpadSize.x = hpadSize.y = (int) ( hpadSize.x + hpadSize.y ) * diag;
+ else if( apad->GetShape() == PAD_OVAL ) // oval pads are oriented
+ {
+ hpadSize.x = hpadSize.y = 0; // no change, to do: calculate value by orientation
+ //if( aPad->GetOrientation() == 0 )
+ //{
+ //
+ //}
+ }
+ if( start.x > end.x )
+ {
+ if( start.y > end.y )
+ {
+ start.x -= hpadSize.x;
+ start.y -= hpadSize.y;
+ }
+ else
+ {
+ start.x -= hpadSize.x;
+ start.y += hpadSize.y;
+ }
+ }
+ else // start.x < end.x
+ {
+ if( start.y > end.y )
+ {
+ start.x += hpadSize.x;
+ start.y -= hpadSize.y;
+ }
+ else
+ {
+ start.x += hpadSize.x;
+ start.y += hpadSize.y;
+ }
+ }
+ }
+ }
+ if( padpos == end ) // end on pad
+ {
+ if( start.x == end.x ) // vertical line
+ {
+ if( start.y < end.y ) // orientation
+ end.y -= hpadSize.y;
+ else
+ end.y += hpadSize.y;
+ }
+ else if( start.y == end.y ) // horizontal line
+ {
+ if( start.x < end.x ) // orientation
+ end.x -= hpadSize.x;
+ else
+ end.x += hpadSize.x;
+ }
+ else // diagonal line
+ {
+ if( apad->GetShape() == PAD_CIRCLE )
+ hpadSize.x = hpadSize.y = (int) (hpadSize.x+hpadSize.y) * diag;
+ else if( apad->GetShape() == PAD_OVAL )
+ {
+ hpadSize.x = hpadSize.y = 0;
+ //if( aPad->GetOrientation() == 0 )
+ //{
+ //
+ //}
+ }
+ if( start.x > end.x )
+ {
+ if( start.y > end.y )
+ {
+ end.x += hpadSize.x;
+ end.y += hpadSize.y;
+ }
+ else
+ {
+ end.x += hpadSize.x;
+ end.y -= hpadSize.y;
+ }
+ }
+ else // start.x < end.x
+ {
+ if( start.y > end.y )
+ {
+ end.x -= hpadSize.x;
+ end.y += hpadSize.y;
+ }
+ else
+ {
+ end.x -= hpadSize.x;
+ end.y -= hpadSize.y;
+ }
+ }
+ }
+ }
+ }
+ }
+ // search for connected vias
+ for( TRACK* atrack = aBoard->m_Track; atrack; atrack = atrack->Next() )
+ {
+ if( atrack->Type() != PCB_VIA_T ) // only for via
+ continue;
+ SEGVIA* Via = (SEGVIA*) atrack;
+ int via_mask_layer = Via->ReturnMaskLayer();
+ if( ( via_mask_layer & aLayerMask ) == 0 )
+ continue;
+ viapos = Via->GetStart();
+ if( plotMode == LINE ) // via size in line mode is smaller the in filled mode
+ {
+ hviaSize = Via->GetWidth() / 2;
+ }
+ else
+ {
+ hviaSize = ( Via->GetWidth() - KiROUND( aPlotOpt.GetHPGLPenDiameter() *
+ IU_PER_MILS / aPlotOpt.GetScale() ) ) / 2;
+ }
+
+ if( viapos == start ) // start on via
+ {
+ if( start.x == end.x ) // vertical line
+ {
+ if( start.y > end.y ) // orientation
+ start.y -= hviaSize;
+ else
+ start.y += hviaSize;
+ }
+ else if( start.y == end.y ) // horizontal line
+ {
+ if( start.x > end.x ) // orientation
+ start.x -= hviaSize;
+ else
+ start.x += hviaSize;
+ }
+ else // diagonal line
+ {
+ hviaSize = (int) (hviaSize+hviaSize) * diag;
+ if( start.x > end.x )
+ {
+ if( start.y > end.y )
+ {
+ start.x -= hviaSize;
+ start.y -= hviaSize;
+ }
+ else
+ {
+ start.x -= hviaSize;
+ start.y += hviaSize;
+ }
+ }
+ else // start.x < end.x
+ {
+ if( start.y > end.y )
+ {
+ start.x += hviaSize;
+ start.y -= hviaSize;
+ }
+ else
+ {
+ start.x += hviaSize;
+ start.y += hviaSize;
+ }
+ }
+ }
+ }
+ if( viapos == end ) // end on via
+ {
+ if( start.x == end.x ) // vertical line
+ {
+ if( start.y < end.y ) // orientation
+ end.y -= hviaSize;
+ else
+ end.y += hviaSize;
+ }
+ else if( start.y == end.y ) // horizontal line
+ {
+ if( start.x < end.x ) // orientation
+ end.x -= hviaSize;
+ else
+ end.x += hviaSize;
+ }
+ else // diagonal line
+ {
+ hviaSize = (int) (hviaSize+hviaSize) * diag;
+ if( start.x > end.x )
+ {
+ if( start.y > end.y )
+ {
+ end.x += hviaSize;
+ end.y += hviaSize;
+ }
+ else
+ {
+ end.x += hviaSize;
+ end.y -= hviaSize;
+ }
+ }
+ else // start.x < end.x
+ {
+ if( start.y > end.y )
+ {
+ end.x -= hviaSize;
+ end.y += hviaSize;
+ }
+ else
+ {
+ end.x -= hviaSize;
+ end.y -= hviaSize;
+ }
+ }
+ }
+ }
+
+ }
+ aPlotter->ThickSegment( start, end, width, plotMode);
+ }
+ else
+ {
+ aPlotter->ThickSegment( start, end, width, plotMode );
+ }
}
// Plot zones (outdated, for old boards compatibility):
Follow ups
-
Re: HPGL
From: Andreas Beutling, 2013-02-16
References
-
HPGL
From: Andreas Beutling, 2013-02-10