Loading pcbnew/specctra.cpp +16 −19 Original line number Original line Diff line number Diff line Loading @@ -2702,36 +2702,32 @@ void SPECCTRA_DB::doWIRE( WIRE* growth ) throw( IOError ) switch( tok ) switch( tok ) { { case T_rect: case T_rect: case T_circle: if( growth->shape ) case T_path: case T_polygon: case T_qarc: if( growth->rectangle || growth->circle || growth->path || growth->qarc ) unexpected( tok ); unexpected( tok ); default: ; growth->shape = new RECTANGLE( growth ); } doRECTANGLE( (RECTANGLE*) growth->shape ); switch( tok ) { case T_rect: growth->rectangle = new RECTANGLE( growth ); doRECTANGLE( growth->rectangle ); break; break; case T_circle: case T_circle: growth->circle = new CIRCLE( growth ); if( growth->shape ) doCIRCLE( growth->circle ); unexpected( tok ); growth->shape = new CIRCLE( growth ); doCIRCLE( (CIRCLE*) growth->shape ); break; break; case T_path: case T_path: case T_polygon: case T_polygon: growth->path = new PATH( growth, tok ); if( growth->shape ) doPATH( growth->path ); unexpected( tok ); growth->shape = new PATH( growth, tok ); doPATH( (PATH*) growth->shape ); break; break; case T_qarc: case T_qarc: growth->qarc = new QARC( growth ); if( growth->shape ) doQARC( growth->qarc ); unexpected( tok ); growth->shape = new QARC( growth ); doQARC( (QARC*) growth->shape ); break; break; case T_net: case T_net: Loading Loading @@ -3472,6 +3468,7 @@ PCB* SPECCTRA_DB::MakePCB() pcb->structure->rules = new RULE( pcb->structure, T_rule ); pcb->structure->rules = new RULE( pcb->structure, T_rule ); pcb->placement = new PLACEMENT( pcb ); pcb->placement = new PLACEMENT( pcb ); pcb->placement->flip_style = T_mirror_first; pcb->library = new LIBRARY( pcb ); pcb->library = new LIBRARY( pcb ); Loading pcbnew/specctra.h +37 −33 Original line number Original line Diff line number Diff line Loading @@ -1782,7 +1782,7 @@ public: ELEM( T_placement, aParent ) ELEM( T_placement, aParent ) { { unit = 0; unit = 0; flip_style = T_NONE; flip_style = T_mirror_first; } } ~PLACEMENT() ~PLACEMENT() Loading Loading @@ -2660,12 +2660,14 @@ class WIRE : public ELEM { { friend class SPECCTRA_DB; friend class SPECCTRA_DB; //----- only one of these is used, like a union ----- /* <shape_descriptor >::= PATH* path; ///< used for both path and polygon [<rectangle_descriptor> | RECTANGLE* rectangle; <circle_descriptor> | CIRCLE* circle; <polygon_descriptor> | QARC* qarc; <path_descriptor> | //--------------------------------------------------- <qarc_descriptor> ] */ ELEM* shape; std::string net_id; std::string net_id; int turret; int turret; Loading @@ -2680,10 +2682,7 @@ public: WIRE( ELEM* aParent ) : WIRE( ELEM* aParent ) : ELEM( T_wire, aParent ) ELEM( T_wire, aParent ) { { path = 0; shape = 0; rectangle = 0; circle = 0; qarc = 0; connect = 0; connect = 0; turret = -1; turret = -1; Loading @@ -2694,27 +2693,29 @@ public: ~WIRE() ~WIRE() { { delete path; delete shape; delete rectangle; delete circle; delete qarc; delete connect; delete connect; } } void FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError ) void SetShape( ELEM* aShape ) { { // these are mutually exclusive delete shape; if( rectangle ) shape = aShape; rectangle->Format( out, nestLevel ); else if( path ) if( aShape ) path->Format( out, nestLevel ); { wxASSERT(aShape->Type()==T_rect || aShape->Type()==T_circle || aShape->Type()==T_qarc || aShape->Type()==T_path || aShape->Type()==T_polygon); else if( circle ) aShape->SetParent( this ); circle->Format( out, nestLevel ); } } else if( qarc ) void FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError ) qarc->Format( out, nestLevel ); { if( shape ) shape->Format( out, nestLevel ); if( net_id.size() ) if( net_id.size() ) { { Loading Loading @@ -3406,6 +3407,9 @@ class SPECCTRA_DB : public OUTPUTFORMATTER STRINGFORMATTER sf; STRINGFORMATTER sf; // FromBOARD() uses this STRINGS layerIds; /** /** * Function nextTok * Function nextTok Loading pcbnew/specctra_export.cpp +142 −66 Original line number Original line Diff line number Diff line Loading @@ -214,6 +214,26 @@ static int Pad_list_Sort_by_Shapes( const void* refptr, const void* objptr ) } } /*********************************************************************/ static int Track_list_Sort_by_Netcode( const void* o1, const void* o2 ) /*********************************************************************/ { TRACK* t1 = *(TRACK**) o1; TRACK* t2 = *(TRACK**) o2; int diff; if( (diff = t1->GetNet() - t2->GetNet()) ) return diff; if( (diff = t1->m_Width - t2->m_Width) ) return diff; if( (diff = t1->GetLayer() - t2->GetLayer()) ) return diff; return diff; // zero here } /** /** * Function makePath * Function makePath * creates a PATH element with a single straight line, a pair of vertices. * creates a PATH element with a single straight line, a pair of vertices. Loading Loading @@ -309,28 +329,6 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads ) #define COPPER_LAYERS 2 // top and bottom #define COPPER_LAYERS 2 // top and bottom int reportedLayers = COPPER_LAYERS; // how many layers are reported. // for now, report on only the top and bottom layers with respect to the copper // within a pad's padstack. this is usually correct, but not rigorous. We could do // better if there was actually a "layer type" field within Kicad which would // hold one of: T_signal, T_power, T_mixed, T_jumper // See bottom of page 74 of the SECCTRA Design Language Reference, May 2000. std::string layerId[COPPER_LAYERS] = { CONV_TO_UTF8(aBoard->GetLayerName( LAYER_CMP_N )), CONV_TO_UTF8(aBoard->GetLayerName( COPPER_LAYER_N )), }; #if 1 // Late breaking news: we can use the reserved layer name "signal" and report the // padstack as a single layer. See <reserved_layer_name> in the spec. // But this probably gives problems for a "power" layer or power pin, we'll see. reportedLayers = 1; layerId[0] = "signal"; #endif for( int i=0; i<aPads.GetCount(); ++i ) for( int i=0; i<aPads.GetCount(); ++i ) { { D_PAD* pad = (D_PAD*) aPads[i]; D_PAD* pad = (D_PAD*) aPads[i]; Loading Loading @@ -359,10 +357,6 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads ) continue; continue; } } #if 1 // late breaking news..... see above doLayer[0] = true; #endif old_pad = pad; old_pad = pad; PADSTACK* padstack = new PADSTACK( pcb->library ); PADSTACK* padstack = new PADSTACK( pcb->library ); Loading @@ -378,7 +372,17 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads ) // Note that the y correction here is set negative. // Note that the y correction here is set negative. POINT padOffset( scale(pad->m_Offset.x), -scale(pad->m_Offset.y) ); POINT padOffset( scale(pad->m_Offset.x), -scale(pad->m_Offset.y) ); int coppers = 0; // for now, we will report only one layer for the pads. SMD pads are reported on the // top layer, and through hole are reported on <reserved_layer_name> "signal" int reportedLayers = 1; // how many layers are reported. doLayer[0] = true; const char* layerName = ( pad->m_Attribut == PAD_SMD ) ? layerIds[0].c_str() : "signal"; int coppers = 0; // will always be one for now switch( pad->m_PadShape ) switch( pad->m_PadShape ) { { Loading @@ -397,7 +401,7 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads ) CIRCLE* circle = new CIRCLE( shape ); CIRCLE* circle = new CIRCLE( shape ); shape->SetShape( circle ); shape->SetShape( circle ); circle->SetLayerId( layerId[layer].c_str() ); circle->SetLayerId( layerName ); circle->SetDiameter( diameter ); circle->SetDiameter( diameter ); circle->SetVertex( padOffset ); circle->SetVertex( padOffset ); ++coppers; ++coppers; Loading Loading @@ -436,7 +440,7 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads ) RECTANGLE* rect = new RECTANGLE( shape ); RECTANGLE* rect = new RECTANGLE( shape ); shape->SetShape( rect ); shape->SetShape( rect ); rect->SetLayerId( layerId[layer].c_str() ); rect->SetLayerId( layerName ); rect->SetCorners( lowerLeft, upperRight ); rect->SetCorners( lowerLeft, upperRight ); ++coppers; ++coppers; } } Loading Loading @@ -479,7 +483,7 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads ) path = makePath( path = makePath( POINT( -dr + padOffset.x, padOffset.y - radius ), // aStart POINT( -dr + padOffset.x, padOffset.y - radius ), // aStart POINT( dr + padOffset.x, padOffset.y - radius ), // aEnd POINT( dr + padOffset.x, padOffset.y - radius ), // aEnd layerId[layer] ); layerName ); shape->SetShape( path ); shape->SetShape( path ); shape = new SHAPE( padstack ); shape = new SHAPE( padstack ); Loading @@ -489,7 +493,7 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads ) POINT( dr + padOffset.x, padOffset.y - radius), // aStart POINT( dr + padOffset.x, padOffset.y - radius), // aStart POINT( dr + padOffset.x, padOffset.y + radius), // aEnd POINT( dr + padOffset.x, padOffset.y + radius), // aEnd POINT( dr + padOffset.x, padOffset.y ), // aCenter POINT( dr + padOffset.x, padOffset.y ), // aCenter layerId[layer] ); layerName ); shape->SetShape( qarc ); shape->SetShape( qarc ); shape = new SHAPE( padstack ); shape = new SHAPE( padstack ); Loading @@ -497,7 +501,7 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads ) path = makePath( path = makePath( POINT( dr + padOffset.x, padOffset.y + radius ), // aStart POINT( dr + padOffset.x, padOffset.y + radius ), // aStart POINT( -dr + padOffset.x, padOffset.y + radius ), // aEnd POINT( -dr + padOffset.x, padOffset.y + radius ), // aEnd layerId[layer] ); layerName ); shape->SetShape( path ); shape->SetShape( path ); shape = new SHAPE( padstack ); shape = new SHAPE( padstack ); Loading @@ -507,7 +511,7 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads ) POINT( -dr + padOffset.x, padOffset.y + radius), // aStart POINT( -dr + padOffset.x, padOffset.y + radius), // aStart POINT( -dr + padOffset.x, padOffset.y - radius), // aEnd POINT( -dr + padOffset.x, padOffset.y - radius), // aEnd POINT( -dr + padOffset.x, padOffset.y ), // aCenter POINT( -dr + padOffset.x, padOffset.y ), // aCenter layerId[layer] ); layerName ); shape->SetShape( qarc ); shape->SetShape( qarc ); ++coppers; ++coppers; } } Loading @@ -534,7 +538,7 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads ) path = makePath( path = makePath( POINT( -radius + padOffset.x, padOffset.y - dr ), // aStart POINT( -radius + padOffset.x, padOffset.y - dr ), // aStart POINT( -radius + padOffset.x, padOffset.y + dr ), // aEnd POINT( -radius + padOffset.x, padOffset.y + dr ), // aEnd layerId[layer] ); layerName ); shape->SetShape( path ); shape->SetShape( path ); shape = new SHAPE( padstack ); shape = new SHAPE( padstack ); Loading @@ -544,7 +548,7 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads ) POINT( -radius + padOffset.x, padOffset.y + dr ), // aStart POINT( -radius + padOffset.x, padOffset.y + dr ), // aStart POINT( radius + padOffset.x, padOffset.y + dr), // aEnd POINT( radius + padOffset.x, padOffset.y + dr), // aEnd POINT( padOffset.x, padOffset.y +dr ), // aCenter POINT( padOffset.x, padOffset.y +dr ), // aCenter layerId[layer] ); layerName ); shape->SetShape( qarc ); shape->SetShape( qarc ); shape = new SHAPE( padstack ); shape = new SHAPE( padstack ); Loading @@ -552,7 +556,7 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads ) path = makePath( path = makePath( POINT( radius + padOffset.x, padOffset.y + dr ), // aStart POINT( radius + padOffset.x, padOffset.y + dr ), // aStart POINT( radius + padOffset.x, padOffset.y - dr ), // aEnd POINT( radius + padOffset.x, padOffset.y - dr ), // aEnd layerId[layer] ); layerName ); shape->SetShape( path ); shape->SetShape( path ); shape = new SHAPE( padstack ); shape = new SHAPE( padstack ); Loading @@ -562,7 +566,7 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads ) POINT( radius + padOffset.x, padOffset.y - dr), // aStart POINT( radius + padOffset.x, padOffset.y - dr), // aStart POINT( -radius + padOffset.x, padOffset.y - dr), // aEnd POINT( -radius + padOffset.x, padOffset.y - dr), // aEnd POINT( padOffset.x, padOffset.y - dr ), // aCenter POINT( padOffset.x, padOffset.y - dr ), // aCenter layerId[layer] ); layerName ); shape->SetShape( qarc ); shape->SetShape( qarc ); ++coppers; ++coppers; } } Loading Loading @@ -607,7 +611,7 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads ) CIRCLE* circle = new CIRCLE( shape ); CIRCLE* circle = new CIRCLE( shape ); shape->SetShape( circle ); shape->SetShape( circle ); circle->SetLayerId( layerId[0].c_str() ); circle->SetLayerId( "signal" ); circle->SetDiameter( scale(defaultViaSize) ); circle->SetDiameter( scale(defaultViaSize) ); padstack->SetPadstackId( "Via_Default" ); padstack->SetPadstackId( "Via_Default" ); Loading @@ -630,7 +634,7 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads ) CIRCLE* circle = new CIRCLE( shape ); CIRCLE* circle = new CIRCLE( shape ); shape->SetShape( circle ); shape->SetShape( circle ); circle->SetLayerId( layerId[0].c_str() ); circle->SetLayerId( "signal" ); circle->SetDiameter( scale(viaSize) ); circle->SetDiameter( scale(viaSize) ); snprintf( name, sizeof(name), "Via_%.6g_mil", scale(viaSize) ); snprintf( name, sizeof(name), "Via_%.6g_mil", scale(viaSize) ); Loading Loading @@ -663,6 +667,43 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) } } } } // Since none of these statements cause any immediate output, the order // of them is somewhat flexible. The outputting to disk is done at the // end. We start by gathering all the layer information from the board. //-----<layer_descriptor>----------------------------------------------- { // specctra wants top physical layer first, then going down to the // bottom most physical layer in physical sequence. // @question : why does Kicad not display layers in that order? int layerCount = aBoard->GetCopperLayerCount(); layerIds.clear(); for( int ndx=layerCount-1; ndx >= 0; --ndx ) { // save the specctra layer name in SPECCTRA_DB::layerIds for later. layerIds.push_back( CONV_TO_UTF8( aBoard->GetLayerName( ndx>0 && ndx==layerCount-1 ? LAYER_CMP_N : ndx ))); LAYER* layer = new LAYER( pcb->structure ); pcb->structure->layers.push_back( layer ); layer->name = layerIds.back(); // layer->type = @todo need this, the export would be better. } } // for now, report on only the top and bottom layers with respect to the copper // within a pad's padstack. this is usually correct, but not rigorous. We could do // better if there was actually a "layer type" field within Kicad which would // hold one of: T_signal, T_power, T_mixed, T_jumper // See bottom of page 74 of the SECCTRA Design Language Reference, May 2000. // a space in a quoted token is NOT a terminator, true establishes this. // a space in a quoted token is NOT a terminator, true establishes this. pcb->parser->space_in_quoted_tokens = true; pcb->parser->space_in_quoted_tokens = true; Loading Loading @@ -764,27 +805,6 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) } } //-----<layer_descriptor>----------------------------------------------- { // specctra wants top physical layer first, then going down to the // bottom most physical layer in physical sequence. // @question : why does Kicad not display layers in that order? int layerCount = aBoard->GetCopperLayerCount(); for( int ndx=layerCount-1; ndx >= 0; --ndx ) { wxString layerName = aBoard->GetLayerName( ndx>0 && ndx==layerCount-1 ? LAYER_CMP_N : ndx ); LAYER* layer = new LAYER( pcb->structure ); layer->name = CONV_TO_UTF8( layerName ); // layer->type = @todo need this, the export would be better. pcb->structure->layers.push_back( layer ); } } //-----<zone containers become planes>-------------------------------------------- //-----<zone containers become planes>-------------------------------------------- { { static const KICAD_T scanZONEs[] = { TYPEZONE_CONTAINER, EOT }; static const KICAD_T scanZONEs[] = { TYPEZONE_CONTAINER, EOT }; Loading @@ -794,13 +814,13 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) { { ZONE_CONTAINER* item = (ZONE_CONTAINER*) items[i]; ZONE_CONTAINER* item = (ZONE_CONTAINER*) items[i]; wxString layerName = aBoard->GetLayerName( item->GetLayer() ); COPPER_PLANE* plane = new COPPER_PLANE( pcb->structure ); COPPER_PLANE* plane = new COPPER_PLANE( pcb->structure ); PATH* polygon = new PATH( plane, T_polygon ); PATH* polygon = new PATH( plane, T_polygon ); plane->SetShape( polygon ); plane->SetShape( polygon ); plane->name = CONV_TO_UTF8( item->m_Netname ); plane->name = CONV_TO_UTF8( item->m_Netname ); wxString layerName = aBoard->GetLayerName( item->GetLayer() ); polygon->layer_id = CONV_TO_UTF8( layerName ); polygon->layer_id = CONV_TO_UTF8( layerName ); int count = item->m_Poly->corner.size(); int count = item->m_Poly->corner.size(); Loading Loading @@ -938,18 +958,75 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) //-----<create the wires from tracks>----------------------------------- //-----<create the wires from tracks>----------------------------------- { { #if 0 // export all of them for now, later we'll decide what controls we need // export all of them for now, later we'll decide what controls we need // on this. // on this. static KICAD_T scanTRACKs[] = { TYPETRACK, TYPEVIA, EOT }; static KICAD_T scanTRACKs[] = { TYPETRACK, TYPEVIA, EOT }; items.Collect( aBoard, scanTRACKs ); items.Collect( aBoard, scanTRACKs ); if( items.GetCount() ) qsort( (void*) items.BasePtr(), items.GetCount(), sizeof(TRACK*), Track_list_Sort_by_Netcode ); WIRING* wiring = pcb->wiring; WIRE* wire; int old_netcode = -1; int old_width = -1; int old_layer = -1; for( int i=0; i<items.GetCount(); ++i ) for( int i=0; i<items.GetCount(); ++i ) { { TRACK* torv = (TRACK*) items[i]; // torv == track or via TRACK* track = (TRACK*) items[i]; // torv == track or via if( track->GetNet() == 0 ) continue; if( old_netcode != track->GetNet() ) { old_netcode = track->GetNet(); EQUIPOT* equipot = aBoard->FindNet( track->GetNet() ); wxASSERT( equipot ); wire = new WIRE( wiring ); wiring->wires.push_back( wire ); wire->net_id = CONV_TO_UTF8( equipot->m_Netname ); } } if( old_width != track->m_Width ) { old_width = track->m_Width; wire = new WIRE( wiring ); wiring.wires.push_back( wire ); wire->net_id = CONV_TO_UTF8( equipot->m_NetName ); } if( (track->Type() == TYPETRACK) || (track->Type() == TYPEZONE) ) { if( old_layer != track->GetLayer() ) { old_layer = track->GetLayer(); fprintf( file, "LAYER %s\n", CONV_TO_UTF8( GenCAD_Layer_Name[track->GetLayer() & 0x1F] ) ); } fprintf( file, "LINE %d %d %d %d\n", mapXto( track->m_Start.x ), mapYto( track->m_Start.y ), mapXto( track->m_End.x ), mapYto( track->m_End.y ) ); } if( track->Type() == TYPEVIA ) { fprintf( file, "VIA viapad%d %d %d ALL %d via%d\n", track->m_Width, mapXto( track->m_Start.x ), mapYto( track->m_Start.y ), g_DesignSettings.m_ViaDrill, vianum++ ); } } #endif } } //-----<restore MODULEs>------------------------------------------------ //-----<restore MODULEs>------------------------------------------------ Loading @@ -964,7 +1041,6 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) module->flag = 0; module->flag = 0; } } } } } } Loading Loading
pcbnew/specctra.cpp +16 −19 Original line number Original line Diff line number Diff line Loading @@ -2702,36 +2702,32 @@ void SPECCTRA_DB::doWIRE( WIRE* growth ) throw( IOError ) switch( tok ) switch( tok ) { { case T_rect: case T_rect: case T_circle: if( growth->shape ) case T_path: case T_polygon: case T_qarc: if( growth->rectangle || growth->circle || growth->path || growth->qarc ) unexpected( tok ); unexpected( tok ); default: ; growth->shape = new RECTANGLE( growth ); } doRECTANGLE( (RECTANGLE*) growth->shape ); switch( tok ) { case T_rect: growth->rectangle = new RECTANGLE( growth ); doRECTANGLE( growth->rectangle ); break; break; case T_circle: case T_circle: growth->circle = new CIRCLE( growth ); if( growth->shape ) doCIRCLE( growth->circle ); unexpected( tok ); growth->shape = new CIRCLE( growth ); doCIRCLE( (CIRCLE*) growth->shape ); break; break; case T_path: case T_path: case T_polygon: case T_polygon: growth->path = new PATH( growth, tok ); if( growth->shape ) doPATH( growth->path ); unexpected( tok ); growth->shape = new PATH( growth, tok ); doPATH( (PATH*) growth->shape ); break; break; case T_qarc: case T_qarc: growth->qarc = new QARC( growth ); if( growth->shape ) doQARC( growth->qarc ); unexpected( tok ); growth->shape = new QARC( growth ); doQARC( (QARC*) growth->shape ); break; break; case T_net: case T_net: Loading Loading @@ -3472,6 +3468,7 @@ PCB* SPECCTRA_DB::MakePCB() pcb->structure->rules = new RULE( pcb->structure, T_rule ); pcb->structure->rules = new RULE( pcb->structure, T_rule ); pcb->placement = new PLACEMENT( pcb ); pcb->placement = new PLACEMENT( pcb ); pcb->placement->flip_style = T_mirror_first; pcb->library = new LIBRARY( pcb ); pcb->library = new LIBRARY( pcb ); Loading
pcbnew/specctra.h +37 −33 Original line number Original line Diff line number Diff line Loading @@ -1782,7 +1782,7 @@ public: ELEM( T_placement, aParent ) ELEM( T_placement, aParent ) { { unit = 0; unit = 0; flip_style = T_NONE; flip_style = T_mirror_first; } } ~PLACEMENT() ~PLACEMENT() Loading Loading @@ -2660,12 +2660,14 @@ class WIRE : public ELEM { { friend class SPECCTRA_DB; friend class SPECCTRA_DB; //----- only one of these is used, like a union ----- /* <shape_descriptor >::= PATH* path; ///< used for both path and polygon [<rectangle_descriptor> | RECTANGLE* rectangle; <circle_descriptor> | CIRCLE* circle; <polygon_descriptor> | QARC* qarc; <path_descriptor> | //--------------------------------------------------- <qarc_descriptor> ] */ ELEM* shape; std::string net_id; std::string net_id; int turret; int turret; Loading @@ -2680,10 +2682,7 @@ public: WIRE( ELEM* aParent ) : WIRE( ELEM* aParent ) : ELEM( T_wire, aParent ) ELEM( T_wire, aParent ) { { path = 0; shape = 0; rectangle = 0; circle = 0; qarc = 0; connect = 0; connect = 0; turret = -1; turret = -1; Loading @@ -2694,27 +2693,29 @@ public: ~WIRE() ~WIRE() { { delete path; delete shape; delete rectangle; delete circle; delete qarc; delete connect; delete connect; } } void FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError ) void SetShape( ELEM* aShape ) { { // these are mutually exclusive delete shape; if( rectangle ) shape = aShape; rectangle->Format( out, nestLevel ); else if( path ) if( aShape ) path->Format( out, nestLevel ); { wxASSERT(aShape->Type()==T_rect || aShape->Type()==T_circle || aShape->Type()==T_qarc || aShape->Type()==T_path || aShape->Type()==T_polygon); else if( circle ) aShape->SetParent( this ); circle->Format( out, nestLevel ); } } else if( qarc ) void FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError ) qarc->Format( out, nestLevel ); { if( shape ) shape->Format( out, nestLevel ); if( net_id.size() ) if( net_id.size() ) { { Loading Loading @@ -3406,6 +3407,9 @@ class SPECCTRA_DB : public OUTPUTFORMATTER STRINGFORMATTER sf; STRINGFORMATTER sf; // FromBOARD() uses this STRINGS layerIds; /** /** * Function nextTok * Function nextTok Loading
pcbnew/specctra_export.cpp +142 −66 Original line number Original line Diff line number Diff line Loading @@ -214,6 +214,26 @@ static int Pad_list_Sort_by_Shapes( const void* refptr, const void* objptr ) } } /*********************************************************************/ static int Track_list_Sort_by_Netcode( const void* o1, const void* o2 ) /*********************************************************************/ { TRACK* t1 = *(TRACK**) o1; TRACK* t2 = *(TRACK**) o2; int diff; if( (diff = t1->GetNet() - t2->GetNet()) ) return diff; if( (diff = t1->m_Width - t2->m_Width) ) return diff; if( (diff = t1->GetLayer() - t2->GetLayer()) ) return diff; return diff; // zero here } /** /** * Function makePath * Function makePath * creates a PATH element with a single straight line, a pair of vertices. * creates a PATH element with a single straight line, a pair of vertices. Loading Loading @@ -309,28 +329,6 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads ) #define COPPER_LAYERS 2 // top and bottom #define COPPER_LAYERS 2 // top and bottom int reportedLayers = COPPER_LAYERS; // how many layers are reported. // for now, report on only the top and bottom layers with respect to the copper // within a pad's padstack. this is usually correct, but not rigorous. We could do // better if there was actually a "layer type" field within Kicad which would // hold one of: T_signal, T_power, T_mixed, T_jumper // See bottom of page 74 of the SECCTRA Design Language Reference, May 2000. std::string layerId[COPPER_LAYERS] = { CONV_TO_UTF8(aBoard->GetLayerName( LAYER_CMP_N )), CONV_TO_UTF8(aBoard->GetLayerName( COPPER_LAYER_N )), }; #if 1 // Late breaking news: we can use the reserved layer name "signal" and report the // padstack as a single layer. See <reserved_layer_name> in the spec. // But this probably gives problems for a "power" layer or power pin, we'll see. reportedLayers = 1; layerId[0] = "signal"; #endif for( int i=0; i<aPads.GetCount(); ++i ) for( int i=0; i<aPads.GetCount(); ++i ) { { D_PAD* pad = (D_PAD*) aPads[i]; D_PAD* pad = (D_PAD*) aPads[i]; Loading Loading @@ -359,10 +357,6 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads ) continue; continue; } } #if 1 // late breaking news..... see above doLayer[0] = true; #endif old_pad = pad; old_pad = pad; PADSTACK* padstack = new PADSTACK( pcb->library ); PADSTACK* padstack = new PADSTACK( pcb->library ); Loading @@ -378,7 +372,17 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads ) // Note that the y correction here is set negative. // Note that the y correction here is set negative. POINT padOffset( scale(pad->m_Offset.x), -scale(pad->m_Offset.y) ); POINT padOffset( scale(pad->m_Offset.x), -scale(pad->m_Offset.y) ); int coppers = 0; // for now, we will report only one layer for the pads. SMD pads are reported on the // top layer, and through hole are reported on <reserved_layer_name> "signal" int reportedLayers = 1; // how many layers are reported. doLayer[0] = true; const char* layerName = ( pad->m_Attribut == PAD_SMD ) ? layerIds[0].c_str() : "signal"; int coppers = 0; // will always be one for now switch( pad->m_PadShape ) switch( pad->m_PadShape ) { { Loading @@ -397,7 +401,7 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads ) CIRCLE* circle = new CIRCLE( shape ); CIRCLE* circle = new CIRCLE( shape ); shape->SetShape( circle ); shape->SetShape( circle ); circle->SetLayerId( layerId[layer].c_str() ); circle->SetLayerId( layerName ); circle->SetDiameter( diameter ); circle->SetDiameter( diameter ); circle->SetVertex( padOffset ); circle->SetVertex( padOffset ); ++coppers; ++coppers; Loading Loading @@ -436,7 +440,7 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads ) RECTANGLE* rect = new RECTANGLE( shape ); RECTANGLE* rect = new RECTANGLE( shape ); shape->SetShape( rect ); shape->SetShape( rect ); rect->SetLayerId( layerId[layer].c_str() ); rect->SetLayerId( layerName ); rect->SetCorners( lowerLeft, upperRight ); rect->SetCorners( lowerLeft, upperRight ); ++coppers; ++coppers; } } Loading Loading @@ -479,7 +483,7 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads ) path = makePath( path = makePath( POINT( -dr + padOffset.x, padOffset.y - radius ), // aStart POINT( -dr + padOffset.x, padOffset.y - radius ), // aStart POINT( dr + padOffset.x, padOffset.y - radius ), // aEnd POINT( dr + padOffset.x, padOffset.y - radius ), // aEnd layerId[layer] ); layerName ); shape->SetShape( path ); shape->SetShape( path ); shape = new SHAPE( padstack ); shape = new SHAPE( padstack ); Loading @@ -489,7 +493,7 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads ) POINT( dr + padOffset.x, padOffset.y - radius), // aStart POINT( dr + padOffset.x, padOffset.y - radius), // aStart POINT( dr + padOffset.x, padOffset.y + radius), // aEnd POINT( dr + padOffset.x, padOffset.y + radius), // aEnd POINT( dr + padOffset.x, padOffset.y ), // aCenter POINT( dr + padOffset.x, padOffset.y ), // aCenter layerId[layer] ); layerName ); shape->SetShape( qarc ); shape->SetShape( qarc ); shape = new SHAPE( padstack ); shape = new SHAPE( padstack ); Loading @@ -497,7 +501,7 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads ) path = makePath( path = makePath( POINT( dr + padOffset.x, padOffset.y + radius ), // aStart POINT( dr + padOffset.x, padOffset.y + radius ), // aStart POINT( -dr + padOffset.x, padOffset.y + radius ), // aEnd POINT( -dr + padOffset.x, padOffset.y + radius ), // aEnd layerId[layer] ); layerName ); shape->SetShape( path ); shape->SetShape( path ); shape = new SHAPE( padstack ); shape = new SHAPE( padstack ); Loading @@ -507,7 +511,7 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads ) POINT( -dr + padOffset.x, padOffset.y + radius), // aStart POINT( -dr + padOffset.x, padOffset.y + radius), // aStart POINT( -dr + padOffset.x, padOffset.y - radius), // aEnd POINT( -dr + padOffset.x, padOffset.y - radius), // aEnd POINT( -dr + padOffset.x, padOffset.y ), // aCenter POINT( -dr + padOffset.x, padOffset.y ), // aCenter layerId[layer] ); layerName ); shape->SetShape( qarc ); shape->SetShape( qarc ); ++coppers; ++coppers; } } Loading @@ -534,7 +538,7 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads ) path = makePath( path = makePath( POINT( -radius + padOffset.x, padOffset.y - dr ), // aStart POINT( -radius + padOffset.x, padOffset.y - dr ), // aStart POINT( -radius + padOffset.x, padOffset.y + dr ), // aEnd POINT( -radius + padOffset.x, padOffset.y + dr ), // aEnd layerId[layer] ); layerName ); shape->SetShape( path ); shape->SetShape( path ); shape = new SHAPE( padstack ); shape = new SHAPE( padstack ); Loading @@ -544,7 +548,7 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads ) POINT( -radius + padOffset.x, padOffset.y + dr ), // aStart POINT( -radius + padOffset.x, padOffset.y + dr ), // aStart POINT( radius + padOffset.x, padOffset.y + dr), // aEnd POINT( radius + padOffset.x, padOffset.y + dr), // aEnd POINT( padOffset.x, padOffset.y +dr ), // aCenter POINT( padOffset.x, padOffset.y +dr ), // aCenter layerId[layer] ); layerName ); shape->SetShape( qarc ); shape->SetShape( qarc ); shape = new SHAPE( padstack ); shape = new SHAPE( padstack ); Loading @@ -552,7 +556,7 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads ) path = makePath( path = makePath( POINT( radius + padOffset.x, padOffset.y + dr ), // aStart POINT( radius + padOffset.x, padOffset.y + dr ), // aStart POINT( radius + padOffset.x, padOffset.y - dr ), // aEnd POINT( radius + padOffset.x, padOffset.y - dr ), // aEnd layerId[layer] ); layerName ); shape->SetShape( path ); shape->SetShape( path ); shape = new SHAPE( padstack ); shape = new SHAPE( padstack ); Loading @@ -562,7 +566,7 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads ) POINT( radius + padOffset.x, padOffset.y - dr), // aStart POINT( radius + padOffset.x, padOffset.y - dr), // aStart POINT( -radius + padOffset.x, padOffset.y - dr), // aEnd POINT( -radius + padOffset.x, padOffset.y - dr), // aEnd POINT( padOffset.x, padOffset.y - dr ), // aCenter POINT( padOffset.x, padOffset.y - dr ), // aCenter layerId[layer] ); layerName ); shape->SetShape( qarc ); shape->SetShape( qarc ); ++coppers; ++coppers; } } Loading Loading @@ -607,7 +611,7 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads ) CIRCLE* circle = new CIRCLE( shape ); CIRCLE* circle = new CIRCLE( shape ); shape->SetShape( circle ); shape->SetShape( circle ); circle->SetLayerId( layerId[0].c_str() ); circle->SetLayerId( "signal" ); circle->SetDiameter( scale(defaultViaSize) ); circle->SetDiameter( scale(defaultViaSize) ); padstack->SetPadstackId( "Via_Default" ); padstack->SetPadstackId( "Via_Default" ); Loading @@ -630,7 +634,7 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads ) CIRCLE* circle = new CIRCLE( shape ); CIRCLE* circle = new CIRCLE( shape ); shape->SetShape( circle ); shape->SetShape( circle ); circle->SetLayerId( layerId[0].c_str() ); circle->SetLayerId( "signal" ); circle->SetDiameter( scale(viaSize) ); circle->SetDiameter( scale(viaSize) ); snprintf( name, sizeof(name), "Via_%.6g_mil", scale(viaSize) ); snprintf( name, sizeof(name), "Via_%.6g_mil", scale(viaSize) ); Loading Loading @@ -663,6 +667,43 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) } } } } // Since none of these statements cause any immediate output, the order // of them is somewhat flexible. The outputting to disk is done at the // end. We start by gathering all the layer information from the board. //-----<layer_descriptor>----------------------------------------------- { // specctra wants top physical layer first, then going down to the // bottom most physical layer in physical sequence. // @question : why does Kicad not display layers in that order? int layerCount = aBoard->GetCopperLayerCount(); layerIds.clear(); for( int ndx=layerCount-1; ndx >= 0; --ndx ) { // save the specctra layer name in SPECCTRA_DB::layerIds for later. layerIds.push_back( CONV_TO_UTF8( aBoard->GetLayerName( ndx>0 && ndx==layerCount-1 ? LAYER_CMP_N : ndx ))); LAYER* layer = new LAYER( pcb->structure ); pcb->structure->layers.push_back( layer ); layer->name = layerIds.back(); // layer->type = @todo need this, the export would be better. } } // for now, report on only the top and bottom layers with respect to the copper // within a pad's padstack. this is usually correct, but not rigorous. We could do // better if there was actually a "layer type" field within Kicad which would // hold one of: T_signal, T_power, T_mixed, T_jumper // See bottom of page 74 of the SECCTRA Design Language Reference, May 2000. // a space in a quoted token is NOT a terminator, true establishes this. // a space in a quoted token is NOT a terminator, true establishes this. pcb->parser->space_in_quoted_tokens = true; pcb->parser->space_in_quoted_tokens = true; Loading Loading @@ -764,27 +805,6 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) } } //-----<layer_descriptor>----------------------------------------------- { // specctra wants top physical layer first, then going down to the // bottom most physical layer in physical sequence. // @question : why does Kicad not display layers in that order? int layerCount = aBoard->GetCopperLayerCount(); for( int ndx=layerCount-1; ndx >= 0; --ndx ) { wxString layerName = aBoard->GetLayerName( ndx>0 && ndx==layerCount-1 ? LAYER_CMP_N : ndx ); LAYER* layer = new LAYER( pcb->structure ); layer->name = CONV_TO_UTF8( layerName ); // layer->type = @todo need this, the export would be better. pcb->structure->layers.push_back( layer ); } } //-----<zone containers become planes>-------------------------------------------- //-----<zone containers become planes>-------------------------------------------- { { static const KICAD_T scanZONEs[] = { TYPEZONE_CONTAINER, EOT }; static const KICAD_T scanZONEs[] = { TYPEZONE_CONTAINER, EOT }; Loading @@ -794,13 +814,13 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) { { ZONE_CONTAINER* item = (ZONE_CONTAINER*) items[i]; ZONE_CONTAINER* item = (ZONE_CONTAINER*) items[i]; wxString layerName = aBoard->GetLayerName( item->GetLayer() ); COPPER_PLANE* plane = new COPPER_PLANE( pcb->structure ); COPPER_PLANE* plane = new COPPER_PLANE( pcb->structure ); PATH* polygon = new PATH( plane, T_polygon ); PATH* polygon = new PATH( plane, T_polygon ); plane->SetShape( polygon ); plane->SetShape( polygon ); plane->name = CONV_TO_UTF8( item->m_Netname ); plane->name = CONV_TO_UTF8( item->m_Netname ); wxString layerName = aBoard->GetLayerName( item->GetLayer() ); polygon->layer_id = CONV_TO_UTF8( layerName ); polygon->layer_id = CONV_TO_UTF8( layerName ); int count = item->m_Poly->corner.size(); int count = item->m_Poly->corner.size(); Loading Loading @@ -938,18 +958,75 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) //-----<create the wires from tracks>----------------------------------- //-----<create the wires from tracks>----------------------------------- { { #if 0 // export all of them for now, later we'll decide what controls we need // export all of them for now, later we'll decide what controls we need // on this. // on this. static KICAD_T scanTRACKs[] = { TYPETRACK, TYPEVIA, EOT }; static KICAD_T scanTRACKs[] = { TYPETRACK, TYPEVIA, EOT }; items.Collect( aBoard, scanTRACKs ); items.Collect( aBoard, scanTRACKs ); if( items.GetCount() ) qsort( (void*) items.BasePtr(), items.GetCount(), sizeof(TRACK*), Track_list_Sort_by_Netcode ); WIRING* wiring = pcb->wiring; WIRE* wire; int old_netcode = -1; int old_width = -1; int old_layer = -1; for( int i=0; i<items.GetCount(); ++i ) for( int i=0; i<items.GetCount(); ++i ) { { TRACK* torv = (TRACK*) items[i]; // torv == track or via TRACK* track = (TRACK*) items[i]; // torv == track or via if( track->GetNet() == 0 ) continue; if( old_netcode != track->GetNet() ) { old_netcode = track->GetNet(); EQUIPOT* equipot = aBoard->FindNet( track->GetNet() ); wxASSERT( equipot ); wire = new WIRE( wiring ); wiring->wires.push_back( wire ); wire->net_id = CONV_TO_UTF8( equipot->m_Netname ); } } if( old_width != track->m_Width ) { old_width = track->m_Width; wire = new WIRE( wiring ); wiring.wires.push_back( wire ); wire->net_id = CONV_TO_UTF8( equipot->m_NetName ); } if( (track->Type() == TYPETRACK) || (track->Type() == TYPEZONE) ) { if( old_layer != track->GetLayer() ) { old_layer = track->GetLayer(); fprintf( file, "LAYER %s\n", CONV_TO_UTF8( GenCAD_Layer_Name[track->GetLayer() & 0x1F] ) ); } fprintf( file, "LINE %d %d %d %d\n", mapXto( track->m_Start.x ), mapYto( track->m_Start.y ), mapXto( track->m_End.x ), mapYto( track->m_End.y ) ); } if( track->Type() == TYPEVIA ) { fprintf( file, "VIA viapad%d %d %d ALL %d via%d\n", track->m_Width, mapXto( track->m_Start.x ), mapYto( track->m_Start.y ), g_DesignSettings.m_ViaDrill, vianum++ ); } } #endif } } //-----<restore MODULEs>------------------------------------------------ //-----<restore MODULEs>------------------------------------------------ Loading @@ -964,7 +1041,6 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) module->flag = 0; module->flag = 0; } } } } } } Loading