/* Plot trapezoidal pad. * aPadPos is pad position, aCorners the corners positions of the basic shape * Orientation aPadOrient in 0.1 degrees * Plot mode = FILLED or SKETCH */ void GERBER_PLOTTER::flash_pad_trapez( wxPoint aPadPos, wxPoint aCorners[4], int aPadOrient, EDA_DRAW_MODE_T aTrace_Mode ) { // polygon corners list static std::vector< wxPoint > cornerList; cornerList.clear(); for( int ii = 0; ii < 4; ii++ ) cornerList.push_back( aCorners[ii] ); /* Draw the polygon and fill the interior as required. */ for( unsigned ii = 0; ii < 4; ii++ ) { RotatePoint( &cornerList[ii], aPadOrient ); cornerList[ii] += aPadPos; } // Close the polygon cornerList.push_back( cornerList[0] ); set_current_line_width( -1 ); PlotPoly( cornerList, aTrace_Mode==FILLED ? FILLED_SHAPE : NO_FILL ); }
void HPGL_PLOTTER::FlashPadRect( const wxPoint& pos, const wxSize& padsize, double orient, EDA_DRAW_MODE_T trace_mode ) { // Build rect polygon: std::vector<wxPoint> corners; int dx = padsize.x / 2; int dy = padsize.y / 2; if( trace_mode == FILLED ) { // in filled mode, the pen diameter is removed from size // to compensate the extra size due to this pen size dx -= KiROUND( penDiameter ) / 2; dx = std::max( dx, 0); dy -= KiROUND( penDiameter ) / 2; dy = std::max( dy, 0); } corners.push_back( wxPoint( - dx, - dy ) ); corners.push_back( wxPoint( - dx, + dy ) ); corners.push_back( wxPoint( + dx, + dy ) ); corners.push_back( wxPoint( + dx, - dy ) ); for( unsigned ii = 0; ii < corners.size(); ii++ ) { RotatePoint( &corners[ii], orient ); corners[ii] += pos; } PlotPoly( corners, trace_mode == FILLED ? FILLED_SHAPE : NO_FILL ); }
void DXF_PLOTTER::ThickSegment( const wxPoint& aStart, const wxPoint& aEnd, int aWidth, EDA_DRAW_MODE_T aPlotMode, void* aData ) { if( aPlotMode == SKETCH ) { std::vector<wxPoint> cornerList; SHAPE_POLY_SET outlineBuffer; TransformOvalClearanceToPolygon( outlineBuffer, aStart, aEnd, aWidth, 32 , 1.0 ); const SHAPE_LINE_CHAIN& path = outlineBuffer.COutline(0 ); for( int jj = 0; jj < path.PointCount(); jj++ ) cornerList.push_back( wxPoint( path.CPoint( jj ).x , path.CPoint( jj ).y ) ); // Ensure the polygon is closed if( cornerList[0] != cornerList[cornerList.size() - 1] ) cornerList.push_back( cornerList[0] ); PlotPoly( cornerList, NO_FILL ); } else { MoveTo( aStart ); FinishTo( aEnd ); } }
void PSLIKE_PLOTTER::FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize, SHAPE_POLY_SET* aPolygons, EDA_DRAW_MODE_T aTraceMode, void* aData ) { wxSize size( aSize ); if( aTraceMode == FILLED ) SetCurrentLineWidth( 0 ); else { SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH ); size.x -= GetCurrentLineWidth(); size.y -= GetCurrentLineWidth(); } std::vector< wxPoint > cornerList; for( int cnt = 0; cnt < aPolygons->OutlineCount(); ++cnt ) { SHAPE_LINE_CHAIN& poly = aPolygons->Outline( cnt ); cornerList.clear(); for( int ii = 0; ii < poly.PointCount(); ++ii ) cornerList.push_back( wxPoint( poly.Point( ii ).x, poly.Point( ii ).y ) ); // Close polygon cornerList.push_back( cornerList[0] ); PlotPoly( cornerList, ( aTraceMode == FILLED ) ? FILLED_SHAPE : NO_FILL, GetCurrentLineWidth() ); } }
void HPGL_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize, int aCornerRadius, double aOrient, EDA_DRAW_MODE_T aTraceMode ) { SHAPE_POLY_SET outline; const int segmentToCircleCount = 32; wxSize size = aSize; if( aTraceMode == FILLED ) { // in filled mode, the pen diameter is removed from size // to keep the pad size size.x -= KiROUND( penDiameter ) / 2; size.x = std::max( size.x, 0); size.y -= KiROUND( penDiameter ) / 2; size.y = std::max( size.y, 0); // keep aCornerRadius to a value < min size x,y < 2: aCornerRadius = std::min( aCornerRadius, std::min( size.x, size.y ) /2 ); } TransformRoundRectToPolygon( outline, aPadPos, size, aOrient, aCornerRadius, segmentToCircleCount ); // TransformRoundRectToPolygon creates only one convex polygon std::vector< wxPoint > cornerList; cornerList.reserve( segmentToCircleCount + 4 ); SHAPE_LINE_CHAIN& poly = outline.Outline( 0 ); for( int ii = 0; ii < poly.PointCount(); ++ii ) cornerList.push_back( wxPoint( poly.Point( ii ).x, poly.Point( ii ).y ) ); PlotPoly( cornerList, aTraceMode == FILLED ? FILLED_SHAPE : NO_FILL ); }
void GERBER_PLOTTER::FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize, SHAPE_POLY_SET* aPolygons, EDA_DRAW_MODE_T aTraceMode, void* aData ) { // A Pad custom is plotted as polygon. // A flashed circle @aPadPos is added (anchor pad) // However, because the anchor pad can be circle or rect, we use only // a circle not bigger than the rect. // the main purpose is to print a flashed DCode as pad anchor if( aTraceMode == FILLED ) FlashPadCircle( aPadPos, std::min( aSize.x, aSize.y ), aTraceMode, aData ); GBR_METADATA gbr_metadata; if( aData ) { gbr_metadata = *static_cast<GBR_METADATA*>( aData ); // If the pad is drawn on a copper layer, // set attribute to GBR_APERTURE_ATTRIB_CONDUCTOR if( gbr_metadata.IsCopper() ) gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_CONDUCTOR ); wxString attrname( ".P" ); gbr_metadata.m_NetlistMetadata.ClearAttribute( &attrname ); // not allowed on inner layers } SHAPE_POLY_SET polyshape = *aPolygons; if( aTraceMode != FILLED ) { SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH, &gbr_metadata ); polyshape.Inflate( -GetCurrentLineWidth()/2, 16 ); } std::vector< wxPoint > cornerList; for( int cnt = 0; cnt < polyshape.OutlineCount(); ++cnt ) { SHAPE_LINE_CHAIN& poly = polyshape.Outline( cnt ); cornerList.clear(); for( int ii = 0; ii < poly.PointCount(); ++ii ) cornerList.push_back( wxPoint( poly.Point( ii ).x, poly.Point( ii ).y ) ); // Close polygon cornerList.push_back( cornerList[0] ); PlotPoly( cornerList, aTraceMode == FILLED ? FILLED_SHAPE : NO_FILL, aTraceMode == FILLED ? 0 : GetCurrentLineWidth(), &gbr_metadata ); } }
void GERBER_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize, int aCornerRadius, double aOrient, EDA_DRAW_MODE_T aTraceMode, void* aData ) { GBR_METADATA gbr_metadata; if( aData ) { gbr_metadata = *static_cast<GBR_METADATA*>( aData ); // If the pad is drawn on a copper layer, // set attribute to GBR_APERTURE_ATTRIB_CONDUCTOR if( gbr_metadata.IsCopper() ) gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_CONDUCTOR ); wxString attrname( ".P" ); gbr_metadata.m_NetlistMetadata.ClearAttribute( &attrname ); // not allowed on inner layers } if( aTraceMode != FILLED ) SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH, &gbr_metadata ); // Currently, a Pad RoundRect is plotted as polygon. // TODO: use Aperture macro and flash it SHAPE_POLY_SET outline; const int segmentToCircleCount = 64; TransformRoundRectToPolygon( outline, aPadPos, aSize, aOrient, aCornerRadius, segmentToCircleCount ); if( aTraceMode != FILLED ) outline.Inflate( -GetCurrentLineWidth()/2, 16 ); std::vector< wxPoint > cornerList; // TransformRoundRectToPolygon creates only one convex polygon SHAPE_LINE_CHAIN& poly = outline.Outline( 0 ); cornerList.reserve( poly.PointCount() + 1 ); for( int ii = 0; ii < poly.PointCount(); ++ii ) cornerList.push_back( wxPoint( poly.Point( ii ).x, poly.Point( ii ).y ) ); // Close polygon cornerList.push_back( cornerList[0] ); PlotPoly( cornerList, aTraceMode == FILLED ? FILLED_SHAPE : NO_FILL, aTraceMode == FILLED ? 0 : GetCurrentLineWidth(), &gbr_metadata ); // Now, flash a pad anchor, if a netlist attribute is set // (remove me when a Aperture macro will be used) if( aData && aTraceMode == FILLED ) { int diameter = std::min( aSize.x, aSize.y ); FlashPadCircle( aPadPos, diameter, aTraceMode , aData ); } }
void PSLIKE_PLOTTER::FlashPadRect( const wxPoint& aPadPos, const wxSize& aSize, double aPadOrient, EDA_DRAW_MODE_T aTraceMode, void* aData ) { static std::vector< wxPoint > cornerList; wxSize size( aSize ); cornerList.clear(); if( aTraceMode == FILLED ) SetCurrentLineWidth( 0 ); else SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH ); size.x -= GetCurrentLineWidth(); size.y -= GetCurrentLineWidth(); if( size.x < 1 ) size.x = 1; if( size.y < 1 ) size.y = 1; int dx = size.x / 2; int dy = size.y / 2; wxPoint corner; corner.x = aPadPos.x - dx; corner.y = aPadPos.y + dy; cornerList.push_back( corner ); corner.x = aPadPos.x - dx; corner.y = aPadPos.y - dy; cornerList.push_back( corner ); corner.x = aPadPos.x + dx; corner.y = aPadPos.y - dy; cornerList.push_back( corner ); corner.x = aPadPos.x + dx; corner.y = aPadPos.y + dy, cornerList.push_back( corner ); for( unsigned ii = 0; ii < cornerList.size(); ii++ ) { RotatePoint( &cornerList[ii], aPadPos, aPadOrient ); } cornerList.push_back( cornerList[0] ); PlotPoly( cornerList, ( aTraceMode == FILLED ) ? FILLED_SHAPE : NO_FILL, GetCurrentLineWidth() ); }
void GERBER_PLOTTER::Rect( const wxPoint& p1, const wxPoint& p2, FILL_T fill, int width ) { std::vector< wxPoint > cornerList; // Build corners list cornerList.push_back( p1 ); wxPoint corner(p1.x, p2.y); cornerList.push_back( corner ); cornerList.push_back( p2 ); corner.x = p2.x; corner.y = p1.y; cornerList.push_back( corner ); cornerList.push_back( p1 ); PlotPoly( cornerList, fill, width ); }
void HPGL_PLOTTER::FlashPadTrapez( const wxPoint& aPadPos, const wxPoint* aCorners, double aPadOrient, EDA_DRAW_MODE_T aTrace_Mode ) { std::vector< wxPoint > cornerList; cornerList.reserve( 4 ); for( int ii = 0; ii < 4; ii++ ) { wxPoint coord( aCorners[ii] ); RotatePoint( &coord, aPadOrient ); coord += aPadPos; cornerList.push_back( coord ); } PlotPoly( cornerList, aTrace_Mode == FILLED ? FILLED_SHAPE : NO_FILL ); }
void GERBER_PLOTTER::rect( wxPoint p1, wxPoint p2, FILL_T fill, int width ) { static std::vector< wxPoint > cornerList; cornerList.clear(); // Build corners list cornerList.push_back( p1 ); wxPoint corner(p1.x, p2.y); cornerList.push_back( corner ); cornerList.push_back( p2 ); corner.x = p2.x; corner.y = p1.y; cornerList.push_back( corner ); cornerList.push_back( p1 ); PlotPoly( cornerList, fill, width ); }
void PSLIKE_PLOTTER::FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorners, double aPadOrient, EDA_DRAW_MODE_T aTraceMode, void* aData ) { static std::vector< wxPoint > cornerList; cornerList.clear(); for( int ii = 0; ii < 4; ii++ ) cornerList.push_back( aCorners[ii] ); if( aTraceMode == FILLED ) { SetCurrentLineWidth( 0 ); } else { SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH ); int w = GetCurrentLineWidth(); // offset polygon by w // coord[0] is assumed the lower left // coord[1] is assumed the upper left // coord[2] is assumed the upper right // coord[3] is assumed the lower right /* Trace the outline. */ cornerList[0].x += w; cornerList[0].y -= w; cornerList[1].x += w; cornerList[1].y += w; cornerList[2].x -= w; cornerList[2].y += w; cornerList[3].x -= w; cornerList[3].y -= w; } for( int ii = 0; ii < 4; ii++ ) { RotatePoint( &cornerList[ii], aPadOrient ); cornerList[ii] += aPadPos; } cornerList.push_back( cornerList[0] ); PlotPoly( cornerList, ( aTraceMode == FILLED ) ? FILLED_SHAPE : NO_FILL, GetCurrentLineWidth() ); }
void HPGL_PLOTTER::FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize, SHAPE_POLY_SET* aPolygons, EDA_DRAW_MODE_T aTraceMode ) { std::vector< wxPoint > cornerList; for( int cnt = 0; cnt < aPolygons->OutlineCount(); ++cnt ) { SHAPE_LINE_CHAIN& poly = aPolygons->Outline( cnt ); cornerList.clear(); cornerList.reserve( poly.PointCount() ); for( int ii = 1; ii < poly.PointCount(); ++ii ) cornerList.push_back( wxPoint( poly.Point( ii ).x, poly.Point( ii ).y ) ); PlotPoly( cornerList, aTraceMode == FILLED ? FILLED_SHAPE : NO_FILL ); } }
void PSLIKE_PLOTTER::FlashPadRect( const wxPoint& pos, const wxSize& aSize, double orient, EDA_DRAW_MODE_T trace_mode ) { static std::vector< wxPoint > cornerList; wxSize size( aSize ); cornerList.clear(); SetCurrentLineWidth( -1 ); int w = currentPenWidth; size.x -= w; if( size.x < 1 ) size.x = 1; size.y -= w; if( size.y < 1 ) size.y = 1; int dx = size.x / 2; int dy = size.y / 2; wxPoint corner; corner.x = pos.x - dx; corner.y = pos.y + dy; cornerList.push_back( corner ); corner.x = pos.x - dx; corner.y = pos.y - dy; cornerList.push_back( corner ); corner.x = pos.x + dx; corner.y = pos.y - dy; cornerList.push_back( corner ); corner.x = pos.x + dx; corner.y = pos.y + dy, cornerList.push_back( corner ); for( unsigned ii = 0; ii < cornerList.size(); ii++ ) { RotatePoint( &cornerList[ii], pos, orient ); } cornerList.push_back( cornerList[0] ); PlotPoly( cornerList, ( trace_mode == FILLED ) ? FILLED_SHAPE : NO_FILL ); }
void PLOTTER::markerLozenge( const wxPoint& position, int radius ) { std::vector< wxPoint > corner_list; wxPoint corner; corner.x = position.x; corner.y = position.y + radius; corner_list.push_back( corner ); corner.x = position.x + radius; corner.y = position.y, corner_list.push_back( corner ); corner.x = position.x; corner.y = position.y - radius; corner_list.push_back( corner ); corner.x = position.x - radius; corner.y = position.y; corner_list.push_back( corner ); corner.x = position.x; corner.y = position.y + radius; corner_list.push_back( corner ); PlotPoly( corner_list, NO_FILL, GetCurrentLineWidth() ); }
void PLOTTER::markerSquare( const wxPoint& position, int radius ) { double r = KiROUND( radius / 1.4142 ); std::vector< wxPoint > corner_list; wxPoint corner; corner.x = position.x + r; corner.y = position.y + r; corner_list.push_back( corner ); corner.x = position.x + r; corner.y = position.y - r; corner_list.push_back( corner ); corner.x = position.x - r; corner.y = position.y - r; corner_list.push_back( corner ); corner.x = position.x - r; corner.y = position.y + r; corner_list.push_back( corner ); corner.x = position.x + r; corner.y = position.y + r; corner_list.push_back( corner ); PlotPoly( corner_list, NO_FILL, GetCurrentLineWidth() ); }
void PSLIKE_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize, int aCornerRadius, double aOrient, EDA_DRAW_MODE_T aTraceMode, void* aData ) { wxSize size( aSize ); if( aTraceMode == FILLED ) SetCurrentLineWidth( 0 ); else { SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH ); size.x -= GetCurrentLineWidth(); size.y -= GetCurrentLineWidth(); aCornerRadius -= GetCurrentLineWidth()/2; } SHAPE_POLY_SET outline; const int segmentToCircleCount = 64; TransformRoundRectToPolygon( outline, aPadPos, size, aOrient, aCornerRadius, segmentToCircleCount ); std::vector< wxPoint > cornerList; cornerList.reserve( segmentToCircleCount + 5 ); // TransformRoundRectToPolygon creates only one convex polygon SHAPE_LINE_CHAIN& poly = outline.Outline( 0 ); for( int ii = 0; ii < poly.PointCount(); ++ii ) cornerList.push_back( wxPoint( poly.Point( ii ).x, poly.Point( ii ).y ) ); // Close polygon cornerList.push_back( cornerList[0] ); PlotPoly( cornerList, ( aTraceMode == FILLED ) ? FILLED_SHAPE : NO_FILL, GetCurrentLineWidth() ); }
void GERBER_PLOTTER::FlashPadTrapez( const wxPoint& aPadPos, const wxPoint* aCorners, double aPadOrient, EDA_DRAW_MODE_T aTrace_Mode ) { // XXX to do: use an aperture macro to declare the pad // polygon corners list std::vector< wxPoint > cornerList; for( int ii = 0; ii < 4; ii++ ) cornerList.push_back( aCorners[ii] ); // Draw the polygon and fill the interior as required for( unsigned ii = 0; ii < 4; ii++ ) { RotatePoint( &cornerList[ii], aPadOrient ); cornerList[ii] += aPadPos; } // Close the polygon cornerList.push_back( cornerList[0] ); SetCurrentLineWidth( -1 ); PlotPoly( cornerList, aTrace_Mode==FILLED ? FILLED_SHAPE : NO_FILL ); }
void GERBER_PLOTTER::FlashPadTrapez( const wxPoint& aPadPos, const wxPoint* aCorners, double aPadOrient, EDA_DRAW_MODE_T aTrace_Mode, void* aData ) { // Currently, a Pad Trapezoid is plotted as polygon. // TODO: use Aperture macro and flash it // polygon corners list std::vector< wxPoint > cornerList; for( int ii = 0; ii < 4; ii++ ) cornerList.push_back( aCorners[ii] ); // Now, flash a pad anchor, if a netlist attribute is set // (remove me when a Aperture macro will be used) if( aData && ( aTrace_Mode == FILLED ) ) { // Calculate the radius of the circle inside the shape // It is the smaller dist from shape pos to edges int radius = INT_MAX; for( unsigned ii = 0, jj = cornerList.size()-1; ii < cornerList.size(); jj = ii, ii++ ) { SEG segment( aCorners[ii], aCorners[jj] ); int dist = segment.LineDistance( VECTOR2I( 0, 0) ); radius = std::min( radius, dist ); } FlashPadCircle( aPadPos, radius*2, aTrace_Mode, aData ); } // Draw the polygon and fill the interior as required for( unsigned ii = 0; ii < 4; ii++ ) { RotatePoint( &cornerList[ii], aPadOrient ); cornerList[ii] += aPadPos; } // Close the polygon cornerList.push_back( cornerList[0] ); GBR_METADATA* gbr_metadata = static_cast<GBR_METADATA*>( aData ); GBR_METADATA metadata; if( gbr_metadata ) { metadata = *gbr_metadata; // If the pad is drawn on a copper layer, // set attribute to GBR_APERTURE_ATTRIB_CONDUCTOR if( metadata.IsCopper() ) metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_CONDUCTOR ); wxString attrname( ".P" ); metadata.m_NetlistMetadata.ClearAttribute( &attrname ); // not allowed on inner layers } SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH, &metadata ); PlotPoly( cornerList, aTrace_Mode == FILLED ? FILLED_SHAPE : NO_FILL, aTrace_Mode == FILLED ? 0 : GetCurrentLineWidth(), &metadata ); }