You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

157 lines
4.9 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 1992-2017 Jean-Pierre Charras <jp.charras at wanadoo.fr>
  5. * Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
  6. * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License
  10. * as published by the Free Software Foundation; either version 2
  11. * of the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, you may find one here:
  20. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  21. * or you may search the http://www.gnu.org website for the version 2 license,
  22. * or you may write to the Free Software Foundation, Inc.,
  23. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  24. */
  25. /**
  26. * @file aperture_macro.cpp
  27. */
  28. #include <gerbview.h>
  29. #include <aperture_macro.h>
  30. #include <gerber_draw_item.h>
  31. void APERTURE_MACRO::InitLocalParams( const D_CODE* aDcode )
  32. {
  33. // store the initial values coming from aDcode into m_localParamValues
  34. // for n parameters, they are local params $1 to $n
  35. m_localParamValues.clear();
  36. // Note: id_param = 1... n, not 0
  37. for( unsigned id_param = 1; id_param <= aDcode->GetParamCount(); id_param++ )
  38. m_localParamValues[id_param] = aDcode->GetParam( id_param );
  39. m_paramLevelEval = 0;
  40. }
  41. void APERTURE_MACRO::EvalLocalParams( const AM_PRIMITIVE& aPrimitive )
  42. {
  43. // Evaluate m_localParamValues from current m_paramLevelEval to
  44. // aPrimitive.m_LocalParamLevel
  45. // if m_paramLevelEval >= m_LocalParamLevel, do nothing: the
  46. // m_localParamValues are already up to date
  47. if( m_paramLevelEval >= aPrimitive.m_LocalParamLevel )
  48. return;
  49. for( ; m_paramLevelEval < aPrimitive.m_LocalParamLevel; m_paramLevelEval++ )
  50. {
  51. AM_PARAM& am_param = m_localParamStack.at( m_paramLevelEval );
  52. int prm_index = am_param.GetIndex();
  53. double value = am_param.GetValueFromMacro( this );
  54. // if am_param value is not yet stored in m_localParamValues, add it.
  55. // if it is already in m_localParamValues, update its value;
  56. m_localParamValues[ prm_index ] = value;
  57. }
  58. }
  59. double APERTURE_MACRO::GetLocalParamValue( int aIndex )
  60. {
  61. // return the local param value stored in m_localParamValues
  62. // if not existing, returns 0
  63. if( m_localParamValues.find( aIndex ) != m_localParamValues.end() )
  64. return m_localParamValues[ aIndex ];
  65. return 0.0;
  66. }
  67. void APERTURE_MACRO::AddPrimitiveToList( AM_PRIMITIVE& aPrimitive )
  68. {
  69. m_primitivesList.push_back( aPrimitive );
  70. m_primitivesList.back().m_LocalParamLevel = m_localParamStack.size();
  71. }
  72. void APERTURE_MACRO::AddLocalParamDefToStack()
  73. {
  74. m_localParamStack.push_back( AM_PARAM() );
  75. }
  76. AM_PARAM& APERTURE_MACRO::GetLastLocalParamDefFromStack()
  77. {
  78. return m_localParamStack.back();
  79. }
  80. SHAPE_POLY_SET* APERTURE_MACRO::GetApertureMacroShape( const GERBER_DRAW_ITEM* aParent,
  81. const VECTOR2I& aShapePos )
  82. {
  83. SHAPE_POLY_SET holeBuffer;
  84. m_shape.RemoveAllContours();
  85. D_CODE* dcode = aParent->GetDcodeDescr();
  86. InitLocalParams( dcode );
  87. for( AM_PRIMITIVE& prim_macro : m_primitivesList )
  88. {
  89. if( prim_macro.m_Primitive_id == AMP_COMMENT )
  90. continue;
  91. if( prim_macro.IsAMPrimitiveExposureOn( this ) )
  92. {
  93. prim_macro.ConvertBasicShapeToPolygon( this, m_shape );
  94. }
  95. else
  96. {
  97. prim_macro.ConvertBasicShapeToPolygon( this, holeBuffer );
  98. if( holeBuffer.OutlineCount() ) // we have a new hole in shape: remove the hole
  99. {
  100. m_shape.BooleanSubtract( holeBuffer );
  101. holeBuffer.RemoveAllContours();
  102. }
  103. }
  104. }
  105. // Merge and cleanup basic shape polygons
  106. m_shape.Simplify();
  107. // A hole can be is defined inside a polygon, or the polygons themselve can create
  108. // a hole when merged, so we must fracture the polygon to be able to drawn it
  109. // (i.e link holes by overlapping edges)
  110. m_shape.Fracture();
  111. // Move m_shape to the actual draw position:
  112. for( int icnt = 0; icnt < m_shape.OutlineCount(); icnt++ )
  113. {
  114. SHAPE_LINE_CHAIN& outline = m_shape.Outline( icnt );
  115. for( int jj = 0; jj < outline.PointCount(); jj++ )
  116. {
  117. VECTOR2I point = outline.CPoint( jj );
  118. point += aShapePos;
  119. point = aParent->GetABPosition( point );
  120. outline.SetPoint( jj, point );
  121. }
  122. }
  123. return &m_shape;
  124. }