diff --git a/change_log.txt b/change_log.txt index 3fc3b118a8..c312f9ad6c 100644 --- a/change_log.txt +++ b/change_log.txt @@ -8,7 +8,10 @@ email address. 2008-Feb-7 UPDATE Dick Hollenbeck ================================================================================ +pcbnew - specctra import of *.ses, done by end of today probably. + specctra import of *.ses, did tracks and components. + renamed copy_track.cpp to copy_track.cpp.notused + removed copy_track.cpp from pcbnew/CMakeLists.txt + added setlocale() around import and export for float text style. 2008-Feb-6 UPDATE Dick Hollenbeck diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index 646287b5e8..be6a863ac9 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -39,7 +39,7 @@ SET(PCBNEW_SRCS collectors.cpp connect.cpp controle.cpp - copy_track.cpp +# copy_track.cpp cotation.cpp cross-probing.cpp deltrack.cpp @@ -74,7 +74,7 @@ SET(PCBNEW_SRCS files.cpp find.cpp gen_drill_report_files.cpp - gen_holes_and_tools_lists_for_drill.cpp + gen_holes_and_tools_lists_for_drill.cpp gen_modules_placefile.cpp gendrill.cpp globaleditpad.cpp diff --git a/pcbnew/basepcbframe.cpp b/pcbnew/basepcbframe.cpp index 8c8545276f..4189fa8bc5 100644 --- a/pcbnew/basepcbframe.cpp +++ b/pcbnew/basepcbframe.cpp @@ -41,7 +41,7 @@ WinEDA_BasePcbFrame::WinEDA_BasePcbFrame( wxWindow* father, const wxString& title, const wxPoint& pos, const wxSize& size, - long style) : + long style) : WinEDA_DrawFrame( father, idtype, parent, title, pos, size, style ) { m_InternalUnits = 10000; // Internal unit = 1/10000 inch @@ -103,9 +103,9 @@ void WinEDA_BasePcbFrame::CursorGoto( const wxPoint& aPos ) // factored out of pcbnew/find.cpp PCB_SCREEN* screen = GetScreen(); - + wxClientDC dc( DrawPanel ); - + /* Il y a peut-etre necessite de recadrer le dessin: */ if( !DrawPanel->IsPointOnDisplay( aPos ) ) { @@ -159,10 +159,10 @@ void WinEDA_BasePcbFrame::Show3D_Frame( wxCommandEvent& event ) DisplayInfo( this, _( "3D Frame already opened" ) ); return; } - + #ifdef CVPCB m_Draw3DFrame = new WinEDA3D_DrawFrame( this, m_Parent, _( "3D Viewer" ), - KICAD_DEFAULT_3D_DRAWFRAME_STYLE | wxFRAME_FLOAT_ON_PARENT ); + KICAD_DEFAULT_3D_DRAWFRAME_STYLE | wxFRAME_FLOAT_ON_PARENT ); #else m_Draw3DFrame = new WinEDA3D_DrawFrame( this, m_Parent, _( "3D Viewer" ) ); #endif @@ -277,23 +277,23 @@ void WinEDA_BasePcbFrame::SetCurItem( BOARD_ITEM* aItem ) /*****************************************************************/ { m_CurrentScreen->SetCurItem( aItem ); - + if( aItem ) { aItem->Display_Infos( this ); - -#if 0 && defined(DEBUG) + +#if 1 && defined(DEBUG) aItem->Show( 0, std::cout ); #endif - + } else { // we can use either of these two: - + //MsgPanel->EraseMsgBox(); m_Pcb->Display_Infos( this ); // show the BOARD stuff - + #if 0 && defined(DEBUG) std::cout << "SetCurItem(NULL)\n"; #endif diff --git a/pcbnew/copy_track.cpp b/pcbnew/copy_track.cpp deleted file mode 100644 index 4847c7f1f6..0000000000 --- a/pcbnew/copy_track.cpp +++ /dev/null @@ -1,287 +0,0 @@ - /*******************************************/ - /* Track editing: routines to copy tracks */ - /*******************************************/ - -#include "fctsys.h" -#include "gr_basic.h" - -#include "common.h" -#include "pcbnew.h" -#include "autorout.h" - -#include "drag.h" - -#include "protos.h" - - -/* local functions */ - - -/* variables locales */ - - -#if 0 - -/***************************************************************/ -void WinEDA_PcbFrame::Place_Dupl_Track(Track * Track, wxDC * DC) -/***************************************************************/ -/* - Routine de placement d'une piste (succession de segments) -*/ -{ -D_PAD * pt_pad; -TRACK * pt_track, *Track, * pt_classe, *NextS; -int masquelayer; -EDA_BaseStruct * LockPoint; -int ii, old_net_code, new_net_code, DRC_error = 0; -wxDC * DC = Cmd->DC; - - ActiveDrawPanel->ManageCurseur = NULL; - - if( NewTrack == NULL ) return ; - - old_net_code = NewTrack->net_code; - - /* Placement du flag BUSY de la piste originelle, qui ne doit - pas etre vue dans les recherches de raccordement suivantes */ - ii = NbPtNewTrack; pt_track = NewTrack; - for ( ; ii > 0; ii --, pt_track = (TRACK*) pt_track->Pnext) - { - pt_track->SetState(BUSY, ON); - } - - /* Detection du nouveau net_code */ - ii = NbPtNewTrack; pt_track = NewTrack; - for ( ; ii > 0; ii --, pt_track = (TRACK*) pt_track->Pnext) - { - pt_track->net_code = 0; - } - - new_net_code = 0; - ii = 0; pt_track = NewTrack; - for( ; ii < NbPtNewTrack ; ii++, pt_track = (TRACK*)pt_track->Pnext) - { - /* Localisation de la pastille ou segment en debut de segment: */ - masquelayer = tab_layer[pt_track->Layer]; - LockPoint = LocateLockPoint(pt_track->m_Start.x,pt_track->m_Start.y,masquelayer); - if( LockPoint ) - { - if ( LockPoint->Type() == TYPEPAD ) - { - pt_pad = (D_PAD*) LockPoint; - new_net_code = pt_pad->net_code; - if ( new_net_code > 0 ) break; - } - else /* debut de piste sur un segment de piste */ - { - Track = (TRACK *) LockPoint; - new_net_code = Track->net_code; - if ( new_net_code > 0 ) break; - } - } - LockPoint = LocateLockPoint(pt_track->m_End.x,pt_track->m_End.y,masquelayer); - if( LockPoint ) - { - if ( LockPoint->Type() == TYPEPAD ) - { - pt_pad = (D_PAD*) LockPoint; - new_net_code = pt_pad->net_code; - if ( new_net_code > 0 ) break; - } - else /* debut de piste sur un segment de piste */ - { - Track = (TRACK *) LockPoint; - new_net_code = Track->net_code; - if ( new_net_code > 0 ) break; - } - } - } - - /* Mise a jour du nouveau net code de la piste */ - ii = 0; pt_track = NewTrack; - for( ; ii < NbPtNewTrack; ii++, pt_track = (TRACK*)pt_track->Pnext) - { - pt_track->net_code = new_net_code; - } - - /* Controle DRC de la nouvelle piste */ - ii = 0; pt_track = NewTrack; - for( ; ii < NbPtNewTrack; ii++, pt_track = pt_track->Next() ) - { - if( Drc_On == RUN ) - if( drc(DC, pt_track, pt_pcb->Track, 1) == BAD_DRC ) - { - if( confirmation(" Erreur DRC, Place piste:") == YES ) continue; - else { DRC_error = 1; break; } - } - } - - if( DRC_error == 0) - { - if(FlagState == MOVE_ROUTE) - { - /* copie nouvelle piste */ - pt_track = NewTrack; - NewTrack = pt_track->Copy(NbPtNewTrack); - /* effacement ancienne ( chainage et liens mauvais */ - ii = NbPtNewTrack; - for ( ; ii > 0; ii --, pt_track = NextS) - { - NextS = (TRACK*) pt_track->Pnext; - pt_track->DeleteStructure(); - } - test_1_net_connexion(DC, old_net_code ); - } - - pt_classe = NewTrack->GetBestInsertPoint(); - NewTrack->Insert(pt_classe); - - Trace_Une_Piste(DC, NewTrack,NbPtNewTrack,GR_OR) ; - - /* Mise a jour des connexions sur pads et sur pistes */ - ii = 0; pt_track = NewTrack; - for( ; ii < NbPtNewTrack; ii++, pt_track = NextS) - { - NextS = (TRACK*)pt_track->Pnext; - pt_track->SetState(BEGIN_ONPAD|END_ONPAD, OFF); - masquelayer = tab_layer[pt_track->Layer]; - - /* Localisation de la pastille ou segment sur debut segment: */ - LockPoint = LocateLockPoint(pt_track->m_Start.x,pt_track->m_Start.y,masquelayer); - if( LockPoint ) - { - pt_track->start = LockPoint; - if ( LockPoint->Type() == TYPEPAD ) - { /* fin de piste sur un pad */ - pt_pad = (D_PAD*) LockPoint; - pt_track->SetState(BEGIN_ONPAD, ON); - } - else /* debut de piste sur un segment de piste */ - { - Track = (TRACK *) LockPoint; - CreateLockPoint(&pt_track->m_Start.x,&pt_track->m_Start.y,Track,pt_track); - } - } - - /* Localisation de la pastille ou segment sur fin de segment: */ - LockPoint = LocateLockPoint(pt_track->m_End.x,pt_track->m_End.y,masquelayer); - if( LockPoint ) - { - pt_track->end = LockPoint; - if ( LockPoint->Type() == TYPEPAD ) - { /* fin de piste sur un pad */ - pt_pad = (D_PAD*) LockPoint; - pt_track->SetState(END_ONPAD, ON); - } - else /* debut de piste sur un segment de piste */ - { - Track = (TRACK *) LockPoint; - CreateLockPoint(&pt_track->m_Start.x,&pt_track->m_Start.y,Track,pt_track); - } - } - } - - /* Clear the BUSY flag */ - ii = NbPtNewTrack; pt_track = NewTrack; - for ( ; ii > 0; ii --, pt_track = (TRACK*) pt_track->Pnext) - { - pt_track->SetState(BUSY, OFF); - } - - test_1_net_connexion(DC, new_net_code ); - ActiveScreen->SetModify(); - } - - else /* DRC error: Annulation commande */ - { - DisplayOpt.DisplayPcbTrackFill = FALSE ; - Trace_Une_Piste(DC, NewTrack,NbPtNewTrack,GR_XOR); - DisplayOpt.DisplayPcbTrackFill = Track_fill_copy ; - - if(FlagState == MOVE_ROUTE) - { /* Remise en position de la piste deplacee */ - Track = NewTrack; - PosInitX -= Track->m_Start.x; PosInitY -= Track->m_Start.y; - for( ii = 0; ii < NbPtNewTrack; ii++, Track = (TRACK*) Track->Pnext) - { - if( Track == NULL ) break; - Track->m_Start.x += PosInitX; Track->m_Start.y += PosInitY; - Track->m_End.x += PosInitX; Track->m_End.y += PosInitY; - Track->SetState(BUSY,OFF); - } - Trace_Une_Piste(DC, NewTrack,NbPtNewTrack,GR_OR); - } - - if (FlagState == COPY_ROUTE ) - { /* Suppression copie */ - for( ii = 0; ii < NbPtNewTrack; NewTrack = NextS) - { - if(NewTrack == NULL) break; - NextS = (TRACK*) NewTrack->Pnext; - delete NewTrack; - } - } - } - NewTrack = NULL; - Affiche_Infos_Status_Pcb(Cmd); - if(Etat_Surbrillance) Hight_Light(DC); -} - -/*******************************************************************************/ -void WinEDA_PcbFrame::Start_CopyOrMove_Route(TRACK * track, wxDC * DC, bool Drag) -/*******************************************************************************/ -/* Routine permettant la recopie d'une piste (suite de segments) deja tracee -*/ -{ -int ii; -TRACK *pt_segm, *pt_track; -int masquelayer = tab_layer[ActiveScreen->Active_Layer]; - - if( NewTrack ) return; - - FlagState = (int)Cmd->Menu->param_inf; - - /* Recherche de la piste sur la couche active (non zone) */ - for(pt_segm = pt_pcb->Track; pt_segm != NULL; pt_segm = (TRACK*)pt_segm->Pnext) - { - pt_segm = Locate_Pistes(pt_segm,masquelayer, CURSEUR_OFF_GRILLE); - if( pt_segm == NULL ) break ; - break ; - } - - if( pt_segm != NULL ) - { - if (FlagState == COPY_ROUTE ) - pt_track = Marque_Une_Piste(DC, pt_segm, &NbPtNewTrack, 0); - else pt_track = Marque_Une_Piste(DC, pt_segm, &NbPtNewTrack, GR_XOR); - - if(NbPtNewTrack) /* Il y a NbPtNewTrack segments de piste a traiter */ - { - /* effacement du flag BUSY de la piste originelle */ - ii = NbPtNewTrack; pt_segm = pt_track; - for ( ; ii > 0; ii --, pt_segm = (TRACK*) pt_segm->Pnext) - { - pt_segm->SetState(BUSY, OFF); - } - - if (FlagState == COPY_ROUTE ) - NewTrack = pt_track->Copy(NbPtNewTrack); - else NewTrack = pt_track; - - Affiche_Infos_Piste(Cmd, pt_track) ; - - startX = ActiveScreen->Curseur_X; - startY = ActiveScreen->Curseur_Y; - Place_Dupl_Route_Item.State = WAIT; - ActiveDrawPanel->ManageCurseur = Show_Move_Piste; - DisplayOpt.DisplayPcbTrackFill = FALSE ; - Trace_Une_Piste(DC, NewTrack,NbPtNewTrack,GR_XOR) ; - DisplayOpt.DisplayPcbTrackFill = Track_fill_copy ; - PosInitX = NewTrack->m_Start.x; PosInitY = NewTrack->m_Start.y; - } - } -} - - -#endif - diff --git a/pcbnew/copy_track.cpp.notused b/pcbnew/copy_track.cpp.notused new file mode 100644 index 0000000000..b2d00722ee --- /dev/null +++ b/pcbnew/copy_track.cpp.notused @@ -0,0 +1,306 @@ +/*******************************************/ +/* Track editing: routines to copy tracks */ +/*******************************************/ + +#include "fctsys.h" +#include "gr_basic.h" + +#include "common.h" +#include "pcbnew.h" +#include "autorout.h" + +#include "drag.h" + +#include "protos.h" + + +/* local functions */ + + +/* variables locales */ + + +#if 0 + +/***************************************************************/ +void WinEDA_PcbFrame::Place_Dupl_Track( Track* Track, wxDC* DC ) +/***************************************************************/ + +/* + * Routine de placement d'une piste (succession de segments) + */ +{ + D_PAD* pt_pad; + TRACK* pt_track, * Track, * pt_classe, * NextS; + int masquelayer; + EDA_BaseStruct* LockPoint; + int ii, old_net_code, new_net_code, DRC_error = 0; + wxDC* DC = Cmd->DC; + + ActiveDrawPanel->ManageCurseur = NULL; + + if( NewTrack == NULL ) + return; + + old_net_code = NewTrack->net_code; + + /* Placement du flag BUSY de la piste originelle, qui ne doit + * pas etre vue dans les recherches de raccordement suivantes */ + ii = NbPtNewTrack; pt_track = NewTrack; + for( ; ii > 0; ii--, pt_track = (TRACK*) pt_track->Pnext ) + { + pt_track->SetState( BUSY, ON ); + } + + /* Detection du nouveau net_code */ + ii = NbPtNewTrack; pt_track = NewTrack; + for( ; ii > 0; ii--, pt_track = (TRACK*) pt_track->Pnext ) + { + pt_track->net_code = 0; + } + + new_net_code = 0; + ii = 0; pt_track = NewTrack; + for( ; ii < NbPtNewTrack; ii++, pt_track = (TRACK*) pt_track->Pnext ) + { + /* Localisation de la pastille ou segment en debut de segment: */ + masquelayer = tab_layer[pt_track->Layer]; + LockPoint = LocateLockPoint( pt_track->m_Start.x, pt_track->m_Start.y, masquelayer ); + if( LockPoint ) + { + if( LockPoint->Type() == TYPEPAD ) + { + pt_pad = (D_PAD*) LockPoint; + new_net_code = pt_pad->net_code; + if( new_net_code > 0 ) + break; + } + else /* debut de piste sur un segment de piste */ + { + Track = (TRACK*) LockPoint; + new_net_code = Track->net_code; + if( new_net_code > 0 ) + break; + } + } + LockPoint = LocateLockPoint( pt_track->m_End.x, pt_track->m_End.y, masquelayer ); + if( LockPoint ) + { + if( LockPoint->Type() == TYPEPAD ) + { + pt_pad = (D_PAD*) LockPoint; + new_net_code = pt_pad->net_code; + if( new_net_code > 0 ) + break; + } + else /* debut de piste sur un segment de piste */ + { + Track = (TRACK*) LockPoint; + new_net_code = Track->net_code; + if( new_net_code > 0 ) + break; + } + } + } + + /* Mise a jour du nouveau net code de la piste */ + ii = 0; pt_track = NewTrack; + for( ; ii < NbPtNewTrack; ii++, pt_track = (TRACK*) pt_track->Pnext ) + { + pt_track->net_code = new_net_code; + } + + /* Controle DRC de la nouvelle piste */ + ii = 0; pt_track = NewTrack; + for( ; ii < NbPtNewTrack; ii++, pt_track = pt_track->Next() ) + { + if( Drc_On == RUN ) + if( drc( DC, pt_track, pt_pcb->Track, 1 ) == BAD_DRC ) + { + if( confirmation( " Erreur DRC, Place piste:" ) == YES ) + continue; + else + { + DRC_error = 1; break; + } + } + } + + if( DRC_error == 0 ) + { + if( FlagState == MOVE_ROUTE ) + { + /* copie nouvelle piste */ + pt_track = NewTrack; + NewTrack = pt_track->Copy( NbPtNewTrack ); + /* effacement ancienne ( chainage et liens mauvais */ + ii = NbPtNewTrack; + for( ; ii > 0; ii--, pt_track = NextS ) + { + NextS = (TRACK*) pt_track->Pnext; + pt_track->DeleteStructure(); + } + + test_1_net_connexion( DC, old_net_code ); + } + + pt_classe = NewTrack->GetBestInsertPoint(); + NewTrack->Insert( pt_classe ); + + Trace_Une_Piste( DC, NewTrack, NbPtNewTrack, GR_OR ); + + /* Mise a jour des connexions sur pads et sur pistes */ + ii = 0; pt_track = NewTrack; + for( ; ii < NbPtNewTrack; ii++, pt_track = NextS ) + { + NextS = (TRACK*) pt_track->Pnext; + pt_track->SetState( BEGIN_ONPAD | END_ONPAD, OFF ); + masquelayer = tab_layer[pt_track->Layer]; + + /* Localisation de la pastille ou segment sur debut segment: */ + LockPoint = LocateLockPoint( pt_track->m_Start.x, pt_track->m_Start.y, masquelayer ); + if( LockPoint ) + { + pt_track->start = LockPoint; + if( LockPoint->Type() == TYPEPAD ) + { /* fin de piste sur un pad */ + pt_pad = (D_PAD*) LockPoint; + pt_track->SetState( BEGIN_ONPAD, ON ); + } + else /* debut de piste sur un segment de piste */ + { + Track = (TRACK*) LockPoint; + CreateLockPoint( &pt_track->m_Start.x, &pt_track->m_Start.y, Track, pt_track ); + } + } + + /* Localisation de la pastille ou segment sur fin de segment: */ + LockPoint = LocateLockPoint( pt_track->m_End.x, pt_track->m_End.y, masquelayer ); + if( LockPoint ) + { + pt_track->end = LockPoint; + if( LockPoint->Type() == TYPEPAD ) + { /* fin de piste sur un pad */ + pt_pad = (D_PAD*) LockPoint; + pt_track->SetState( END_ONPAD, ON ); + } + else /* debut de piste sur un segment de piste */ + { + Track = (TRACK*) LockPoint; + CreateLockPoint( &pt_track->m_Start.x, &pt_track->m_Start.y, Track, pt_track ); + } + } + } + + /* Clear the BUSY flag */ + ii = NbPtNewTrack; pt_track = NewTrack; + for( ; ii > 0; ii--, pt_track = (TRACK*) pt_track->Pnext ) + { + pt_track->SetState( BUSY, OFF ); + } + + test_1_net_connexion( DC, new_net_code ); + ActiveScreen->SetModify(); + } + else /* DRC error: Annulation commande */ + { + DisplayOpt.DisplayPcbTrackFill = FALSE; + Trace_Une_Piste( DC, NewTrack, NbPtNewTrack, GR_XOR ); + DisplayOpt.DisplayPcbTrackFill = Track_fill_copy; + + if( FlagState == MOVE_ROUTE ) + { /* Remise en position de la piste deplacee */ + Track = NewTrack; + PosInitX -= Track->m_Start.x; PosInitY -= Track->m_Start.y; + for( ii = 0; ii < NbPtNewTrack; ii++, Track = (TRACK*) Track->Pnext ) + { + if( Track == NULL ) + break; + Track->m_Start.x += PosInitX; Track->m_Start.y += PosInitY; + Track->m_End.x += PosInitX; Track->m_End.y += PosInitY; + Track->SetState( BUSY, OFF ); + } + + Trace_Une_Piste( DC, NewTrack, NbPtNewTrack, GR_OR ); + } + + if( FlagState == COPY_ROUTE ) + { /* Suppression copie */ + for( ii = 0; ii < NbPtNewTrack; NewTrack = NextS ) + { + if( NewTrack == NULL ) + break; + NextS = (TRACK*) NewTrack->Pnext; + delete NewTrack; + } + } + } + NewTrack = NULL; + Affiche_Infos_Status_Pcb( Cmd ); + if( Etat_Surbrillance ) + Hight_Light( DC ); +} + + +/*******************************************************************************/ +void WinEDA_PcbFrame::Start_CopyOrMove_Route( TRACK* track, wxDC* DC, bool Drag ) +/*******************************************************************************/ + +/* Routine permettant la recopie d'une piste (suite de segments) deja tracee + */ +{ + int ii; + TRACK* pt_segm, * pt_track; + int masquelayer = tab_layer[ActiveScreen->Active_Layer]; + + if( NewTrack ) + return; + + FlagState = (int) Cmd->Menu->param_inf; + + /* Recherche de la piste sur la couche active (non zone) */ + for( pt_segm = pt_pcb->Track; pt_segm != NULL; pt_segm = (TRACK*) pt_segm->Pnext ) + { + pt_segm = Locate_Pistes( pt_segm, masquelayer, CURSEUR_OFF_GRILLE ); + if( pt_segm == NULL ) + break; + break; + } + + if( pt_segm != NULL ) + { + if( FlagState == COPY_ROUTE ) + pt_track = Marque_Une_Piste( DC, pt_segm, &NbPtNewTrack, 0 ); + else + pt_track = Marque_Une_Piste( DC, pt_segm, &NbPtNewTrack, GR_XOR ); + + if( NbPtNewTrack ) /* Il y a NbPtNewTrack segments de piste a traiter */ + { + /* effacement du flag BUSY de la piste originelle */ + ii = NbPtNewTrack; pt_segm = pt_track; + for( ; ii > 0; ii--, pt_segm = (TRACK*) pt_segm->Pnext ) + { + pt_segm->SetState( BUSY, OFF ); + } + + if( FlagState == COPY_ROUTE ) + NewTrack = pt_track->Copy( NbPtNewTrack ); + else + NewTrack = pt_track; + + Affiche_Infos_Piste( Cmd, pt_track ); + + startX = ActiveScreen->Curseur_X; + startY = ActiveScreen->Curseur_Y; + Place_Dupl_Route_Item.State = WAIT; + ActiveDrawPanel->ManageCurseur = Show_Move_Piste; + DisplayOpt.DisplayPcbTrackFill = FALSE; + Trace_Une_Piste( DC, NewTrack, NbPtNewTrack, GR_XOR ); + DisplayOpt.DisplayPcbTrackFill = Track_fill_copy; + PosInitX = NewTrack->m_Start.x; PosInitY = NewTrack->m_Start.y; + } + } +} + + +#endif diff --git a/pcbnew/specctra.cpp b/pcbnew/specctra.cpp index 9643d7f924..2aaa14bea2 100644 --- a/pcbnew/specctra.cpp +++ b/pcbnew/specctra.cpp @@ -76,6 +76,43 @@ namespace DSN { //------------------------------------------------------ + +void SPECCTRA_DB::buildLayerMaps( BOARD* aBoard ) +{ + // 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(); + pcbLayer2kicad.resize( layerCount ); + kicadLayer2pcb.resize( LAYER_CMP_N+1 ); + + for( int kiNdx=layerCount-1, pcbNdx=0; kiNdx >= 0; --kiNdx, ++pcbNdx ) + { + int kilayer = kiNdx>0 && kiNdx==layerCount-1 ? LAYER_CMP_N : kiNdx; + + // establish bi-directional mapping between kicad's BOARD layer and PCB layer + pcbLayer2kicad[pcbNdx] = kilayer; + kicadLayer2pcb[kilayer] = pcbNdx; + + // save the specctra layer name in SPECCTRA_DB::layerIds for later. + layerIds.push_back( CONV_TO_UTF8( aBoard->GetLayerName( kilayer ) ) ); + } +} + + +int SPECCTRA_DB::findLayerName( const std::string& aLayerName ) const +{ + for( unsigned i=0; i pcbLayer2kicad; + /// used during FromSESSION() only, memory for it is not owned here. + UNIT_RES* routeResolution; + + /// a copy to avoid passing as an argument, memory for it is not owned here. + BOARD* sessionBoard; + static const KICAD_T scanPADs[]; + /** + * Function buildLayerMaps + * creates a few data translation structures for layer name and number + * mapping between the DSN::PCB structure and the kicad BOARD structure. + * @param aBoard The BOARD to create the maps for. + */ + void buildLayerMaps( BOARD* aBoard ); + + /** + * Function findLayerName + * returns the PCB layer index for a given layer name + */ + int findLayerName( const std::string& aLayerName ) const; /** * Function nextTok @@ -3698,6 +3725,17 @@ class SPECCTRA_DB : public OUTPUTFORMATTER */ PADSTACK* makeVia( const SEGVIA* aVia ); + + //---------------------------------------------------------- + + /** + * Function makeTRACK + * creates a TRACK form the PATH and BOARD info. + */ + TRACK* makeTRACK( PATH* aPath, int aPointIndex, int aNetcode ) throw( IOError ); + + //--------------------------------------------------------- + public: SPECCTRA_DB() diff --git a/pcbnew/specctra_export.cpp b/pcbnew/specctra_export.cpp index 1f9f7c58bb..ccd9113ecf 100644 --- a/pcbnew/specctra_export.cpp +++ b/pcbnew/specctra_export.cpp @@ -701,27 +701,17 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) // 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? + + buildLayerMaps( aBoard ); + int layerCount = aBoard->GetCopperLayerCount(); - layerIds.clear(); - pcbLayer2kicad.resize( layerCount ); - kicadLayer2pcb.resize( LAYER_CMP_N+1 ); - - for( int kiNdx=layerCount-1, pcbNdx=0; kiNdx >= 0; --kiNdx, ++pcbNdx ) + for( int pcbNdx=0; pcbNdx0 && kiNdx==layerCount-1 ? LAYER_CMP_N : kiNdx; - - // establish bi-directional mapping between kicad's BOARD layer and PCB layer - pcbLayer2kicad[pcbNdx] = kilayer; - kicadLayer2pcb[kilayer] = pcbNdx; - - // save the specctra layer name in SPECCTRA_DB::layerIds for later. - layerIds.push_back( CONV_TO_UTF8( aBoard->GetLayerName( kilayer ) ) ); - LAYER* layer = new LAYER( pcb->structure ); pcb->structure->layers.push_back( layer ); - layer->name = layerIds.back(); + layer->name = layerIds[pcbNdx]; layer->properties.push_back( PROPERTY() ); PROPERTY* property = &layer->properties.back(); diff --git a/pcbnew/specctra_import.cpp b/pcbnew/specctra_import.cpp index 8344b28f84..5b99d4d3d1 100644 --- a/pcbnew/specctra_import.cpp +++ b/pcbnew/specctra_import.cpp @@ -110,32 +110,29 @@ void WinEDA_PcbFrame::ImportSpecctraSession( wxCommandEvent& event ) namespace DSN { - -static wxPoint mapPt( const POINT& aPoint, UNIT_RES* aResolution ) +static int scale( double distance, UNIT_RES* aResolution ) { - wxPoint ret; - double resValue = aResolution->GetValue(); - double factor; // multiply this times units to get mils for Kicad. + double factor; // multiply this times session value to get mils for Kicad. switch( aResolution->GetEngUnits() ) { default: case T_inch: - factor = 0.001; + factor = 1000.0; break; case T_mil: factor = 1.0; break; case T_cm: - factor = 2.54/1000.0; + factor = 1000.0/2.54; break; case T_mm: - factor = 25.4/1000.0; + factor = 1000.0/25.4; break; case T_um: - factor = 25.4; + factor = 1.0/25.4; break; } @@ -143,19 +140,47 @@ static wxPoint mapPt( const POINT& aPoint, UNIT_RES* aResolution ) // used within Kicad. factor *= 10.0; - ret.x = (int) (factor * aPoint.x / resValue); - ret.y = (int) -(factor * aPoint.y / resValue); // negate y coord + return (int) round(factor * distance / resValue); +} + +static wxPoint mapPt( const POINT& aPoint, UNIT_RES* aResolution ) +{ + wxPoint ret( scale( aPoint.x, aResolution ), + -scale( aPoint.y, aResolution )); // negate y return ret; } +TRACK* SPECCTRA_DB::makeTRACK( PATH* aPath, int aPointIndex, int aNetcode ) throw( IOError ) +{ + int layerNdx = findLayerName( aPath->layer_id ); + + if( layerNdx == -1 ) + { + wxString layerName = CONV_FROM_UTF8( aPath->layer_id.c_str() ); + ThrowIOError( _("Session file uses invalid layer id \"%s\""), + layerName.GetData() ); + } + + TRACK* track = new TRACK( sessionBoard ); + + track->m_Start = mapPt( aPath->points[aPointIndex+0], routeResolution ); + track->m_End = mapPt( aPath->points[aPointIndex+1], routeResolution ); + track->SetLayer( pcbLayer2kicad[layerNdx] ); + track->m_Width = scale( aPath->aperture_width, routeResolution ); + track->SetNet( aNetcode ); + + return track; +} + + // no UI code in this function, throw exception to report problems to the // UI handler: void WinEDA_PcbFrame::ImportSpecctraSession( wxCommandEvent& event ) void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IOError ) { - //wxASSERT( session ); + sessionBoard = aBoard; // not owned here if( !session ) ThrowIOError( _("Session file is missing the \"session\" section") ); @@ -176,6 +201,8 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IOError ) aBoard->DeleteMARKERs(); + buildLayerMaps( aBoard ); + // Walk the PLACEMENT object's COMPONENTs list, and for each PLACE within // each COMPONENT, reposition and re-orient each component and put on // correct side of the board. @@ -235,13 +262,53 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IOError ) } } + routeResolution = session->route->GetUnits(); + // Walk the NET_OUTs and create tracks and vias anew. NET_OUTS& net_outs = session->route->net_outs; - for( NET_OUTS::iterator i=net_outs.begin(); i!=net_outs.end(); ++i ) + for( NET_OUTS::iterator net=net_outs.begin(); net!=net_outs.end(); ++net ) { - // create a track or via and position it. + wxString netName( CONV_FROM_UTF8( net->net_id.c_str() ) ); + EQUIPOT* equipot = aBoard->FindNet( netName ); + if( !equipot ) + { + ThrowIOError( _("Session file uses invalid net::net_id \"%s\""), + netName.GetData() ); + } + WIRES& wires = net->wires; + for( unsigned i=0; ishape->Type(); + + if( shape != T_path ) + { + wxString netId = CONV_FROM_UTF8( wire->net_id.c_str() ); + ThrowIOError( + _("Unsupported wire shape: \"%s\" for net: \"%s\""), + LEXER::GetTokenString(shape).GetData(), + netId.GetData() + ); + } + + PATH* path = (PATH*) wire->shape; + for( unsigned pt=0; ptpoints.size()-1; ++pt ) + { + TRACK* track = makeTRACK( path, pt, equipot->GetNet() ); + + TRACK* insertAid = track->GetBestInsertPoint( aBoard ); + track->Insert( aBoard, insertAid ); + } + } + + WIRE_VIAS& wire_vias = net->wire_vias; + for( unsigned i=0; im_Start.x,y - point d'arrivee pt_newtrack->m_End.x,y -*/ + * pointee par pt_new_track (nbptnewpiste segments) + * + * la piste cree est supposee constituee de segments contigus en memoire avec: + * point de depart pt_newtrack->m_Start.x,y + * point d'arrivee pt_newtrack->m_End.x,y + */ { -TRACK * StartTrack, * EndTrack; /* Pointeurs des segments de debut et fin - (extremites) de la nouvelle piste */ -TRACK * EndNewTrack, /* Pointeur sur le dernier segment de la liste - chainee de la mouvelle piste */ - * pt_segm, * pt_del; -int ii, jj, nb_segm, nbconnect; -wxPoint start; /* coord du point de depart de la piste */ -wxPoint end; /* coord du point de fin de la piste */ -int startmasklayer, endmasklayer; /* masque couche de depart et de fin */ -TRACK * BufDeb, *BufEnd; /* Pointeurs de debut et de fin de la zone - des pistes equipotentielles */ + TRACK* StartTrack, * EndTrack;/* Pointeurs des segments de debut et fin + * (extremites) de la nouvelle piste */ + TRACK* EndNewTrack, /* Pointeur sur le dernier segment de la liste + * chainee de la mouvelle piste */ + * pt_segm, * pt_del; + int ii, jj, nb_segm, nbconnect; + wxPoint start; /* coord du point de depart de la piste */ + wxPoint end; /* coord du point de fin de la piste */ + int startmasklayer, endmasklayer; /* masque couche de depart et de fin */ + TRACK* BufDeb, * BufEnd; /* Pointeurs de debut et de fin de la zone + * des pistes equipotentielles */ - /* Reconstitution de la piste complete ( la nouvelle piste - a pu demarrer sur un segment de piste en l'air */ - ListSetState(pt_new_track,nbptnewpiste,BUSY,OFF); - /* si la novelle piste commence par une via, il est plus sur de rechercher - la piste complete en utilisant le segment suivant comme reference, car - une via est souvent sur un carrefour de segments, et ne caracterise pas - une piste */ - if( pt_new_track->Type() == TYPEVIA && (nbptnewpiste > 1 ) ) - pt_new_track = (TRACK *) pt_new_track->Pnext; - pt_new_track = Marque_Une_Piste(frame, DC, pt_new_track, &nbptnewpiste, 0); + /* Reconstitution de la piste complete ( la nouvelle piste + * a pu demarrer sur un segment de piste en l'air */ - EndNewTrack = pt_new_track; - for( ii = 1; ii < nbptnewpiste; ii++ ) - { - EndNewTrack = (TRACK *) EndNewTrack->Pnext; - } + ListSetState( pt_new_track, nbptnewpiste, BUSY, OFF ); - /* Calcul des limites de recherche des segments de piste */ - /* BufDeb pointe le 1er segment utile */ - BufDeb = Pcb->m_Track->GetStartNetCode(pt_new_track->GetNet()); + /* si la novelle piste commence par une via, il est plus sur de rechercher + * la piste complete en utilisant le segment suivant comme reference, car + * une via est souvent sur un carrefour de segments, et ne caracterise pas + * une piste */ + if( pt_new_track->Type() == TYPEVIA && (nbptnewpiste > 1 ) ) + pt_new_track = (TRACK*) pt_new_track->Pnext; + pt_new_track = Marque_Une_Piste( frame, DC, pt_new_track, &nbptnewpiste, 0 ); - /* BufEnd Pointe le dernier segment */ - BufEnd = BufDeb->GetEndNetCode(pt_new_track->GetNet()); + EndNewTrack = pt_new_track; + for( ii = 1; ii < nbptnewpiste; ii++ ) + { + EndNewTrack = (TRACK*) EndNewTrack->Pnext; + } - /* nettoyage des flags pour tout le net */ - for(pt_del = BufDeb; pt_del != NULL; pt_del = (TRACK*)pt_del->Pnext) - { - pt_del->SetState(BUSY|EDIT|CHAIN, OFF); - if( pt_del == BufEnd ) break; - } + /* Calcul des limites de recherche des segments de piste */ + /* BufDeb pointe le 1er segment utile */ + BufDeb = Pcb->m_Track->GetStartNetCode( pt_new_track->GetNet() ); - /* Calcul des points limites de la nouvelle piste */ - if( ReturnEndsTrack(pt_new_track,nbptnewpiste, - &StartTrack, &EndTrack) == 0 ) return(0); + /* BufEnd Pointe le dernier segment */ + BufEnd = BufDeb->GetEndNetCode( pt_new_track->GetNet() ); - if( (StartTrack == NULL) || (EndTrack == NULL) ) return(0); + /* nettoyage des flags pour tout le net */ + for( pt_del = BufDeb; pt_del != NULL; pt_del = (TRACK*) pt_del->Pnext ) + { + pt_del->SetState( BUSY | EDIT | CHAIN, OFF ); + if( pt_del == BufEnd ) + break; + } - /* Calcul des caracteristiques des points de debut et de fin */ - start = StartTrack->m_Start; - end = EndTrack->m_End; + /* Calcul des points limites de la nouvelle piste */ + if( ReturnEndsTrack( pt_new_track, nbptnewpiste, + &StartTrack, &EndTrack ) == 0 ) + return 0; - /* Les points de depart et de fin doivent etre distincts */ - if( start == end ) return(0); + if( (StartTrack == NULL) || (EndTrack == NULL) ) + return 0; - /* Determinations des couches interconnectees a ces points */ - startmasklayer = StartTrack->ReturnMaskLayer(); - endmasklayer = EndTrack->ReturnMaskLayer(); - /* Il peut y avoir une via ou un pad sur les extremites: */ - pt_segm = Fast_Locate_Via(Pcb->m_Track, NULL, start, startmasklayer); - if( pt_segm ) startmasklayer |= pt_segm->ReturnMaskLayer(); - if( StartTrack->start && (StartTrack->start->Type() == TYPEPAD) ) - { /* start sur pad */ - D_PAD * pt_pad = (D_PAD*) (StartTrack->start) ; - startmasklayer |= pt_pad->m_Masque_Layer; - } + /* Calcul des caracteristiques des points de debut et de fin */ + start = StartTrack->m_Start; + end = EndTrack->m_End; - pt_segm = Fast_Locate_Via(Pcb->m_Track, NULL, end, endmasklayer); - if( pt_segm ) endmasklayer |= pt_segm->ReturnMaskLayer(); - if( EndTrack->end && ( EndTrack->end->Type() == TYPEPAD) ) - { - D_PAD * pt_pad = (D_PAD*) (EndTrack->end) ; - endmasklayer |= pt_pad->m_Masque_Layer; - } + /* Les points de depart et de fin doivent etre distincts */ + if( start == end ) + return 0; - /* Marquage a DELETED de la piste nouvelle (qui ne doit pas intervenir - dans la recherche d'autres connexions) */ - ListSetState(pt_new_track, nbptnewpiste,DELETED,ON); + /* Determinations des couches interconnectees a ces points */ + startmasklayer = StartTrack->ReturnMaskLayer(); + endmasklayer = EndTrack->ReturnMaskLayer(); + /* Il peut y avoir une via ou un pad sur les extremites: */ + pt_segm = Fast_Locate_Via( Pcb->m_Track, NULL, start, startmasklayer ); + if( pt_segm ) + startmasklayer |= pt_segm->ReturnMaskLayer(); + if( StartTrack->start && (StartTrack->start->Type() == TYPEPAD) ) + { /* start sur pad */ + D_PAD* pt_pad = (D_PAD*) (StartTrack->start); + startmasklayer |= pt_pad->m_Masque_Layer; + } - /* test : un segment doit etre connecte au point de depart car sinon - il est inutile d'analyser l'autre point */ + pt_segm = Fast_Locate_Via( Pcb->m_Track, NULL, end, endmasklayer ); + if( pt_segm ) + endmasklayer |= pt_segm->ReturnMaskLayer(); + if( EndTrack->end && ( EndTrack->end->Type() == TYPEPAD) ) + { + D_PAD* pt_pad = (D_PAD*) (EndTrack->end); + endmasklayer |= pt_pad->m_Masque_Layer; + } - pt_segm = Fast_Locate_Piste(BufDeb, BufEnd, start, startmasklayer); + /* Marquage a DELETED de la piste nouvelle (qui ne doit pas intervenir + * dans la recherche d'autres connexions) */ + ListSetState( pt_new_track, nbptnewpiste, DELETED, ON ); - if(pt_segm == NULL) /* Pas de piste reliee au point de depart */ - { - /* Suppression du flag DELETED */ - ListSetState(pt_new_track,nbptnewpiste, DELETED,OFF); - return(0); - } + /* test : un segment doit etre connecte au point de depart car sinon + * il est inutile d'analyser l'autre point */ - /* Marquage a CHAIN des segments candidats connectes au point de fin - Remarque: les vias ne sont pas prises en compte car elles ne permettent - pas de definir une piste, puisque elles sont sur un carrefour */ - for( pt_del = BufDeb, nbconnect = 0; ; ) - { - pt_segm = Fast_Locate_Piste( pt_del,BufEnd, end, endmasklayer ); - if( pt_segm == NULL) break; + pt_segm = Fast_Locate_Piste( BufDeb, BufEnd, start, startmasklayer ); - if(pt_segm->Type() != TYPEVIA) - { /* Segment trouve */ - if( pt_segm->GetState(CHAIN) == 0 ) - { - pt_segm->SetState(CHAIN,ON); - nbconnect++; - } - } - if( pt_del == BufEnd ) break; - pt_del = (TRACK*)pt_segm->Pnext; - } + if( pt_segm == NULL ) /* Pas de piste reliee au point de depart */ + { + /* Suppression du flag DELETED */ + ListSetState( pt_new_track, nbptnewpiste, DELETED, OFF ); + return 0; + } + /* Marquage a CHAIN des segments candidats connectes au point de fin + * Remarque: les vias ne sont pas prises en compte car elles ne permettent + * pas de definir une piste, puisque elles sont sur un carrefour */ + for( pt_del = BufDeb, nbconnect = 0; ; ) + { + pt_segm = Fast_Locate_Piste( pt_del, BufEnd, end, endmasklayer ); + if( pt_segm == NULL ) + break; - if( nbconnect == 0) - { - /* nettoyage des flags */ - for(pt_del = BufDeb; pt_del != NULL; pt_del = (TRACK*)pt_del->Pnext) - { - pt_del->SetState(DELETED|EDIT|CHAIN, OFF); - if( pt_del == BufEnd ) break; - } - return(0); - } + if( pt_segm->Type() != TYPEVIA ) + { /* Segment trouve */ + if( pt_segm->GetState( CHAIN ) == 0 ) + { + pt_segm->SetState( CHAIN, ON ); + nbconnect++; + } + } + if( pt_del == BufEnd ) + break; + pt_del = (TRACK*) pt_segm->Pnext; + } - /* Marquage a EDIT de la piste nouvelle (qui ne doit pas intervenir - dans la recherche d'autres pistes) */ - ListSetState(pt_new_track,nbptnewpiste, DELETED,OFF); + if( nbconnect == 0 ) + { + /* nettoyage des flags */ + for( pt_del = BufDeb; pt_del != NULL; pt_del = (TRACK*) pt_del->Pnext ) + { + pt_del->SetState( DELETED | EDIT | CHAIN, OFF ); + if( pt_del == BufEnd ) + break; + } - ListSetState(pt_new_track,nbptnewpiste, EDIT,ON); + return 0; + } - /* Examen de tous les segments marques */ - while( nbconnect ) - { - for(pt_del = BufDeb; pt_del != NULL; pt_del = (TRACK*)pt_del->Pnext) - { - if( pt_del->GetState(CHAIN) ) break; - if( pt_del == BufEnd ) break; - } + /* Marquage a EDIT de la piste nouvelle (qui ne doit pas intervenir + * dans la recherche d'autres pistes) */ + ListSetState( pt_new_track, nbptnewpiste, DELETED, OFF ); - nbconnect--; pt_del->SetState(CHAIN,OFF); - pt_del = Marque_Une_Piste(frame, DC, pt_del, &nb_segm, 0); + ListSetState( pt_new_track, nbptnewpiste, EDIT, ON ); - /* Test si La piste marquee est redondante, c'est a dire si l'un des - segments marques est connecte au point de depart de la piste nouvelle - */ - ii = 0; pt_segm = pt_del; - for( ;pt_segm && (ii < nb_segm); pt_segm = (TRACK*)pt_segm->Pnext, ii++) - { - if( (pt_segm->GetState(BUSY)) == 0 ) break; + /* Examen de tous les segments marques */ + while( nbconnect ) + { + for( pt_del = BufDeb; pt_del != NULL; pt_del = (TRACK*) pt_del->Pnext ) + { + if( pt_del->GetState( CHAIN ) ) + break; + if( pt_del == BufEnd ) + break; + } - if( (pt_segm->m_Start == start) || (pt_segm->m_End == start) ) - { /* la piste marquee peut etre effacee */ - TRACK* NextS; - Trace_Une_Piste(frame->DrawPanel, DC, pt_del, nb_segm, GR_XOR|GR_SURBRILL); - for ( jj = 0; jj < nb_segm; jj++, pt_del = NextS) - { - NextS = (TRACK*) pt_del->Pnext; - pt_del->DeleteStructure(); - } - /* nettoyage des flags */ - for(pt_del = Pcb->m_Track; pt_del != NULL; pt_del = (TRACK*)pt_del->Pnext) - { - if (pt_del->GetState(EDIT) ) - { - pt_del->SetState(EDIT, OFF); - pt_del->Draw(frame->DrawPanel, DC, GR_OR); - } - pt_del->SetState(EDIT|CHAIN, OFF); - } - return(1); - } - } + nbconnect--; pt_del->SetState( CHAIN, OFF ); + pt_del = Marque_Une_Piste( frame, DC, pt_del, &nb_segm, 0 ); - /* nettoyage du flag BUSY puisque ici la piste marquee n'a pas - ete retenuee */ - ListSetState(pt_del, nb_segm, BUSY,OFF); - } + /* Test si La piste marquee est redondante, c'est a dire si l'un des + * segments marques est connecte au point de depart de la piste nouvelle + */ + ii = 0; pt_segm = pt_del; + for( ; pt_segm && (ii < nb_segm); pt_segm = (TRACK*) pt_segm->Pnext, ii++ ) + { + if( ( pt_segm->GetState( BUSY ) ) == 0 ) + break; - /* nettoyage des flags */ - for(pt_del = Pcb->m_Track; pt_del != NULL; pt_del = (TRACK*)pt_del->Pnext) - { - pt_del->SetState(DELETED|EDIT|CHAIN, OFF); - if( pt_del == BufEnd ) break; - } - return(0); + if( (pt_segm->m_Start == start) || (pt_segm->m_End == start) ) + { /* la piste marquee peut etre effacee */ + TRACK* NextS; + Trace_Une_Piste( frame->DrawPanel, DC, pt_del, nb_segm, GR_XOR | GR_SURBRILL ); + for( jj = 0; jj < nb_segm; jj++, pt_del = NextS ) + { + NextS = (TRACK*) pt_del->Pnext; + pt_del->DeleteStructure(); + } + + /* nettoyage des flags */ + for( pt_del = Pcb->m_Track; pt_del != NULL; pt_del = (TRACK*) pt_del->Pnext ) + { + if( pt_del->GetState( EDIT ) ) + { + pt_del->SetState( EDIT, OFF ); + pt_del->Draw( frame->DrawPanel, DC, GR_OR ); + } + pt_del->SetState( EDIT | CHAIN, OFF ); + } + + return 1; + } + } + + /* nettoyage du flag BUSY puisque ici la piste marquee n'a pas + * ete retenuee */ + ListSetState( pt_del, nb_segm, BUSY, OFF ); + } + + /* nettoyage des flags */ + for( pt_del = Pcb->m_Track; pt_del != NULL; pt_del = (TRACK*) pt_del->Pnext ) + { + pt_del->SetState( DELETED | EDIT | CHAIN, OFF ); + if( pt_del == BufEnd ) + break; + } + + return 0; } -