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.

347 lines
9.6 KiB

14 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2015 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
  5. * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
  6. * Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
  7. * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
  8. *
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU General Public License
  11. * as published by the Free Software Foundation; either version 2
  12. * of the License, or (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, you may find one here:
  21. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  22. * or you may search the http://www.gnu.org website for the version 2 license,
  23. * or you may write to the Free Software Foundation, Inc.,
  24. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  25. */
  26. #include <bitmaps.h>
  27. #include <math/util.h> // for KiROUND
  28. #include <settings/color_settings.h>
  29. #include <settings/settings_manager.h>
  30. #include <pcb_edit_frame.h>
  31. #include <class_board.h>
  32. #include <class_module.h>
  33. #include <fp_shape.h>
  34. #include <view/view.h>
  35. FP_SHAPE::FP_SHAPE( MODULE* parent, PCB_SHAPE_TYPE_T aShape ) :
  36. PCB_SHAPE( parent, PCB_FP_SHAPE_T )
  37. {
  38. m_Shape = aShape;
  39. m_Angle = 0;
  40. m_Layer = F_SilkS;
  41. }
  42. FP_SHAPE::~FP_SHAPE()
  43. {
  44. }
  45. void FP_SHAPE::SetLocalCoord()
  46. {
  47. MODULE* fp = (MODULE*) m_Parent;
  48. if( fp == NULL )
  49. {
  50. m_Start0 = m_Start;
  51. m_End0 = m_End;
  52. m_ThirdPoint0 = m_ThirdPoint;
  53. m_Bezier0_C1 = m_BezierC1;
  54. m_Bezier0_C2 = m_BezierC2;
  55. return;
  56. }
  57. m_Start0 = m_Start - fp->GetPosition();
  58. m_End0 = m_End - fp->GetPosition();
  59. m_ThirdPoint0 = m_ThirdPoint - fp->GetPosition();
  60. m_Bezier0_C1 = m_BezierC1 - fp->GetPosition();
  61. m_Bezier0_C2 = m_BezierC2 - fp->GetPosition();
  62. double angle = fp->GetOrientation();
  63. RotatePoint( &m_Start0.x, &m_Start0.y, -angle );
  64. RotatePoint( &m_End0.x, &m_End0.y, -angle );
  65. RotatePoint( &m_ThirdPoint0.x, &m_ThirdPoint0.y, -angle );
  66. RotatePoint( &m_Bezier0_C1.x, &m_Bezier0_C1.y, -angle );
  67. RotatePoint( &m_Bezier0_C2.x, &m_Bezier0_C2.y, -angle );
  68. }
  69. void FP_SHAPE::SetDrawCoord()
  70. {
  71. MODULE* fp = (MODULE*) m_Parent;
  72. m_Start = m_Start0;
  73. m_End = m_End0;
  74. m_ThirdPoint = m_ThirdPoint0;
  75. m_BezierC1 = m_Bezier0_C1;
  76. m_BezierC2 = m_Bezier0_C2;
  77. if( fp )
  78. {
  79. RotatePoint( &m_Start.x, &m_Start.y, fp->GetOrientation() );
  80. RotatePoint( &m_End.x, &m_End.y, fp->GetOrientation() );
  81. RotatePoint( &m_ThirdPoint.x, &m_ThirdPoint.y, fp->GetOrientation() );
  82. RotatePoint( &m_BezierC1.x, &m_BezierC1.y, fp->GetOrientation() );
  83. RotatePoint( &m_BezierC2.x, &m_BezierC2.y, fp->GetOrientation() );
  84. m_Start += fp->GetPosition();
  85. m_End += fp->GetPosition();
  86. m_ThirdPoint += fp->GetPosition();
  87. m_BezierC1 += fp->GetPosition();
  88. m_BezierC2 += fp->GetPosition();
  89. }
  90. RebuildBezierToSegmentsPointsList( m_Width );
  91. }
  92. // see class_edge_mod.h
  93. void FP_SHAPE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
  94. {
  95. wxString msg;
  96. MODULE* fp = (MODULE*) m_Parent;
  97. if( !fp )
  98. return;
  99. BOARD* board = (BOARD*) fp->GetParent();
  100. if( !board )
  101. return;
  102. aList.emplace_back( _( "Footprint" ), fp->GetReference(), DARKCYAN );
  103. // append the features shared with the base class
  104. PCB_SHAPE::GetMsgPanelInfo( aFrame, aList );
  105. }
  106. wxString FP_SHAPE::GetSelectMenuText( EDA_UNITS aUnits ) const
  107. {
  108. return wxString::Format( _( "%s on %s" ),
  109. ShowShape( m_Shape ),
  110. GetLayerName() );
  111. }
  112. BITMAP_DEF FP_SHAPE::GetMenuImage() const
  113. {
  114. return show_mod_edge_xpm;
  115. }
  116. EDA_ITEM* FP_SHAPE::Clone() const
  117. {
  118. return new FP_SHAPE( *this );
  119. }
  120. void FP_SHAPE::SetAngle( double aAngle, bool aUpdateEnd )
  121. {
  122. // Mark as depreciated.
  123. // m_Angle does not define the arc anymore
  124. // m_Angle must be >= -360 and <= +360 degrees
  125. m_Angle = NormalizeAngle360Max( aAngle );
  126. if( aUpdateEnd )
  127. {
  128. m_ThirdPoint0 = m_End0;
  129. RotatePoint( &m_ThirdPoint0, m_Start0, -m_Angle );
  130. }
  131. }
  132. void FP_SHAPE::Flip( const wxPoint& aCentre, bool aFlipLeftRight )
  133. {
  134. wxPoint pt( 0, 0 );
  135. switch( GetShape() )
  136. {
  137. case S_ARC:
  138. SetAngle( -GetAngle() );
  139. KI_FALLTHROUGH;
  140. default:
  141. case S_SEGMENT:
  142. case S_CURVE:
  143. // If Start0 and Start are equal (ie: ModEdit), then flip both sets around the
  144. // centre point.
  145. if( m_Start == m_Start0 )
  146. pt = aCentre;
  147. if( aFlipLeftRight )
  148. {
  149. MIRROR( m_Start.x, aCentre.x );
  150. MIRROR( m_End.x, aCentre.x );
  151. MIRROR( m_ThirdPoint.x, aCentre.x );
  152. MIRROR( m_BezierC1.x, aCentre.x );
  153. MIRROR( m_BezierC2.x, aCentre.x );
  154. MIRROR( m_Start0.x, pt.x );
  155. MIRROR( m_End0.x, pt.x );
  156. MIRROR( m_ThirdPoint0.x, pt.x );
  157. MIRROR( m_Bezier0_C1.x, pt.x );
  158. MIRROR( m_Bezier0_C2.x, pt.x );
  159. }
  160. else
  161. {
  162. MIRROR( m_Start.y, aCentre.y );
  163. MIRROR( m_End.y, aCentre.y );
  164. MIRROR( m_ThirdPoint.y, aCentre.y );
  165. MIRROR( m_BezierC1.y, aCentre.y );
  166. MIRROR( m_BezierC2.y, aCentre.y );
  167. MIRROR( m_Start0.y, pt.y );
  168. MIRROR( m_End0.y, pt.y );
  169. MIRROR( m_ThirdPoint0.y, pt.y );
  170. MIRROR( m_Bezier0_C1.y, pt.y );
  171. MIRROR( m_Bezier0_C2.y, pt.y );
  172. }
  173. RebuildBezierToSegmentsPointsList( m_Width );
  174. break;
  175. case S_POLYGON:
  176. // polygon corners coordinates are relative to the footprint position, orientation 0
  177. m_Poly.Mirror( aFlipLeftRight, !aFlipLeftRight );
  178. break;
  179. }
  180. // PCB_SHAPE items are not usually on copper layers, but it can happen in microwave apps.
  181. // However, currently, only on Front or Back layers.
  182. // So the copper layers count is not taken in account
  183. SetLayer( FlipLayer( GetLayer() ) );
  184. }
  185. bool FP_SHAPE::IsParentFlipped() const
  186. {
  187. if( GetParent() && GetParent()->GetLayer() == B_Cu )
  188. return true;
  189. return false;
  190. }
  191. void FP_SHAPE::Mirror( const wxPoint& aCentre, bool aMirrorAroundXAxis )
  192. {
  193. // Mirror an edge of the footprint. the layer is not modified
  194. // This is a footprint shape modification.
  195. switch( GetShape() )
  196. {
  197. case S_ARC:
  198. SetAngle( -GetAngle() );
  199. KI_FALLTHROUGH;
  200. default:
  201. case S_CURVE:
  202. case S_SEGMENT:
  203. if( aMirrorAroundXAxis )
  204. {
  205. MIRROR( m_Start0.y, aCentre.y );
  206. MIRROR( m_End0.y, aCentre.y );
  207. MIRROR( m_Bezier0_C1.y, aCentre.y );
  208. MIRROR( m_Bezier0_C2.y, aCentre.y );
  209. }
  210. else
  211. {
  212. MIRROR( m_Start0.x, aCentre.x );
  213. MIRROR( m_End0.x, aCentre.x );
  214. MIRROR( m_Bezier0_C1.x, aCentre.x );
  215. MIRROR( m_Bezier0_C2.x, aCentre.x );
  216. }
  217. for( unsigned ii = 0; ii < m_BezierPoints.size(); ii++ )
  218. {
  219. if( aMirrorAroundXAxis )
  220. MIRROR( m_BezierPoints[ii].y, aCentre.y );
  221. else
  222. MIRROR( m_BezierPoints[ii].x, aCentre.x );
  223. }
  224. break;
  225. case S_POLYGON:
  226. // polygon corners coordinates are always relative to the
  227. // footprint position, orientation 0
  228. m_Poly.Mirror( !aMirrorAroundXAxis, aMirrorAroundXAxis );
  229. break;
  230. }
  231. SetDrawCoord();
  232. }
  233. void FP_SHAPE::Rotate( const wxPoint& aRotCentre, double aAngle )
  234. {
  235. // We should rotate the relative coordinates, but to avoid duplicate code do the base class
  236. // rotation of draw coordinates, which is acceptable because in the footprint editor
  237. // m_Pos0 = m_Pos
  238. PCB_SHAPE::Rotate( aRotCentre, aAngle );
  239. // and now update the relative coordinates, which are the reference in most transforms.
  240. SetLocalCoord();
  241. }
  242. void FP_SHAPE::Move( const wxPoint& aMoveVector )
  243. {
  244. // Move an edge of the footprint.
  245. // This is a footprint shape modification.
  246. m_Start0 += aMoveVector;
  247. m_End0 += aMoveVector;
  248. m_ThirdPoint0 += aMoveVector;
  249. m_Bezier0_C1 += aMoveVector;
  250. m_Bezier0_C2 += aMoveVector;
  251. switch( GetShape() )
  252. {
  253. default:
  254. break;
  255. case S_POLYGON:
  256. // polygon corners coordinates are always relative to the
  257. // footprint position, orientation 0
  258. m_Poly.Move( VECTOR2I( aMoveVector ) );
  259. break;
  260. }
  261. SetDrawCoord();
  262. }
  263. double FP_SHAPE::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
  264. {
  265. constexpr double HIDE = std::numeric_limits<double>::max();
  266. if( !aView )
  267. return 0;
  268. // Handle Render tab switches
  269. if( !IsParentFlipped() && !aView->IsLayerVisible( LAYER_MOD_FR ) )
  270. return HIDE;
  271. if( IsParentFlipped() && !aView->IsLayerVisible( LAYER_MOD_BK ) )
  272. return HIDE;
  273. // Other layers are shown without any conditions
  274. return 0.0;
  275. }
  276. static struct FP_SHAPE_DESC
  277. {
  278. FP_SHAPE_DESC()
  279. {
  280. PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
  281. REGISTER_TYPE( FP_SHAPE );
  282. propMgr.InheritsAfter( TYPE_HASH( FP_SHAPE ), TYPE_HASH( PCB_SHAPE ) );
  283. }
  284. } _FP_SHAPE_DESC;