Loading CHANGELOG.txt +1 −2 Original line number Diff line number Diff line Loading @@ -12,12 +12,11 @@ email address. graphics items are now specific to gerbview (added a GERBER_DRAW_ITEM class) and do not use tracks from pcbnew. The way used to draw them is also new. Apertures are now correctly drawn for round, oval and rectangular shapes Apertures are now correctly drawn for round, oval, rectangular and regular polygon shapes (with or without holes) Aperture definition type Polygon is not yet handle. Polygons are correctly drawn. TODO: Draw functions for aperture definition type Polygon. Draw functions for aperture macros. Work in progress. Loading gerbview/class_gerber_draw_item.cpp +5 −1 Original line number Diff line number Diff line Loading @@ -106,10 +106,13 @@ wxString GERBER_DRAW_ITEM::ShowGBRShape() case GBR_SPOT_RECT: return wxT( "spot_rect" ); case GBR_SPOT_POLY: return wxT( "spot_poly" ); case GBR_POLYGON: return wxT( "polygon" ); case GBR_MACRO: case GBR_SPOT_MACRO: return wxT( "apt_macro" ); // TODO: add aperture macro name default: Loading Loading @@ -276,6 +279,7 @@ void GERBER_DRAW_ITEM::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode, case GBR_SPOT_CIRCLE: case GBR_SPOT_RECT: case GBR_SPOT_OVAL: case GBR_SPOT_POLY: isFilled = DisplayOpt.DisplayPadFill ? true : false; d_codeDescr->DrawFlashedShape( &panel->m_ClipBox, DC, color, m_Start, isFilled ); Loading gerbview/class_gerber_draw_item.h +2 −1 Original line number Diff line number Diff line Loading @@ -40,7 +40,8 @@ enum Gbr_Basic_Shapes { GBR_SPOT_CIRCLE, // flashed shape: round shape (can have hole) GBR_SPOT_RECT, // flashed shape: rectangular shape can have hole) GBR_SPOT_OVAL, // flashed shape: oval shape GBR_MACRO, // complex shape described by a macro GBR_SPOT_POLY, // flashed shape: regulat polygon, 3 to 12 edges GBR_SPOT_MACRO, // complex shape described by a macro GBR_LAST // last value for this list }; Loading gerbview/dcode.cpp +113 −102 Original line number Diff line number Diff line Loading @@ -56,11 +56,12 @@ void D_CODE::Clear_D_CODE_Data() m_Size.y = DEFAULT_SIZE; m_Shape = APT_CIRCLE; m_Drill.x = m_Drill.y = 0; m_DrillShape = 0; m_DrillShape = APT_DEF_NO_HOLE; m_InUse = FALSE; m_Defined = FALSE; m_Macro = 0; m_Macro = NULL; m_Rotation = 0.0; m_EdgesCount = 0; } Loading Loading @@ -252,17 +253,29 @@ void WinEDA_GerberFrame::CopyDCodesSizeToItems() { case APT_LINE: // might not appears here, but some broken // gerber files use it case APT_CIRCLE: /* spot round (for GERBER) */ case APT_CIRCLE: /* spot round */ gerb_item->m_Shape = GBR_SPOT_CIRCLE; break; case APT_OVAL: /* spot oval (for GERBER)*/ case APT_OVAL: /* spot oval*/ gerb_item->m_Shape = GBR_SPOT_OVAL; break; default: /* spot rect (for GERBER)*/ case APT_RECT: /* spot rect*/ gerb_item->m_Shape = GBR_SPOT_RECT; break; case APT_POLYGON: /* spot regular polyg 3 to 1 edges */ gerb_item->m_Shape = GBR_SPOT_POLY; break; case APT_MACRO: /* spot defined by a macro */ gerb_item->m_Shape = GBR_SPOT_MACRO; break; default: wxMessageBox( wxT("WinEDA_GerberFrame::CopyDCodesSizeToItems() error" ) ); break; } } } Loading @@ -280,14 +293,16 @@ void D_CODE::DrawFlashedShape( EDA_Rect* aClipBox, wxDC* aDC, int aColor, switch( m_Shape ) { case APT_MACRO: // TODO: current a round shape case APT_CIRCLE: radius = m_Size.x >> 1; if( !aFilledShape ) GRCircle( aClipBox, aDC, aShapePos.x, aShapePos.y, radius, aColor ); else if( m_DrillShape == 0 ) if( m_DrillShape == APT_DEF_NO_HOLE ) GRFilledCircle( aClipBox, aDC, aShapePos, radius, aColor ); else if( m_DrillShape == 1 ) // round hole else if( APT_DEF_ROUND_HOLE == 1 ) // round hole in shape { int width = (m_Size.x - m_Drill.x ) / 2; GRCircle( aClipBox, aDC, aShapePos, radius - (width / 2), width, aColor ); Loading @@ -301,6 +316,7 @@ void D_CODE::DrawFlashedShape( EDA_Rect* aClipBox, wxDC* aDC, int aColor, break; case APT_LINE: // not used for flashed items break; Loading @@ -315,7 +331,7 @@ void D_CODE::DrawFlashedShape( EDA_Rect* aClipBox, wxDC* aDC, int aColor, GRRect( aClipBox, aDC, start.x, start.y, end.x, end.y, 0, aColor ); } else if( m_DrillShape == 0 ) else if( m_DrillShape == APT_DEF_NO_HOLE ) { GRFilledRect( aClipBox, aDC, start.x, start.y, end.x, end.y, 0, aColor, aColor ); Loading Loading @@ -352,7 +368,7 @@ void D_CODE::DrawFlashedShape( EDA_Rect* aClipBox, wxDC* aDC, int aColor, GRCSegm( aClipBox, aDC, start.x, start.y, end.x, end.y, radius, aColor ); } else if( m_DrillShape == 0 ) else if( m_DrillShape == APT_DEF_NO_HOLE ) { GRFillCSegm( aClipBox, aDC, start.x, start.y, end.x, end.y, radius, aColor ); Loading @@ -371,10 +387,6 @@ void D_CODE::DrawFlashedShape( EDA_Rect* aClipBox, wxDC* aDC, int aColor, ConvertShapeToPolygon(); DrawFlashedPolygon( aClipBox, aDC, aColor, aFilledShape, aShapePos ); break; case APT_MACRO: // TODO break; } } Loading Loading @@ -403,6 +415,15 @@ void D_CODE::DrawFlashedPolygon( EDA_Rect* aClipBox, wxDC* aDC, } #define SEGS_CNT 32 // number of segments to approximate a circle // A helper function for D_CODE::ConvertShapeToPolygon(). // Add a hole to a polygon static void addHoleToPolygon( std::vector<wxPoint>& aBuffer, APERTURE_DEF_HOLETYPE aHoleShape, wxSize aSize, wxPoint aAnchorPos ); /** function ConvertShapeToPolygon * convert a shape to an equivalent polygon. * Arcs and circles are approximated by segments Loading @@ -411,7 +432,6 @@ void D_CODE::DrawFlashedPolygon( EDA_Rect* aClipBox, wxDC* aDC, */ void D_CODE::ConvertShapeToPolygon() { #define SEGS_CNT 32 // number of segments to approximate a circle wxPoint initialpos; wxPoint currpos;; m_PolyCorners.clear(); Loading @@ -427,35 +447,12 @@ void D_CODE::ConvertShapeToPolygon() RotatePoint( &currpos, ii * 3600 / SEGS_CNT ); m_PolyCorners.push_back( currpos ); } if( m_DrillShape == 1 ) { for( unsigned ii = 0 ; ii <= SEGS_CNT; ii++ ) { currpos.x = m_Drill.x / 2; currpos.y = 0; RotatePoint( &currpos, ii * 3600 / SEGS_CNT ); m_PolyCorners.push_back( currpos ); } m_PolyCorners.push_back( initialpos ); // link to outline } if( m_DrillShape == 2 ) // Create rectangular hole { currpos.x = m_Drill.x / 2; currpos.y = m_Drill.y / 2; m_PolyCorners.push_back( currpos ); // link to hole and begin hole currpos.x -= m_Drill.x; m_PolyCorners.push_back( currpos ); currpos.y -= m_Drill.y; m_PolyCorners.push_back( currpos ); currpos.x += m_Drill.x; m_PolyCorners.push_back( currpos ); currpos.y += m_Drill.y; m_PolyCorners.push_back( currpos ); // close hole m_PolyCorners.push_back( initialpos ); // link to outline } addHoleToPolygon( m_PolyCorners, m_DrillShape, m_Drill, initialpos ); break; case APT_LINE: // Not used for flashed shapes break; Loading @@ -472,32 +469,8 @@ void D_CODE::ConvertShapeToPolygon() m_PolyCorners.push_back( currpos ); currpos.y += m_Size.y; m_PolyCorners.push_back( currpos ); // close polygon if( m_DrillShape == 1 ) // build a round hole { for( int ii = 0 ; ii <= SEGS_CNT; ii++ ) { currpos.x = 0; currpos.y = m_Drill.x / 2; // m_Drill.x / 2 is the radius of the hole RotatePoint( &currpos, ii * 3600 / SEGS_CNT ); m_PolyCorners.push_back( currpos ); } m_PolyCorners.push_back( initialpos ); // link to outline } if( m_DrillShape == 2 ) // Create rectangular hole { currpos.x = m_Drill.x / 2; currpos.y = m_Drill.y / 2; m_PolyCorners.push_back( currpos ); // link to hole and begin hole currpos.x -= m_Drill.x; m_PolyCorners.push_back( currpos ); currpos.y -= m_Drill.y; m_PolyCorners.push_back( currpos ); currpos.x += m_Drill.x; m_PolyCorners.push_back( currpos ); currpos.y += m_Drill.y; m_PolyCorners.push_back( currpos ); // close hole m_PolyCorners.push_back( initialpos ); // link to outline } addHoleToPolygon( m_PolyCorners, m_DrillShape, m_Drill, initialpos ); break; case APT_OVAL: Loading Loading @@ -537,47 +510,85 @@ void D_CODE::ConvertShapeToPolygon() currpos.x -= delta; m_PolyCorners.push_back( currpos ); } m_PolyCorners.push_back( initialpos ); // close outline if( m_Size.y > m_Size.x ) // vertical oval, rotate polygon. { for( unsigned jj = 0; jj < m_PolyCorners.size(); jj++ ) RotatePoint( &m_PolyCorners[jj], 900 ); } if( m_DrillShape == 1 ) // build a round hole { for( ii = 0 ; ii <= SEGS_CNT; ii++ ) addHoleToPolygon( m_PolyCorners, m_DrillShape, m_Drill, initialpos ); } break; 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; if( m_EdgesCount > 12 ) m_EdgesCount = 12; for( int ii = 0; ii <= m_EdgesCount; ii++ ) { currpos.x = 0; currpos.y = m_Drill.x / 2; // m_Drill.x / 2 is the radius of the hole RotatePoint( &currpos, ii * 3600 / SEGS_CNT ); currpos = initialpos; RotatePoint( &currpos, ii * 3600 / m_EdgesCount ); m_PolyCorners.push_back( currpos ); } m_PolyCorners.push_back( initialpos ); // link to outline } if( m_DrillShape == 2 ) // Create rectangular hole addHoleToPolygon( m_PolyCorners, m_DrillShape, m_Drill, initialpos ); if( m_Rotation ) // vertical oval, rotate polygon. { currpos.x = m_Drill.x / 2; currpos.y = m_Drill.y / 2; m_PolyCorners.push_back( currpos ); // link to hole and begin hole currpos.x -= m_Drill.x; m_PolyCorners.push_back( currpos ); currpos.y -= m_Drill.y; m_PolyCorners.push_back( currpos ); currpos.x += m_Drill.x; m_PolyCorners.push_back( currpos ); currpos.y += m_Drill.y; m_PolyCorners.push_back( currpos ); // close hole m_PolyCorners.push_back( initialpos ); // link to outline 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); } } break; case APT_POLYGON: // TODO break; case APT_MACRO: // TODO break; } } // The helper function for D_CODE::ConvertShapeToPolygon(). // Add a hole to a polygon static void addHoleToPolygon( std::vector<wxPoint>& aBuffer, APERTURE_DEF_HOLETYPE aHoleShape, wxSize aSize, wxPoint aAnchorPos ) { wxPoint currpos; if( aHoleShape == APT_DEF_ROUND_HOLE ) // build a round hole { for( int ii = 0; ii <= SEGS_CNT; ii++ ) { currpos.x = 0; currpos.y = aSize.x / 2; // aSize.x / 2 is the radius of the hole RotatePoint( &currpos, ii * 3600 / SEGS_CNT ); aBuffer.push_back( currpos ); } aBuffer.push_back( aAnchorPos ); // link to outline } if( aHoleShape == APT_DEF_RECT_HOLE ) // Create rectangular hole { currpos.x = aSize.x / 2; currpos.y = aSize.y / 2; aBuffer.push_back( currpos ); // link to hole and begin hole currpos.x -= aSize.x; aBuffer.push_back( currpos ); currpos.y -= aSize.y; aBuffer.push_back( currpos ); 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 } } gerbview/dcode.h +65 −48 Original line number Diff line number Diff line Loading @@ -16,8 +16,7 @@ * is the set of all gerber aperture types allowed, according to page 16 of * http://gerbv.sourceforge.net/docs/rs274xrevd_e.pdf */ enum APERTURE_T { enum APERTURE_T { APT_CIRCLE = 'C', APT_LINE = 'L', APT_RECT = 'R', Loading @@ -26,9 +25,20 @@ enum APERTURE_T APT_MACRO = 'M' }; // In aperture definition, round, oval and rectangular flashed shapes // can have a hole (ropund or rectangular) // this option is stored in .m_DrillShape D_CODE member enum APERTURE_DEF_HOLETYPE { APT_DEF_NO_HOLE = 0, APT_DEF_ROUND_HOLE, APT_DEF_RECT_HOLE }; /* define min and max values for D Codes values. * note: values >= 0 and > FIRST_DCODE can be used for specila purposes */ #define FIRST_DCODE 10 #define LAST_DCODE 999 // dcodes values are from 10 to 999 #define LAST_DCODE 999 #define TOOLS_MAX_COUNT (LAST_DCODE + 1) class D_CODE; Loading @@ -51,12 +61,14 @@ public: {} double GetValue( const D_CODE* aDcode ) const; void SetValue( double aValue ) { value = aValue; index = -1; } /** * Function IsImmediate * tests if this DCODE_PARAM holds an immediate parameter or is a pointer Loading @@ -69,11 +81,13 @@ public: return (unsigned) index; } void SetIndex( int aIndex ) { index = aIndex; } private: int index; ///< if -1, then \a value field is an immediate value, // else this is an index into parent's Loading @@ -88,8 +102,7 @@ private: * is the set of all "aperture macro primitives" (primitive numbers). See * Table 3 in http://gerbv.sourceforge.net/docs/rs274xrevd_e.pdf */ enum AM_PRIMITIVE_ID { enum AM_PRIMITIVE_ID { AMP_CIRCLE = 1, AMP_LINE2 = 2, AMP_LINE20 = 20, Loading Loading @@ -194,8 +207,9 @@ public: 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) */ int m_DrillShape; /* shape of the hole (round = 1, rect = 2) */ 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; Loading @@ -214,10 +228,13 @@ public: m_am_params.push_back( param ); } void SetMacro( APERTURE_MACRO* aMacro ) { m_Macro = aMacro; } APERTURE_MACRO* GetMacro() { return m_Macro; } /** Loading Loading @@ -250,7 +267,6 @@ public: * rotated shape ... ) and cannot be easily drawn. */ void ConvertShapeToPolygon(); }; Loading @@ -263,6 +279,7 @@ inline double DCODE_PARAM::GetValue( const D_CODE* aDcode ) const // the first one was numbered 1, not zero, as in $1, see page 19 of spec. unsigned ndx = GetIndex() - 1; wxASSERT( aDcode ); // get the parameter from the aDcode if( ndx < aDcode->m_am_params.size() ) return aDcode->m_am_params[ndx].GetValue( NULL ); Loading Loading
CHANGELOG.txt +1 −2 Original line number Diff line number Diff line Loading @@ -12,12 +12,11 @@ email address. graphics items are now specific to gerbview (added a GERBER_DRAW_ITEM class) and do not use tracks from pcbnew. The way used to draw them is also new. Apertures are now correctly drawn for round, oval and rectangular shapes Apertures are now correctly drawn for round, oval, rectangular and regular polygon shapes (with or without holes) Aperture definition type Polygon is not yet handle. Polygons are correctly drawn. TODO: Draw functions for aperture definition type Polygon. Draw functions for aperture macros. Work in progress. Loading
gerbview/class_gerber_draw_item.cpp +5 −1 Original line number Diff line number Diff line Loading @@ -106,10 +106,13 @@ wxString GERBER_DRAW_ITEM::ShowGBRShape() case GBR_SPOT_RECT: return wxT( "spot_rect" ); case GBR_SPOT_POLY: return wxT( "spot_poly" ); case GBR_POLYGON: return wxT( "polygon" ); case GBR_MACRO: case GBR_SPOT_MACRO: return wxT( "apt_macro" ); // TODO: add aperture macro name default: Loading Loading @@ -276,6 +279,7 @@ void GERBER_DRAW_ITEM::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode, case GBR_SPOT_CIRCLE: case GBR_SPOT_RECT: case GBR_SPOT_OVAL: case GBR_SPOT_POLY: isFilled = DisplayOpt.DisplayPadFill ? true : false; d_codeDescr->DrawFlashedShape( &panel->m_ClipBox, DC, color, m_Start, isFilled ); Loading
gerbview/class_gerber_draw_item.h +2 −1 Original line number Diff line number Diff line Loading @@ -40,7 +40,8 @@ enum Gbr_Basic_Shapes { GBR_SPOT_CIRCLE, // flashed shape: round shape (can have hole) GBR_SPOT_RECT, // flashed shape: rectangular shape can have hole) GBR_SPOT_OVAL, // flashed shape: oval shape GBR_MACRO, // complex shape described by a macro GBR_SPOT_POLY, // flashed shape: regulat polygon, 3 to 12 edges GBR_SPOT_MACRO, // complex shape described by a macro GBR_LAST // last value for this list }; Loading
gerbview/dcode.cpp +113 −102 Original line number Diff line number Diff line Loading @@ -56,11 +56,12 @@ void D_CODE::Clear_D_CODE_Data() m_Size.y = DEFAULT_SIZE; m_Shape = APT_CIRCLE; m_Drill.x = m_Drill.y = 0; m_DrillShape = 0; m_DrillShape = APT_DEF_NO_HOLE; m_InUse = FALSE; m_Defined = FALSE; m_Macro = 0; m_Macro = NULL; m_Rotation = 0.0; m_EdgesCount = 0; } Loading Loading @@ -252,17 +253,29 @@ void WinEDA_GerberFrame::CopyDCodesSizeToItems() { case APT_LINE: // might not appears here, but some broken // gerber files use it case APT_CIRCLE: /* spot round (for GERBER) */ case APT_CIRCLE: /* spot round */ gerb_item->m_Shape = GBR_SPOT_CIRCLE; break; case APT_OVAL: /* spot oval (for GERBER)*/ case APT_OVAL: /* spot oval*/ gerb_item->m_Shape = GBR_SPOT_OVAL; break; default: /* spot rect (for GERBER)*/ case APT_RECT: /* spot rect*/ gerb_item->m_Shape = GBR_SPOT_RECT; break; case APT_POLYGON: /* spot regular polyg 3 to 1 edges */ gerb_item->m_Shape = GBR_SPOT_POLY; break; case APT_MACRO: /* spot defined by a macro */ gerb_item->m_Shape = GBR_SPOT_MACRO; break; default: wxMessageBox( wxT("WinEDA_GerberFrame::CopyDCodesSizeToItems() error" ) ); break; } } } Loading @@ -280,14 +293,16 @@ void D_CODE::DrawFlashedShape( EDA_Rect* aClipBox, wxDC* aDC, int aColor, switch( m_Shape ) { case APT_MACRO: // TODO: current a round shape case APT_CIRCLE: radius = m_Size.x >> 1; if( !aFilledShape ) GRCircle( aClipBox, aDC, aShapePos.x, aShapePos.y, radius, aColor ); else if( m_DrillShape == 0 ) if( m_DrillShape == APT_DEF_NO_HOLE ) GRFilledCircle( aClipBox, aDC, aShapePos, radius, aColor ); else if( m_DrillShape == 1 ) // round hole else if( APT_DEF_ROUND_HOLE == 1 ) // round hole in shape { int width = (m_Size.x - m_Drill.x ) / 2; GRCircle( aClipBox, aDC, aShapePos, radius - (width / 2), width, aColor ); Loading @@ -301,6 +316,7 @@ void D_CODE::DrawFlashedShape( EDA_Rect* aClipBox, wxDC* aDC, int aColor, break; case APT_LINE: // not used for flashed items break; Loading @@ -315,7 +331,7 @@ void D_CODE::DrawFlashedShape( EDA_Rect* aClipBox, wxDC* aDC, int aColor, GRRect( aClipBox, aDC, start.x, start.y, end.x, end.y, 0, aColor ); } else if( m_DrillShape == 0 ) else if( m_DrillShape == APT_DEF_NO_HOLE ) { GRFilledRect( aClipBox, aDC, start.x, start.y, end.x, end.y, 0, aColor, aColor ); Loading Loading @@ -352,7 +368,7 @@ void D_CODE::DrawFlashedShape( EDA_Rect* aClipBox, wxDC* aDC, int aColor, GRCSegm( aClipBox, aDC, start.x, start.y, end.x, end.y, radius, aColor ); } else if( m_DrillShape == 0 ) else if( m_DrillShape == APT_DEF_NO_HOLE ) { GRFillCSegm( aClipBox, aDC, start.x, start.y, end.x, end.y, radius, aColor ); Loading @@ -371,10 +387,6 @@ void D_CODE::DrawFlashedShape( EDA_Rect* aClipBox, wxDC* aDC, int aColor, ConvertShapeToPolygon(); DrawFlashedPolygon( aClipBox, aDC, aColor, aFilledShape, aShapePos ); break; case APT_MACRO: // TODO break; } } Loading Loading @@ -403,6 +415,15 @@ void D_CODE::DrawFlashedPolygon( EDA_Rect* aClipBox, wxDC* aDC, } #define SEGS_CNT 32 // number of segments to approximate a circle // A helper function for D_CODE::ConvertShapeToPolygon(). // Add a hole to a polygon static void addHoleToPolygon( std::vector<wxPoint>& aBuffer, APERTURE_DEF_HOLETYPE aHoleShape, wxSize aSize, wxPoint aAnchorPos ); /** function ConvertShapeToPolygon * convert a shape to an equivalent polygon. * Arcs and circles are approximated by segments Loading @@ -411,7 +432,6 @@ void D_CODE::DrawFlashedPolygon( EDA_Rect* aClipBox, wxDC* aDC, */ void D_CODE::ConvertShapeToPolygon() { #define SEGS_CNT 32 // number of segments to approximate a circle wxPoint initialpos; wxPoint currpos;; m_PolyCorners.clear(); Loading @@ -427,35 +447,12 @@ void D_CODE::ConvertShapeToPolygon() RotatePoint( &currpos, ii * 3600 / SEGS_CNT ); m_PolyCorners.push_back( currpos ); } if( m_DrillShape == 1 ) { for( unsigned ii = 0 ; ii <= SEGS_CNT; ii++ ) { currpos.x = m_Drill.x / 2; currpos.y = 0; RotatePoint( &currpos, ii * 3600 / SEGS_CNT ); m_PolyCorners.push_back( currpos ); } m_PolyCorners.push_back( initialpos ); // link to outline } if( m_DrillShape == 2 ) // Create rectangular hole { currpos.x = m_Drill.x / 2; currpos.y = m_Drill.y / 2; m_PolyCorners.push_back( currpos ); // link to hole and begin hole currpos.x -= m_Drill.x; m_PolyCorners.push_back( currpos ); currpos.y -= m_Drill.y; m_PolyCorners.push_back( currpos ); currpos.x += m_Drill.x; m_PolyCorners.push_back( currpos ); currpos.y += m_Drill.y; m_PolyCorners.push_back( currpos ); // close hole m_PolyCorners.push_back( initialpos ); // link to outline } addHoleToPolygon( m_PolyCorners, m_DrillShape, m_Drill, initialpos ); break; case APT_LINE: // Not used for flashed shapes break; Loading @@ -472,32 +469,8 @@ void D_CODE::ConvertShapeToPolygon() m_PolyCorners.push_back( currpos ); currpos.y += m_Size.y; m_PolyCorners.push_back( currpos ); // close polygon if( m_DrillShape == 1 ) // build a round hole { for( int ii = 0 ; ii <= SEGS_CNT; ii++ ) { currpos.x = 0; currpos.y = m_Drill.x / 2; // m_Drill.x / 2 is the radius of the hole RotatePoint( &currpos, ii * 3600 / SEGS_CNT ); m_PolyCorners.push_back( currpos ); } m_PolyCorners.push_back( initialpos ); // link to outline } if( m_DrillShape == 2 ) // Create rectangular hole { currpos.x = m_Drill.x / 2; currpos.y = m_Drill.y / 2; m_PolyCorners.push_back( currpos ); // link to hole and begin hole currpos.x -= m_Drill.x; m_PolyCorners.push_back( currpos ); currpos.y -= m_Drill.y; m_PolyCorners.push_back( currpos ); currpos.x += m_Drill.x; m_PolyCorners.push_back( currpos ); currpos.y += m_Drill.y; m_PolyCorners.push_back( currpos ); // close hole m_PolyCorners.push_back( initialpos ); // link to outline } addHoleToPolygon( m_PolyCorners, m_DrillShape, m_Drill, initialpos ); break; case APT_OVAL: Loading Loading @@ -537,47 +510,85 @@ void D_CODE::ConvertShapeToPolygon() currpos.x -= delta; m_PolyCorners.push_back( currpos ); } m_PolyCorners.push_back( initialpos ); // close outline if( m_Size.y > m_Size.x ) // vertical oval, rotate polygon. { for( unsigned jj = 0; jj < m_PolyCorners.size(); jj++ ) RotatePoint( &m_PolyCorners[jj], 900 ); } if( m_DrillShape == 1 ) // build a round hole { for( ii = 0 ; ii <= SEGS_CNT; ii++ ) addHoleToPolygon( m_PolyCorners, m_DrillShape, m_Drill, initialpos ); } break; 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; if( m_EdgesCount > 12 ) m_EdgesCount = 12; for( int ii = 0; ii <= m_EdgesCount; ii++ ) { currpos.x = 0; currpos.y = m_Drill.x / 2; // m_Drill.x / 2 is the radius of the hole RotatePoint( &currpos, ii * 3600 / SEGS_CNT ); currpos = initialpos; RotatePoint( &currpos, ii * 3600 / m_EdgesCount ); m_PolyCorners.push_back( currpos ); } m_PolyCorners.push_back( initialpos ); // link to outline } if( m_DrillShape == 2 ) // Create rectangular hole addHoleToPolygon( m_PolyCorners, m_DrillShape, m_Drill, initialpos ); if( m_Rotation ) // vertical oval, rotate polygon. { currpos.x = m_Drill.x / 2; currpos.y = m_Drill.y / 2; m_PolyCorners.push_back( currpos ); // link to hole and begin hole currpos.x -= m_Drill.x; m_PolyCorners.push_back( currpos ); currpos.y -= m_Drill.y; m_PolyCorners.push_back( currpos ); currpos.x += m_Drill.x; m_PolyCorners.push_back( currpos ); currpos.y += m_Drill.y; m_PolyCorners.push_back( currpos ); // close hole m_PolyCorners.push_back( initialpos ); // link to outline 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); } } break; case APT_POLYGON: // TODO break; case APT_MACRO: // TODO break; } } // The helper function for D_CODE::ConvertShapeToPolygon(). // Add a hole to a polygon static void addHoleToPolygon( std::vector<wxPoint>& aBuffer, APERTURE_DEF_HOLETYPE aHoleShape, wxSize aSize, wxPoint aAnchorPos ) { wxPoint currpos; if( aHoleShape == APT_DEF_ROUND_HOLE ) // build a round hole { for( int ii = 0; ii <= SEGS_CNT; ii++ ) { currpos.x = 0; currpos.y = aSize.x / 2; // aSize.x / 2 is the radius of the hole RotatePoint( &currpos, ii * 3600 / SEGS_CNT ); aBuffer.push_back( currpos ); } aBuffer.push_back( aAnchorPos ); // link to outline } if( aHoleShape == APT_DEF_RECT_HOLE ) // Create rectangular hole { currpos.x = aSize.x / 2; currpos.y = aSize.y / 2; aBuffer.push_back( currpos ); // link to hole and begin hole currpos.x -= aSize.x; aBuffer.push_back( currpos ); currpos.y -= aSize.y; aBuffer.push_back( currpos ); 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 } }
gerbview/dcode.h +65 −48 Original line number Diff line number Diff line Loading @@ -16,8 +16,7 @@ * is the set of all gerber aperture types allowed, according to page 16 of * http://gerbv.sourceforge.net/docs/rs274xrevd_e.pdf */ enum APERTURE_T { enum APERTURE_T { APT_CIRCLE = 'C', APT_LINE = 'L', APT_RECT = 'R', Loading @@ -26,9 +25,20 @@ enum APERTURE_T APT_MACRO = 'M' }; // In aperture definition, round, oval and rectangular flashed shapes // can have a hole (ropund or rectangular) // this option is stored in .m_DrillShape D_CODE member enum APERTURE_DEF_HOLETYPE { APT_DEF_NO_HOLE = 0, APT_DEF_ROUND_HOLE, APT_DEF_RECT_HOLE }; /* define min and max values for D Codes values. * note: values >= 0 and > FIRST_DCODE can be used for specila purposes */ #define FIRST_DCODE 10 #define LAST_DCODE 999 // dcodes values are from 10 to 999 #define LAST_DCODE 999 #define TOOLS_MAX_COUNT (LAST_DCODE + 1) class D_CODE; Loading @@ -51,12 +61,14 @@ public: {} double GetValue( const D_CODE* aDcode ) const; void SetValue( double aValue ) { value = aValue; index = -1; } /** * Function IsImmediate * tests if this DCODE_PARAM holds an immediate parameter or is a pointer Loading @@ -69,11 +81,13 @@ public: return (unsigned) index; } void SetIndex( int aIndex ) { index = aIndex; } private: int index; ///< if -1, then \a value field is an immediate value, // else this is an index into parent's Loading @@ -88,8 +102,7 @@ private: * is the set of all "aperture macro primitives" (primitive numbers). See * Table 3 in http://gerbv.sourceforge.net/docs/rs274xrevd_e.pdf */ enum AM_PRIMITIVE_ID { enum AM_PRIMITIVE_ID { AMP_CIRCLE = 1, AMP_LINE2 = 2, AMP_LINE20 = 20, Loading Loading @@ -194,8 +207,9 @@ public: 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) */ int m_DrillShape; /* shape of the hole (round = 1, rect = 2) */ 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; Loading @@ -214,10 +228,13 @@ public: m_am_params.push_back( param ); } void SetMacro( APERTURE_MACRO* aMacro ) { m_Macro = aMacro; } APERTURE_MACRO* GetMacro() { return m_Macro; } /** Loading Loading @@ -250,7 +267,6 @@ public: * rotated shape ... ) and cannot be easily drawn. */ void ConvertShapeToPolygon(); }; Loading @@ -263,6 +279,7 @@ inline double DCODE_PARAM::GetValue( const D_CODE* aDcode ) const // the first one was numbered 1, not zero, as in $1, see page 19 of spec. unsigned ndx = GetIndex() - 1; wxASSERT( aDcode ); // get the parameter from the aDcode if( ndx < aDcode->m_am_params.size() ) return aDcode->m_am_params[ndx].GetValue( NULL ); Loading