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.

266 lines
7.0 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2007, 2008 Lubo Racko <developer@lura.sk>
  5. * Copyright (C) 2007, 2008, 2012-2013 Alexander Lunev <al.lunev@yahoo.com>
  6. * Copyright (C) 2017-2020 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 pcb_polygon.cpp
  27. */
  28. #include <wx/wx.h>
  29. #include <common.h>
  30. #include <math/util.h> // for KiROUND
  31. #include <pcb_polygon.h>
  32. namespace PCAD2KICAD {
  33. PCB_POLYGON::PCB_POLYGON( PCB_CALLBACKS* aCallbacks, BOARD* aBoard, int aPCadLayer ) :
  34. PCB_COMPONENT( aCallbacks, aBoard )
  35. {
  36. m_width = 0;
  37. m_priority = 0;
  38. m_objType = wxT( 'Z' );
  39. m_PCadLayer = aPCadLayer;
  40. m_KiCadLayer = GetKiCadLayer();
  41. m_filled = true;
  42. }
  43. PCB_POLYGON::~PCB_POLYGON()
  44. {
  45. int i, island;
  46. for( i = 0; i < (int) m_outline.GetCount(); i++ )
  47. {
  48. delete m_outline[i];
  49. }
  50. for( island = 0; island < (int) m_cutouts.GetCount(); island++ )
  51. {
  52. for( i = 0; i < (int) m_cutouts[island]->GetCount(); i++ )
  53. {
  54. delete (*m_cutouts[island])[i];
  55. }
  56. delete m_cutouts[island];
  57. }
  58. for( island = 0; island < (int) m_islands.GetCount(); island++ )
  59. {
  60. for( i = 0; i < (int) m_islands[island]->GetCount(); i++ )
  61. {
  62. delete (*m_islands[island])[i];
  63. }
  64. delete m_islands[island];
  65. }
  66. }
  67. void PCB_POLYGON::AssignNet( const wxString& aNetName )
  68. {
  69. m_net = aNetName;
  70. m_netCode = GetNetCode( m_net );
  71. }
  72. void PCB_POLYGON::SetOutline( VERTICES_ARRAY* aOutline )
  73. {
  74. int i;
  75. m_outline.Empty();
  76. for( i = 0; i < (int) aOutline->GetCount(); i++ )
  77. m_outline.Add( new wxRealPoint( (*aOutline)[i]->x, (*aOutline)[i]->y ) );
  78. if( m_outline.Count() > 0 )
  79. {
  80. m_positionX = m_outline[0]->x;
  81. m_positionY = m_outline[0]->y;
  82. }
  83. }
  84. void PCB_POLYGON::FormPolygon( XNODE* aNode, VERTICES_ARRAY* aPolygon,
  85. const wxString& aDefaultMeasurementUnit,
  86. const wxString& aActualConversion )
  87. {
  88. XNODE* lNode;
  89. double x, y;
  90. lNode = FindNode( aNode, wxT( "pt" ) );
  91. while( lNode )
  92. {
  93. if( lNode->GetName() == wxT( "pt" ) )
  94. {
  95. SetDoublePrecisionPosition(
  96. lNode->GetNodeContent(), aDefaultMeasurementUnit, &x, &y, aActualConversion );
  97. aPolygon->Add( new wxRealPoint( x, y ) );
  98. }
  99. lNode = lNode->GetNext();
  100. }
  101. }
  102. bool PCB_POLYGON::Parse( XNODE* aNode,
  103. const wxString& aDefaultMeasurementUnit,
  104. const wxString& aActualConversion )
  105. {
  106. XNODE* lNode;
  107. wxString propValue;
  108. lNode = FindNode( aNode, wxT( "netNameRef" ) );
  109. if( lNode )
  110. {
  111. lNode->GetAttribute( wxT( "Name" ), &propValue );
  112. propValue.Trim( false );
  113. propValue.Trim( true );
  114. m_net = propValue;
  115. m_netCode = GetNetCode( m_net );
  116. }
  117. // retrieve polygon outline
  118. FormPolygon( aNode, &m_outline, aDefaultMeasurementUnit, aActualConversion );
  119. m_positionX = m_outline[0]->x;
  120. m_positionY = m_outline[0]->y;
  121. // fill the polygon with the same contour as its outline is
  122. m_islands.Add( new VERTICES_ARRAY );
  123. FormPolygon( aNode, m_islands[0], aDefaultMeasurementUnit, aActualConversion );
  124. return true;
  125. }
  126. void PCB_POLYGON::AddToModule( MODULE* aModule )
  127. {
  128. if( IsNonCopperLayer( m_KiCadLayer ) )
  129. {
  130. EDGE_MODULE* dwg = new EDGE_MODULE( aModule, S_POLYGON );
  131. aModule->Add( dwg );
  132. dwg->SetWidth( 0 );
  133. dwg->SetLayer( m_KiCadLayer );
  134. auto outline = new std::vector<wxPoint>;
  135. for( auto point : m_outline )
  136. outline->push_back( wxPoint( point->x, point->y ) );
  137. dwg->SetPolyPoints( *outline );
  138. dwg->SetStart0( *outline->begin() );
  139. dwg->SetEnd0( outline->back() );
  140. dwg->SetDrawCoord();
  141. delete( outline );
  142. }
  143. }
  144. void PCB_POLYGON::AddToBoard()
  145. {
  146. int i = 0;
  147. if( m_outline.GetCount() > 0 )
  148. {
  149. ZONE_CONTAINER* zone = new ZONE_CONTAINER( m_board );
  150. m_board->Add( zone, ADD_MODE::APPEND );
  151. zone->SetLayer( m_KiCadLayer );
  152. zone->SetNetCode( m_netCode );
  153. // add outline
  154. for( i = 0; i < (int) m_outline.GetCount(); i++ )
  155. {
  156. zone->AppendCorner( wxPoint( KiROUND( m_outline[i]->x ),
  157. KiROUND( m_outline[i]->y ) ), -1 );
  158. }
  159. zone->SetZoneClearance( m_width );
  160. zone->SetPriority( m_priority );
  161. zone->SetHatch( ZONE_HATCH_STYLE::DIAGONAL_EDGE, zone->GetDefaultHatchPitch(), true );
  162. if ( m_objType == wxT( 'K' ) )
  163. {
  164. zone->SetIsKeepout( true );
  165. zone->SetDoNotAllowTracks( true );
  166. zone->SetDoNotAllowVias( true );
  167. zone->SetDoNotAllowCopperPour( true );
  168. }
  169. else if( m_objType == wxT( 'C' ) )
  170. {
  171. // convert cutouts to keepouts because standalone cutouts are not supported in KiCad
  172. zone->SetIsKeepout( true );
  173. zone->SetDoNotAllowCopperPour( true );
  174. }
  175. //if( m_filled )
  176. // zone->BuildFilledPolysListData( m_board );
  177. }
  178. }
  179. void PCB_POLYGON::Flip()
  180. {
  181. PCB_COMPONENT::Flip();
  182. m_KiCadLayer = FlipLayer( m_KiCadLayer );
  183. }
  184. void PCB_POLYGON::SetPosOffset( int aX_offs, int aY_offs )
  185. {
  186. int i, island;
  187. PCB_COMPONENT::SetPosOffset( aX_offs, aY_offs );
  188. for( i = 0; i < (int) m_outline.GetCount(); i++ )
  189. {
  190. m_outline[i]->x += aX_offs;
  191. m_outline[i]->y += aY_offs;
  192. }
  193. for( island = 0; island < (int) m_islands.GetCount(); island++ )
  194. {
  195. for( i = 0; i < (int) m_islands[island]->GetCount(); i++ )
  196. {
  197. (*m_islands[island])[i]->x += aX_offs;
  198. (*m_islands[island])[i]->y += aY_offs;
  199. }
  200. }
  201. for( island = 0; island < (int) m_cutouts.GetCount(); island++ )
  202. {
  203. for( i = 0; i < (int) m_cutouts[island]->GetCount(); i++ )
  204. {
  205. (*m_cutouts[island])[i]->x += aX_offs;
  206. (*m_cutouts[island])[i]->y += aY_offs;
  207. }
  208. }
  209. }
  210. } // namespace PCAD2KICAD