From 9992a07def4f959c6a019406df9059325dfdf999 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Sat, 8 Apr 2017 17:41:53 +0200 Subject: [PATCH] Gerbview: Fix an issue in aperture macro for a Circle AM primitive inside a macro definition --- gerbview/class_aperture_macro.cpp | 47 +++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/gerbview/class_aperture_macro.cpp b/gerbview/class_aperture_macro.cpp index 24b3c43860..fd25940a42 100644 --- a/gerbview/class_aperture_macro.cpp +++ b/gerbview/class_aperture_macro.cpp @@ -92,6 +92,7 @@ bool AM_PRIMITIVE::IsAMPrimitiveExposureOn(GERBER_DRAW_ITEM* aParent) const } } +const int seg_per_circle = 64; // Number of segments to approximate a circle void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent, SHAPE_POLY_SET& aShapeBuffer, @@ -101,7 +102,6 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent, for( unsigned jj = 0; jj < polybuffer.size(); jj++ )\ aShapeBuffer.Append( polybuffer[jj].x, polybuffer[jj].y );} - const int seg_per_circle = 64; // Number of segments to approximate a circle // Draw the primitive shape for flashed items. static std::vector polybuffer; // create a static buffer to avoid a lot of memory reallocation polybuffer.clear(); @@ -117,15 +117,10 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent, /* Generated by an aperture macro declaration like: * "1,1,0.3,0.5, 1.0*" * type (1), exposure, diameter, pos.x, pos.y, - * is a optional parameter: rotation form origin + * is a optional parameter: rotation from origin. * type is not stored in parameters list, so the first parameter is exposure */ - wxPoint center = mapPt( params[2].GetValue( tool ), params[3].GetValue( tool ), m_GerbMetric ); - int radius = scaletoIU( params[1].GetValue( tool ), m_GerbMetric ) / 2; - - TransformCircleToPolygon( aShapeBuffer, center, radius, seg_per_circle ); - - SHAPE_LINE_CHAIN& poly = aShapeBuffer.Outline( aShapeBuffer.OutlineCount() - 1 ); + ConvertShapeToPolygon( aParent, polybuffer ); // shape rotation (if any): if( params.size() >= 5 ) @@ -134,13 +129,20 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent, if( rotation != 0) { - for( int ii = 0; ii < poly.PointCount(); ii++ ) - RotatePoint( &poly.Point(ii).x, &poly.Point(ii).y, rotation ); + for( unsigned ii = 0; ii < polybuffer.size(); ii++ ) + RotatePoint( &polybuffer[ii], -rotation ); } } + // Move to current position: - poly.Move( aParent->GetABPosition( curPos ) ); + for( unsigned ii = 0; ii < polybuffer.size(); ii++ ) + { + polybuffer[ii] += curPos; + polybuffer[ii] = aParent->GetABPosition( polybuffer[ii] ); + } + + TO_POLY_SHAPE; } break; @@ -437,7 +439,28 @@ void AM_PRIMITIVE::ConvertShapeToPolygon( GERBER_DRAW_ITEM* aParent, switch( primitive_id ) { - case AMP_CIRCLE: // Circle, currently convertion not needed + case AMP_CIRCLE: + { + /* Generated by an aperture macro declaration like: + * "1,1,0.3,0.5, 1.0*" + * type (1), exposure, diameter, pos.x, pos.y, + * is a optional parameter: rotation from origin. + * type is not stored in parameters list, so the first parameter is exposure + */ + wxPoint center = mapPt( params[2].GetValue( tool ), params[3].GetValue( tool ), m_GerbMetric ); + int radius = scaletoIU( params[1].GetValue( tool ), m_GerbMetric ) / 2; + wxPoint corner; + const int delta = 3600 / seg_per_circle; // rot angle in 0.1 degree + + for( int angle = 0; angle < 3600; angle += delta ) + { + corner.x = radius; + corner.y = 0; + RotatePoint( &corner, angle ); + corner += center; + aBuffer.push_back( corner ); + } + } break; case AMP_LINE2: