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.

563 lines
18 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2007-2014 Jean-Pierre Charras jp.charras at wanadoo.fr
  5. * Copyright (C) 1992-2020 KiCad Developers, see change_log.txt for contributors.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version 2
  10. * of the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, you may find one here:
  19. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  20. * or you may search the http://www.gnu.org website for the version 2 license,
  21. * or you may write to the Free Software Foundation, Inc.,
  22. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  23. */
  24. #include <vector>
  25. #include <export_to_pcbnew.h>
  26. #include <confirm.h>
  27. #include <macros.h>
  28. #include <trigo.h>
  29. #include <gerbview_frame.h>
  30. #include <gerber_file_image.h>
  31. #include <gerber_file_image_list.h>
  32. #include <build_version.h>
  33. #include <wildcards_and_files_ext.h>
  34. #include "excellon_image.h"
  35. // Imported function
  36. extern const wxString GetPCBDefaultLayerName( LAYER_NUM aLayerNumber );
  37. GBR_TO_PCB_EXPORTER::GBR_TO_PCB_EXPORTER( GERBVIEW_FRAME* aFrame, const wxString& aFileName )
  38. {
  39. m_gerbview_frame = aFrame;
  40. m_pcb_file_name = aFileName;
  41. m_fp = NULL;
  42. m_pcbCopperLayersCount = 2;
  43. }
  44. GBR_TO_PCB_EXPORTER::~GBR_TO_PCB_EXPORTER()
  45. {
  46. }
  47. bool GBR_TO_PCB_EXPORTER::ExportPcb( LAYER_NUM* aLayerLookUpTable, int aCopperLayers )
  48. {
  49. LOCALE_IO toggle; // toggles on, then off, the C locale.
  50. m_fp = wxFopen( m_pcb_file_name, wxT( "wt" ) );
  51. if( m_fp == NULL )
  52. {
  53. wxString msg;
  54. msg.Printf( _( "Cannot create file \"%s\"" ), m_pcb_file_name );
  55. DisplayError( m_gerbview_frame, msg );
  56. return false;
  57. }
  58. m_pcbCopperLayersCount = aCopperLayers;
  59. writePcbHeader( aLayerLookUpTable );
  60. // create an image of gerber data
  61. const int pcbCopperLayerMax = 31;
  62. GERBER_FILE_IMAGE_LIST* images = m_gerbview_frame->GetGerberLayout()->GetImagesList();
  63. // First collect all the holes. We'll use these to generate pads, vias, etc.
  64. for( unsigned layer = 0; layer < images->ImagesMaxCount(); ++layer )
  65. {
  66. EXCELLON_IMAGE* excellon = dynamic_cast<EXCELLON_IMAGE*>( images->GetGbrImage( layer ) );
  67. if( excellon == NULL ) // Layer not yet used or not a drill image
  68. continue;
  69. for( GERBER_DRAW_ITEM* gerb_item : excellon->GetItems() )
  70. collect_hole( gerb_item );
  71. }
  72. // Next: non copper layers:
  73. for( unsigned layer = 0; layer < images->ImagesMaxCount(); ++layer )
  74. {
  75. GERBER_FILE_IMAGE* gerber = images->GetGbrImage( layer );
  76. if( gerber == NULL ) // Graphic layer not yet used
  77. continue;
  78. LAYER_NUM pcb_layer_number = aLayerLookUpTable[layer];
  79. if( !IsPcbLayer( pcb_layer_number ) )
  80. continue;
  81. if( pcb_layer_number <= pcbCopperLayerMax ) // copper layer
  82. continue;
  83. for( GERBER_DRAW_ITEM* gerb_item : gerber->GetItems() )
  84. export_non_copper_item( gerb_item, pcb_layer_number );
  85. }
  86. // Copper layers
  87. for( unsigned layer = 0; layer < images->ImagesMaxCount(); ++layer )
  88. {
  89. GERBER_FILE_IMAGE* gerber = images->GetGbrImage( layer );
  90. if( gerber == NULL ) // Graphic layer not yet used
  91. continue;
  92. LAYER_NUM pcb_layer_number = aLayerLookUpTable[layer];
  93. if( pcb_layer_number < 0 || pcb_layer_number > pcbCopperLayerMax )
  94. continue;
  95. for( GERBER_DRAW_ITEM* gerb_item : gerber->GetItems() )
  96. export_copper_item( gerb_item, pcb_layer_number );
  97. }
  98. // Now write out the holes we collected earlier as vias
  99. for( const EXPORT_VIA& via : m_vias )
  100. export_via( via );
  101. fprintf( m_fp, ")\n" );
  102. fclose( m_fp );
  103. m_fp = NULL;
  104. return true;
  105. }
  106. void GBR_TO_PCB_EXPORTER::export_non_copper_item( GERBER_DRAW_ITEM* aGbrItem, LAYER_NUM aLayer )
  107. {
  108. // used when a D_CODE is not found. default D_CODE to draw a flashed item
  109. static D_CODE dummyD_CODE( 0 );
  110. wxPoint seg_start = aGbrItem->m_Start;
  111. wxPoint seg_end = aGbrItem->m_End;
  112. D_CODE* d_codeDescr = aGbrItem->GetDcodeDescr();
  113. SHAPE_POLY_SET polygon;
  114. if( d_codeDescr == NULL )
  115. d_codeDescr = &dummyD_CODE;
  116. switch( aGbrItem->m_Shape )
  117. {
  118. case GBR_POLYGON:
  119. writePcbPolygon( aGbrItem->m_Polygon, aLayer );
  120. break;
  121. case GBR_SPOT_CIRCLE:
  122. case GBR_SPOT_RECT:
  123. case GBR_SPOT_OVAL:
  124. case GBR_SPOT_POLY:
  125. case GBR_SPOT_MACRO:
  126. d_codeDescr->ConvertShapeToPolygon();
  127. writePcbPolygon( d_codeDescr->m_Polygon, aLayer, aGbrItem->GetABPosition( seg_start ) );
  128. break;
  129. case GBR_ARC:
  130. {
  131. double a = atan2( (double) ( aGbrItem->m_Start.y - aGbrItem->m_ArcCentre.y ),
  132. (double) ( aGbrItem->m_Start.x - aGbrItem->m_ArcCentre.x ) );
  133. double b = atan2( (double) ( aGbrItem->m_End.y - aGbrItem->m_ArcCentre.y ),
  134. (double) ( aGbrItem->m_End.x - aGbrItem->m_ArcCentre.x ) );
  135. double angle = RAD2DEG(b - a);
  136. seg_start = aGbrItem->m_ArcCentre;
  137. // Ensure arc orientation is CCW
  138. if( angle < 0 )
  139. angle += 360.0;
  140. // Reverse Y axis:
  141. seg_start.y = -seg_start.y;
  142. seg_end.y = -seg_end.y;
  143. if( angle == 360.0 || angle == 0 )
  144. {
  145. fprintf( m_fp, "(gr_circle (center %s %s) (end %s %s) (layer %s) (width %s))\n",
  146. Double2Str( MapToPcbUnits(seg_start.x) ).c_str(),
  147. Double2Str( MapToPcbUnits(seg_start.y) ).c_str(),
  148. Double2Str( MapToPcbUnits(seg_end.x) ).c_str(),
  149. Double2Str( MapToPcbUnits(seg_end.y) ).c_str(),
  150. TO_UTF8( GetPCBDefaultLayerName( aLayer ) ),
  151. Double2Str( MapToPcbUnits( aGbrItem->m_Size.x ) ).c_str()
  152. );
  153. }
  154. else
  155. {
  156. fprintf( m_fp, "(gr_arc (start %s %s) (end %s %s) (angle %s) (layer %s) (width %s))\n",
  157. Double2Str( MapToPcbUnits(seg_start.x) ).c_str(),
  158. Double2Str( MapToPcbUnits(seg_start.y) ).c_str(),
  159. Double2Str( MapToPcbUnits(seg_end.x) ).c_str(),
  160. Double2Str( MapToPcbUnits(seg_end.y) ).c_str(),
  161. Double2Str( angle ).c_str(),
  162. TO_UTF8( GetPCBDefaultLayerName( aLayer ) ),
  163. Double2Str( MapToPcbUnits( aGbrItem->m_Size.x ) ).c_str()
  164. );
  165. }
  166. }
  167. break;
  168. case GBR_CIRCLE:
  169. // Reverse Y axis:
  170. seg_start.y = -seg_start.y;
  171. seg_end.y = -seg_end.y;
  172. fprintf( m_fp, "(gr_circle (start %s %s) (end %s %s) (layer %s) (width %s))\n",
  173. Double2Str( MapToPcbUnits( seg_start.x ) ).c_str(),
  174. Double2Str( MapToPcbUnits( seg_start.y ) ).c_str(),
  175. Double2Str( MapToPcbUnits( seg_end.x ) ).c_str(),
  176. Double2Str( MapToPcbUnits( seg_end.y ) ).c_str(),
  177. TO_UTF8( GetPCBDefaultLayerName( aLayer ) ),
  178. Double2Str( MapToPcbUnits( aGbrItem->m_Size.x ) ).c_str() );
  179. break;
  180. case GBR_SEGMENT:
  181. // Reverse Y axis:
  182. seg_start.y = -seg_start.y;
  183. seg_end.y = -seg_end.y;
  184. fprintf( m_fp, "(gr_line (start %s %s) (end %s %s) (layer %s) (width %s))\n",
  185. Double2Str( MapToPcbUnits( seg_start.x ) ).c_str(),
  186. Double2Str( MapToPcbUnits( seg_start.y ) ).c_str(),
  187. Double2Str( MapToPcbUnits( seg_end.x ) ).c_str(),
  188. Double2Str( MapToPcbUnits( seg_end.y ) ).c_str(),
  189. TO_UTF8( GetPCBDefaultLayerName( aLayer ) ),
  190. Double2Str( MapToPcbUnits( aGbrItem->m_Size.x ) ).c_str() );
  191. break;
  192. }
  193. }
  194. /*
  195. * Many holes will be pads, but we have no way to create those without modules, and creating
  196. * a module per pad is not really viable.
  197. *
  198. * So we use vias to mimic holes, with the loss of any hole shape (as we only have round holes
  199. * in vias at present).
  200. *
  201. * We start out with a via size minimally larger than the hole. We'll leave it this way if
  202. * the pad gets drawn as a copper polygon, or increase it to the proper size if it has a
  203. * circular, concentric copper flashing.
  204. */
  205. void GBR_TO_PCB_EXPORTER::collect_hole( GERBER_DRAW_ITEM* aGbrItem )
  206. {
  207. int size = std::min( aGbrItem->m_Size.x, aGbrItem->m_Size.y );
  208. m_vias.emplace_back( aGbrItem->m_Start, size + 1, size );
  209. }
  210. void GBR_TO_PCB_EXPORTER::export_via( const EXPORT_VIA& aVia )
  211. {
  212. wxPoint via_pos = aVia.m_Pos;
  213. // Reverse Y axis:
  214. via_pos.y = -via_pos.y;
  215. // Layers are Front to Back
  216. fprintf( m_fp, " (via (at %s %s) (size %s) (drill %s)",
  217. Double2Str( MapToPcbUnits( via_pos.x ) ).c_str(),
  218. Double2Str( MapToPcbUnits( via_pos.y ) ).c_str(),
  219. Double2Str( MapToPcbUnits( aVia.m_Size ) ).c_str(),
  220. Double2Str( MapToPcbUnits( aVia.m_Drill ) ).c_str() );
  221. fprintf( m_fp, " (layers %s %s))\n",
  222. TO_UTF8( GetPCBDefaultLayerName( F_Cu ) ),
  223. TO_UTF8( GetPCBDefaultLayerName( B_Cu ) ) );
  224. }
  225. void GBR_TO_PCB_EXPORTER::export_copper_item( GERBER_DRAW_ITEM* aGbrItem, LAYER_NUM aLayer )
  226. {
  227. switch( aGbrItem->m_Shape )
  228. {
  229. case GBR_SPOT_CIRCLE:
  230. case GBR_SPOT_RECT:
  231. case GBR_SPOT_OVAL:
  232. export_flashed_copper_item( aGbrItem, aLayer );
  233. break;
  234. case GBR_ARC:
  235. export_segarc_copper_item( aGbrItem, aLayer );
  236. break;
  237. case GBR_POLYGON:
  238. // One can use a polygon or a zone to output a Gerber region.
  239. // none are perfect.
  240. // The current way is use a polygon, as the zone export
  241. // is exprimental and only for tests.
  242. #if 1
  243. writePcbPolygon( aGbrItem->m_Polygon, aLayer );
  244. #else
  245. // Only for tests:
  246. writePcbZoneItem( aGbrItem, aLayer );
  247. #endif
  248. break;
  249. default:
  250. export_segline_copper_item( aGbrItem, aLayer );
  251. break;
  252. }
  253. }
  254. void GBR_TO_PCB_EXPORTER::export_segline_copper_item( GERBER_DRAW_ITEM* aGbrItem, LAYER_NUM aLayer )
  255. {
  256. wxPoint seg_start, seg_end;
  257. seg_start = aGbrItem->m_Start;
  258. seg_end = aGbrItem->m_End;
  259. // Reverse Y axis:
  260. seg_start.y = -seg_start.y;
  261. seg_end.y = -seg_end.y;
  262. writeCopperLineItem( seg_start, seg_end, aGbrItem->m_Size.x, aLayer );
  263. }
  264. void GBR_TO_PCB_EXPORTER::writeCopperLineItem( wxPoint& aStart, wxPoint& aEnd,
  265. int aWidth, LAYER_NUM aLayer )
  266. {
  267. fprintf( m_fp, "(segment (start %s %s) (end %s %s) (width %s) (layer %s) (net 0))\n",
  268. Double2Str( MapToPcbUnits(aStart.x) ).c_str(),
  269. Double2Str( MapToPcbUnits(aStart.y) ).c_str(),
  270. Double2Str( MapToPcbUnits(aEnd.x) ).c_str(),
  271. Double2Str( MapToPcbUnits(aEnd.y) ).c_str(),
  272. Double2Str( MapToPcbUnits( aWidth ) ).c_str(),
  273. TO_UTF8( GetPCBDefaultLayerName( aLayer ) ) );
  274. }
  275. void GBR_TO_PCB_EXPORTER::export_segarc_copper_item( GERBER_DRAW_ITEM* aGbrItem, LAYER_NUM aLayer )
  276. {
  277. double a = atan2( (double) ( aGbrItem->m_Start.y - aGbrItem->m_ArcCentre.y ),
  278. (double) ( aGbrItem->m_Start.x - aGbrItem->m_ArcCentre.x ) );
  279. double b = atan2( (double) ( aGbrItem->m_End.y - aGbrItem->m_ArcCentre.y ),
  280. (double) ( aGbrItem->m_End.x - aGbrItem->m_ArcCentre.x ) );
  281. wxPoint start = aGbrItem->m_Start;
  282. wxPoint end = aGbrItem->m_End;
  283. /* Because Pcbnew does not know arcs in tracks,
  284. * approximate arc by segments (SEG_COUNT__CIRCLE segment per 360 deg)
  285. * The arc is drawn anticlockwise from the start point to the end point.
  286. */
  287. #define SEG_COUNT_CIRCLE 16
  288. #define DELTA_ANGLE 2 * M_PI / SEG_COUNT_CIRCLE
  289. // calculate the number of segments from a to b.
  290. // we want CNT_PER_360 segments fo a circle
  291. if( a > b )
  292. b += 2 * M_PI;
  293. wxPoint curr_start = start;
  294. wxPoint seg_start, seg_end;
  295. int ii = 1;
  296. for( double rot = a; rot < (b - DELTA_ANGLE); rot += DELTA_ANGLE, ii++ )
  297. {
  298. seg_start = curr_start;
  299. wxPoint curr_end = start;
  300. RotatePoint( &curr_end, aGbrItem->m_ArcCentre,
  301. -RAD2DECIDEG( DELTA_ANGLE * ii ) );
  302. seg_end = curr_end;
  303. // Reverse Y axis:
  304. seg_start.y = -seg_start.y;
  305. seg_end.y = -seg_end.y;
  306. writeCopperLineItem( seg_start, seg_end, aGbrItem->m_Size.x, aLayer );
  307. curr_start = curr_end;
  308. }
  309. if( end != curr_start )
  310. {
  311. seg_start = curr_start;
  312. seg_end = end;
  313. // Reverse Y axis:
  314. seg_start.y = -seg_start.y;
  315. seg_end.y = -seg_end.y;
  316. writeCopperLineItem( seg_start, seg_end, aGbrItem->m_Size.x, aLayer );
  317. }
  318. }
  319. /*
  320. * Flashed items are usually pads or vias. Pads are problematic because we have no way to
  321. * represent one in Pcbnew outside of a module (and creating a module per pad isn't really
  322. * viable).
  323. * If we've already created a via from a hole, and the flashed copper item is a simple circle
  324. * then we'll enlarge the via to the proper size. Otherwise we create a copper polygon to
  325. * represent the flashed item (which is presumably a pad).
  326. */
  327. void GBR_TO_PCB_EXPORTER::export_flashed_copper_item( GERBER_DRAW_ITEM* aGbrItem,
  328. LAYER_NUM aLayer )
  329. {
  330. static D_CODE flashed_item_D_CODE( 0 );
  331. D_CODE* d_codeDescr = aGbrItem->GetDcodeDescr();
  332. SHAPE_POLY_SET polygon;
  333. if( d_codeDescr == NULL )
  334. d_codeDescr = &flashed_item_D_CODE;
  335. if( aGbrItem->m_Shape == GBR_SPOT_CIRCLE )
  336. {
  337. // See if there's a via that we can enlarge to fit this flashed item
  338. for( EXPORT_VIA& via : m_vias )
  339. {
  340. if( via.m_Pos == aGbrItem->m_Start )
  341. {
  342. via.m_Size = std::max( via.m_Size, aGbrItem->m_Size.x );
  343. return;
  344. }
  345. }
  346. }
  347. d_codeDescr->ConvertShapeToPolygon();
  348. wxPoint offset = aGbrItem->GetABPosition( aGbrItem->m_Start );
  349. writePcbPolygon( d_codeDescr->m_Polygon, aLayer, offset );
  350. }
  351. void GBR_TO_PCB_EXPORTER::writePcbHeader( LAYER_NUM* aLayerLookUpTable )
  352. {
  353. fprintf( m_fp, "(kicad_pcb (version 4) (host Gerbview \"%s\")\n\n",
  354. TO_UTF8( GetBuildVersion() ) );
  355. // Write layers section
  356. fprintf( m_fp, " (layers \n" );
  357. for( int ii = 0; ii < m_pcbCopperLayersCount; ii++ )
  358. {
  359. int id = ii;
  360. if( ii == m_pcbCopperLayersCount-1)
  361. id = B_Cu;
  362. fprintf( m_fp, " (%d %s signal)\n", id, TO_UTF8( GetPCBDefaultLayerName( id ) ) );
  363. }
  364. for( int ii = B_Adhes; ii < PCB_LAYER_ID_COUNT; ii++ )
  365. {
  366. if( GetPCBDefaultLayerName( ii ).IsEmpty() ) // Layer not available for export
  367. continue;
  368. fprintf( m_fp, " (%d %s user)\n", ii, TO_UTF8( GetPCBDefaultLayerName( ii ) ) );
  369. }
  370. fprintf( m_fp, " )\n\n" );
  371. }
  372. void GBR_TO_PCB_EXPORTER::writePcbPolygon( const SHAPE_POLY_SET& aPolys, LAYER_NUM aLayer,
  373. const wxPoint& aOffset )
  374. {
  375. SHAPE_POLY_SET polys = aPolys;
  376. // Cleanup the polygon
  377. polys.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
  378. // Ensure the polygon is valid:
  379. if( polys.OutlineCount() == 0 )
  380. return;
  381. polys.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
  382. SHAPE_LINE_CHAIN& poly = polys.Outline( 0 );
  383. fprintf( m_fp, "(gr_poly (pts " );
  384. #define MAX_COORD_CNT 4
  385. int jj = MAX_COORD_CNT;
  386. int cnt_max = poly.PointCount() -1;
  387. // Do not generate last corner, if it is the same point as the first point:
  388. if( poly.CPoint( 0 ) == poly.CPoint( cnt_max ) )
  389. cnt_max--;
  390. for( int ii = 0; ii <= cnt_max; ii++ )
  391. {
  392. if( --jj == 0 )
  393. {
  394. jj = MAX_COORD_CNT;
  395. fprintf( m_fp, "\n" );
  396. }
  397. fprintf( m_fp, " (xy %s %s)",
  398. Double2Str( MapToPcbUnits( poly.CPoint( ii ).x + aOffset.x ) ).c_str(),
  399. Double2Str( MapToPcbUnits( -poly.CPoint( ii ).y + aOffset.y ) ).c_str() );
  400. }
  401. fprintf( m_fp, ")" );
  402. if( jj != MAX_COORD_CNT )
  403. fprintf( m_fp, "\n" );
  404. fprintf( m_fp, "(layer %s) (width 0) )\n",
  405. TO_UTF8( GetPCBDefaultLayerName( aLayer ) ) );
  406. }
  407. void GBR_TO_PCB_EXPORTER::writePcbZoneItem( GERBER_DRAW_ITEM* aGbrItem, LAYER_NUM aLayer )
  408. {
  409. SHAPE_POLY_SET polys = aGbrItem->m_Polygon;
  410. polys.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
  411. if( polys.OutlineCount() == 0 )
  412. return;
  413. fprintf( m_fp, "(zone (net 0) (net_name \"\") (layer %s) (tstamp 0000000) (hatch edge 0.508)\n",
  414. TO_UTF8( GetPCBDefaultLayerName( aLayer ) ) );
  415. fprintf( m_fp, " (connect_pads (clearance 0.0))\n" );
  416. fprintf( m_fp, " (min_thickness 0.1) (filled_areas_thickness no)\n"
  417. " (fill (thermal_gap 0.3) (thermal_bridge_width 0.3))\n" );
  418. // Now, write the zone outlines with holes.
  419. // first polygon is the main outline, next are holes
  420. // One cannot know the initial zone outline.
  421. // However most of (if not all) holes are just items with clearance,
  422. // not really a hole in the initial zone outline.
  423. // So we build a zone outline only with no hole.
  424. fprintf( m_fp, " (polygon\n (pts" );
  425. SHAPE_LINE_CHAIN& poly = polys.Outline( 0 );
  426. #define MAX_COORD_CNT 4
  427. int jj = MAX_COORD_CNT;
  428. int cnt_max = poly.PointCount() -1;
  429. // Do not generate last corner, if it is the same point as the first point:
  430. if( poly.CPoint( 0 ) == poly.CPoint( cnt_max ) )
  431. cnt_max--;
  432. for( int ii = 0; ii <= cnt_max; ii++ )
  433. {
  434. if( --jj == 0 )
  435. {
  436. jj = MAX_COORD_CNT;
  437. fprintf( m_fp, "\n " );
  438. }
  439. fprintf( m_fp, " (xy %s %s)", Double2Str( MapToPcbUnits( poly.CPoint( ii ).x ) ).c_str(),
  440. Double2Str( MapToPcbUnits( -poly.CPoint( ii ).y ) ).c_str() );
  441. }
  442. fprintf( m_fp, ")\n" );
  443. fprintf( m_fp, " )\n)\n" );
  444. }