~pierre-parent-k/kicad/length-tunning

« back to all changes in this revision

Viewing changes to pcbnew/exporters/export_gencad.cpp

  • Committer: Pierre Parent
  • Date: 2014-07-06 10:32:13 UTC
  • mfrom: (4798.1.179 kicad)
  • Revision ID: pierre.parent@insa-rouen.fr-20140706103213-wjsdy0hc9q6wbz5v
Merge with lp:kicad 4977

Show diffs side-by-side

added added

removed removed

Lines of Context:
59
59
static void CreatePadsShapesSection( FILE* aFile, BOARD* aPcb );
60
60
static void FootprintWriteShape( FILE* File, MODULE* module );
61
61
 
62
 
// layer name for Gencad export
63
 
static const wxString GenCADLayerName[32] =
 
62
// layer names for Gencad export
 
63
 
 
64
#if 0 // was:
 
65
static const wxString GenCADLayerName[] =
64
66
{
65
67
    wxT( "BOTTOM" ),             wxT( "INNER1" ),          wxT( "INNER2" ),
66
68
    wxT( "INNER3" ),             wxT( "INNER4" ),          wxT( "INNER5" ),
93
95
    wxT( "LAYER32" )
94
96
};
95
97
 
 
98
#else
 
99
 
 
100
static std::string GenCADLayerName( int aCuCount, LAYER_ID aId )
 
101
{
 
102
    if( IsCopperLayer( aId ) )
 
103
    {
 
104
        if( aId == F_Cu )
 
105
            return "TOP";
 
106
        else if( aId == B_Cu )
 
107
            return "BOTTOM";
 
108
 
 
109
        else if( aId <= 14 )
 
110
        {
 
111
            return StrPrintf(  "INNER%d", aCuCount - aId - 1 );
 
112
        }
 
113
        else
 
114
        {
 
115
            return StrPrintf( "LAYER%d", aId );
 
116
        }
 
117
    }
 
118
 
 
119
    else
 
120
    {
 
121
        const char* txt;
 
122
 
 
123
        // using a switch to clearly show mapping & catch out of bounds index.
 
124
        switch( aId )
 
125
        {
 
126
        // Technicals
 
127
        case B_Adhes:   txt = "B.Adhes";                break;
 
128
        case F_Adhes:   txt = "F.Adhes";                break;
 
129
        case B_Paste:   txt = "SOLDERPASTE_BOTTOM";     break;
 
130
        case F_Paste:   txt = "SOLDERPASTE_TOP";        break;
 
131
        case B_SilkS:   txt = "SILKSCREEN_BOTTOM";      break;
 
132
        case F_SilkS:   txt = "SILKSCREEN_TOP";         break;
 
133
        case B_Mask:    txt = "SOLDERMASK_BOTTOM";      break;
 
134
        case F_Mask:    txt = "SOLDERMASK_TOP";         break;
 
135
 
 
136
        // Users
 
137
        case Dwgs_User: txt = "Dwgs.User";              break;
 
138
        case Cmts_User: txt = "Cmts.User";              break;
 
139
        case Eco1_User: txt = "Eco1.User";              break;
 
140
        case Eco2_User: txt = "Eco2.User";              break;
 
141
        case Edge_Cuts: txt = "Edge.Cuts";              break;
 
142
        case Margin:    txt = "Margin";                 break;
 
143
 
 
144
        // Footprint
 
145
        case F_CrtYd:   txt = "F_CrtYd";                break;
 
146
        case B_CrtYd:   txt = "B_CrtYd";                break;
 
147
        case F_Fab:     txt = "F_Fab";                  break;
 
148
        case B_Fab:     txt = "B_Fab";                  break;
 
149
 
 
150
        default:
 
151
            wxASSERT_MSG( 0, wxT( "aId UNEXPECTED" ) );
 
152
                        txt = "BAD-INDEX!";             break;
 
153
        }
 
154
 
 
155
        return txt;
 
156
    }
 
157
};
 
158
 
 
159
 
 
160
static const LAYER_ID gc_seq[] = {
 
161
    B_Cu,
 
162
    In30_Cu,
 
163
    In29_Cu,
 
164
    In28_Cu,
 
165
    In27_Cu,
 
166
    In26_Cu,
 
167
    In25_Cu,
 
168
    In24_Cu,
 
169
    In23_Cu,
 
170
    In22_Cu,
 
171
    In21_Cu,
 
172
    In20_Cu,
 
173
    In19_Cu,
 
174
    In18_Cu,
 
175
    In17_Cu,
 
176
    In16_Cu,
 
177
    In15_Cu,
 
178
    In14_Cu,
 
179
    In13_Cu,
 
180
    In12_Cu,
 
181
    In11_Cu,
 
182
    In10_Cu,
 
183
    In9_Cu,
 
184
    In8_Cu,
 
185
    In7_Cu,
 
186
    In6_Cu,
 
187
    In5_Cu,
 
188
    In4_Cu,
 
189
    In3_Cu,
 
190
    In2_Cu,
 
191
    In1_Cu,
 
192
    F_Cu,
 
193
};
 
194
 
 
195
 
 
196
// flipped layer name for Gencad export (to make CAM350 imports correct)
 
197
static std::string GenCADLayerNameFlipped( int aCuCount, LAYER_ID aId )
 
198
{
 
199
    if( 1<= aId && aId <= 14 )
 
200
    {
 
201
        return StrPrintf(  "INNER%d", 14 - aId );
 
202
    }
 
203
 
 
204
    return GenCADLayerName( aCuCount, aId );
 
205
};
 
206
 
 
207
 
 
208
#endif
 
209
 
 
210
static std::string fmt_mask( LSET aSet )
 
211
{
 
212
#if 0
 
213
    return aSet.FmtHex();
 
214
#else
 
215
    return StrPrintf( "%08x", (unsigned) ( aSet & LSET::AllCuMask() ).to_ulong() );
 
216
#endif
 
217
}
 
218
 
 
219
 
96
220
// These are the export origin (the auxiliary axis)
97
221
static int GencadOffsetX, GencadOffsetY;
98
222
 
119
243
/* Driver function: processing starts here */
120
244
void PCB_EDIT_FRAME::ExportToGenCAD( wxCommandEvent& aEvent )
121
245
{
122
 
    wxFileName fn = GetBoard()->GetFileName();
123
 
    wxString   msg, ext, wildcard;
124
 
    FILE*      file;
125
 
 
126
 
    ext = wxT( "cad" );
127
 
    wildcard = _( "GenCAD 1.4 board files (.cad)|*.cad" );
 
246
    wxFileName  fn = GetBoard()->GetFileName();
 
247
    FILE*       file;
 
248
 
 
249
    wxString    ext = wxT( "cad" );
 
250
    wxString    wildcard = _( "GenCAD 1.4 board files (.cad)|*.cad" );
 
251
 
128
252
    fn.SetExt( ext );
129
253
 
130
254
    wxFileDialog dlg( this, _( "Save GenCAD Board File" ), wxGetCwd(),
136
260
 
137
261
    if( ( file = wxFopen( dlg.GetPath(), wxT( "wt" ) ) ) == NULL )
138
262
    {
 
263
        wxString    msg;
 
264
 
139
265
        msg.Printf( _( "Unable to create <%s>" ), GetChars( dlg.GetPath() ) );
140
266
        DisplayError( this, msg ); return;
141
267
    }
161
287
    BOARD*  pcb = GetBoard();
162
288
    MODULE* module;
163
289
 
164
 
    for( module = pcb->m_Modules; module != NULL; module = module->Next() )
 
290
    for( module = pcb->m_Modules; module; module = module->Next() )
165
291
    {
166
292
        module->SetFlag( 0 );
167
293
 
168
 
        if( module->GetLayer() == LAYER_N_BACK )
 
294
        if( module->GetLayer() == B_Cu )
169
295
        {
170
296
            module->Flip( module->GetPosition() );
171
297
            module->SetFlag( 1 );
198
324
    SetLocaleTo_Default();  // revert to the current locale
199
325
 
200
326
    // Undo the footprints modifications (flipped footprints)
201
 
    for( module = pcb->m_Modules; module != NULL; module = module->Next() )
 
327
    for( module = pcb->m_Modules; module; module = module->Next() )
202
328
    {
203
329
        if( module->GetFlag() )
204
330
        {
222
348
// Sort vias for uniqueness
223
349
static int ViaSort( const void* aRefptr, const void* aObjptr )
224
350
{
225
 
    TRACK* padref = *(TRACK**) aRefptr;
226
 
    TRACK* padcmp = *(TRACK**) aObjptr;
 
351
    VIA* padref = *(VIA**) aRefptr;
 
352
    VIA* padcmp = *(VIA**) aObjptr;
227
353
 
228
354
    if( padref->GetWidth() != padcmp->GetWidth() )
229
355
        return padref->GetWidth() - padcmp->GetWidth();
231
357
    if( padref->GetDrillValue() != padcmp->GetDrillValue() )
232
358
        return padref->GetDrillValue() - padcmp->GetDrillValue();
233
359
 
234
 
    if( padref->GetLayerMask() != padcmp->GetLayerMask() )
235
 
        return padref->GetLayerMask() - padcmp->GetLayerMask();
 
360
    if( padref->GetLayerSet() != padcmp->GetLayerSet() )
 
361
        return padref->GetLayerSet().FmtBin().compare( padcmp->GetLayerSet().FmtBin() );
236
362
 
237
363
    return 0;
238
364
}
253
379
{
254
380
    std::vector<D_PAD*> pads;
255
381
    std::vector<D_PAD*> padstacks;
256
 
    std::vector<TRACK*> vias;
257
 
    std::vector<TRACK*> viastacks;
 
382
    std::vector<VIA*>   vias;
 
383
    std::vector<VIA*>   viastacks;
 
384
 
258
385
    padstacks.resize( 1 ); // We count pads from 1
259
386
 
260
387
    // The master layermask (i.e. the enabled layers) for padstack generation
261
 
    LAYER_MSK master_layermask = aPcb->GetDesignSettings().GetEnabledLayers();
 
388
    LSET    master_layermask = aPcb->GetDesignSettings().GetEnabledLayers();
 
389
    int     cu_count = aPcb->GetCopperLayerCount();
262
390
 
263
391
    fputs( "$PADS\n", aFile );
264
392
 
271
399
    }
272
400
 
273
401
    // The same for vias
274
 
    for( TRACK* track = aPcb->m_Track; track != NULL; track = track->Next() )
 
402
    for( VIA* via = GetFirstVia( aPcb->m_Track ); via;
 
403
            via = GetFirstVia( via->Next() ) )
275
404
    {
276
 
        if( track->Type() == PCB_VIA_T )
277
 
        {
278
 
            vias.push_back( track );
279
 
        }
 
405
        vias.push_back( via );
280
406
    }
281
407
 
282
 
    qsort( &vias[0], vias.size(), sizeof(TRACK*), ViaSort );
 
408
    qsort( &vias[0], vias.size(), sizeof(VIA*), ViaSort );
283
409
 
284
410
    // Emit vias pads
285
411
    TRACK* old_via = 0;
 
412
 
286
413
    for( unsigned i = 0; i < vias.size(); i++ )
287
414
    {
288
 
        TRACK* via = vias[i];
 
415
        VIA* via = vias[i];
 
416
 
289
417
        if( old_via && 0 == ViaSort( &old_via, &via ) )
290
418
            continue;
291
419
 
292
420
        old_via = via;
293
421
        viastacks.push_back( via );
294
 
        fprintf( aFile, "PAD V%d.%d.%X ROUND %g\nCIRCLE 0 0 %g\n",
 
422
        fprintf( aFile, "PAD V%d.%d.%s ROUND %g\nCIRCLE 0 0 %g\n",
295
423
                via->GetWidth(), via->GetDrillValue(),
296
 
                via->GetLayerMask(),
 
424
                fmt_mask( via->GetLayerSet() ).c_str(),
297
425
                via->GetDrillValue() / SCALE_FACTOR,
298
426
                via->GetWidth() / (SCALE_FACTOR * 2) );
299
427
    }
301
429
    // Emit component pads
302
430
    D_PAD* old_pad = 0;
303
431
    int    pad_name_number = 0;
 
432
 
304
433
    for( unsigned i = 0; i<pads.size(); ++i )
305
434
    {
306
435
        D_PAD* pad = pads[i];
346
475
            break;
347
476
 
348
477
        case PAD_OVAL:     // Create outline by 2 lines and 2 arcs
349
 
        {
350
 
            // OrCAD Layout call them OVAL or OBLONG - GenCAD call them FINGERs
351
 
            fprintf( aFile, " FINGER %g\n",
352
 
                     pad->GetDrillSize().x / SCALE_FACTOR );
353
 
            int dr = dx - dy;
354
 
 
355
 
            if( dr >= 0 )       // Horizontal oval
356
 
            {
357
 
                int radius = dy;
358
 
                fprintf( aFile, "LINE %g %g %g %g\n",
359
 
                         (-dr + pad->GetOffset().x) / SCALE_FACTOR,
360
 
                         (-pad->GetOffset().y - radius) / SCALE_FACTOR,
361
 
                         (dr + pad->GetOffset().x ) / SCALE_FACTOR,
362
 
                         (-pad->GetOffset().y - radius) / SCALE_FACTOR );
363
 
 
364
 
                // GenCAD arcs are (start, end, center)
365
 
                fprintf( aFile, "ARC %g %g %g %g %g %g\n",
366
 
                         (dr + pad->GetOffset().x) / SCALE_FACTOR,
367
 
                         (-pad->GetOffset().y - radius) / SCALE_FACTOR,
368
 
                         (dr + pad->GetOffset().x) / SCALE_FACTOR,
369
 
                         (-pad->GetOffset().y + radius) / SCALE_FACTOR,
370
 
                         (dr + pad->GetOffset().x) / SCALE_FACTOR,
371
 
                         -pad->GetOffset().y / SCALE_FACTOR );
372
 
 
373
 
                fprintf( aFile, "LINE %g %g %g %g\n",
374
 
                         (dr + pad->GetOffset().x) / SCALE_FACTOR,
375
 
                         (-pad->GetOffset().y + radius) / SCALE_FACTOR,
376
 
                         (-dr + pad->GetOffset().x) / SCALE_FACTOR,
377
 
                         (-pad->GetOffset().y + radius) / SCALE_FACTOR );
378
 
                fprintf( aFile, "ARC %g %g %g %g %g %g\n",
379
 
                         (-dr + pad->GetOffset().x) / SCALE_FACTOR,
380
 
                         (-pad->GetOffset().y + radius) / SCALE_FACTOR,
381
 
                         (-dr + pad->GetOffset().x) / SCALE_FACTOR,
382
 
                         (-pad->GetOffset().y - radius) / SCALE_FACTOR,
383
 
                         (-dr + pad->GetOffset().x) / SCALE_FACTOR,
384
 
                         -pad->GetOffset().y / SCALE_FACTOR );
385
 
            }
386
 
            else        // Vertical oval
387
 
            {
388
 
                dr = -dr;
389
 
                int radius = dx;
390
 
                fprintf( aFile, "LINE %g %g %g %g\n",
391
 
                         (-radius + pad->GetOffset().x) / SCALE_FACTOR,
392
 
                         (-pad->GetOffset().y - dr) / SCALE_FACTOR,
393
 
                         (-radius + pad->GetOffset().x ) / SCALE_FACTOR,
394
 
                         (-pad->GetOffset().y + dr) / SCALE_FACTOR );
395
 
                fprintf( aFile, "ARC %g %g %g %g %g %g\n",
396
 
                         (-radius + pad->GetOffset().x ) / SCALE_FACTOR,
397
 
                         (-pad->GetOffset().y + dr) / SCALE_FACTOR,
398
 
                         (radius + pad->GetOffset().x ) / SCALE_FACTOR,
399
 
                         (-pad->GetOffset().y + dr) / SCALE_FACTOR,
400
 
                         pad->GetOffset().x / SCALE_FACTOR,
401
 
                         (-pad->GetOffset().y + dr) / SCALE_FACTOR );
402
 
 
403
 
                fprintf( aFile, "LINE %g %g %g %g\n",
404
 
                         (radius + pad->GetOffset().x) / SCALE_FACTOR,
405
 
                         (-pad->GetOffset().y + dr) / SCALE_FACTOR,
406
 
                         (radius + pad->GetOffset().x) / SCALE_FACTOR,
407
 
                         (-pad->GetOffset().y - dr) / SCALE_FACTOR );
408
 
                fprintf( aFile, "ARC %g %g %g %g %g %g\n",
409
 
                         (radius + pad->GetOffset().x) / SCALE_FACTOR,
410
 
                         (-pad->GetOffset().y - dr) / SCALE_FACTOR,
411
 
                         (-radius + pad->GetOffset().x) / SCALE_FACTOR,
412
 
                         (-pad->GetOffset().y - dr) / SCALE_FACTOR,
413
 
                         pad->GetOffset().x / SCALE_FACTOR,
414
 
                         (-pad->GetOffset().y - dr) / SCALE_FACTOR );
 
478
            {
 
479
                // OrCAD Layout call them OVAL or OBLONG - GenCAD call them FINGERs
 
480
                fprintf( aFile, " FINGER %g\n",
 
481
                         pad->GetDrillSize().x / SCALE_FACTOR );
 
482
                int dr = dx - dy;
 
483
 
 
484
                if( dr >= 0 )       // Horizontal oval
 
485
                {
 
486
                    int radius = dy;
 
487
                    fprintf( aFile, "LINE %g %g %g %g\n",
 
488
                             (-dr + pad->GetOffset().x) / SCALE_FACTOR,
 
489
                             (-pad->GetOffset().y - radius) / SCALE_FACTOR,
 
490
                             (dr + pad->GetOffset().x ) / SCALE_FACTOR,
 
491
                             (-pad->GetOffset().y - radius) / SCALE_FACTOR );
 
492
 
 
493
                    // GenCAD arcs are (start, end, center)
 
494
                    fprintf( aFile, "ARC %g %g %g %g %g %g\n",
 
495
                             (dr + pad->GetOffset().x) / SCALE_FACTOR,
 
496
                             (-pad->GetOffset().y - radius) / SCALE_FACTOR,
 
497
                             (dr + pad->GetOffset().x) / SCALE_FACTOR,
 
498
                             (-pad->GetOffset().y + radius) / SCALE_FACTOR,
 
499
                             (dr + pad->GetOffset().x) / SCALE_FACTOR,
 
500
                             -pad->GetOffset().y / SCALE_FACTOR );
 
501
 
 
502
                    fprintf( aFile, "LINE %g %g %g %g\n",
 
503
                             (dr + pad->GetOffset().x) / SCALE_FACTOR,
 
504
                             (-pad->GetOffset().y + radius) / SCALE_FACTOR,
 
505
                             (-dr + pad->GetOffset().x) / SCALE_FACTOR,
 
506
                             (-pad->GetOffset().y + radius) / SCALE_FACTOR );
 
507
                    fprintf( aFile, "ARC %g %g %g %g %g %g\n",
 
508
                             (-dr + pad->GetOffset().x) / SCALE_FACTOR,
 
509
                             (-pad->GetOffset().y + radius) / SCALE_FACTOR,
 
510
                             (-dr + pad->GetOffset().x) / SCALE_FACTOR,
 
511
                             (-pad->GetOffset().y - radius) / SCALE_FACTOR,
 
512
                             (-dr + pad->GetOffset().x) / SCALE_FACTOR,
 
513
                             -pad->GetOffset().y / SCALE_FACTOR );
 
514
                }
 
515
                else        // Vertical oval
 
516
                {
 
517
                    dr = -dr;
 
518
                    int radius = dx;
 
519
                    fprintf( aFile, "LINE %g %g %g %g\n",
 
520
                             (-radius + pad->GetOffset().x) / SCALE_FACTOR,
 
521
                             (-pad->GetOffset().y - dr) / SCALE_FACTOR,
 
522
                             (-radius + pad->GetOffset().x ) / SCALE_FACTOR,
 
523
                             (-pad->GetOffset().y + dr) / SCALE_FACTOR );
 
524
                    fprintf( aFile, "ARC %g %g %g %g %g %g\n",
 
525
                             (-radius + pad->GetOffset().x ) / SCALE_FACTOR,
 
526
                             (-pad->GetOffset().y + dr) / SCALE_FACTOR,
 
527
                             (radius + pad->GetOffset().x ) / SCALE_FACTOR,
 
528
                             (-pad->GetOffset().y + dr) / SCALE_FACTOR,
 
529
                             pad->GetOffset().x / SCALE_FACTOR,
 
530
                             (-pad->GetOffset().y + dr) / SCALE_FACTOR );
 
531
 
 
532
                    fprintf( aFile, "LINE %g %g %g %g\n",
 
533
                             (radius + pad->GetOffset().x) / SCALE_FACTOR,
 
534
                             (-pad->GetOffset().y + dr) / SCALE_FACTOR,
 
535
                             (radius + pad->GetOffset().x) / SCALE_FACTOR,
 
536
                             (-pad->GetOffset().y - dr) / SCALE_FACTOR );
 
537
                    fprintf( aFile, "ARC %g %g %g %g %g %g\n",
 
538
                             (radius + pad->GetOffset().x) / SCALE_FACTOR,
 
539
                             (-pad->GetOffset().y - dr) / SCALE_FACTOR,
 
540
                             (-radius + pad->GetOffset().x) / SCALE_FACTOR,
 
541
                             (-pad->GetOffset().y - dr) / SCALE_FACTOR,
 
542
                             pad->GetOffset().x / SCALE_FACTOR,
 
543
                             (-pad->GetOffset().y - dr) / SCALE_FACTOR );
 
544
                }
415
545
            }
416
546
            break;
417
 
        }
418
547
 
419
548
        case PAD_TRAPEZOID:
420
549
            fprintf( aFile, " POLYGON %g\n",
433
562
    // Via padstacks
434
563
    for( unsigned i = 0; i < viastacks.size(); i++ )
435
564
    {
436
 
        TRACK*   via  = viastacks[i];
437
 
        LAYER_MSK mask = via->GetLayerMask() & master_layermask;
438
 
        fprintf( aFile, "PADSTACK VIA%d.%d.%X %g\n",
439
 
                 via->GetWidth(), via->GetDrillValue(), mask,
 
565
        VIA* via = viastacks[i];
 
566
 
 
567
        LSET mask = via->GetLayerSet() & master_layermask;
 
568
 
 
569
        fprintf( aFile, "PADSTACK VIA%d.%d.%s %g\n",
 
570
                 via->GetWidth(), via->GetDrillValue(),
 
571
                 fmt_mask( mask ).c_str(),
440
572
                 via->GetDrillValue() / SCALE_FACTOR );
441
573
 
442
 
        for( LAYER_NUM layer = FIRST_LAYER; layer < NB_LAYERS; ++layer )
 
574
        for( LSEQ seq = mask.Seq( gc_seq, DIM( gc_seq ) );  seq;  ++seq )
443
575
        {
444
 
            if( mask & GetLayerMask( layer ) )
445
 
            {
446
 
                fprintf( aFile, "PAD V%d.%d.%X %s 0 0\n",
447
 
                        via->GetWidth(), via->GetDrillValue(),
448
 
                        mask,
449
 
                        TO_UTF8( GenCADLayerName[layer] ) );
450
 
            }
 
576
            LAYER_ID layer = *seq;
 
577
 
 
578
            fprintf( aFile, "PAD V%d.%d.%s %s 0 0\n",
 
579
                    via->GetWidth(), via->GetDrillValue(),
 
580
                    fmt_mask( mask ).c_str(),
 
581
                    GenCADLayerName( cu_count, layer ).c_str()
 
582
                    );
451
583
        }
452
584
    }
453
585
 
461
593
        D_PAD* pad = padstacks[i];
462
594
 
463
595
        // Straight padstack
464
 
        fprintf( aFile, "PADSTACK PAD%d %g\n", i,
465
 
                 pad->GetDrillSize().x / SCALE_FACTOR );
466
 
        for( LAYER_NUM layer = FIRST_LAYER; layer < NB_LAYERS; ++layer )
 
596
        fprintf( aFile, "PADSTACK PAD%d %g\n", i, pad->GetDrillSize().x / SCALE_FACTOR );
 
597
 
 
598
        LSET pad_set = pad->GetLayerSet() & master_layermask;
 
599
 
 
600
        // the special gc_seq
 
601
        for( LSEQ seq = pad_set.Seq( gc_seq, DIM( gc_seq ) );  seq;  ++seq )
467
602
        {
468
 
            if( pad->GetLayerMask() & GetLayerMask( layer ) & master_layermask )
469
 
            {
470
 
                fprintf( aFile, "PAD P%d %s 0 0\n", i,
471
 
                        TO_UTF8( GenCADLayerName[layer] ) );
472
 
            }
 
603
            LAYER_ID layer = *seq;
 
604
 
 
605
            fprintf( aFile, "PAD P%d %s 0 0\n", i, GenCADLayerName( cu_count, layer ).c_str() );
473
606
        }
474
607
 
475
608
        // Flipped padstack
476
 
        fprintf( aFile, "PADSTACK PAD%dF %g\n", i,
477
 
                 pad->GetDrillSize().x / SCALE_FACTOR );
478
 
        for( LAYER_NUM layer = FIRST_LAYER; layer < NB_LAYERS; ++layer )
 
609
        fprintf( aFile, "PADSTACK PAD%dF %g\n", i, pad->GetDrillSize().x / SCALE_FACTOR );
 
610
 
 
611
        // the normal LAYER_ID sequence is inverted from gc_seq[]
 
612
        for( LSEQ seq = pad_set.Seq();  seq;  ++seq )
479
613
        {
480
 
            if( pad->GetLayerMask() & GetLayerMask( layer ) & master_layermask )
481
 
            {
482
 
                fprintf( aFile, "PAD P%d %s 0 0\n", i,
483
 
                        TO_UTF8( GenCADLayerNameFlipped[layer] ) );
484
 
            }
 
614
            LAYER_ID layer = *seq;
 
615
 
 
616
            fprintf( aFile, "PAD P%d %s 0 0\n", i, GenCADLayerNameFlipped( cu_count, layer ).c_str() );
485
617
        }
486
618
    }
487
619
 
503
635
 
504
636
    fputs( "$SHAPES\n", aFile );
505
637
 
506
 
    for( module = aPcb->m_Modules; module != NULL; module = module->Next() )
 
638
    const LSET all_cu = LSET::AllCuMask();
 
639
 
 
640
    for( module = aPcb->m_Modules; module; module = module->Next() )
507
641
    {
508
642
        FootprintWriteShape( aFile, module );
509
643
 
510
 
        for( pad = module->Pads(); pad != NULL; pad = pad->Next() )
 
644
        for( pad = module->Pads(); pad; pad = pad->Next() )
511
645
        {
512
646
            /* Funny thing: GenCAD requires the pad side even if you use
513
647
             *  padstacks (which are theorically optional but gerbtools
516
650
             *  if the spec explicitly says it's not... */
517
651
            layer = "ALL";
518
652
 
519
 
            if( ( pad->GetLayerMask() & ALL_CU_LAYERS ) == LAYER_BACK )
 
653
            if( ( pad->GetLayerSet() & all_cu ) == LSET( B_Cu ) )
520
654
            {
521
 
                layer = ( module->GetFlag() ) ? "TOP" : "BOTTOM";
 
655
                layer = module->GetFlag() ? "TOP" : "BOTTOM";
522
656
            }
523
 
            else if( ( pad->GetLayerMask() & ALL_CU_LAYERS ) == LAYER_FRONT )
 
657
            else if( ( pad->GetLayerSet() & all_cu ) == LSET( F_Cu ) )
524
658
            {
525
 
                layer = ( module->GetFlag() ) ? "BOTTOM" : "TOP";
 
659
                layer = module->GetFlag() ? "BOTTOM" : "TOP";
526
660
            }
527
661
 
528
662
            pad->StringPadName( pinname );
557
691
{
558
692
    fputs( "$COMPONENTS\n", aFile );
559
693
 
560
 
    for( MODULE* module = aPcb->m_Modules; module != NULL; module = module->Next() )
 
694
    int cu_count = aPcb->GetCopperLayerCount();
 
695
 
 
696
    for( MODULE* module = aPcb->m_Modules; module; module = module->Next() )
561
697
    {
562
698
        TEXTE_MODULE* textmod;
563
699
        const char*   mirror;
597
733
 
598
734
        for( int ii = 0; ii < 2; ii++ )
599
735
        {
600
 
            double   orient = textmod->GetOrientation();
601
 
            wxString layer  = GenCADLayerName[(module->GetFlag()) ?
602
 
                                              SILKSCREEN_N_BACK : SILKSCREEN_N_FRONT];
 
736
            double      orient = textmod->GetOrientation();
 
737
            std::string layer  = GenCADLayerName( cu_count, module->GetFlag() ? B_SilkS : F_SilkS );
603
738
 
604
739
            fprintf( aFile, "TEXT %g %g %g %g %s %s \"%s\"",
605
740
                     textmod->GetPos0().x / SCALE_FACTOR,
607
742
                     textmod->GetSize().x / SCALE_FACTOR,
608
743
                     orient / 10.0,
609
744
                     mirror,
610
 
                     TO_UTF8( layer ),
 
745
                     layer.c_str(),
611
746
                     TO_UTF8( textmod->GetText() ) );
612
747
 
613
748
            // Please note, the width is approx
657
792
        fputs( TO_UTF8( msg ), aFile );
658
793
        fputs( "\n", aFile );
659
794
 
660
 
        for( module = aPcb->m_Modules; module != NULL; module = module->Next() )
 
795
        for( module = aPcb->m_Modules; module; module = module->Next() )
661
796
        {
662
 
            for( pad = module->Pads(); pad != NULL; pad = pad->Next() )
 
797
            for( pad = module->Pads(); pad; pad = pad->Next() )
663
798
            {
664
799
                wxString padname;
665
800
 
754
889
 */
755
890
static void CreateRoutesSection( FILE* aFile, BOARD* aPcb )
756
891
{
757
 
    TRACK*   track, ** tracklist;
758
 
    int      vianum = 1;
759
 
    int      old_netcode, old_width, old_layer;
760
 
    int      nbitems, ii;
761
 
    LAYER_MSK master_layermask = aPcb->GetDesignSettings().GetEnabledLayers();
 
892
    TRACK*  track, ** tracklist;
 
893
    int     vianum = 1;
 
894
    int     old_netcode, old_width, old_layer;
 
895
    int     nbitems, ii;
 
896
    LSET    master_layermask = aPcb->GetDesignSettings().GetEnabledLayers();
 
897
 
 
898
    int     cu_count = aPcb->GetCopperLayerCount();
762
899
 
763
900
    // Count items
764
901
    nbitems = 0;
765
902
 
766
 
    for( track = aPcb->m_Track; track != NULL; track = track->Next() )
 
903
    for( track = aPcb->m_Track; track; track = track->Next() )
767
904
        nbitems++;
768
905
 
769
 
    for( track = aPcb->m_Zone; track != NULL; track = track->Next() )
 
906
    for( track = aPcb->m_Zone; track; track = track->Next() )
770
907
    {
771
908
        if( track->Type() == PCB_ZONE_T )
772
909
            nbitems++;
776
913
 
777
914
    nbitems = 0;
778
915
 
779
 
    for( track = aPcb->m_Track; track != NULL; track = track->Next() )
 
916
    for( track = aPcb->m_Track; track; track = track->Next() )
780
917
        tracklist[nbitems++] = track;
781
918
 
782
 
    for( track = aPcb->m_Zone; track != NULL; track = track->Next() )
 
919
    for( track = aPcb->m_Zone; track; track = track->Next() )
783
920
    {
784
921
        if( track->Type() == PCB_ZONE_T )
785
922
            tracklist[nbitems++] = track;
823
960
            {
824
961
                old_layer = track->GetLayer();
825
962
                fprintf( aFile, "LAYER %s\n",
826
 
                        TO_UTF8( GenCADLayerName[track->GetLayer() & 0x1F] ) );
 
963
                        GenCADLayerName( cu_count, track->GetLayer() ).c_str()
 
964
                        );
827
965
            }
828
966
 
829
967
            fprintf( aFile, "LINE %g %g %g %g\n",
830
968
                    MapXTo( track->GetStart().x ), MapYTo( track->GetStart().y ),
831
969
                    MapXTo( track->GetEnd().x ), MapYTo( track->GetEnd().y ) );
832
970
        }
 
971
 
833
972
        if( track->Type() == PCB_VIA_T )
834
973
        {
835
 
            fprintf( aFile, "VIA VIA%d.%d.%X %g %g ALL %g via%d\n",
836
 
                     track->GetWidth(), track->GetDrillValue(),
837
 
                     track->GetLayerMask() & master_layermask,
838
 
                     MapXTo( track->GetStart().x ), MapYTo( track->GetStart().y ),
839
 
                     track->GetDrillValue() / SCALE_FACTOR, vianum++ );
 
974
            const VIA* via = static_cast<const VIA*>(track);
 
975
 
 
976
            LSET vset = via->GetLayerSet() & master_layermask;
 
977
 
 
978
            fprintf( aFile, "VIA VIA%d.%d.%s %g %g ALL %g via%d\n",
 
979
                     via->GetWidth(), via->GetDrillValue(),
 
980
                     fmt_mask( vset ).c_str(),
 
981
                     MapXTo( via->GetStart().x ), MapYTo( via->GetStart().y ),
 
982
                     via->GetDrillValue() / SCALE_FACTOR, vianum++ );
840
983
        }
841
984
    }
842
985
 
856
999
 
857
1000
    fputs( "$DEVICES\n", aFile );
858
1001
 
859
 
    for( module = aPcb->m_Modules; module != NULL; module = module->Next() )
 
1002
    for( module = aPcb->m_Modules; module; module = module->Next() )
860
1003
    {
861
1004
        fprintf( aFile, "DEVICE \"%s\"\n", TO_UTF8( module->GetReference() ) );
862
1005
        fprintf( aFile, "PART \"%s\"\n", TO_UTF8( module->GetValue() ) );
893
1036
        if( drawing->Type() == PCB_LINE_T )
894
1037
        {
895
1038
            DRAWSEGMENT* drawseg = dynamic_cast<DRAWSEGMENT*>( drawing );
896
 
            if( drawseg->GetLayer() == EDGE_N )
 
1039
            if( drawseg->GetLayer() == Edge_Cuts )
897
1040
            {
898
1041
                // XXX GenCAD supports arc boundaries but I've seen nothing that reads them
899
1042
                fprintf( aFile, "LINE %g %g %g %g\n",
929
1072
 
930
1073
    unsigned          ii;
931
1074
 
932
 
    for( track = aPcb->m_Track; track != NULL; track = track->Next() )
 
1075
    for( track = aPcb->m_Track; track; track = track->Next() )
933
1076
    {
934
1077
        if( last_width != track->GetWidth() ) // Find a thickness already used.
935
1078
        {
946
1089
        }
947
1090
    }
948
1091
 
949
 
    for( track = aPcb->m_Zone; track != NULL; track = track->Next() )
 
1092
    for( track = aPcb->m_Zone; track; track = track->Next() )
950
1093
    {
951
1094
        if( last_width != track->GetWidth() ) // Find a thickness already used.
952
1095
        {
1033
1176
    // CAM350 read it right but only closed shapes
1034
1177
    // ProntoPlace double-flip it (at least the pads are correct)
1035
1178
    // GerberTool usually get it right...
1036
 
    for( PtStruct = module->GraphicalItems(); PtStruct != NULL; PtStruct = PtStruct->Next() )
 
1179
    for( PtStruct = module->GraphicalItems(); PtStruct; PtStruct = PtStruct->Next() )
1037
1180
    {
1038
1181
        switch( PtStruct->Type() )
1039
1182
        {
1044
1187
 
1045
1188
        case PCB_MODULE_EDGE_T:
1046
1189
            PtEdge = (EDGE_MODULE*) PtStruct;
1047
 
            if( PtEdge->GetLayer() == SILKSCREEN_N_FRONT
1048
 
                || PtEdge->GetLayer() == SILKSCREEN_N_BACK )
 
1190
            if( PtEdge->GetLayer() == F_SilkS
 
1191
                || PtEdge->GetLayer() == B_SilkS )
1049
1192
            {
1050
1193
                switch( PtEdge->GetShape() )
1051
1194
                {