finished Draw functions for aperture macros. Now aperture macros are drawn correctly. Known bug: aperture macros having parameters are incorrect: parameters are not read correctly. Work still in progress.
This commit is contained in:
commit
3144853b1f
|
@ -4,6 +4,14 @@ KiCad ChangeLog 2010
|
|||
Please add newer entries at the top, list the date and your name with
|
||||
email address.
|
||||
|
||||
2010-oct-03, UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
|
||||
================================================================================
|
||||
++gerbview:
|
||||
finished Draw functions for aperture macros.
|
||||
Now aperture macros are draww correctly.
|
||||
Known bug: aperture macros having parameters are incorrect: parameters are not transmited correctly.
|
||||
Work still in progress.
|
||||
|
||||
2010-sept-28, UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
|
||||
================================================================================
|
||||
++gerbview:
|
||||
|
|
|
@ -1163,6 +1163,9 @@ static bool IsGRSPolyDrawable( EDA_Rect* ClipBox, int n, wxPoint Points[] )
|
|||
if( ! ClipBox )
|
||||
return true;
|
||||
|
||||
if( n <= 0 )
|
||||
return false;
|
||||
|
||||
int Xmin, Xmax, Ymin, Ymax;
|
||||
|
||||
Xmin = Xmax = Points[0].x;
|
||||
|
|
|
@ -15,6 +15,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}
|
|||
###
|
||||
set(GERBVIEW_SRCS
|
||||
block.cpp
|
||||
class_aperture_macro.cpp
|
||||
class_GERBER.cpp
|
||||
class_gerber_draw_item.cpp
|
||||
class_gerbview_layer_widget.cpp
|
||||
|
|
|
@ -0,0 +1,625 @@
|
|||
/****************************/
|
||||
/* class_aperture_macro.cpp */
|
||||
/****************************/
|
||||
|
||||
|
||||
/*
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 1992-2010 Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
|
||||
* Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
||||
* Copyright (C) 1992-2010 Kicad Developers, see change_log.txt for contributors.
|
||||
*
|
||||
* 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 2
|
||||
* 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, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "fctsys.h"
|
||||
#include "common.h"
|
||||
#include "macros.h"
|
||||
#include "trigo.h"
|
||||
#include "gerbview.h"
|
||||
|
||||
/** helper Function mapPt
|
||||
* translates a point from the aperture macro coordinate system to our
|
||||
* deci-mils coordinate system.
|
||||
* @return wxPoint - The gerbview coordinate system vector.
|
||||
*/
|
||||
extern wxPoint mapPt( double x, double y, bool isMetric ); // defined it rs274d.cpp
|
||||
|
||||
/**
|
||||
* Function scale
|
||||
* converts a distance given in floating point to our deci-mils
|
||||
*/
|
||||
extern int scale( double aCoord, bool isMetric ); // defined it rs274d.cpp
|
||||
|
||||
|
||||
/**
|
||||
* Function mapExposure
|
||||
* translates the first parameter from an aperture macro into a current
|
||||
* exposure setting.
|
||||
* @param aParent = a GERBER_DRAW_ITEM that handle:
|
||||
* ** m_Exposure A dynamic setting which can change throughout the
|
||||
* reading of the gerber file, and it indicates whether the current tool
|
||||
* is lit or not.
|
||||
* ** m_ImageNegative A dynamic setting which can change throughout the reading
|
||||
* of the gerber file, and it indicates whether the current D codes are to
|
||||
* be interpreted as erasures or not.
|
||||
* @return true to draw with current color, false to draw with alt color (erase)
|
||||
*/
|
||||
bool AM_PRIMITIVE::mapExposure( GERBER_DRAW_ITEM* aParent )
|
||||
{
|
||||
bool exposure;
|
||||
switch( primitive_id )
|
||||
{
|
||||
case AMP_CIRCLE:
|
||||
case AMP_LINE2:
|
||||
case AMP_LINE20:
|
||||
case AMP_LINE_CENTER:
|
||||
case AMP_LINE_LOWER_LEFT:
|
||||
case AMP_OUTLINE:
|
||||
case AMP_THERMAL:
|
||||
case AMP_POLYGON:
|
||||
// All have an exposure parameter and can return true or false
|
||||
switch( GetExposure() )
|
||||
{
|
||||
case 0: // exposure always OFF
|
||||
exposure = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
case 1: // exposure always OON
|
||||
exposure = true;
|
||||
break;
|
||||
|
||||
case 2: // reverse exposure
|
||||
exposure = !aParent->m_LayerNegative;
|
||||
}
|
||||
break;
|
||||
|
||||
case AMP_MOIRE:
|
||||
case AMP_EOF:
|
||||
case AMP_UNKNOWN:
|
||||
default:
|
||||
return true; // All have no exposure parameter and must return true (no change for exposure)
|
||||
break;
|
||||
}
|
||||
|
||||
return exposure ^ aParent->m_ImageNegative;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function GetExposure
|
||||
* returns the first parameter in integer form. Some but not all primitives
|
||||
* use the first parameter as an exposure control.
|
||||
*/
|
||||
int AM_PRIMITIVE::GetExposure() const
|
||||
{
|
||||
// No D_CODE* for GetValue()
|
||||
wxASSERT( params.size() && params[0].IsImmediate() );
|
||||
return (int) params[0].GetValue( NULL );
|
||||
}
|
||||
|
||||
/** function DrawBasicShape
|
||||
* Draw the primitive shape for flashed items.
|
||||
*/
|
||||
void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent,
|
||||
EDA_Rect* aClipBox,
|
||||
wxDC* aDC,
|
||||
int aColor, int aAltColor,
|
||||
wxPoint aShapePos,
|
||||
bool aFilledShape )
|
||||
{
|
||||
static std::vector<wxPoint> polybuffer; // create a static buffer to avoid a lot of memory reallocation
|
||||
polybuffer.clear();
|
||||
|
||||
wxPoint curPos = aShapePos;
|
||||
D_CODE* tool = aParent->GetDcodeDescr();
|
||||
bool gerberMetric = aParent->m_UnitsMetric;
|
||||
int rotation;
|
||||
if( mapExposure( aParent ) == false )
|
||||
{
|
||||
EXCHG(aColor, aAltColor);
|
||||
}
|
||||
|
||||
switch( primitive_id )
|
||||
{
|
||||
case AMP_CIRCLE: // Circle, given diameter and position
|
||||
{
|
||||
/* Generated by an aperture macro declaration like:
|
||||
* "1,1,0.3,0.5, 1.0*"
|
||||
* type (1), exposure, diameter, pos.x, pos.y
|
||||
* type is not stored in parameters list, so the first parameter is exposure
|
||||
*/
|
||||
curPos += mapPt( params[2].GetValue( tool ), params[3].GetValue( tool ), gerberMetric );
|
||||
int radius = scale( params[1].GetValue( tool ), gerberMetric ) / 2;
|
||||
if( !aFilledShape )
|
||||
GRCircle( aClipBox, aDC, curPos.x, curPos.y, radius, aColor );
|
||||
else
|
||||
GRFilledCircle( aClipBox, aDC, curPos, radius, aColor );
|
||||
}
|
||||
break;
|
||||
|
||||
case AMP_LINE2:
|
||||
case AMP_LINE20: // Line with rectangle ends. (Width, start and end pos + rotation)
|
||||
{
|
||||
/* Generated by an aperture macro declaration like:
|
||||
* "2,1,0.3,0,0, 0.5, 1.0,-135*"
|
||||
* type (2), exposure, width, start.x, start.y, end.x, end.y, rotation
|
||||
* type is not stored in parameters list, so the first parameter is exposure
|
||||
*/
|
||||
ConvertShapeToPolygon( aParent, polybuffer, gerberMetric );
|
||||
|
||||
// shape rotation:
|
||||
rotation = wxRound( params[6].GetValue( tool ) * 10.0 );
|
||||
if( rotation )
|
||||
{
|
||||
for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
|
||||
RotatePoint( &polybuffer[ii], rotation );
|
||||
}
|
||||
|
||||
// Move to current position:
|
||||
for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
|
||||
polybuffer[ii] += curPos;
|
||||
|
||||
GRClosedPoly( aClipBox, aDC,
|
||||
polybuffer.size(), &polybuffer[0], aFilledShape, aColor, aColor );
|
||||
}
|
||||
break;
|
||||
|
||||
case AMP_LINE_CENTER:
|
||||
{
|
||||
/* Generated by an aperture macro declaration like:
|
||||
* "21,1,0.3,0.03,0,0,-135*"
|
||||
* type (21), exposure, ,width, height, center pos.x, center pos.y, rotation
|
||||
* type is not stored in parameters list, so the first parameter is exposure
|
||||
*/
|
||||
ConvertShapeToPolygon( aParent, polybuffer, gerberMetric );
|
||||
|
||||
// shape rotation:
|
||||
rotation = wxRound( params[5].GetValue( tool ) * 10.0 );
|
||||
if( rotation )
|
||||
{
|
||||
for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
|
||||
RotatePoint( &polybuffer[ii], rotation );
|
||||
}
|
||||
|
||||
// Move to current position:
|
||||
for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
|
||||
polybuffer[ii] += curPos;
|
||||
|
||||
GRClosedPoly( aClipBox, aDC,
|
||||
polybuffer.size(), &polybuffer[0], aFilledShape, aColor, aColor );
|
||||
}
|
||||
break;
|
||||
|
||||
case AMP_LINE_LOWER_LEFT:
|
||||
{
|
||||
/* Generated by an aperture macro declaration like:
|
||||
* "22,1,0.3,0.03,0,0,-135*"
|
||||
* type (22), exposure, ,width, height, corner pos.x, corner pos.y, rotation
|
||||
* type is not stored in parameters list, so the first parameter is exposure
|
||||
*/
|
||||
ConvertShapeToPolygon( aParent, polybuffer, gerberMetric );
|
||||
|
||||
// shape rotation:
|
||||
rotation = wxRound( params[5].GetValue( tool ) * 10.0 );
|
||||
if( rotation )
|
||||
{
|
||||
for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
|
||||
RotatePoint( &polybuffer[ii], rotation );
|
||||
}
|
||||
|
||||
// Move to current position:
|
||||
for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
|
||||
polybuffer[ii] += curPos;
|
||||
|
||||
GRClosedPoly( aClipBox, aDC,
|
||||
polybuffer.size(), &polybuffer[0], aFilledShape, aColor, aColor );
|
||||
}
|
||||
break;
|
||||
|
||||
case AMP_THERMAL:
|
||||
{
|
||||
/* Generated by an aperture macro declaration like:
|
||||
* "7, 0,0,1.0,0.3,0.01,-13*"
|
||||
* type (7), center.x , center.y, outside diam, inside diam, crosshair thickness, rotation
|
||||
* type is not stored in parameters list, so the first parameter is center.x
|
||||
*/
|
||||
curPos += mapPt( params[0].GetValue( tool ), params[1].GetValue( tool ), gerberMetric );
|
||||
/* int outerRadius = scale( params[2].GetValue( tool ), gerberMetric ) / 2;
|
||||
if( !aFilledShape )
|
||||
GRCircle( aClipBox, aDC, curPos.x, curPos.y, outerRadius, aColor );
|
||||
else
|
||||
GRFilledCircle( aClipBox, aDC, curPos, outerRadius, aColor );
|
||||
*/
|
||||
ConvertShapeToPolygon( aParent, polybuffer, gerberMetric );
|
||||
|
||||
// shape rotation:
|
||||
rotation = wxRound( params[5].GetValue( tool ) * 10.0 );
|
||||
|
||||
// Because a thermal shape has 4 identical sub-shapes, only one is created in polybuffer.
|
||||
// We must draw 4 sub-shapes rotated by 90 deg
|
||||
std::vector<wxPoint> subshape_poly;
|
||||
for( int ii = 0; ii < 4; ii++ )
|
||||
{
|
||||
subshape_poly = polybuffer;
|
||||
int sub_rotation = rotation + 900 * ii;
|
||||
for( unsigned jj = 0; jj < subshape_poly.size(); jj++ )
|
||||
RotatePoint( &subshape_poly[jj], sub_rotation );
|
||||
|
||||
// Move to current position:
|
||||
for( unsigned jj = 0; jj < subshape_poly.size(); jj++ )
|
||||
subshape_poly[jj] += curPos;
|
||||
|
||||
GRClosedPoly( aClipBox, aDC,
|
||||
subshape_poly.size(), &subshape_poly[0], true, aAltColor,
|
||||
aAltColor );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case AMP_MOIRE: // A cross hair with n concentric circles
|
||||
{
|
||||
curPos += mapPt( params[0].GetValue( tool ), params[1].GetValue( tool ),
|
||||
gerberMetric );
|
||||
|
||||
/* Generated by an aperture macro declaration like:
|
||||
* "6,0,0,0.125,.01,0.01,3,0.003,0.150,0"
|
||||
* type(6), pos.x, pos.y, diam, penwidth, gap, circlecount, crosshair thickness, crosshaire len, rotation
|
||||
* type is not stored in parameters list, so the first parameter is pos.x
|
||||
*/
|
||||
int outerDiam = scale( params[2].GetValue( tool ), gerberMetric );
|
||||
int penThickness = scale( params[3].GetValue( tool ), gerberMetric );
|
||||
int gap = scale( params[4].GetValue( tool ), gerberMetric );
|
||||
int numCircles = wxRound( params[5].GetValue( tool ) );
|
||||
|
||||
// adjust outerDiam by this on each nested circle
|
||||
int diamAdjust = (gap + penThickness); //*2; //Should we use * 2 ?
|
||||
for( int i = 0; i < numCircles; ++i, outerDiam -= diamAdjust )
|
||||
{
|
||||
if( outerDiam <= 0 )
|
||||
break;
|
||||
if( !aFilledShape )
|
||||
{
|
||||
// draw the border of the pen's path using two circles, each as narrow as possible
|
||||
GRCircle( aClipBox, aDC, curPos.x, curPos.y, outerDiam / 2, 0, aColor );
|
||||
GRCircle( aClipBox, aDC, curPos.x, curPos.y,
|
||||
outerDiam / 2 - penThickness, 0, aColor );
|
||||
}
|
||||
else // Filled mode
|
||||
{
|
||||
GRCircle( aClipBox, aDC, curPos.x, curPos.y,
|
||||
(outerDiam - penThickness) / 2, penThickness, aColor );
|
||||
}
|
||||
}
|
||||
|
||||
// Draw the cross:
|
||||
ConvertShapeToPolygon( aParent, polybuffer, gerberMetric );
|
||||
|
||||
// shape rotation:
|
||||
rotation = wxRound( params[8].GetValue( tool ) * 10.0 );
|
||||
if( rotation )
|
||||
{
|
||||
for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
|
||||
RotatePoint( &polybuffer[ii], rotation );
|
||||
}
|
||||
|
||||
// Move to current position:
|
||||
for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
|
||||
polybuffer[ii] += curPos;
|
||||
|
||||
GRClosedPoly( aClipBox, aDC,
|
||||
polybuffer.size(), &polybuffer[0], aFilledShape, aColor, aColor );
|
||||
}
|
||||
break;
|
||||
|
||||
case AMP_OUTLINE:
|
||||
{
|
||||
/* Generated by an aperture macro declaration like:
|
||||
* "4,1,3,0.0,0.0,0.0,0.5,0.5,0.5,0.5,0.0,-25"
|
||||
* type(4), exposure, corners count, corner1.x, corner.1y, ..., rotation
|
||||
* type is not stored in parameters list, so the first parameter is exposure
|
||||
*/
|
||||
int numPoints = (int) params[1].GetValue( tool );
|
||||
rotation = wxRound( params[numPoints * 2 + 4].GetValue( tool ) * 10.0 );
|
||||
wxPoint pos;
|
||||
// Read points. numPoints does not include the starting point, so add 1.
|
||||
for( int i = 0; i<numPoints + 1; ++i )
|
||||
{
|
||||
int jj = i * 2 + 2;
|
||||
pos.x = scale( params[jj].GetValue( tool ), gerberMetric );
|
||||
pos.y = scale( params[jj + 1].GetValue( tool ), gerberMetric );
|
||||
polybuffer.push_back(pos);
|
||||
}
|
||||
// rotate polygon and move it to the actual position
|
||||
// shape rotation:
|
||||
for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
|
||||
{
|
||||
NEGATE(polybuffer[ii].y);
|
||||
RotatePoint( &polybuffer[ii], rotation );
|
||||
}
|
||||
|
||||
// Move to current position:
|
||||
for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
|
||||
polybuffer[ii] += curPos;
|
||||
|
||||
GRClosedPoly( aClipBox, aDC,
|
||||
polybuffer.size(), &polybuffer[0], aFilledShape, aColor, aColor );
|
||||
}
|
||||
break;
|
||||
|
||||
case AMP_POLYGON: // Is a regular polygon
|
||||
/* Generated by an aperture macro declaration like:
|
||||
* "5,1,0.6,0,0,0.5,25"
|
||||
* type(5), exposure, vertices count, pox.x, pos.y, diameter, rotation
|
||||
* type is not stored in parameters list, so the first parameter is exposure
|
||||
*/
|
||||
curPos += mapPt( params[2].GetValue( tool ), params[3].GetValue( tool ),
|
||||
gerberMetric );
|
||||
// Creates the shape:
|
||||
ConvertShapeToPolygon( aParent, polybuffer, gerberMetric );
|
||||
|
||||
// rotate polygon and move it to the actual position
|
||||
rotation = wxRound( params[5].GetValue( tool ) * 10.0 );
|
||||
for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
|
||||
{
|
||||
NEGATE(polybuffer[ii].y);
|
||||
RotatePoint( &polybuffer[ii], rotation );
|
||||
polybuffer[ii] += curPos;
|
||||
}
|
||||
GRClosedPoly( aClipBox, aDC,
|
||||
polybuffer.size(), &polybuffer[0], aFilledShape, aColor, aColor );
|
||||
break;
|
||||
|
||||
case AMP_EOF:
|
||||
// not yet supported, waiting for you.
|
||||
break;
|
||||
|
||||
case AMP_UNKNOWN:
|
||||
default:
|
||||
D( printf( "AM_PRIMITIVE::DrawBasicShape() err: unknown prim id %d\n",primitive_id) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** function ConvertShapeToPolygon (virtual)
|
||||
* convert a shape to an equivalent polygon.
|
||||
* Arcs and circles are approximated by segments
|
||||
* Useful when a shape is not a graphic primitive (shape with hole,
|
||||
* rotated shape ... ) and cannot be easily drawn.
|
||||
* note for some schapes conbining circles and solid lines (rectangles), only rectangles are converted
|
||||
* because circles are very easy to draw (no rotation problem) so convert them in polygons,
|
||||
* and draw them as polygons is not a good idea.
|
||||
*/
|
||||
void AM_PRIMITIVE::ConvertShapeToPolygon( GERBER_DRAW_ITEM* aParent,
|
||||
std::vector<wxPoint>& aBuffer,
|
||||
bool aUnitsMetric )
|
||||
{
|
||||
D_CODE* tool = aParent->GetDcodeDescr();
|
||||
|
||||
switch( primitive_id )
|
||||
{
|
||||
case AMP_CIRCLE: // Circle, currently convertion not needed
|
||||
break;
|
||||
|
||||
case AMP_LINE2:
|
||||
case AMP_LINE20: // Line with rectangle ends. (Width, start and end pos + rotation)
|
||||
{
|
||||
int width = scale( params[1].GetValue( tool ), aUnitsMetric );
|
||||
wxPoint start = mapPt( params[2].GetValue( tool ),
|
||||
params[3].GetValue( tool ), aUnitsMetric );
|
||||
wxPoint end = mapPt( params[4].GetValue( tool ),
|
||||
params[5].GetValue( tool ), aUnitsMetric );
|
||||
wxPoint delta = end - start;
|
||||
int len = wxRound( hypot( delta.x, delta.y ) );
|
||||
|
||||
// To build the polygon, we must create a horizonta polygon starting to "start"
|
||||
// and rotate it to have it end point to "end"
|
||||
wxPoint currpt;
|
||||
currpt.y += width / 2; // Upper left
|
||||
aBuffer.push_back( currpt );
|
||||
currpt.x = len; // Upper right
|
||||
aBuffer.push_back( currpt );
|
||||
currpt.y -= width; // lower right
|
||||
aBuffer.push_back( currpt );
|
||||
currpt.x = 0; // Upper left
|
||||
aBuffer.push_back( currpt );
|
||||
|
||||
// Rotate rectangle and move it to the actual start point
|
||||
int angle = wxRound( atan2( delta.y, delta.x ) * 1800.0 / M_PI );
|
||||
for( unsigned ii = 0; ii < 4; ii++ )
|
||||
{
|
||||
RotatePoint( &aBuffer[ii], -angle );
|
||||
aBuffer[ii] += start;
|
||||
NEGATE( aBuffer[ii].y );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case AMP_LINE_CENTER:
|
||||
{
|
||||
wxPoint size = mapPt( params[1].GetValue( tool ), params[2].GetValue( tool ), aUnitsMetric );
|
||||
wxPoint pos = mapPt( params[3].GetValue( tool ), params[4].GetValue( tool ), aUnitsMetric );
|
||||
|
||||
// Build poly:
|
||||
pos.x -= size.x / 2;
|
||||
pos.y -= size.y / 2; // Lower left
|
||||
aBuffer.push_back( pos );
|
||||
pos.y += size.y; // Upper left
|
||||
aBuffer.push_back( pos );
|
||||
pos.x += size.x; // Upper right
|
||||
aBuffer.push_back( pos );
|
||||
pos.y -= size.y; // lower right
|
||||
aBuffer.push_back( pos );
|
||||
}
|
||||
break;
|
||||
|
||||
case AMP_LINE_LOWER_LEFT:
|
||||
{
|
||||
wxPoint size = mapPt( params[1].GetValue( tool ), params[2].GetValue( tool ), aUnitsMetric );
|
||||
wxPoint lowerLeft = mapPt( params[3].GetValue( tool ), params[4].GetValue(
|
||||
tool ), aUnitsMetric );
|
||||
|
||||
// Build poly:
|
||||
NEGATE( lowerLeft.y );
|
||||
aBuffer.push_back( lowerLeft );
|
||||
lowerLeft.y += size.y; // Upper left
|
||||
aBuffer.push_back( lowerLeft );
|
||||
lowerLeft.x += size.x; // Upper right
|
||||
aBuffer.push_back( lowerLeft );
|
||||
lowerLeft.y -= size.y; // lower right
|
||||
aBuffer.push_back( lowerLeft );
|
||||
|
||||
// Negate y coordinates:
|
||||
for( unsigned ii = 0; ii < aBuffer.size(); ii++ )
|
||||
NEGATE( aBuffer[ii].y );
|
||||
}
|
||||
break;
|
||||
|
||||
case AMP_THERMAL:
|
||||
{
|
||||
// Only 1/4 of the full shape is built, because the other 3 shapes will be draw from this first
|
||||
// rotated by 90, 180 and 270 deg.
|
||||
// params = center.x (unused here), center.y (unused here), outside diam, inside diam, crosshair thickness
|
||||
int outerRadius = scale( params[2].GetValue( tool ), aUnitsMetric ) / 2;
|
||||
int innerRadius = scale( params[3].GetValue( tool ), aUnitsMetric ) / 2;
|
||||
int halfthickness = scale( params[4].GetValue( tool ), aUnitsMetric ) / 2;
|
||||
int angle_start = wxRound( asin(
|
||||
(double) halfthickness / innerRadius ) * 1800 / M_PI );
|
||||
|
||||
// Draw shape in the first cadrant (X and Y > 0)
|
||||
wxPoint pos, startpos;
|
||||
|
||||
// Inner arc
|
||||
startpos.x = innerRadius;
|
||||
int angle_end = 900 - angle_start;
|
||||
int angle;
|
||||
for( angle = angle_start; angle < angle_end; angle += 100 )
|
||||
{
|
||||
pos = startpos;
|
||||
RotatePoint( &pos, angle );
|
||||
aBuffer.push_back( pos );
|
||||
}
|
||||
|
||||
// Last point
|
||||
pos = startpos;
|
||||
RotatePoint( &pos, angle_end );
|
||||
aBuffer.push_back( pos );
|
||||
|
||||
// outer arc
|
||||
startpos.x = outerRadius;
|
||||
startpos.y = 0;
|
||||
angle_start = wxRound( asin( (double) halfthickness / outerRadius ) * 1800 / M_PI );
|
||||
angle_end = 900 - angle_start;
|
||||
|
||||
// First point, near Y axis, outer arc
|
||||
for( angle = angle_end; angle > angle_start; angle -= 100 )
|
||||
{
|
||||
pos = startpos;
|
||||
RotatePoint( &pos, angle );
|
||||
aBuffer.push_back( pos );
|
||||
}
|
||||
|
||||
// last point
|
||||
pos = startpos;
|
||||
RotatePoint( &pos, angle_start );
|
||||
aBuffer.push_back( pos );
|
||||
|
||||
aBuffer.push_back( aBuffer[0] ); // Close poly
|
||||
}
|
||||
break;
|
||||
|
||||
case AMP_MOIRE: // A cross hair with n concentric circles. Only the cros is build as polygon
|
||||
// because circles can be drawn easily
|
||||
{
|
||||
int crossHairThickness = scale( params[6].GetValue( tool ), aUnitsMetric );
|
||||
int crossHairLength = scale( params[7].GetValue( tool ), aUnitsMetric );
|
||||
|
||||
// Create cross. First create 1/4 of the shape.
|
||||
// Others point are the same, totated by 90, 180 and 270 deg
|
||||
wxPoint pos( crossHairThickness / 2, crossHairLength / 2 );
|
||||
aBuffer.push_back( pos );
|
||||
pos.y = crossHairThickness / 2;
|
||||
aBuffer.push_back( pos );
|
||||
pos.x = -crossHairLength / 2;
|
||||
aBuffer.push_back( pos );
|
||||
pos.y = -crossHairThickness / 2;
|
||||
aBuffer.push_back( pos );
|
||||
|
||||
// Copy the 4 shape, rotated by 90, 180 and 270 deg
|
||||
for( int jj = 900; jj <= 2700; jj += 900 )
|
||||
{
|
||||
for( int ii = 0; ii < 4; ii++ )
|
||||
{
|
||||
pos = aBuffer[ii];
|
||||
RotatePoint( &pos, jj );
|
||||
aBuffer.push_back( pos );
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case AMP_OUTLINE:
|
||||
// already is a polygon. Do nothing
|
||||
break;
|
||||
|
||||
case AMP_POLYGON: // Creates a regular polygon
|
||||
{
|
||||
int vertexcount = wxRound( params[1].GetValue( tool ) );
|
||||
int radius = scale( params[4].GetValue( tool ), aUnitsMetric ) / 2;
|
||||
// rs274x said: vertex count = 3 ... 10, and the first corner is on the X axis
|
||||
if( vertexcount < 3 )
|
||||
vertexcount = 3;
|
||||
if( vertexcount > 10 )
|
||||
vertexcount = 10;
|
||||
for( int ii = 0; ii <= vertexcount; ii++ )
|
||||
{
|
||||
wxPoint pos( radius, 0);
|
||||
RotatePoint( &pos, ii * 3600 / vertexcount );
|
||||
aBuffer.push_back( pos );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case AMP_UNKNOWN:
|
||||
case AMP_EOF:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** function DrawApertureMacroShape
|
||||
* Draw the primitive shape for flashed items.
|
||||
* When an item is flashed, this is the shape of the item
|
||||
*/
|
||||
void APERTURE_MACRO::DrawApertureMacroShape( GERBER_DRAW_ITEM* aParent,
|
||||
EDA_Rect* aClipBox, wxDC* aDC,
|
||||
int aColor, int aAltColor,
|
||||
wxPoint aShapePos, bool aFilledShape )
|
||||
{
|
||||
for( AM_PRIMITIVES::iterator prim_macro = primitives.begin();
|
||||
prim_macro != primitives.end(); ++prim_macro )
|
||||
{
|
||||
prim_macro->DrawBasicShape( aParent, aClipBox, aDC,
|
||||
aColor, aAltColor,
|
||||
aShapePos,
|
||||
aFilledShape );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,182 @@
|
|||
/**************************/
|
||||
/* class_aperture_macro.h */
|
||||
/**************************/
|
||||
|
||||
#ifndef _APERTURE_MACRO_H_
|
||||
#define _APERTURE_MACRO_H_
|
||||
|
||||
/*
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 1992-2010 Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
|
||||
* Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
||||
* Copyright (C) 1992-2010 Kicad Developers, see change_log.txt for contributors.
|
||||
*
|
||||
* 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 2
|
||||
* 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, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
#include "base_struct.h"
|
||||
|
||||
|
||||
/**
|
||||
* Enum AM_PRIMITIVE_ID
|
||||
* is the set of all "aperture macro primitives" (primitive numbers). See
|
||||
* Table 3 in http://gerbv.sourceforge.net/docs/rs274xrevd_e.pdf
|
||||
* aperture macro primitives are basic shapes which can be combined to create a complex shape
|
||||
* This complex shape is flashed.
|
||||
*/
|
||||
enum AM_PRIMITIVE_ID {
|
||||
AMP_UNKNOWN = 0, // A value for uninitialized AM_PRIMITIVE.
|
||||
AMP_CIRCLE = 1, // Circle. (diameter and position)
|
||||
AMP_LINE2 = 2, // Line with rectangle ends. (Width, start and end pos + rotation)
|
||||
AMP_LINE20 = 20, // Same as AMP_LINE2
|
||||
AMP_LINE_CENTER = 21, // Rectangle. (height, width and center pos + rotation)
|
||||
AMP_LINE_LOWER_LEFT = 22, // Rectangle. (height, width and left bottom corner pos + rotation)
|
||||
AMP_EOF = 3, // End Of File marquer: not really a shape
|
||||
AMP_OUTLINE = 4, // Free polyline (n corners + rotation)
|
||||
AMP_POLYGON = 5, // Closed regular polygon(diameter, number of vertices (3 to 10), rotation)
|
||||
AMP_MOIRE = 6, // A cross hair with n concentric circles + rotation
|
||||
AMP_THERMAL = 7, // Thermal shape (pos, outer and inner diameter, cross hair thickness + rotation)
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Struct AM_PRIMITIVE
|
||||
* holds an aperture macro primitive as given in Table 3 of
|
||||
* http://gerbv.sourceforge.net/docs/rs274xrevd_e.pdf
|
||||
*/
|
||||
class AM_PRIMITIVE
|
||||
{
|
||||
public:
|
||||
AM_PRIMITIVE_ID primitive_id; ///< The primitive type
|
||||
DCODE_PARAMS params; ///< A sequence of parameters used by
|
||||
// the primitive
|
||||
|
||||
public:
|
||||
AM_PRIMITIVE( AM_PRIMITIVE_ID aId = AMP_UNKNOWN )
|
||||
{
|
||||
primitive_id = aId;
|
||||
}
|
||||
|
||||
|
||||
~AM_PRIMITIVE() {}
|
||||
|
||||
/**
|
||||
* Function GetExposure
|
||||
* returns the first parameter in integer form. Some but not all primitives
|
||||
* use the first parameter as an exposure control.
|
||||
*/
|
||||
int GetExposure() const;
|
||||
|
||||
/**
|
||||
* Function mapExposure
|
||||
* translates the first parameter from an aperture macro into a current
|
||||
* exposure setting.
|
||||
* @param aParent = a GERBER_DRAW_ITEM that handle:
|
||||
* ** m_Exposure A dynamic setting which can change throughout the
|
||||
* reading of the gerber file, and it indicates whether the current tool
|
||||
* is lit or not.
|
||||
* ** m_ImageNegative A dynamic setting which can change throughout the reading
|
||||
* of the gerber file, and it indicates whether the current D codes are to
|
||||
* be interpreted as erasures or not.
|
||||
* @return true to draw with current color, false to draw with alt color (erase)
|
||||
*/
|
||||
bool mapExposure( GERBER_DRAW_ITEM* aParent );
|
||||
|
||||
/* Draw functions: */
|
||||
|
||||
/** function DrawBasicShape
|
||||
* Draw the primitive shape for flashed items.
|
||||
* @param aParent = the parent GERBER_DRAW_ITEM which is actually drawn
|
||||
* @param aClipBox = DC clip box (NULL is no clip)
|
||||
* @param aDC = device context
|
||||
* @param aColor = the normal color to use
|
||||
* @param aAltColor = the color used to draw with "reverse" exposure mode (used in aperture macros only)
|
||||
* @param aShapePos = the actual shape position
|
||||
* @param aFilledShape = true to draw in filled mode, false to draw in skecth mode
|
||||
*/
|
||||
void DrawBasicShape( GERBER_DRAW_ITEM* aParent, EDA_Rect* aClipBox, wxDC* aDC,
|
||||
int aColor, int aAltColor, wxPoint aShapePos, bool aFilledShape );
|
||||
|
||||
private:
|
||||
|
||||
/** function ConvertShapeToPolygon
|
||||
* convert a shape to an equivalent polygon.
|
||||
* Arcs and circles are approximated by segments
|
||||
* Useful when a shape is not a graphic primitive (shape with hole,
|
||||
* rotated shape ... ) and cannot be easily drawn.
|
||||
*/
|
||||
void ConvertShapeToPolygon( GERBER_DRAW_ITEM* aParent, std::vector<wxPoint>& aBuffer, bool aUnitsMetric);
|
||||
};
|
||||
|
||||
|
||||
typedef std::vector<AM_PRIMITIVE> AM_PRIMITIVES;
|
||||
|
||||
/**
|
||||
* Struct APERTURE_MACRO
|
||||
* helps support the "aperture macro" defined within standard RS274X.
|
||||
*/
|
||||
struct APERTURE_MACRO
|
||||
{
|
||||
wxString name; ///< The name of the aperture macro
|
||||
AM_PRIMITIVES primitives; ///< A sequence of AM_PRIMITIVEs
|
||||
|
||||
/** function DrawApertureMacroShape
|
||||
* Draw the primitive shape for flashed items.
|
||||
* When an item is flashed, this is the shape of the item
|
||||
* @param aParent = the parent GERBER_DRAW_ITEM which is actually drawn
|
||||
* @param aClipBox = DC clip box (NULL is no clip)
|
||||
* @param aDC = device context
|
||||
* @param aColor = the normal color to use
|
||||
* @param aAltColor = the color used to draw with "reverse" exposure mode (used in aperture macros only)
|
||||
* @param aShapePos = the actual shape position
|
||||
* @param aFilledShape = true to draw in filled mode, false to draw in skecth mode
|
||||
*/
|
||||
void DrawApertureMacroShape( GERBER_DRAW_ITEM* aParent, EDA_Rect* aClipBox, wxDC* aDC,
|
||||
int aColor, int aAltColor, wxPoint aShapePos, bool aFilledShape );
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Struct APERTURE_MACRO_less_than
|
||||
* is used by std:set<APERTURE_MACRO> instantiation which uses
|
||||
* APERTURE_MACRO.name as its key.
|
||||
*/
|
||||
struct APERTURE_MACRO_less_than
|
||||
{
|
||||
// a "less than" test on two APERTURE_MACROs (.name wxStrings)
|
||||
bool operator()( const APERTURE_MACRO& am1, const APERTURE_MACRO& am2 ) const
|
||||
{
|
||||
return am1.name.Cmp( am2.name ) < 0; // case specific wxString compare
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Type APERTURE_MACRO_SET
|
||||
* is a sorted collection of APERTURE_MACROS whose key is the name field in
|
||||
* the APERTURE_MACRO.
|
||||
*/
|
||||
typedef std::set<APERTURE_MACRO, APERTURE_MACRO_less_than> APERTURE_MACRO_SET;
|
||||
typedef std::pair<APERTURE_MACRO_SET::iterator, bool> APERTURE_MACRO_SET_PAIR;
|
||||
|
||||
|
||||
#endif // ifndef _APERTURE_MACRO_H_
|
|
@ -49,6 +49,9 @@ GERBER_DRAW_ITEM::GERBER_DRAW_ITEM( BOARD_ITEM* aParent ) :
|
|||
m_Shape = GBR_SEGMENT;
|
||||
m_Flashed = false;
|
||||
m_DCode = 0;
|
||||
m_UnitsMetric = false;
|
||||
m_ImageNegative = false;
|
||||
m_LayerNegative = false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -70,6 +73,10 @@ GERBER_DRAW_ITEM::GERBER_DRAW_ITEM( const GERBER_DRAW_ITEM& aSource ) :
|
|||
m_Flashed = aSource.m_Flashed;
|
||||
m_DCode = aSource.m_DCode;
|
||||
m_PolyCorners = aSource.m_PolyCorners;
|
||||
m_UnitsMetric = aSource.m_UnitsMetric;
|
||||
m_ImageNegative = aSource.m_ImageNegative;
|
||||
m_LayerNegative = aSource.m_LayerNegative;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -176,12 +183,12 @@ bool GERBER_DRAW_ITEM::Save( FILE* aFile ) const
|
|||
|
||||
|
||||
/*********************************************************************/
|
||||
void GERBER_DRAW_ITEM::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode,
|
||||
void GERBER_DRAW_ITEM::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, int aDrawMode,
|
||||
const wxPoint& aOffset )
|
||||
/*********************************************************************/
|
||||
{
|
||||
static D_CODE dummyD_CODE( 0 ); // used when a D_CODE is not found. default D_CODE to draw a flashed item
|
||||
int color;
|
||||
int color, alt_color;
|
||||
bool isFilled;
|
||||
int radius;
|
||||
int halfPenWidth;
|
||||
|
@ -192,29 +199,29 @@ void GERBER_DRAW_ITEM::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode,
|
|||
if( d_codeDescr == NULL )
|
||||
d_codeDescr = &dummyD_CODE;
|
||||
|
||||
if( brd->IsLayerVisible( GetLayer() ) == false )
|
||||
return;
|
||||
|
||||
color = brd->GetLayerColor( GetLayer() );
|
||||
|
||||
if( aDrawMode & GR_SURBRILL )
|
||||
{
|
||||
if( aDrawMode & GR_AND )
|
||||
color &= ~HIGHT_LIGHT_FLAG;
|
||||
else
|
||||
color |= HIGHT_LIGHT_FLAG;
|
||||
}
|
||||
if( color & HIGHT_LIGHT_FLAG )
|
||||
color = ColorRefs[color & MASKCOLOR].m_LightColor;
|
||||
|
||||
alt_color = g_DrawBgColor ;
|
||||
|
||||
if( m_Flags & DRAW_ERASED ) // draw in background color ("negative" color)
|
||||
{
|
||||
color = g_DrawBgColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( brd->IsLayerVisible( GetLayer() ) == false )
|
||||
return;
|
||||
|
||||
color = brd->GetLayerColor( GetLayer() );
|
||||
|
||||
if( draw_mode & GR_SURBRILL )
|
||||
{
|
||||
if( draw_mode & GR_AND )
|
||||
color &= ~HIGHT_LIGHT_FLAG;
|
||||
else
|
||||
color |= HIGHT_LIGHT_FLAG;
|
||||
}
|
||||
if( color & HIGHT_LIGHT_FLAG )
|
||||
color = ColorRefs[color & MASKCOLOR].m_LightColor;
|
||||
EXCHG(color, alt_color);
|
||||
}
|
||||
|
||||
GRSetDrawMode( DC, draw_mode );
|
||||
GRSetDrawMode( aDC, aDrawMode );
|
||||
|
||||
isFilled = DisplayOpt.DisplayPcbTrackFill ? true : false;
|
||||
|
||||
|
@ -224,7 +231,7 @@ void GERBER_DRAW_ITEM::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode,
|
|||
isFilled = (g_DisplayPolygonsModeSketch == false);
|
||||
if( m_Flags & DRAW_ERASED )
|
||||
isFilled = true;
|
||||
DrawGbrPoly( &panel->m_ClipBox, DC, color, aOffset, isFilled );
|
||||
DrawGbrPoly( &aPanel->m_ClipBox, aDC, color, aOffset, isFilled );
|
||||
break;
|
||||
|
||||
case GBR_CIRCLE:
|
||||
|
@ -236,14 +243,14 @@ void GERBER_DRAW_ITEM::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode,
|
|||
if( !isFilled )
|
||||
{
|
||||
// draw the border of the pen's path using two circles, each as narrow as possible
|
||||
GRCircle( &panel->m_ClipBox, DC, m_Start.x, m_Start.y,
|
||||
GRCircle( &aPanel->m_ClipBox, aDC, m_Start.x, m_Start.y,
|
||||
radius - halfPenWidth, 0, color );
|
||||
GRCircle( &panel->m_ClipBox, DC, m_Start.x, m_Start.y,
|
||||
GRCircle( &aPanel->m_ClipBox, aDC, m_Start.x, m_Start.y,
|
||||
radius + halfPenWidth, 0, color );
|
||||
}
|
||||
else // Filled mode
|
||||
{
|
||||
GRCircle( &panel->m_ClipBox, DC, m_Start.x, m_Start.y,
|
||||
GRCircle( &aPanel->m_ClipBox, aDC, m_Start.x, m_Start.y,
|
||||
radius, m_Size.x, color );
|
||||
}
|
||||
break;
|
||||
|
@ -251,13 +258,13 @@ void GERBER_DRAW_ITEM::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode,
|
|||
case GBR_ARC:
|
||||
if( !isFilled )
|
||||
{
|
||||
GRArc1( &panel->m_ClipBox, DC, m_Start.x, m_Start.y,
|
||||
GRArc1( &aPanel->m_ClipBox, aDC, m_Start.x, m_Start.y,
|
||||
m_End.x, m_End.y,
|
||||
m_ArcCentre.x, m_ArcCentre.y, 0, color );
|
||||
}
|
||||
else
|
||||
{
|
||||
GRArc1( &panel->m_ClipBox, DC, m_Start.x, m_Start.y,
|
||||
GRArc1( &aPanel->m_ClipBox, aDC, m_Start.x, m_Start.y,
|
||||
m_End.x, m_End.y,
|
||||
m_ArcCentre.x, m_ArcCentre.y,
|
||||
m_Size.x, color );
|
||||
|
@ -268,17 +275,18 @@ void GERBER_DRAW_ITEM::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode,
|
|||
case GBR_SPOT_RECT:
|
||||
case GBR_SPOT_OVAL:
|
||||
case GBR_SPOT_POLY:
|
||||
case GBR_SPOT_MACRO:
|
||||
isFilled = DisplayOpt.DisplayPadFill ? true : false;
|
||||
d_codeDescr->DrawFlashedShape( &panel->m_ClipBox, DC, color,
|
||||
d_codeDescr->DrawFlashedShape( this, &aPanel->m_ClipBox, aDC, color, alt_color,
|
||||
m_Start, isFilled );
|
||||
break;
|
||||
|
||||
case GBR_SEGMENT:
|
||||
if( !isFilled )
|
||||
GRCSegm( &panel->m_ClipBox, DC, m_Start.x, m_Start.y,
|
||||
GRCSegm( &aPanel->m_ClipBox, aDC, m_Start.x, m_Start.y,
|
||||
m_End.x, m_End.y, m_Size.x, color );
|
||||
else
|
||||
GRFillCSegm( &panel->m_ClipBox, DC, m_Start.x,
|
||||
GRFillCSegm( &aPanel->m_ClipBox, aDC, m_Start.x,
|
||||
m_Start.y, m_End.x, m_End.y, m_Size.x, color );
|
||||
break;
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
*/
|
||||
|
||||
#include "base_struct.h"
|
||||
#include "class_board_item.h"
|
||||
|
||||
/* Shapes id for basic shapes ( .m_Shape member ) */
|
||||
enum Gbr_Basic_Shapes {
|
||||
|
@ -57,6 +58,8 @@ private:
|
|||
|
||||
|
||||
public:
|
||||
bool m_UnitsMetric; /* store here the gerber units (inch/mm).
|
||||
* Used only to calculate aperture macros shapes sizes */
|
||||
int m_Shape; // Shape and type of this gerber item
|
||||
wxPoint m_Start; // Line or arc start point or position of the shape
|
||||
// for flashed items
|
||||
|
@ -71,6 +74,8 @@ public:
|
|||
// 0 for items that do not use DCodes (polygons)
|
||||
// or when unknown and normal values are 10 to 999
|
||||
// values 0 to 9 can be used for special purposes
|
||||
bool m_ImageNegative; // true = item in negative image
|
||||
bool m_LayerNegative; // TRUE = item in negative Layer
|
||||
|
||||
public:
|
||||
GERBER_DRAW_ITEM( BOARD_ITEM* aParent );
|
||||
|
|
|
@ -96,10 +96,11 @@ const wxChar* D_CODE::ShowApertureType( APERTURE_T aType )
|
|||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/** Function Read_D_Code_File
|
||||
* Can be useful only with old RS274D Gerber file format.
|
||||
* Is not needed with RS274X files format.
|
||||
* These files need an auxiliary DCode file description. Ther is no defined file format for this.
|
||||
* These files need an auxiliary DCode file description. There is no defined file format for this.
|
||||
* This function read a file format I needed a long time ago.
|
||||
* reads in a dcode file assuming ALSPCB file format with ';' indicating comments.
|
||||
* Format is like CSV but with optional ';' delineated comments:
|
||||
|
@ -165,7 +166,7 @@ int WinEDA_GerberFrame::Read_D_Code_File( const wxString& D_Code_FullFileName )
|
|||
if( ii >= 6 ) /* valeurs en mils */
|
||||
{
|
||||
sscanf( line, "%d,%d,%d,%d,%d,%d,%d", &ii,
|
||||
&dimH, &dimV, &drill, &dummy, &dummy, &type_outil );
|
||||
&dimH, &dimV, &drill, &dummy, &dummy, &type_outil );
|
||||
|
||||
dimH = wxRound( dimH * dcode_scale );
|
||||
dimV = wxRound( dimV * dcode_scale );
|
||||
|
@ -279,7 +280,7 @@ void WinEDA_GerberFrame::CopyDCodesSizeToItems()
|
|||
break;
|
||||
|
||||
default:
|
||||
wxMessageBox( wxT("WinEDA_GerberFrame::CopyDCodesSizeToItems() error" ) );
|
||||
wxMessageBox( wxT( "WinEDA_GerberFrame::CopyDCodesSizeToItems() error" ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -291,15 +292,19 @@ void WinEDA_GerberFrame::CopyDCodesSizeToItems()
|
|||
* Draw the dcode shape for flashed items.
|
||||
* When an item is flashed, the DCode shape is the shape of the item
|
||||
*/
|
||||
void D_CODE::DrawFlashedShape( EDA_Rect* aClipBox, wxDC* aDC, int aColor,
|
||||
wxPoint aShapePos, bool aFilledShape )
|
||||
void D_CODE::DrawFlashedShape( GERBER_DRAW_ITEM* aParent,
|
||||
EDA_Rect* aClipBox, wxDC* aDC, int aColor, int aAltColor,
|
||||
wxPoint aShapePos, bool aFilledShape )
|
||||
{
|
||||
int radius;
|
||||
|
||||
switch( m_Shape )
|
||||
{
|
||||
case APT_MACRO:
|
||||
GetMacro()->DrawApertureMacroShape( aParent, aClipBox, aDC, aColor, aAltColor,
|
||||
aShapePos, aFilledShape);
|
||||
break;
|
||||
|
||||
case APT_MACRO: // TODO: current a round shape
|
||||
case APT_CIRCLE:
|
||||
radius = m_Size.x >> 1;
|
||||
if( !aFilledShape )
|
||||
|
@ -427,7 +432,7 @@ void D_CODE::DrawFlashedPolygon( EDA_Rect* aClipBox, wxDC* aDC,
|
|||
static void addHoleToPolygon( std::vector<wxPoint>& aBuffer,
|
||||
APERTURE_DEF_HOLETYPE aHoleShape,
|
||||
wxSize aSize,
|
||||
wxPoint aAnchorPos );
|
||||
wxPoint aAnchorPos );
|
||||
|
||||
/** function ConvertShapeToPolygon
|
||||
* convert a shape to an equivalent polygon.
|
||||
|
@ -439,6 +444,7 @@ void D_CODE::ConvertShapeToPolygon()
|
|||
{
|
||||
wxPoint initialpos;
|
||||
wxPoint currpos;;
|
||||
|
||||
m_PolyCorners.clear();
|
||||
|
||||
switch( m_Shape )
|
||||
|
@ -530,6 +536,7 @@ void D_CODE::ConvertShapeToPolygon()
|
|||
case APT_POLYGON:
|
||||
currpos.x = m_Size.x >> 1; // first point is on X axis
|
||||
initialpos = currpos;
|
||||
|
||||
// rs274x said: m_EdgesCount = 3 ... 12
|
||||
if( m_EdgesCount < 3 )
|
||||
m_EdgesCount = 3;
|
||||
|
@ -541,15 +548,16 @@ void D_CODE::ConvertShapeToPolygon()
|
|||
RotatePoint( &currpos, ii * 3600 / m_EdgesCount );
|
||||
m_PolyCorners.push_back( currpos );
|
||||
}
|
||||
|
||||
addHoleToPolygon( m_PolyCorners, m_DrillShape, m_Drill, initialpos );
|
||||
if( m_Rotation ) // vertical oval, rotate polygon.
|
||||
{
|
||||
int angle = wxRound( m_Rotation*10 );
|
||||
int angle = wxRound( m_Rotation * 10 );
|
||||
for( unsigned jj = 0; jj < m_PolyCorners.size(); jj++ )
|
||||
{
|
||||
// Remember the Y axis is from top to bottom when draw items.
|
||||
RotatePoint( &m_PolyCorners[jj], -angle );
|
||||
NEGATE(m_PolyCorners[jj].y);
|
||||
NEGATE( m_PolyCorners[jj].y );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -561,6 +569,7 @@ void D_CODE::ConvertShapeToPolygon()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// The helper function for D_CODE::ConvertShapeToPolygon().
|
||||
// Add a hole to a polygon
|
||||
static void addHoleToPolygon( std::vector<wxPoint>& aBuffer,
|
||||
|
@ -569,6 +578,7 @@ static void addHoleToPolygon( std::vector<wxPoint>& aBuffer,
|
|||
wxPoint aAnchorPos )
|
||||
{
|
||||
wxPoint currpos;
|
||||
|
||||
if( aHoleShape == APT_DEF_ROUND_HOLE ) // build a round hole
|
||||
{
|
||||
for( int ii = 0; ii <= SEGS_CNT; ii++ )
|
||||
|
@ -579,9 +589,9 @@ static void addHoleToPolygon( std::vector<wxPoint>& aBuffer,
|
|||
aBuffer.push_back( currpos );
|
||||
}
|
||||
|
||||
aBuffer.push_back( aAnchorPos ); // link to outline
|
||||
aBuffer.push_back( aAnchorPos ); // link to outline
|
||||
}
|
||||
if( aHoleShape == APT_DEF_RECT_HOLE ) // Create rectangular hole
|
||||
if( aHoleShape == APT_DEF_RECT_HOLE ) // Create rectangular hole
|
||||
{
|
||||
currpos.x = aSize.x / 2;
|
||||
currpos.y = aSize.y / 2;
|
||||
|
@ -593,7 +603,7 @@ static void addHoleToPolygon( std::vector<wxPoint>& aBuffer,
|
|||
currpos.x += aSize.x;
|
||||
aBuffer.push_back( currpos );
|
||||
currpos.y += aSize.y;
|
||||
aBuffer.push_back( currpos ); // close hole
|
||||
aBuffer.push_back( aAnchorPos ); // link to outline
|
||||
aBuffer.push_back( currpos ); // close hole
|
||||
aBuffer.push_back( aAnchorPos ); // link to outline
|
||||
}
|
||||
}
|
||||
|
|
147
gerbview/dcode.h
147
gerbview/dcode.h
|
@ -2,6 +2,31 @@
|
|||
/* dcode.h */
|
||||
/**************/
|
||||
|
||||
/*
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 1992-2010 Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
|
||||
* Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
||||
* Copyright (C) 1992-2010 Kicad Developers, see change_log.txt for contributors.
|
||||
*
|
||||
* 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 2
|
||||
* 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, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef _DCODE_H_
|
||||
#define _DCODE_H_
|
||||
|
||||
|
@ -9,7 +34,7 @@
|
|||
#include <set>
|
||||
|
||||
#include "base_struct.h"
|
||||
|
||||
class GERBER_DRAW_ITEM;
|
||||
|
||||
/**
|
||||
* Enum APERTURE_T
|
||||
|
@ -42,6 +67,7 @@ enum APERTURE_DEF_HOLETYPE {
|
|||
#define LAST_DCODE 999
|
||||
#define TOOLS_MAX_COUNT (LAST_DCODE + 1)
|
||||
|
||||
class APERTURE_MACRO;
|
||||
class D_CODE;
|
||||
|
||||
|
||||
|
@ -97,91 +123,8 @@ private:
|
|||
// not used.
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Enum AM_PRIMITIVE_ID
|
||||
* is the set of all "aperture macro primitives" (primitive numbers). See
|
||||
* Table 3 in http://gerbv.sourceforge.net/docs/rs274xrevd_e.pdf
|
||||
* aperture macro primitives are basic shapes which can be combined to create a complex shape
|
||||
* This complex shape is flashed.
|
||||
*/
|
||||
enum AM_PRIMITIVE_ID {
|
||||
AMP_CIRCLE = 1, // Circle. (diameter and position)
|
||||
AMP_LINE2 = 2, // Line with rectangle ends. (Width, start and end pos + rotation)
|
||||
AMP_LINE20 = 20, // Same as AMP_LINE2
|
||||
AMP_LINE_CENTER = 21, // Rectangle. (height, width and center pos + rotation)
|
||||
AMP_LINE_LOWER_LEFT = 22, // Rectangle. (height, width and lrft bottom corner pos + rotation)
|
||||
AMP_EOF = 3, // End Of File marquer: not really a shape
|
||||
AMP_OUTLINE = 4, // Free polyline (n corners + rotation)
|
||||
AMP_POLYGON = 5, // Closed regular polygon(diameter, number of vertices (3 to 10), rotation)
|
||||
AMP_MOIRE = 6, // A cross hair with n concentric circles + rotation
|
||||
AMP_THERMAL = 7, // Thermal shape (pos, outer and inner dioameter, cross hair thickness + rotation)
|
||||
};
|
||||
|
||||
|
||||
typedef std::vector<DCODE_PARAM> DCODE_PARAMS;
|
||||
|
||||
/**
|
||||
* Struct AM_PRIMITIVE
|
||||
* holds an aperture macro primitive as given in Table 3 of
|
||||
* http://gerbv.sourceforge.net/docs/rs274xrevd_e.pdf
|
||||
*/
|
||||
struct AM_PRIMITIVE
|
||||
{
|
||||
AM_PRIMITIVE_ID primitive_id; ///< The primitive type
|
||||
DCODE_PARAMS params; ///< A sequence of parameters used by
|
||||
// the primitive
|
||||
|
||||
/**
|
||||
* Function GetExposure
|
||||
* returns the first parameter in integer form. Some but not all primitives
|
||||
* use the first parameter as an exposure control.
|
||||
*/
|
||||
int GetExposure() const
|
||||
{
|
||||
// No D_CODE* for GetValue()
|
||||
wxASSERT( params.size() && params[0].IsImmediate() );
|
||||
return (int) params[0].GetValue( NULL );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
typedef std::vector<AM_PRIMITIVE> AM_PRIMITIVES;
|
||||
|
||||
/**
|
||||
* Struct APERTURE_MACRO
|
||||
* helps support the "aperture macro" defined within standard RS274X.
|
||||
*/
|
||||
struct APERTURE_MACRO
|
||||
{
|
||||
wxString name; ///< The name of the aperture macro
|
||||
AM_PRIMITIVES primitives; ///< A sequence of AM_PRIMITIVEs
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Struct APERTURE_MACRO_less_than
|
||||
* is used by std:set<APERTURE_MACRO> instantiation which uses
|
||||
* APERTURE_MACRO.name as its key.
|
||||
*/
|
||||
struct APERTURE_MACRO_less_than
|
||||
{
|
||||
// a "less than" test on two APERTURE_MACROs (.name wxStrings)
|
||||
bool operator()( const APERTURE_MACRO& am1, const APERTURE_MACRO& am2 ) const
|
||||
{
|
||||
return am1.name.Cmp( am2.name ) < 0; // case specific wxString compare
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Type APERTURE_MACRO_SET
|
||||
* is a sorted collection of APERTURE_MACROS whose key is the name field in
|
||||
* the APERTURE_MACRO.
|
||||
*/
|
||||
typedef std::set<APERTURE_MACRO, APERTURE_MACRO_less_than> APERTURE_MACRO_SET;
|
||||
typedef std::pair<APERTURE_MACRO_SET::iterator, bool> APERTURE_MACRO_SET_PAIR;
|
||||
|
||||
|
||||
/**
|
||||
* Class D_CODE
|
||||
|
@ -206,15 +149,15 @@ class D_CODE
|
|||
*/
|
||||
|
||||
public:
|
||||
wxSize m_Size; /* Horizontal and vertical dimensions. */
|
||||
APERTURE_T m_Shape; /* shape ( Line, rectangle, circle , oval .. ) */
|
||||
int m_Num_Dcode; /* D code ( >= 10 ) */
|
||||
wxSize m_Drill; /* dimension of the hole (if any) */
|
||||
APERTURE_DEF_HOLETYPE m_DrillShape; /* shape of the hole (0 = no hole, round = 1, rect = 2) */
|
||||
double m_Rotation; /* shape rotation in degrees */
|
||||
int m_EdgesCount; /* in apeture definition Polygon only: number of edges for the polygon */
|
||||
bool m_InUse; /* FALSE if not used */
|
||||
bool m_Defined; /* FALSE if not defined */
|
||||
wxSize m_Size; /* Horizontal and vertical dimensions. */
|
||||
APERTURE_T m_Shape; /* shape ( Line, rectangle, circle , oval .. ) */
|
||||
int m_Num_Dcode; /* D code ( >= 10 ) */
|
||||
wxSize m_Drill; /* dimension of the hole (if any) */
|
||||
APERTURE_DEF_HOLETYPE m_DrillShape; /* shape of the hole (0 = no hole, round = 1, rect = 2) */
|
||||
double m_Rotation; /* shape rotation in degrees */
|
||||
int m_EdgesCount; /* in apeture definition Polygon only: number of edges for the polygon */
|
||||
bool m_InUse; /* FALSE if not used */
|
||||
bool m_Defined; /* FALSE if not defined */
|
||||
wxString m_SpecialDescr;
|
||||
|
||||
public:
|
||||
|
@ -250,16 +193,28 @@ public:
|
|||
/** function DrawFlashedShape
|
||||
* Draw the dcode shape for flashed items.
|
||||
* When an item is flashed, the DCode shape is the shape of the item
|
||||
* @param aClipBox = DC clip box (NULL is no clip)
|
||||
* @param aDC = device context
|
||||
* @param aColor = the normal color to use
|
||||
* @param aAltColor = the color used to draw with "reverse" exposure mode (used in aperture macros only)
|
||||
* @param aFilled = true to draw in filled mode, false to draw in skecth mode
|
||||
* @param aPosition = the actual shape position
|
||||
*/
|
||||
void DrawFlashedShape( EDA_Rect* aClipBox, wxDC* aDC, int aColor,
|
||||
wxPoint aShapePos, bool aFilledShape );
|
||||
void DrawFlashedShape( GERBER_DRAW_ITEM* aParent,
|
||||
EDA_Rect* aClipBox, wxDC* aDC, int aColor, int aAltColor,
|
||||
wxPoint aShapePos, bool aFilledShape );
|
||||
|
||||
/** function DrawFlashedPolygon
|
||||
* a helper function used id ::Draw to draw the polygon stored ion m_PolyCorners
|
||||
* Draw some Apertures shapes when they are defined as filled polygons.
|
||||
* APT_POLYGON is always a polygon, but some complex shapes are also converted to
|
||||
* polygons (shapes with holes, some rotated shapes)
|
||||
*/
|
||||
* @param aClipBox = DC clip box (NULL is no clip)
|
||||
* @param aDC = device context
|
||||
* @param aColor = the normal color to use
|
||||
* @param aFilled = true to draw in filled mode, false to draw in skecth mode
|
||||
* @param aPosition = the actual shape position
|
||||
*/
|
||||
void DrawFlashedPolygon( EDA_Rect* aClipBox, wxDC* aDC, int aColor,
|
||||
bool aFilled, const wxPoint& aPosition );
|
||||
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
G04 Verification of all aperture macros *
|
||||
G04 Handcoded by Stefan Petersen *
|
||||
%MOIN*%
|
||||
%FSLAX23Y23*%
|
||||
%OFA0.0000B0.0000*%
|
||||
G90*
|
||||
%AMCIRCLE*
|
||||
1,1,0.5,0,0*
|
||||
%
|
||||
%AMVECTOR*
|
||||
2,1,0.3,0,0,1,1,-15*
|
||||
%
|
||||
%AMLINE*
|
||||
21,1,0.3,0.05,0,0,-135*
|
||||
%
|
||||
%AMLINE2*
|
||||
22,1,0.8,0.5,0,0,-45*
|
||||
%
|
||||
%AMOUTLINE*
|
||||
4,1,3,0.0,0.0,0.0,0.5,0.5,0.5,0.5,0.0,-25*
|
||||
%
|
||||
%AMPOLYGON*
|
||||
5,1,5,0,0,0.5,25*
|
||||
%
|
||||
%AMMOIRE*
|
||||
6,0,0,1.0,0.1,0.4,2,0.01,1,20*
|
||||
%
|
||||
%AMTHERMAL*
|
||||
7,0,0,1.0,0.3,0.04,-13*
|
||||
%
|
||||
%ADD10C,0.0650*%
|
||||
%ADD11CIRCLE*%
|
||||
%ADD12VECTOR*%
|
||||
%ADD13LINE*%
|
||||
%ADD14LINE2*%
|
||||
%ADD15OUTLINE*%
|
||||
%ADD16POLYGON*%
|
||||
%ADD18MOIRE*%
|
||||
%ADD19THERMAL*%
|
||||
G04 Outline*
|
||||
X0Y0D02*
|
||||
G54D10*
|
||||
X0Y0D01*
|
||||
X10000D01*
|
||||
Y10000D01*
|
||||
X0D01*
|
||||
Y0D01*
|
||||
G04 Dots *
|
||||
X2000Y5000D03*
|
||||
X3000D03*
|
||||
X4000D03*
|
||||
X5000D03*
|
||||
X6000D03*
|
||||
X7000D03*
|
||||
X8000D03*
|
||||
X9000D03*
|
||||
Y6200X9000D03*
|
||||
G04 Draw circle*
|
||||
G54D11*
|
||||
X2000Y5000D03*
|
||||
G04 Draw line vector *
|
||||
G54D12*
|
||||
X3000D03*
|
||||
G04 Draw line center *
|
||||
G54D13*
|
||||
X4000D03*
|
||||
G04 Draw line lower left *
|
||||
G54D14*
|
||||
X5000D03*
|
||||
G04 Draw outline *
|
||||
G54D15*
|
||||
X6000D03*
|
||||
G04 Draw polygon 1 *
|
||||
G54D16*
|
||||
X7000D03*
|
||||
G04 Draw Moire *
|
||||
G54D18*
|
||||
X9000D03*
|
||||
G04 Draw Thermal *
|
||||
G54D19*
|
||||
Y6200X9000D03*
|
||||
M02*
|
|
@ -9,6 +9,8 @@
|
|||
#include <set>
|
||||
|
||||
#include "dcode.h"
|
||||
#include "class_gerber_draw_item.h"
|
||||
#include "class_aperture_macro.h"
|
||||
|
||||
class WinEDA_GerberFrame;
|
||||
class BOARD;
|
||||
|
|
|
@ -76,123 +76,68 @@ static wxPoint LastPosition;
|
|||
|
||||
|
||||
/**
|
||||
* Function fillCircularGBRITEM
|
||||
* initializes a given GBRITEM so that it can draw a circle which is not filled
|
||||
* and
|
||||
* has a given pen width (\a aPenWidth ).
|
||||
*
|
||||
* @param aGbrItem The GBRITEM to fill in.
|
||||
* @param Dcode_index The DCODE value, like D14
|
||||
* @param aLayer The layer index to set into the GBRITEM
|
||||
* @param aPos The center point of the flash
|
||||
* @param aDiameter The diameter of the round flash
|
||||
* @param aPenWidth The width of the pen used to draw the circle's
|
||||
* circumference.
|
||||
* @param isDark True if flash is positive and should use a drawing
|
||||
* color other than the background color, else use the background color
|
||||
* when drawing so that an erasure happens.
|
||||
*/
|
||||
static void fillCircularGBRITEM( GERBER_DRAW_ITEM* aGbrItem,
|
||||
int Dcode_index,
|
||||
int aLayer,
|
||||
const wxPoint& aPos,
|
||||
int aDiameter,
|
||||
int aPenWidth,
|
||||
bool isDark )
|
||||
{
|
||||
aGbrItem->m_Shape = GBR_CIRCLE;
|
||||
aGbrItem->m_Size.x = aGbrItem->m_Size.y = aPenWidth;
|
||||
|
||||
aGbrItem->SetLayer( aLayer );
|
||||
aGbrItem->m_DCode = Dcode_index;
|
||||
|
||||
// When drawing a GBRITEM with shape GBR_CIRCLE, the hypotenuse (i.e. distance)
|
||||
// between the Start and End points gives the radius of the circle.
|
||||
aGbrItem->m_Start = aGbrItem->m_End = aPos;
|
||||
aGbrItem->m_End.x += max( 0, (aDiameter + 1) / 2 );
|
||||
|
||||
NEGATE( aGbrItem->m_Start.y );
|
||||
NEGATE( aGbrItem->m_End.y );
|
||||
|
||||
if( !isDark )
|
||||
{
|
||||
aGbrItem->m_Flags |= DRAW_ERASED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function fillRoundFlashGBRITEM
|
||||
* Function fillFlashedGBRITEM
|
||||
* initializes a given GBRITEM so that it can draw a circle which is filled and
|
||||
* has no pen border.
|
||||
*
|
||||
* @param aGbrItem The GBRITEM to fill in.
|
||||
* @param aAperture the associated type of aperture
|
||||
* @param Dcode_index The DCODE value, like D14
|
||||
* @param aLayer The layer index to set into the GBRITEM
|
||||
* @param aPos The center point of the flash
|
||||
* @param aDiameter The diameter of the round flash
|
||||
* @param isDark True if flash is positive and should use a drawing
|
||||
* color other than the background color, else use the background color
|
||||
* when drawing so that an erasure happens.
|
||||
* @param aSize The diameter of the round flash
|
||||
* @param aLayerNegative = true if the current layer is negative
|
||||
* @param aImageNegative = true if the current image is negative
|
||||
*/
|
||||
static void fillRoundFlashGBRITEM( GERBER_DRAW_ITEM* aGbrItem,
|
||||
int Dcode_index,
|
||||
int aLayer,
|
||||
const wxPoint& aPos,
|
||||
int aDiameter,
|
||||
bool isDark )
|
||||
static void fillFlashedGBRITEM( GERBER_DRAW_ITEM* aGbrItem,
|
||||
APERTURE_T aAperture,
|
||||
int Dcode_index,
|
||||
int aLayer,
|
||||
const wxPoint& aPos,
|
||||
wxSize aSize,
|
||||
bool aLayerNegative,
|
||||
bool aImageNegative )
|
||||
{
|
||||
aGbrItem->SetLayer( aLayer );
|
||||
aGbrItem->m_Size.x = aGbrItem->m_Size.y = aDiameter;
|
||||
aGbrItem->m_Size = aSize;
|
||||
aGbrItem->m_Start = aPos;
|
||||
NEGATE( aGbrItem->m_Start.y );
|
||||
aGbrItem->m_End = aGbrItem->m_Start;
|
||||
aGbrItem->m_End = aGbrItem->m_Start;
|
||||
aGbrItem->m_DCode = Dcode_index;
|
||||
aGbrItem->m_Shape = GBR_SPOT_CIRCLE;
|
||||
aGbrItem->m_LayerNegative = aLayerNegative;
|
||||
aGbrItem->m_ImageNegative = aImageNegative;
|
||||
aGbrItem->m_Flashed = true;
|
||||
|
||||
if( !isDark )
|
||||
switch( aAperture )
|
||||
{
|
||||
aGbrItem->m_Flags |= DRAW_ERASED;
|
||||
case APT_POLYGON: // flashed regular polygon
|
||||
aGbrItem->m_Shape = GBR_SPOT_POLY;
|
||||
break;
|
||||
|
||||
case APT_LINE: // Should not be used.
|
||||
case APT_CIRCLE:
|
||||
aGbrItem->m_Shape = GBR_SPOT_CIRCLE;
|
||||
aGbrItem->m_Size.y = aGbrItem->m_Size.x;
|
||||
break;
|
||||
|
||||
case APT_OVAL:
|
||||
aGbrItem->m_Shape = GBR_SPOT_OVAL;
|
||||
break;
|
||||
|
||||
case APT_RECT:
|
||||
aGbrItem->m_Shape = GBR_SPOT_RECT;
|
||||
break;
|
||||
|
||||
case APT_MACRO:
|
||||
aGbrItem->m_Shape = GBR_SPOT_MACRO;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool isDark = !(aGbrItem->m_LayerNegative ^ aGbrItem->m_ImageNegative);
|
||||
|
||||
/**
|
||||
* Function fillOvalOrRectFlashGBRITEM
|
||||
* initializes a given GBRITEM so that it can draw an oval or rectangular
|
||||
* filled rectangle.
|
||||
*
|
||||
* @param aGbrItem The GERBER_DRAW_ITEM to fill in.
|
||||
* @param Dcode_index The DCODE value, like D14
|
||||
* @param aLayer The layer index to set into the GBRITEM
|
||||
* @param aPos The center point of the rectangle
|
||||
* @param aSize The size of the flash
|
||||
* @param aShape What type of flash, GBR_SPOT_OVALE or GBR_SPOT_RECT
|
||||
* @param isDark True if flash is positive and should use a drawing
|
||||
* color other than the background color, else use the background color
|
||||
* when drawing so that an erasure happens.
|
||||
*/
|
||||
static void fillOvalOrRectFlashGBRITEM( GERBER_DRAW_ITEM* aGbrItem,
|
||||
int Dcode_index,
|
||||
int aLayer,
|
||||
const wxPoint& aPos,
|
||||
const wxSize& aSize,
|
||||
int aShape,
|
||||
bool isDark )
|
||||
{
|
||||
aGbrItem->SetLayer( aLayer );
|
||||
aGbrItem->m_Flashed = true;
|
||||
|
||||
aGbrItem->m_Size = aSize;
|
||||
|
||||
aGbrItem->m_Start = aPos;
|
||||
NEGATE( aGbrItem->m_Start.y );
|
||||
aGbrItem->m_End = aGbrItem->m_Start;
|
||||
|
||||
aGbrItem->m_DCode = Dcode_index;
|
||||
aGbrItem->m_Shape = aShape;
|
||||
|
||||
/* isDark is true if flash is positive and should use a drawing
|
||||
* color other than the background color, else use the background color
|
||||
* when drawing so that an erasure happens.
|
||||
*/
|
||||
if( !isDark )
|
||||
{
|
||||
aGbrItem->m_Flags |= DRAW_ERASED;
|
||||
|
@ -209,9 +154,8 @@ static void fillOvalOrRectFlashGBRITEM( GERBER_DRAW_ITEM* aGbrItem,
|
|||
* @param aLayer The layer index to set into the GBRITEM
|
||||
* @param aPos The center point of the flash
|
||||
* @param aDiameter The diameter of the round flash
|
||||
* @param isDark True if flash is positive and should use a drawing
|
||||
* color other than the background color, else use the background color
|
||||
* when drawing so that an erasure happens.
|
||||
* @param aLayerNegative = true if the current layer is negative
|
||||
* @param aImageNegative = true if the current image is negative
|
||||
*/
|
||||
static void fillLineGBRITEM( GERBER_DRAW_ITEM* aGbrItem,
|
||||
int Dcode_index,
|
||||
|
@ -219,7 +163,8 @@ static void fillLineGBRITEM( GERBER_DRAW_ITEM* aGbrItem,
|
|||
const wxPoint& aStart,
|
||||
const wxPoint& aEnd,
|
||||
int aWidth,
|
||||
bool isDark )
|
||||
bool aLayerNegative,
|
||||
bool aImageNegative )
|
||||
{
|
||||
aGbrItem->SetLayer( aLayer );
|
||||
aGbrItem->m_Flashed = false;
|
||||
|
@ -233,7 +178,15 @@ static void fillLineGBRITEM( GERBER_DRAW_ITEM* aGbrItem,
|
|||
NEGATE( aGbrItem->m_End.y );
|
||||
|
||||
aGbrItem->m_DCode = Dcode_index;
|
||||
aGbrItem->m_LayerNegative = aLayerNegative;
|
||||
aGbrItem->m_ImageNegative = aImageNegative;
|
||||
|
||||
bool isDark = !(aGbrItem->m_LayerNegative ^ aGbrItem->m_ImageNegative);
|
||||
|
||||
/* isDark is true if flash is positive and should use a drawing
|
||||
* color other than the background color, else use the background color
|
||||
* when drawing so that an erasure happens.
|
||||
*/
|
||||
if( !isDark )
|
||||
{
|
||||
aGbrItem->m_Flags |= DRAW_ERASED;
|
||||
|
@ -267,20 +220,21 @@ static void fillLineGBRITEM( GERBER_DRAW_ITEM* aGbrItem,
|
|||
* same quadrant.
|
||||
* @param aDiameter The diameter of the round flash
|
||||
* @param aWidth is the pen width.
|
||||
* @param isDark True if flash is positive and should use a drawing
|
||||
* color other than the background color, else use the background color
|
||||
* when drawing so that an erasure happens.
|
||||
* @param aLayerNegative = true if the current layer is negative
|
||||
* @param aImageNegative = true if the current image is negative
|
||||
*/
|
||||
static void fillArcGBRITEM( GERBER_DRAW_ITEM* aGbrItem, int Dcode_index, int aLayer,
|
||||
const wxPoint& aStart, const wxPoint& aEnd,
|
||||
const wxPoint& rel_center, int aWidth,
|
||||
bool clockwise, bool multiquadrant, bool isDark )
|
||||
bool clockwise, bool multiquadrant,
|
||||
bool aLayerNegative,
|
||||
bool aImageNegative )
|
||||
{
|
||||
wxPoint center, delta;
|
||||
|
||||
aGbrItem->m_Shape = GBR_ARC;
|
||||
aGbrItem->SetLayer( aLayer );
|
||||
aGbrItem->m_Size.x = aGbrItem->m_Size.y = aWidth;
|
||||
aGbrItem->m_Size.x = aGbrItem->m_Size.y = aWidth;
|
||||
aGbrItem->m_Flashed = false;
|
||||
|
||||
if( multiquadrant )
|
||||
|
@ -347,6 +301,15 @@ static void fillArcGBRITEM( GERBER_DRAW_ITEM* aGbrItem, int Dcode_index, int aL
|
|||
NEGATE( aGbrItem->m_End.y );
|
||||
NEGATE( aGbrItem->m_ArcCentre.y );
|
||||
|
||||
aGbrItem->m_LayerNegative = aLayerNegative;
|
||||
aGbrItem->m_ImageNegative = aImageNegative;
|
||||
|
||||
bool isDark = !(aGbrItem->m_LayerNegative ^ aGbrItem->m_ImageNegative);
|
||||
|
||||
/* isDark is true if flash is positive and should use a drawing
|
||||
* color other than the background color, else use the background color
|
||||
* when drawing so that an erasure happens.
|
||||
*/
|
||||
if( !isDark )
|
||||
{
|
||||
aGbrItem->m_Flags |= DRAW_ERASED;
|
||||
|
@ -379,23 +342,38 @@ static void fillArcGBRITEM( GERBER_DRAW_ITEM* aGbrItem, int Dcode_index, int aL
|
|||
* same quadrant.
|
||||
* @param aDiameter The diameter of the round flash
|
||||
* @param aWidth is the pen width.
|
||||
* @param isDark True if flash is positive and should use a drawing
|
||||
* color other than the background color, else use the background color
|
||||
* when drawing so that an erasure happens.
|
||||
* @param aLayerNegative = true if the current layer is negative
|
||||
* @param aImageNegative = true if the current image is negative
|
||||
*/
|
||||
static void fillArcPOLY( BOARD* aPcb, GERBER_DRAW_ITEM* aGrbrItem,
|
||||
static void fillArcPOLY( BOARD* aPcb, GERBER_DRAW_ITEM* aGbrItem,
|
||||
const wxPoint& aStart, const wxPoint& aEnd,
|
||||
const wxPoint& rel_center,
|
||||
bool clockwise, bool multiquadrant, bool isDark )
|
||||
bool clockwise, bool multiquadrant,
|
||||
bool aLayerNegative,
|
||||
bool aImageNegative )
|
||||
{
|
||||
/* in order to calculate arc parameters, we use fillArcGBRITEM
|
||||
* so we muse create a dummy track and use its geometric parameters
|
||||
*/
|
||||
static GERBER_DRAW_ITEM dummyGbrItem( NULL );
|
||||
|
||||
aGbrItem->m_LayerNegative = aLayerNegative;
|
||||
aGbrItem->m_ImageNegative = aImageNegative;
|
||||
|
||||
bool isDark = !(aGbrItem->m_LayerNegative ^ aGbrItem->m_ImageNegative);
|
||||
|
||||
/* isDark is true if flash is positive and should use a drawing
|
||||
* color other than the background color, else use the background color
|
||||
* when drawing so that an erasure happens.
|
||||
*/
|
||||
if( !isDark )
|
||||
{
|
||||
aGbrItem->m_Flags |= DRAW_ERASED;
|
||||
}
|
||||
|
||||
fillArcGBRITEM( &dummyGbrItem, 0, 0,
|
||||
aStart, aEnd, rel_center, 0,
|
||||
clockwise, multiquadrant, isDark );
|
||||
clockwise, multiquadrant, aLayerNegative, aImageNegative );
|
||||
|
||||
// dummyTrack has right geometric parameters, and has its Y coordinates negated (to match the pcbnew Y axis).
|
||||
// Approximate arc by 36 segments per 360 degree
|
||||
|
@ -457,14 +435,10 @@ static void fillArcPOLY( BOARD* aPcb, GERBER_DRAW_ITEM* aGrbrItem,
|
|||
// D( printf( " >> Add arc %d rot %d, edge poly item %d,%d to %d,%d\n",
|
||||
// ii, rot, start_arc.x, start_arc.y,end_arc.x, end_arc.y ); )
|
||||
|
||||
if( aGrbrItem->m_PolyCorners.size() == 0 )
|
||||
aGrbrItem->m_PolyCorners.push_back( start_arc + center );
|
||||
aGrbrItem->m_PolyCorners.push_back( end_arc + center );
|
||||
if( aGbrItem->m_PolyCorners.size() == 0 )
|
||||
aGbrItem->m_PolyCorners.push_back( start_arc + center );
|
||||
aGbrItem->m_PolyCorners.push_back( end_arc + center );
|
||||
|
||||
if( !isDark )
|
||||
{
|
||||
aGrbrItem->m_Flags |= DRAW_ERASED;
|
||||
}
|
||||
start_arc = end_arc;
|
||||
}
|
||||
}
|
||||
|
@ -537,10 +511,11 @@ wxPoint GERBER::ReadXYCoord( char*& Text )
|
|||
if( fmt_scale < 0 || fmt_scale > 9 )
|
||||
fmt_scale = 4;
|
||||
double scale_list[10] =
|
||||
{ 10000.0, 1000.0, 100.0, 10.0,
|
||||
1,
|
||||
0.1, 0.01, 0.001, 0.0001, 0.00001
|
||||
};
|
||||
{
|
||||
10000.0, 1000.0, 100.0, 10.0,
|
||||
1,
|
||||
0.1, 0.01, 0.001, 0.0001,0.00001
|
||||
};
|
||||
real_scale = scale_list[fmt_scale];
|
||||
|
||||
if( m_GerbMetric )
|
||||
|
@ -631,48 +606,16 @@ wxPoint GERBER::ReadIJCoord( char*& Text )
|
|||
}
|
||||
current_coord = atoi( line );
|
||||
double real_scale = 1.0;
|
||||
if( fmt_scale < 0 || fmt_scale > 9 )
|
||||
fmt_scale = 4; // select scale 1.0
|
||||
|
||||
switch( fmt_scale )
|
||||
double scale_list[10] =
|
||||
{
|
||||
case 0:
|
||||
real_scale = 10000.0;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
real_scale = 1000.0;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
real_scale = 100.0;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
real_scale = 10.0;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
break;
|
||||
|
||||
case 5:
|
||||
real_scale = 0.1;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
real_scale = 0.01;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
real_scale = 0.001;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
real_scale = 0.0001;
|
||||
break;
|
||||
|
||||
case 9:
|
||||
real_scale = 0.00001;
|
||||
break;
|
||||
}
|
||||
10000.0, 1000.0, 100.0, 10.0,
|
||||
1,
|
||||
0.1, 0.01, 0.001, 0.0001,0.00001
|
||||
};
|
||||
real_scale = scale_list[fmt_scale];
|
||||
|
||||
if( m_GerbMetric )
|
||||
real_scale = real_scale / 25.4;
|
||||
|
@ -740,7 +683,7 @@ int GERBER::ReturnDCodeNumber( char*& Text )
|
|||
|
||||
bool GERBER::Execute_G_Command( char*& text, int G_commande )
|
||||
{
|
||||
D( printf( "%22s: G_CODE<%d>\n", __func__, G_commande ); )
|
||||
// D( printf( "%22s: G_CODE<%d>\n", __func__, G_commande ); )
|
||||
|
||||
switch( G_commande )
|
||||
{
|
||||
|
@ -844,7 +787,7 @@ bool GERBER::Execute_G_Command( char*& text, int G_commande )
|
|||
* Function scale
|
||||
* converts a distance given in floating point to our deci-mils
|
||||
*/
|
||||
static int scale( double aCoord, bool isMetric )
|
||||
int scale( double aCoord, bool isMetric )
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
@ -863,53 +806,15 @@ static int scale( double aCoord, bool isMetric )
|
|||
* deci-mils coordinate system.
|
||||
* @return wxPoint - The gerbview coordinate system vector.
|
||||
*/
|
||||
static wxPoint mapPt( double x, double y, bool isMetric )
|
||||
wxPoint mapPt( double x, double y, bool isMetric )
|
||||
{
|
||||
wxPoint ret( scale( x, isMetric ),
|
||||
scale( y, isMetric ) );
|
||||
wxPoint ret( scale( x, isMetric ), scale( y, isMetric ) );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function mapExposure
|
||||
* translates the first parameter from an aperture macro into a current
|
||||
* exposure
|
||||
* setting.
|
||||
* @param curExposure A dynamic setting which can change throughout the
|
||||
* reading of the gerber file, and it indicates whether the current tool
|
||||
* is lit or not.
|
||||
* @param isNegative A dynamic setting which can change throughout the reading
|
||||
* of
|
||||
* the gerber file, and it indicates whether the current D codes are to
|
||||
* be interpreted as erasures or not.
|
||||
*/
|
||||
static bool mapExposure( int param1, bool curExposure, bool isNegative )
|
||||
{
|
||||
bool exposure;
|
||||
|
||||
switch( param1 )
|
||||
{
|
||||
case 0:
|
||||
exposure = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
case 1:
|
||||
exposure = true;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
exposure = !curExposure;
|
||||
}
|
||||
|
||||
return exposure ^ isNegative;
|
||||
}
|
||||
|
||||
|
||||
bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame,
|
||||
char*& text, int D_commande )
|
||||
bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame, char*& text, int D_commande )
|
||||
{
|
||||
wxSize size( 15, 15 );
|
||||
|
||||
|
@ -923,7 +828,7 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame,
|
|||
D_CODE* tool = NULL;
|
||||
wxString msg;
|
||||
|
||||
D( printf( "%22s: D_CODE<%d>\n", __func__, D_commande ); )
|
||||
// D( printf( "%22s: D_CODE<%d>\n", __func__, D_commande ); )
|
||||
|
||||
if( D_commande >= FIRST_DCODE ) // This is a "Set tool" command
|
||||
{
|
||||
|
@ -957,7 +862,8 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame,
|
|||
pcb->m_Drawings.Append( gbritem );
|
||||
gbritem->m_Shape = GBR_POLYGON;
|
||||
gbritem->SetLayer( activeLayer );
|
||||
gbritem->m_Flashed = false;
|
||||
gbritem->m_Flashed = false;
|
||||
gbritem->m_UnitsMetric = m_GerbMetric;
|
||||
}
|
||||
|
||||
switch( m_Iterpolation )
|
||||
|
@ -965,21 +871,20 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame,
|
|||
case GERB_INTERPOL_ARC_NEG:
|
||||
case GERB_INTERPOL_ARC_POS:
|
||||
gbritem = (GERBER_DRAW_ITEM*)( pcb->m_Drawings.GetLast() );
|
||||
D( printf( "Add arc poly %d,%d to %d,%d fill %d interpol %d 360_enb %d\n",
|
||||
m_PreviousPos.x, m_PreviousPos.y, m_CurrentPos.x,
|
||||
m_CurrentPos.y, m_PolygonFillModeState, m_Iterpolation, m_360Arc_enbl ); )
|
||||
// D( printf( "Add arc poly %d,%d to %d,%d fill %d interpol %d 360_enb %d\n",
|
||||
// m_PreviousPos.x, m_PreviousPos.y, m_CurrentPos.x,
|
||||
// m_CurrentPos.y, m_PolygonFillModeState, m_Iterpolation, m_360Arc_enbl ); )
|
||||
fillArcPOLY( pcb, gbritem, m_PreviousPos,
|
||||
m_CurrentPos, m_IJPos,
|
||||
( m_Iterpolation == GERB_INTERPOL_ARC_NEG ) ?
|
||||
false : true, m_360Arc_enbl,
|
||||
!(m_LayerNegative ^ m_ImageNegative) );
|
||||
false : true, m_360Arc_enbl, m_LayerNegative, m_ImageNegative );
|
||||
break;
|
||||
|
||||
default:
|
||||
gbritem = (GERBER_DRAW_ITEM*)( pcb->m_Drawings.GetLast() );
|
||||
D( printf( "Add poly edge %d,%d to %d,%d fill %d\n",
|
||||
m_PreviousPos.x, m_PreviousPos.y,
|
||||
m_CurrentPos.x, m_CurrentPos.y, m_Iterpolation ); )
|
||||
// D( printf( "Add poly edge %d,%d to %d,%d fill %d\n",
|
||||
// m_PreviousPos.x, m_PreviousPos.y,
|
||||
// m_CurrentPos.x, m_CurrentPos.y, m_Iterpolation ); )
|
||||
|
||||
gbritem->m_Start = m_PreviousPos; // m_Start is used as temporary storage
|
||||
NEGATE( gbritem->m_Start.y );
|
||||
|
@ -995,7 +900,6 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame,
|
|||
{
|
||||
if( m_LayerNegative ^ m_ImageNegative )
|
||||
gbritem->m_Flags |= DRAW_ERASED;
|
||||
D( printf( "\nm_Flags=0x%08X\n", gbritem->m_Flags ); )
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1033,11 +937,11 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame,
|
|||
{
|
||||
case GERB_INTERPOL_LINEAR_1X:
|
||||
gbritem = new GERBER_DRAW_ITEM( pcb );
|
||||
gbritem->m_UnitsMetric = m_GerbMetric;
|
||||
pcb->m_Drawings.Append( gbritem );
|
||||
D( printf( "R:%p\n", gbritem ); )
|
||||
// D( printf( "R:%p\n", gbritem ); )
|
||||
fillLineGBRITEM( gbritem, dcode, activeLayer, m_PreviousPos,
|
||||
m_CurrentPos, size.x,
|
||||
!(m_LayerNegative ^ m_ImageNegative) );
|
||||
m_CurrentPos, size.x, m_LayerNegative, m_ImageNegative );
|
||||
break;
|
||||
|
||||
case GERB_INTERPOL_LINEAR_01X:
|
||||
|
@ -1049,13 +953,14 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame,
|
|||
case GERB_INTERPOL_ARC_NEG:
|
||||
case GERB_INTERPOL_ARC_POS:
|
||||
gbritem = new GERBER_DRAW_ITEM( pcb );
|
||||
gbritem->m_UnitsMetric = m_GerbMetric;
|
||||
pcb->m_Drawings.Append( gbritem );
|
||||
D( printf( "R:%p\n", gbritem ); )
|
||||
// D( printf( "R:%p\n", gbritem ); )
|
||||
fillArcGBRITEM( gbritem, dcode, activeLayer, m_PreviousPos,
|
||||
m_CurrentPos, m_IJPos, size.x,
|
||||
( m_Iterpolation == GERB_INTERPOL_ARC_NEG ) ?
|
||||
false : true, m_360Arc_enbl,
|
||||
!(m_LayerNegative ^ m_ImageNegative) );
|
||||
m_LayerNegative, m_ImageNegative );
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1082,277 +987,13 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame,
|
|||
aperture = tool->m_Shape;
|
||||
}
|
||||
|
||||
switch( aperture )
|
||||
{
|
||||
case APT_POLYGON: // flashed regular polygon
|
||||
case APT_CIRCLE:
|
||||
gbritem = new GERBER_DRAW_ITEM( pcb );
|
||||
pcb->m_Drawings.Append( gbritem );
|
||||
D( printf( "R:%p\n", gbritem ); )
|
||||
fillRoundFlashGBRITEM( gbritem, dcode, activeLayer,
|
||||
m_CurrentPos, size.x,
|
||||
!(m_LayerNegative ^ m_ImageNegative) );
|
||||
if( aperture == APT_POLYGON )
|
||||
gbritem->m_Shape = GBR_SPOT_POLY;
|
||||
break;
|
||||
|
||||
case APT_OVAL:
|
||||
case APT_RECT:
|
||||
gbritem = new GERBER_DRAW_ITEM( pcb );
|
||||
pcb->m_Drawings.Append( gbritem );
|
||||
D( printf( "R:%p\n", gbritem ); )
|
||||
fillOvalOrRectFlashGBRITEM( gbritem, dcode, activeLayer,
|
||||
m_CurrentPos, size,
|
||||
( aperture == APT_RECT ) ?
|
||||
GBR_SPOT_RECT : GBR_SPOT_OVAL,
|
||||
!(m_LayerNegative ^ m_ImageNegative) );
|
||||
break;
|
||||
|
||||
case APT_MACRO:
|
||||
{
|
||||
APERTURE_MACRO* macro = tool->GetMacro();
|
||||
wxASSERT( macro );
|
||||
|
||||
// split the macro primitives up into multiple normal GBRITEM
|
||||
// elements
|
||||
for( AM_PRIMITIVES::iterator p = macro->primitives.begin();
|
||||
p!=macro->primitives.end();
|
||||
++p )
|
||||
{
|
||||
bool exposure;
|
||||
wxPoint curPos = m_CurrentPos;
|
||||
|
||||
switch( p->primitive_id )
|
||||
{
|
||||
case AMP_CIRCLE:
|
||||
{
|
||||
exposure = mapExposure( p->GetExposure(), m_Exposure,
|
||||
m_ImageNegative );
|
||||
curPos += mapPt( p->params[2].GetValue( tool ),
|
||||
p->params[3].GetValue( tool ),
|
||||
m_GerbMetric );
|
||||
int diameter = scale( p->params[1].GetValue( tool ),
|
||||
m_GerbMetric );
|
||||
|
||||
gbritem = new GERBER_DRAW_ITEM( pcb );
|
||||
pcb->m_Drawings.Append( gbritem );
|
||||
D( printf( "R:%p\n", gbritem ); )
|
||||
fillRoundFlashGBRITEM( gbritem, dcode, activeLayer,
|
||||
curPos, diameter, exposure );
|
||||
}
|
||||
break;
|
||||
|
||||
case AMP_LINE2:
|
||||
case AMP_LINE20:
|
||||
{
|
||||
exposure = mapExposure(
|
||||
p->GetExposure(), m_Exposure, m_ImageNegative );
|
||||
int width = scale( p->params[1].GetValue( tool ),
|
||||
m_GerbMetric );
|
||||
wxPoint start = mapPt( p->params[2].GetValue( tool ),
|
||||
p->params[3].GetValue( tool ),
|
||||
m_GerbMetric );
|
||||
wxPoint end = mapPt( p->params[4].GetValue( tool ),
|
||||
p->params[5].GetValue( tool ),
|
||||
m_GerbMetric );
|
||||
|
||||
if( start.x == end.x )
|
||||
{
|
||||
size.x = width;
|
||||
size.y = ABS( end.y - start.y ) + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
size.x = ABS( end.x - start.x ) + 1;
|
||||
size.y = width;
|
||||
}
|
||||
|
||||
wxPoint midPoint( ( start.x + end.x ) / 2,
|
||||
( start.y + end.y ) / 2 );
|
||||
curPos += midPoint;
|
||||
gbritem = new GERBER_DRAW_ITEM( pcb );
|
||||
pcb->m_Drawings.Append( gbritem );
|
||||
D( printf( "R:%p\n", gbritem ); )
|
||||
fillOvalOrRectFlashGBRITEM( gbritem, dcode, activeLayer,
|
||||
curPos, size, GBR_SPOT_RECT,
|
||||
exposure );
|
||||
}
|
||||
break;
|
||||
|
||||
case AMP_LINE_CENTER:
|
||||
{
|
||||
exposure = mapExposure( p->GetExposure(), m_Exposure,
|
||||
m_ImageNegative );
|
||||
wxPoint msize = mapPt( p->params[1].GetValue( tool ),
|
||||
p->params[2].GetValue( tool ),
|
||||
m_GerbMetric );
|
||||
size.x = msize.x;
|
||||
size.y = msize.y;
|
||||
curPos += mapPt( p->params[3].GetValue( tool ),
|
||||
p->params[4].GetValue( tool ),
|
||||
m_GerbMetric );
|
||||
gbritem = new GERBER_DRAW_ITEM( pcb );
|
||||
pcb->m_Drawings.Append( gbritem );
|
||||
D( printf( "R:%p\n", gbritem ); )
|
||||
fillOvalOrRectFlashGBRITEM( gbritem, dcode, activeLayer,
|
||||
curPos, size, GBR_SPOT_RECT,
|
||||
exposure );
|
||||
}
|
||||
break;
|
||||
|
||||
case AMP_LINE_LOWER_LEFT:
|
||||
{
|
||||
exposure = mapExposure(
|
||||
p->GetExposure(), m_Exposure, m_ImageNegative );
|
||||
wxPoint msize = mapPt( p->params[1].GetValue( tool ),
|
||||
p->params[2].GetValue( tool ),
|
||||
m_GerbMetric );
|
||||
size.x = msize.x;
|
||||
size.y = msize.y;
|
||||
wxPoint lowerLeft = mapPt( p->params[3].GetValue( tool ),
|
||||
p->params[4].GetValue( tool ),
|
||||
m_GerbMetric );
|
||||
curPos += lowerLeft;
|
||||
|
||||
// need the middle, so adjust from the lower left
|
||||
curPos.y += size.y / 2;
|
||||
curPos.x += size.x / 2;
|
||||
gbritem = new GERBER_DRAW_ITEM( pcb );
|
||||
pcb->m_Drawings.Append( gbritem );
|
||||
D( printf( "R:%p\n", gbritem ); )
|
||||
fillOvalOrRectFlashGBRITEM( gbritem, dcode, activeLayer,
|
||||
curPos, size, GBR_SPOT_RECT,
|
||||
exposure );
|
||||
}
|
||||
break;
|
||||
|
||||
case AMP_THERMAL:
|
||||
{
|
||||
int outerDiam = scale( p->params[2].GetValue( tool ),
|
||||
m_GerbMetric );
|
||||
int innerDiam = scale( p->params[3].GetValue( tool ),
|
||||
m_GerbMetric );
|
||||
|
||||
curPos += mapPt( p->params[0].GetValue( tool ),
|
||||
p->params[1].GetValue( tool ),
|
||||
m_GerbMetric );
|
||||
|
||||
gbritem = new GERBER_DRAW_ITEM( pcb );
|
||||
pcb->m_Drawings.Append( gbritem );
|
||||
D( printf( "R:%p\n", gbritem ); )
|
||||
fillRoundFlashGBRITEM( gbritem, dcode, activeLayer,
|
||||
curPos, outerDiam,
|
||||
!( m_LayerNegative ^ m_ImageNegative ) );
|
||||
|
||||
gbritem = new GERBER_DRAW_ITEM( pcb );
|
||||
pcb->m_Drawings.Append( gbritem );
|
||||
D( printf( "R:%p\n", gbritem ); )
|
||||
fillRoundFlashGBRITEM( gbritem, dcode, activeLayer, curPos,
|
||||
innerDiam,
|
||||
( m_LayerNegative ^ m_ImageNegative ) );
|
||||
|
||||
// @todo: draw the cross hairs, see page 23 of rs274
|
||||
// spec. this might be done with two lines, thickness
|
||||
// from params[4], and drawing
|
||||
// darkness "(m_LayerNegative ^ m_ImageNegative)"
|
||||
}
|
||||
break;
|
||||
|
||||
case AMP_MOIRE:
|
||||
{
|
||||
curPos += mapPt( p->params[0].GetValue( tool ),
|
||||
p->params[1].GetValue( tool ),
|
||||
m_GerbMetric );
|
||||
|
||||
// e.g.: "6,0,0,0.125,.01,0.01,3,0.003,0.150,0"
|
||||
int outerDiam = scale( p->params[2].GetValue( tool ),
|
||||
m_GerbMetric );
|
||||
int penThickness = scale( p->params[3].GetValue( tool ),
|
||||
m_GerbMetric );
|
||||
int gap = scale( p->params[4].GetValue( tool ),
|
||||
m_GerbMetric );
|
||||
int numCircles = (int) p->params[5].GetValue( tool );
|
||||
int crossHairThickness =
|
||||
scale( p->params[6].GetValue( tool ), m_GerbMetric );
|
||||
int crossHairLength =
|
||||
scale( p->params[7].GetValue( tool ), m_GerbMetric );
|
||||
|
||||
// ignore rotation, not supported
|
||||
// adjust outerDiam by this on each nested circle
|
||||
int diamAdjust = 2 * (gap + penThickness);
|
||||
for( int i = 0; i < numCircles; ++i, outerDiam -= diamAdjust )
|
||||
{
|
||||
gbritem = new GERBER_DRAW_ITEM( pcb );
|
||||
pcb->m_Drawings.Append( gbritem );
|
||||
D( printf( "R:%p\n", gbritem ); )
|
||||
fillCircularGBRITEM( gbritem, dcode, activeLayer,
|
||||
curPos, outerDiam,
|
||||
penThickness,
|
||||
!( m_LayerNegative ^ m_ImageNegative ) );
|
||||
}
|
||||
|
||||
gbritem = new GERBER_DRAW_ITEM( pcb );
|
||||
pcb->m_Drawings.Append( gbritem );
|
||||
D( printf( "R:%p\n", gbritem ); )
|
||||
fillOvalOrRectFlashGBRITEM( gbritem, dcode, activeLayer,
|
||||
curPos,
|
||||
wxSize( crossHairThickness,
|
||||
crossHairLength ),
|
||||
GBR_SPOT_RECT,
|
||||
!( m_LayerNegative ^ m_ImageNegative ) );
|
||||
|
||||
gbritem = new GERBER_DRAW_ITEM( pcb );
|
||||
pcb->m_Drawings.Append( gbritem );
|
||||
D( printf( "R:%p\n", gbritem ); )
|
||||
|
||||
// swap x and y in wxSize() for this one
|
||||
fillOvalOrRectFlashGBRITEM( gbritem, dcode, activeLayer,
|
||||
curPos,
|
||||
wxSize( crossHairLength,
|
||||
crossHairThickness ),
|
||||
GBR_SPOT_RECT,
|
||||
!( m_LayerNegative ^ m_ImageNegative ) );
|
||||
}
|
||||
break;
|
||||
|
||||
case AMP_OUTLINE:
|
||||
#if defined(DEBUG)
|
||||
{
|
||||
int numPoints = (int) p->params[1].GetValue( tool );
|
||||
|
||||
printf( "AMP_OUTLINE:\n" );
|
||||
printf( " exposure: %g\n", p->params[0].GetValue( tool ) );
|
||||
printf( " # points: %d\n", numPoints );
|
||||
|
||||
// numPoints does not include the starting point, so add 1.
|
||||
for( int i = 0; i<numPoints + 1; ++i )
|
||||
{
|
||||
printf( " [%d]: X=%g Y=%g\n", i,
|
||||
p->params[i * 2 + 2 + 0].GetValue( tool ),
|
||||
p->params[i * 2 + 2 + 1].GetValue( tool )
|
||||
);
|
||||
}
|
||||
|
||||
printf( " rotation: %g\n", p->params[numPoints * 2 + 4].GetValue( tool ) );
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
case AMP_POLYGON:
|
||||
case AMP_EOF:
|
||||
default:
|
||||
|
||||
// not yet supported, waiting for you.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
gbritem = new GERBER_DRAW_ITEM( pcb );
|
||||
gbritem->m_UnitsMetric = m_GerbMetric;
|
||||
pcb->m_Drawings.Append( gbritem );
|
||||
// D( printf( "R:%p dcode %d layer %d\n", gbritem, dcode, activeLayer ); )
|
||||
fillFlashedGBRITEM( gbritem, aperture,
|
||||
dcode, activeLayer, m_CurrentPos,
|
||||
size, m_LayerNegative, m_ImageNegative );
|
||||
m_PreviousPos = m_CurrentPos;
|
||||
break;
|
||||
|
||||
|
|
|
@ -173,8 +173,7 @@ bool GERBER::ExecuteRS274XCommand( int command,
|
|||
double conv_scale = m_GerbMetric ? PCB_INTERNAL_UNIT /
|
||||
25.4 : PCB_INTERNAL_UNIT;
|
||||
|
||||
D( printf( "%22s: Command <%c%c>\n", __func__, (command >> 8) & 0xFF,
|
||||
command & 0xFF ); )
|
||||
// D( printf( "%22s: Command <%c%c>\n", __func__, (command >> 8) & 0xFF, command & 0xFF ); )
|
||||
|
||||
switch( command )
|
||||
{
|
||||
|
@ -663,7 +662,7 @@ bool GERBER::ReadApertureMacro( char buff[GERBER_BUFZ],
|
|||
break;
|
||||
|
||||
case AMP_POLYGON:
|
||||
paramCount = 4;
|
||||
paramCount = 6;
|
||||
break;
|
||||
|
||||
case AMP_MOIRE:
|
||||
|
@ -703,7 +702,8 @@ bool GERBER::ReadApertureMacro( char buff[GERBER_BUFZ],
|
|||
|
||||
if( i < paramCount ) // maybe some day we can throw an exception and
|
||||
// track a line number
|
||||
printf( "i=%d, insufficient parameters\n", i );
|
||||
printf( "read macro descr type %d: read %d parameters, insufficient parameters\n",
|
||||
prim.primitive_id, i );
|
||||
|
||||
// there are more parameters to read if this is an AMP_OUTLINE
|
||||
if( prim.primitive_id == AMP_OUTLINE )
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
/* Bits characterizing cell */
|
||||
#define HOLE (char)0x01 /* a conducting hole or obstacle */
|
||||
#define CELL_is_MODULE (char)0x02 /* auto placement occupied by a module */
|
||||
#define CELL_is_EDGE (char)0x20 /* Area and auto-placement: limiting cell
|
||||
#define HOLE 0x01 /* a conducting hole or obstacle */
|
||||
#define CELL_is_MODULE 0x02 /* auto placement occupied by a module */
|
||||
#define CELL_is_EDGE 0x20 /* Area and auto-placement: limiting cell
|
||||
* contour (Board, Zone) */
|
||||
#define CELL_is_FRIEND (char)0x40 /* Area and auto-placement: cell part of the
|
||||
#define CELL_is_FRIEND 0x40 /* Area and auto-placement: cell part of the
|
||||
* net */
|
||||
#define CELL_is_ZONE (char)0x80 /* Area and auto-placement: cell available */
|
||||
#define CELL_is_ZONE 0x80 /* Area and auto-placement: cell available */
|
||||
|
||||
/* Bit masks for presence of obstacles to autorouting */
|
||||
#define OCCUPE 1 /* Autorouting: obstacle tracks and vias. */
|
||||
|
|
|
@ -65,7 +65,7 @@ void WinEDA_BasePcbFrame::Plot_Serigraphie( PLOTTER* plotter,
|
|||
Plot_Edges_Modules( plotter, m_Pcb, masque_layer, trace_mode );
|
||||
|
||||
/* Plot pads (creates pads outlines, for pads on silkscreen layers) */
|
||||
bool layersmask_plotpads = masque_layer;
|
||||
int layersmask_plotpads = masque_layer;
|
||||
// Calculate the mask layers of allowed layers for pads
|
||||
if( !g_pcb_plot_options.PlotPadsOnSilkLayer )
|
||||
layersmask_plotpads &= ~(SILKSCREEN_LAYER_BACK || SILKSCREEN_LAYER_FRONT);
|
||||
|
|
Loading…
Reference in New Issue