1073 lines
28 KiB
C++
1073 lines
28 KiB
C++
/****************************************************/
|
||
/* class_module.cpp : fonctions de la classe MODULE */
|
||
/****************************************************/
|
||
|
||
#include "fctsys.h"
|
||
#include "gr_basic.h"
|
||
|
||
#include "wxstruct.h"
|
||
#include "common.h"
|
||
#include "plot_common.h"
|
||
#include "pcbnew.h"
|
||
#include "trigo.h"
|
||
|
||
#ifdef PCBNEW
|
||
#include "autorout.h"
|
||
#include "drag.h"
|
||
#endif
|
||
|
||
#ifdef CVPCB
|
||
#include "cvpcb.h"
|
||
#endif
|
||
|
||
#include "3d_struct.h"
|
||
#include "protos.h"
|
||
|
||
#define MAX_WIDTH 10000 // Epaisseur (en 1/10000 ") max raisonnable des traits, textes...
|
||
|
||
/*********************************************************************************/
|
||
void MODULE::DrawAncre(WinEDA_DrawPanel * panel, wxDC * DC, const wxPoint & offset,
|
||
int dim_ancre, int draw_mode)
|
||
/*********************************************************************************/
|
||
/* trace de l'ancre (croix verticale)
|
||
(doit etre fait apres les pads,
|
||
car le trace du trou efface tout donc peut etre l'ancre */
|
||
{
|
||
int zoom = panel->GetZoom();
|
||
int anchor_size = dim_ancre * zoom;
|
||
|
||
GRSetDrawMode(DC, draw_mode);
|
||
|
||
if((g_AnchorColor & ITEM_NOT_SHOW) == 0 )
|
||
{
|
||
GRLine(&panel->m_ClipBox, DC,
|
||
m_Pos.x - offset.x - anchor_size, m_Pos.y - offset.y,
|
||
m_Pos.x -offset.x + anchor_size,m_Pos.y - offset.y,
|
||
0, g_AnchorColor);
|
||
GRLine(&panel->m_ClipBox, DC,
|
||
m_Pos.x - offset.x, m_Pos.y - offset.y - anchor_size ,
|
||
m_Pos.x - offset.x, m_Pos.y - offset.y + anchor_size ,
|
||
0, g_AnchorColor);
|
||
}
|
||
}
|
||
|
||
|
||
/*************************************************/
|
||
/* Class MODULE : description d'un composant pcb */
|
||
/*************************************************/
|
||
|
||
/* Constructeur de la classe MODULE */
|
||
MODULE::MODULE(BOARD * parent): EDA_BaseStruct( parent, TYPEMODULE)
|
||
{
|
||
m_Pads = NULL;
|
||
m_Drawings = NULL;
|
||
m_3D_Drawings = NULL;
|
||
m_Attributs = MOD_DEFAULT;
|
||
m_Layer = CMP_N;
|
||
m_Orient = 0;
|
||
m_ModuleStatus = 0;
|
||
flag = 0;
|
||
m_CntRot90 = m_CntRot180 = 0;
|
||
m_Surface = 0;
|
||
m_Link = 0;
|
||
m_LastEdit_Time = time(NULL);
|
||
m_Reference = new TEXTE_MODULE(this, TEXT_is_REFERENCE);
|
||
m_Reference->Pback = this;
|
||
m_Value = new TEXTE_MODULE(this, TEXT_is_VALUE);
|
||
m_Value->Pback = this;
|
||
m_3D_Drawings = new Struct3D_Master(this);
|
||
}
|
||
|
||
/* Destructeur */
|
||
MODULE::~MODULE(void)
|
||
{
|
||
D_PAD * Pad;
|
||
EDA_BaseStruct * Struct, * NextStruct;
|
||
|
||
delete m_Reference;
|
||
delete m_Value;
|
||
for ( Struct = m_3D_Drawings; Struct != NULL; Struct = NextStruct)
|
||
{
|
||
NextStruct = Struct->Pnext;
|
||
delete Struct;
|
||
}
|
||
|
||
/* effacement des pads */
|
||
for( Pad = m_Pads; Pad != NULL; Pad = (D_PAD*)NextStruct )
|
||
{
|
||
NextStruct = Pad->Pnext;
|
||
delete Pad;
|
||
}
|
||
|
||
/* effacement des elements de trace */
|
||
for ( Struct = m_Drawings; Struct != NULL; Struct = NextStruct )
|
||
{
|
||
NextStruct = Struct->Pnext;
|
||
switch( (Struct->m_StructType) )
|
||
{
|
||
case TYPEEDGEMODULE:
|
||
delete (EDGE_MODULE*)Struct;
|
||
break;
|
||
|
||
case TYPETEXTEMODULE:
|
||
delete (TEXTE_MODULE*)Struct;
|
||
break;
|
||
|
||
default:
|
||
DisplayError(NULL, wxT("Warn: ItemType not handled in delete MODULE"));
|
||
NextStruct = NULL;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
/*********************************/
|
||
void MODULE::Copy(MODULE * Module)
|
||
/*********************************/
|
||
{
|
||
D_PAD * pad,* lastpad;
|
||
|
||
m_Pos = Module->m_Pos;
|
||
m_Layer = Module->m_Layer;
|
||
m_LibRef = Module->m_LibRef;
|
||
m_Attributs = Module->m_Attributs;
|
||
m_Orient = Module->m_Orient;
|
||
m_BoundaryBox = Module->m_BoundaryBox;
|
||
m_PadNum = Module->m_PadNum;
|
||
m_CntRot90 = Module->m_CntRot90;
|
||
m_CntRot180 = Module->m_CntRot180;
|
||
m_LastEdit_Time = Module->m_LastEdit_Time;
|
||
m_TimeStamp = GetTimeStamp();
|
||
|
||
/* Copy des structures auxiliaires: Reference et value */
|
||
m_Reference->Copy(Module->m_Reference);
|
||
m_Value->Copy(Module->m_Value);
|
||
|
||
/* Copie des structures auxiliaires: Pads */
|
||
lastpad = NULL; pad = Module->m_Pads;
|
||
for( ;pad != NULL ; pad = (D_PAD*)pad->Pnext)
|
||
{
|
||
D_PAD * newpad = new D_PAD (this);
|
||
newpad->Copy(pad);
|
||
|
||
if(m_Pads == NULL)
|
||
{
|
||
newpad->Pback = this;
|
||
m_Pads = (D_PAD*)newpad;
|
||
}
|
||
else
|
||
{
|
||
newpad->Pback = lastpad;
|
||
lastpad->Pnext = newpad;
|
||
}
|
||
lastpad = newpad;
|
||
}
|
||
|
||
/* Copy des structures auxiliaires: Drawings */
|
||
EDA_BaseStruct* OldStruct = (EDA_BaseStruct*) Module->m_Drawings;
|
||
EDA_BaseStruct* NewStruct, *LastStruct = NULL;
|
||
for( ;OldStruct ; OldStruct = OldStruct->Pnext)
|
||
{
|
||
NewStruct = NULL;
|
||
switch(OldStruct->m_StructType)
|
||
{
|
||
case TYPETEXTEMODULE:
|
||
NewStruct = new TEXTE_MODULE( this );
|
||
((TEXTE_MODULE*)NewStruct)->Copy((TEXTE_MODULE*)OldStruct);
|
||
break;
|
||
|
||
case TYPEEDGEMODULE:
|
||
NewStruct = new EDGE_MODULE( this );
|
||
((EDGE_MODULE*)NewStruct)->Copy((EDGE_MODULE*)OldStruct);
|
||
break;
|
||
default:
|
||
DisplayError(NULL, wxT("Internal Err: CopyModule: type indefini"));
|
||
break;
|
||
}
|
||
if( NewStruct == NULL) break;
|
||
if(m_Drawings == NULL)
|
||
{
|
||
NewStruct->Pback = this;
|
||
m_Drawings = NewStruct;
|
||
}
|
||
else
|
||
{
|
||
NewStruct->Pback = LastStruct;
|
||
LastStruct->Pnext = NewStruct;
|
||
}
|
||
LastStruct = NewStruct;
|
||
}
|
||
|
||
/* Copy des elements complementaires Drawings 3D */
|
||
m_3D_Drawings->Copy(Module->m_3D_Drawings);
|
||
Struct3D_Master * Struct3D, *NewStruct3D, *CurrStruct3D;
|
||
Struct3D = (Struct3D_Master *) Module->m_3D_Drawings->Pnext;
|
||
CurrStruct3D = m_3D_Drawings;
|
||
for ( ; Struct3D != NULL; Struct3D = (Struct3D_Master*) Struct3D->Pnext)
|
||
{
|
||
NewStruct3D = new Struct3D_Master(this);
|
||
NewStruct3D->Copy(Struct3D);
|
||
CurrStruct3D->Pnext = NewStruct3D;
|
||
NewStruct3D->Pback = CurrStruct3D;
|
||
CurrStruct3D = NewStruct3D;
|
||
}
|
||
|
||
/* Copie des elements complementaires */
|
||
m_Doc = Module->m_Doc;
|
||
m_KeyWord = Module->m_KeyWord;
|
||
|
||
}
|
||
|
||
/* supprime du chainage la structure Struct
|
||
les structures arrieres et avant sont chainees directement
|
||
*/
|
||
void MODULE::UnLink( void )
|
||
{
|
||
/* Modification du chainage arriere */
|
||
if( Pback )
|
||
{
|
||
if( Pback->m_StructType != TYPEPCB)
|
||
{
|
||
Pback->Pnext = Pnext;
|
||
}
|
||
|
||
else /* Le chainage arriere pointe sur la structure "Pere" */
|
||
{
|
||
if ( GetState(DELETED) ) // A REVOIR car Pback = NULL si place en undelete
|
||
{
|
||
if( g_UnDeleteStack ) g_UnDeleteStack[g_UnDeleteStackPtr-1] = Pnext;
|
||
}
|
||
else ((BOARD*)Pback)->m_Modules = (MODULE *) Pnext;
|
||
}
|
||
}
|
||
|
||
/* Modification du chainage avant */
|
||
if( Pnext) Pnext->Pback = Pback;
|
||
|
||
Pnext = Pback = NULL;
|
||
}
|
||
|
||
|
||
/**********************************************************/
|
||
void MODULE::Draw(WinEDA_DrawPanel * panel, wxDC * DC,
|
||
const wxPoint & offset, int draw_mode)
|
||
/**********************************************************/
|
||
/* Dessin d'une empreinte sur l'ecran actif:
|
||
Entree :
|
||
Module: pointeur sur le module
|
||
ox, oy = offset de trace
|
||
draw_mode = mode de trace ( GR_OR, GR_XOR, GR_AND)
|
||
Utilise par ailleur:
|
||
Description des parametres de l'empreinte calcules par caract() ;
|
||
*/
|
||
{
|
||
D_PAD * pt_pad ;
|
||
EDA_BaseStruct * PtStruct;
|
||
TEXTE_MODULE * PtTexte;
|
||
|
||
/* trace des pastilles */
|
||
pt_pad = m_Pads;
|
||
for( ; pt_pad != NULL; pt_pad = (D_PAD*) pt_pad->Pnext )
|
||
{
|
||
if ( pt_pad->m_Flags & IS_MOVED ) continue;
|
||
pt_pad->Draw(panel, DC, offset,draw_mode);
|
||
}
|
||
|
||
/* Impression de l'ancre du module */
|
||
DrawAncre(panel, DC, offset, DIM_ANCRE_MODULE, draw_mode) ;
|
||
|
||
/* impression des graphismes */
|
||
if ( ! (m_Reference->m_Flags & IS_MOVED) )
|
||
m_Reference->Draw(panel, DC, offset, draw_mode);
|
||
if ( ! (m_Value->m_Flags & IS_MOVED) )
|
||
m_Value->Draw(panel, DC, offset, draw_mode);
|
||
|
||
PtStruct = m_Drawings;
|
||
for( ;PtStruct != NULL; PtStruct = PtStruct->Pnext )
|
||
{
|
||
if ( PtStruct->m_Flags & IS_MOVED ) continue;
|
||
|
||
switch( PtStruct->m_StructType )
|
||
{
|
||
case TYPETEXTEMODULE:
|
||
PtTexte = (TEXTE_MODULE *) PtStruct;
|
||
PtTexte->Draw(panel, DC, offset, draw_mode);
|
||
break;
|
||
|
||
case TYPEEDGEMODULE:
|
||
((EDGE_MODULE *) PtStruct)->Draw(panel, DC, offset, draw_mode);
|
||
break;
|
||
|
||
default: break;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/**************************************************************/
|
||
void MODULE::DrawEdgesOnly(WinEDA_DrawPanel * panel, wxDC * DC,
|
||
const wxPoint & offset, int draw_mode)
|
||
/**************************************************************/
|
||
{
|
||
EDA_BaseStruct * PtStruct;
|
||
|
||
/* impression des graphismes */
|
||
PtStruct = m_Drawings;
|
||
for( ;PtStruct != NULL; PtStruct = PtStruct->Pnext )
|
||
{
|
||
switch( PtStruct->m_StructType )
|
||
{
|
||
case TYPEEDGEMODULE:
|
||
((EDGE_MODULE *) PtStruct)->Draw(panel, DC, offset, draw_mode);
|
||
break;
|
||
|
||
default: break;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/*************************************/
|
||
int MODULE::WriteDescr( FILE * File )
|
||
/*************************************/
|
||
/* Sauvegarde de la description d'un MODULE
|
||
*/
|
||
{
|
||
char StringStat[20];
|
||
TEXTE_MODULE * PtText;
|
||
EDGE_MODULE * PtEdge;
|
||
D_PAD * ptpad;
|
||
EDA_BaseStruct * PtStruct;
|
||
int ii, NbLigne = 0;
|
||
wxString msg;
|
||
|
||
if( GetState(DELETED) ) return(NbLigne);
|
||
|
||
/* Generation du fichier module: */
|
||
fprintf( File,"$MODULE %s\n", CONV_TO_UTF8(m_LibRef));
|
||
NbLigne++;
|
||
|
||
/* Generation des coord et caracteristiques */
|
||
memset(StringStat, 0, sizeof(StringStat) );
|
||
if( m_ModuleStatus & MODULE_is_LOCKED)
|
||
StringStat[0] = 'F';
|
||
else StringStat[0] = '~';
|
||
if( m_ModuleStatus & MODULE_is_PLACED)
|
||
StringStat[1] = 'P';
|
||
else StringStat[1] = '~';
|
||
|
||
fprintf( File,"Po %d %d %d %d %8.8lX %8.8lX %s\n",
|
||
m_Pos.x, m_Pos.y,
|
||
m_Orient, m_Layer,m_LastEdit_Time,
|
||
m_TimeStamp, StringStat);
|
||
NbLigne++;
|
||
|
||
fprintf(File,"Li %s\n", CONV_TO_UTF8(m_LibRef));
|
||
NbLigne++;
|
||
|
||
if ( ! m_Doc.IsEmpty())
|
||
{
|
||
fprintf(File,"Cd %s\n", CONV_TO_UTF8(m_Doc));
|
||
NbLigne++;
|
||
}
|
||
|
||
if ( ! m_KeyWord.IsEmpty())
|
||
{
|
||
fprintf(File,"Kw %s\n", CONV_TO_UTF8(m_KeyWord));
|
||
NbLigne++;
|
||
}
|
||
|
||
fprintf(File,"Sc %8.8lX\n", m_TimeStamp);
|
||
NbLigne++;
|
||
|
||
fprintf(File,"Op %X %X 0\n", m_CntRot90, m_CntRot180);
|
||
NbLigne++;
|
||
|
||
/* Attributs du module */
|
||
if( m_Attributs != MOD_DEFAULT )
|
||
{
|
||
fprintf(File,"At ");
|
||
if( m_Attributs & MOD_CMS ) fprintf(File,"SMD ");
|
||
if( m_Attributs & MOD_VIRTUAL ) fprintf(File,"VIRTUAL ");
|
||
fprintf(File,"\n");
|
||
}
|
||
|
||
/* Texte Reference du module */
|
||
fprintf(File,"T%d %d %d %d %d %d %d %c %c %d \"%.16s\"\n",
|
||
m_Reference->m_Type,
|
||
m_Reference->m_Pos0.x, m_Reference->m_Pos0.y,
|
||
m_Reference->m_Size.y,m_Reference->m_Size.x,
|
||
m_Reference->m_Orient + m_Orient, m_Reference->m_Width,
|
||
m_Reference->m_Miroir ? 'N' : 'M', m_Reference->m_NoShow ? 'I' : 'V',
|
||
m_Reference->m_Layer,
|
||
CONV_TO_UTF8(m_Reference->m_Text) );
|
||
NbLigne++;
|
||
|
||
/* Texte Value du module */
|
||
fprintf(File,"T%d %d %d %d %d %d %d %c %c %d \"%.16s\"\n",
|
||
m_Value->m_Type,
|
||
m_Value->m_Pos0.x, m_Value->m_Pos0.y,
|
||
m_Value->m_Size.y,m_Value->m_Size.x,
|
||
m_Value->m_Orient + m_Orient, m_Value->m_Width,
|
||
m_Value->m_Miroir ? 'N' : 'M', m_Value->m_NoShow ? 'I' : 'V',
|
||
m_Value->m_Layer,
|
||
CONV_TO_UTF8(m_Value->m_Text) );
|
||
NbLigne++;
|
||
|
||
/* Generation des elements Drawing modules */
|
||
PtStruct = m_Drawings;
|
||
for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext)
|
||
{
|
||
switch(PtStruct->m_StructType )
|
||
{
|
||
case TYPETEXTEMODULE:
|
||
PtText = ((TEXTE_MODULE *) PtStruct);
|
||
fprintf(File,"T%d %d %d %d %d %d %d %c %c %d \"%s\"\n",
|
||
PtText->m_Type,
|
||
PtText->m_Pos0.x, PtText->m_Pos0.y,
|
||
PtText->m_Size.y,PtText->m_Size.x,
|
||
PtText->m_Orient + m_Orient, PtText->m_Width,
|
||
PtText->m_Miroir ? 'N' : 'M',
|
||
PtText->m_NoShow ? 'I' : 'V',
|
||
PtText->m_Layer, CONV_TO_UTF8(PtText->m_Text) );
|
||
NbLigne++;
|
||
break;
|
||
|
||
case TYPEEDGEMODULE:
|
||
PtEdge = (EDGE_MODULE*) PtStruct;
|
||
PtEdge->WriteDescr( File );
|
||
break;
|
||
|
||
default:
|
||
msg.Printf( wxT("Type (%d) Draw Module inconnu"),
|
||
PtStruct->m_StructType);
|
||
DisplayError(NULL, msg);
|
||
break;
|
||
} /* Fin switch gestion des Items draw */
|
||
}
|
||
|
||
/* Generation de la liste des pads */
|
||
ptpad = m_Pads;
|
||
for( ; ptpad != NULL; ptpad = (D_PAD*)ptpad->Pnext)
|
||
{
|
||
ii = ptpad->WriteDescr(File);
|
||
NbLigne += ii;
|
||
}
|
||
|
||
/* Generation des informations de trac<61> 3D */
|
||
Write_3D_Descr( File );
|
||
|
||
/* Fin de description: */
|
||
fprintf( File,"$EndMODULE %s\n", CONV_TO_UTF8(m_LibRef));
|
||
NbLigne++;
|
||
return(NbLigne);
|
||
}
|
||
|
||
/***************************************/
|
||
int MODULE::Write_3D_Descr( FILE * File )
|
||
/***************************************/
|
||
/* Sauvegarde de la description 3D du MODULE
|
||
*/
|
||
{
|
||
char buf[512];
|
||
Struct3D_Master * Struct3D = m_3D_Drawings;
|
||
|
||
for ( ; Struct3D != NULL; Struct3D = (Struct3D_Master *) Struct3D->Pnext)
|
||
{
|
||
if ( ! Struct3D->m_Shape3DName.IsEmpty() )
|
||
{
|
||
fprintf( File,"$SHAPE3D\n");
|
||
|
||
fprintf( File,"Na \"%s\"\n", CONV_TO_UTF8(Struct3D->m_Shape3DName));
|
||
|
||
sprintf( buf,"Sc %lf %lf %lf\n",
|
||
Struct3D->m_MatScale.x,
|
||
Struct3D->m_MatScale.y,
|
||
Struct3D->m_MatScale.z);
|
||
fprintf( File, to_point(buf) );
|
||
|
||
sprintf( buf,"Of %lf %lf %lf\n",
|
||
Struct3D->m_MatPosition.x,
|
||
Struct3D->m_MatPosition.y,
|
||
Struct3D->m_MatPosition.z);
|
||
fprintf( File, to_point(buf) );
|
||
|
||
sprintf( buf,"Ro %lf %lf %lf\n",
|
||
Struct3D->m_MatRotation.x,
|
||
Struct3D->m_MatRotation.y,
|
||
Struct3D->m_MatRotation.z);
|
||
fprintf( File, to_point(buf) );
|
||
|
||
fprintf( File,"$EndSHAPE3D\n");
|
||
}
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
/****************************************************/
|
||
int MODULE::Read_3D_Descr( FILE * File, int * LineNum)
|
||
/****************************************************/
|
||
/* Lecture de la description d'un MODULE (format Ascii)
|
||
la 1ere ligne de descr ($MODULE) est supposee etre deja lue
|
||
retourne 0 si OK
|
||
*/
|
||
{
|
||
char Line[1024];
|
||
char * text = Line + 3;
|
||
Struct3D_Master * Struct3D = m_3D_Drawings;
|
||
|
||
if ( ! Struct3D->m_Shape3DName.IsEmpty() )
|
||
{
|
||
Struct3D_Master * NewStruct3D;
|
||
while ( Struct3D->Pnext )
|
||
Struct3D = (Struct3D_Master *)Struct3D->Pnext;
|
||
Struct3D->Pnext = NewStruct3D = new Struct3D_Master(this);
|
||
NewStruct3D->Pback = Struct3D;
|
||
Struct3D = NewStruct3D;
|
||
}
|
||
|
||
while( GetLine(File, Line, LineNum , sizeof(Line) -1) != NULL )
|
||
{
|
||
switch( Line[0] )
|
||
{
|
||
case '$': // Fin de description
|
||
if( Line[1] == 'E' ) return 0;
|
||
return 1;
|
||
|
||
case 'N': // Shape File Name
|
||
{
|
||
char buf[512];
|
||
ReadDelimitedText( buf, text, 512);
|
||
Struct3D->m_Shape3DName = CONV_FROM_UTF8(buf);
|
||
break;
|
||
}
|
||
|
||
case 'S': // Scale
|
||
sscanf( text,"%lf %lf %lf\n",
|
||
&Struct3D->m_MatScale.x,
|
||
&Struct3D->m_MatScale.y,
|
||
&Struct3D->m_MatScale.z);
|
||
break;
|
||
|
||
case 'O': // Offset
|
||
sscanf( text,"%lf %lf %lf\n",
|
||
&Struct3D->m_MatPosition.x,
|
||
&Struct3D->m_MatPosition.y,
|
||
&Struct3D->m_MatPosition.z);
|
||
break;
|
||
|
||
case 'R': // Rotation
|
||
sscanf( text,"%lf %lf %lf\n",
|
||
&Struct3D->m_MatRotation.x,
|
||
&Struct3D->m_MatRotation.y,
|
||
&Struct3D->m_MatRotation.z);
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
return 1;
|
||
}
|
||
|
||
/**************************************************/
|
||
int MODULE::ReadDescr( FILE * File, int * LineNum)
|
||
/**************************************************/
|
||
/* Lecture de la description d'un MODULE (format Ascii)
|
||
la 1ere ligne de descr ($MODULE) est supposee etre deja lue
|
||
retourne 0 si OK
|
||
*/
|
||
{
|
||
D_PAD * LastPad = NULL, * ptpad;
|
||
EDA_BaseStruct * LastModStruct = NULL;
|
||
EDGE_MODULE * DrawSegm;
|
||
TEXTE_MODULE * DrawText;
|
||
char Line[256], BufLine[256], BufCar1[128], BufCar2[128], *PtLine;
|
||
int itmp1, itmp2;
|
||
|
||
while( GetLine(File, Line, LineNum , sizeof(Line) -1) != NULL )
|
||
{
|
||
if( Line[0] == '$' )
|
||
{
|
||
if( Line[1] == 'E' ) break;
|
||
if( Line[1] == 'P' )
|
||
{
|
||
ptpad = new D_PAD(this);
|
||
ptpad->ReadDescr(File, LineNum );
|
||
RotatePoint( &ptpad->m_Pos.x, &ptpad->m_Pos.y, m_Orient );
|
||
ptpad->m_Pos.x += m_Pos.x;
|
||
ptpad->m_Pos.y += m_Pos.y;
|
||
|
||
if(LastPad == NULL )
|
||
{
|
||
ptpad->Pback = (EDA_BaseStruct *) this;
|
||
m_Pads = ptpad;
|
||
}
|
||
else
|
||
{
|
||
ptpad->Pback = (EDA_BaseStruct *) LastPad;
|
||
LastPad->Pnext = (EDA_BaseStruct *)ptpad;
|
||
}
|
||
LastPad = ptpad;
|
||
continue;
|
||
}
|
||
if( Line[1] == 'S' ) Read_3D_Descr(File, LineNum );
|
||
}
|
||
|
||
|
||
if ( strlen(Line) < 4 ) continue;
|
||
PtLine = Line + 3; /* Pointe 1er code utile de la ligne */
|
||
switch( Line[0] )
|
||
{
|
||
case 'P':
|
||
memset(BufCar1, 0, sizeof(BufCar1) );
|
||
sscanf( PtLine,"%d %d %d %d %lX %lX %s",
|
||
&m_Pos.x, &m_Pos.y,
|
||
&m_Orient, &m_Layer ,
|
||
&m_LastEdit_Time, &m_TimeStamp,BufCar1);
|
||
|
||
m_ModuleStatus = 0;
|
||
if(BufCar1[0] == 'F') m_ModuleStatus |= MODULE_is_LOCKED;
|
||
if(BufCar1[1] == 'P') m_ModuleStatus |= MODULE_is_PLACED;
|
||
break;
|
||
|
||
case 'L': /* Li = Lecture du nom librairie du module */
|
||
*BufLine = 0;
|
||
sscanf(PtLine," %s",BufLine);
|
||
m_LibRef = CONV_FROM_UTF8(BufLine);
|
||
break;
|
||
|
||
case 'S':
|
||
sscanf(PtLine," %lX", &m_TimeStamp);
|
||
break;
|
||
|
||
case 'O': /* (Op)tions de placement auto */
|
||
itmp1 = itmp2 = 0;
|
||
sscanf(PtLine," %X %X", &itmp1, &itmp2);
|
||
|
||
m_CntRot180 = itmp2 & 0x0F;
|
||
if( m_CntRot180 > 10 ) m_CntRot180 = 10;
|
||
|
||
m_CntRot90 = itmp1 & 0x0F;
|
||
if( m_CntRot90 > 10 ) m_CntRot90 = 0;
|
||
itmp1 = (itmp1 >> 4) & 0x0F;
|
||
if( itmp1 > 10 ) itmp1 = 0;
|
||
m_CntRot90 |= itmp1 << 4;
|
||
break;
|
||
|
||
case 'A': /* At = (At)tributs du module */
|
||
if ( strstr(PtLine, "SMD") ) m_Attributs |= MOD_CMS;
|
||
if ( strstr(PtLine, "VIRTUAL") ) m_Attributs |= MOD_VIRTUAL;
|
||
break;
|
||
|
||
case 'T': /* lecture des textes modules */
|
||
sscanf(Line+1,"%d", &itmp1);
|
||
if ( itmp1 == TEXT_is_REFERENCE )
|
||
DrawText = m_Reference;
|
||
else if ( itmp1 == TEXT_is_VALUE )
|
||
DrawText = m_Value;
|
||
else /* text is a drawing */
|
||
{DrawText = new TEXTE_MODULE(this);
|
||
if(LastModStruct == NULL )
|
||
{
|
||
DrawText->Pback = this;
|
||
m_Drawings = (EDA_BaseStruct*) DrawText;
|
||
}
|
||
else
|
||
{
|
||
DrawText->Pback = LastModStruct;
|
||
LastModStruct->Pnext = DrawText;
|
||
}
|
||
LastModStruct = (EDA_BaseStruct*) DrawText;
|
||
}
|
||
|
||
sscanf(Line+1,"%d %d %d %d %d %d %d %s %s %d",
|
||
&itmp1,
|
||
&DrawText->m_Pos0.x, &DrawText->m_Pos0.y,
|
||
&DrawText->m_Size.y, &DrawText->m_Size.x,
|
||
&DrawText->m_Orient, &DrawText->m_Width,
|
||
BufCar1, BufCar2, &DrawText->m_Layer);
|
||
|
||
DrawText->m_Type = itmp1;
|
||
DrawText->m_Orient -= m_Orient; // m_Orient texte relative au module
|
||
if( BufCar1[0] == 'M') DrawText->m_Miroir = 0;
|
||
else DrawText->m_Miroir = 1;
|
||
if( BufCar2[0] == 'I') DrawText->m_NoShow = 1;
|
||
else DrawText->m_NoShow = 0;
|
||
|
||
if(m_Layer == CUIVRE_N) DrawText->m_Layer = SILKSCREEN_N_CU;
|
||
if(m_Layer == CMP_N) DrawText->m_Layer = SILKSCREEN_N_CMP;
|
||
|
||
/* calcul de la position vraie */
|
||
DrawText->SetDrawCoord();
|
||
/* Lecture de la chaine "text" */
|
||
ReadDelimitedText(BufLine, Line , sizeof(BufLine) );
|
||
DrawText->m_Text = CONV_FROM_UTF8(BufLine);
|
||
// Controle d'epaisseur raisonnable:
|
||
if( DrawText->m_Width <= 1 ) DrawText->m_Width = 1;
|
||
if( DrawText->m_Width > MAX_WIDTH ) DrawText->m_Width = MAX_WIDTH;
|
||
break;
|
||
|
||
case 'D': /* lecture du contour */
|
||
DrawSegm = new EDGE_MODULE(this);
|
||
|
||
if(LastModStruct == NULL )
|
||
{
|
||
DrawSegm->Pback = this;
|
||
m_Drawings = DrawSegm;
|
||
}
|
||
else
|
||
{
|
||
DrawSegm->Pback = LastModStruct;
|
||
LastModStruct->Pnext = DrawSegm;
|
||
}
|
||
|
||
LastModStruct = DrawSegm;
|
||
DrawSegm->ReadDescr( Line, File, LineNum);
|
||
DrawSegm->SetDrawCoord();
|
||
break;
|
||
|
||
case 'C': /* Lecture de la doc */
|
||
m_Doc = CONV_FROM_UTF8(StrPurge(PtLine));
|
||
break;
|
||
|
||
case 'K': /* Lecture de la liste des mots cle */
|
||
m_KeyWord = CONV_FROM_UTF8(StrPurge(PtLine));
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
/* Recalcul de l'encadrement */
|
||
Set_Rectangle_Encadrement();
|
||
return(0);
|
||
}
|
||
|
||
/****************************************************/
|
||
void MODULE::SetPosition(const wxPoint & newpos)
|
||
/****************************************************/
|
||
// replace le module en position newpos
|
||
{
|
||
int deltaX = newpos.x - m_Pos.x;
|
||
int deltaY = newpos.y - m_Pos.y;
|
||
|
||
/* deplacement de l'ancre */
|
||
m_Pos.x += deltaX ; m_Pos.y += deltaY ;
|
||
|
||
/* deplacement de la reference */
|
||
m_Reference->m_Pos.x += deltaX ; m_Reference->m_Pos.y += deltaY;
|
||
|
||
/* deplacement de la Valeur */
|
||
m_Value->m_Pos.x += deltaX ; m_Value->m_Pos.y += deltaY;
|
||
|
||
/* deplacement des pastilles */
|
||
D_PAD * pad = m_Pads;
|
||
for ( ; pad != NULL; pad = (D_PAD*) pad->Pnext )
|
||
{
|
||
pad->m_Pos.x += deltaX ; pad->m_Pos.y += deltaY ;
|
||
}
|
||
|
||
/* deplacement des dessins de l'empreinte : */
|
||
EDA_BaseStruct * PtStruct = m_Drawings;
|
||
for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext)
|
||
{
|
||
switch( PtStruct->m_StructType)
|
||
{
|
||
case TYPEEDGEMODULE:
|
||
{
|
||
EDGE_MODULE * pt_edgmod = (EDGE_MODULE*) PtStruct;
|
||
pt_edgmod->SetDrawCoord();
|
||
break;
|
||
}
|
||
|
||
case TYPETEXTEMODULE:
|
||
{
|
||
TEXTE_MODULE * pt_texte = (TEXTE_MODULE*) PtStruct;
|
||
pt_texte->m_Pos.x += deltaX ; pt_texte->m_Pos.y += deltaY;
|
||
break;
|
||
}
|
||
|
||
default: DisplayError(NULL, wxT("Type Draw Indefini")); break;
|
||
}
|
||
}
|
||
|
||
Set_Rectangle_Encadrement();
|
||
}
|
||
|
||
|
||
|
||
/*********************************************/
|
||
void MODULE::SetOrientation(int newangle)
|
||
/*********************************************/
|
||
/* Tourne de newangle (en 0.1 degres) le module
|
||
*/
|
||
{
|
||
int px ,py;
|
||
|
||
newangle -= m_Orient; // = delta de rotation
|
||
|
||
m_Orient += newangle;
|
||
NORMALIZE_ANGLE_POS(m_Orient);
|
||
|
||
/* deplacement et rotation des pastilles */
|
||
D_PAD * pad = m_Pads;
|
||
for (; pad != NULL; pad = (D_PAD*) pad->Pnext )
|
||
{
|
||
px = pad->m_Pos0.x;
|
||
py = pad->m_Pos0.y;
|
||
|
||
pad->m_Orient += newangle ; /* change m_Orientation */
|
||
NORMALIZE_ANGLE_POS(pad->m_Orient);
|
||
|
||
RotatePoint( &px, &py, (int) m_Orient );
|
||
pad->m_Pos.x = m_Pos.x + px;
|
||
pad->m_Pos.y = m_Pos.y + py;
|
||
}
|
||
|
||
/* mise a jour de la reference et de la valeur*/
|
||
m_Reference->SetDrawCoord();
|
||
m_Value->SetDrawCoord();
|
||
|
||
/* deplacement des contours et textes de l'empreinte : */
|
||
EDA_BaseStruct * PtStruct = m_Drawings;
|
||
for(; PtStruct != NULL; PtStruct = PtStruct->Pnext )
|
||
{
|
||
if( PtStruct->m_StructType == TYPEEDGEMODULE )
|
||
{
|
||
EDGE_MODULE* pt_edgmod = (EDGE_MODULE*) PtStruct ;
|
||
pt_edgmod->SetDrawCoord();
|
||
}
|
||
if( PtStruct->m_StructType == TYPETEXTEMODULE )
|
||
{
|
||
/* deplacement des inscriptions : */
|
||
TEXTE_MODULE * pt_texte = (TEXTE_MODULE*) PtStruct;
|
||
pt_texte->SetDrawCoord();
|
||
}
|
||
}
|
||
|
||
/* Recalcul du rectangle d'encadrement */
|
||
Set_Rectangle_Encadrement();
|
||
}
|
||
|
||
/************************************************/
|
||
void MODULE::Set_Rectangle_Encadrement(void)
|
||
/************************************************/
|
||
/* Mise a jour du rectangle d'encadrement du module
|
||
Entree : pointeur sur module
|
||
Le rectangle d'encadrement est le rectangle comprenant les contours et les
|
||
pads.
|
||
Le rectangle est calcule:
|
||
pour orient 0
|
||
en coord relatives / position ancre
|
||
*/
|
||
{
|
||
EDGE_MODULE* pt_edge_mod;
|
||
D_PAD * pad;
|
||
int width;
|
||
int cx, cy, uxf, uyf, rayon;
|
||
int xmax, ymax;
|
||
|
||
|
||
/* Init des pointeurs */
|
||
pt_edge_mod = (EDGE_MODULE*) m_Drawings;
|
||
|
||
/* Init des coord du cadre a une valeur limite non nulle */
|
||
m_BoundaryBox.m_Pos.x = -500; xmax = 500;
|
||
m_BoundaryBox.m_Pos.y = -500; ymax = 500;
|
||
|
||
/* Contours: Recherche des coord min et max et mise a jour du cadre */
|
||
for( ;pt_edge_mod != NULL; pt_edge_mod = (EDGE_MODULE*)pt_edge_mod->Pnext )
|
||
{
|
||
if( pt_edge_mod->m_StructType != TYPEEDGEMODULE) continue;
|
||
width = pt_edge_mod->m_Width / 2;
|
||
switch(pt_edge_mod->m_Shape)
|
||
{
|
||
case S_ARC:
|
||
case S_CIRCLE:
|
||
{
|
||
cx = pt_edge_mod->m_Start0.x; cy = pt_edge_mod->m_Start0.y ; // centre
|
||
uxf = pt_edge_mod->m_End0.x; uyf = pt_edge_mod->m_End0.y ;
|
||
rayon = (int)hypot((double)(cx-uxf),(double)(cy - uyf) );
|
||
rayon += width;
|
||
m_BoundaryBox.m_Pos.x = min(m_BoundaryBox.m_Pos.x,cx - rayon);
|
||
m_BoundaryBox.m_Pos.y = min(m_BoundaryBox.m_Pos.y,cy - rayon);
|
||
xmax = max(xmax, cx + rayon);
|
||
ymax = max(ymax, cy + rayon);
|
||
break;
|
||
}
|
||
|
||
default:
|
||
m_BoundaryBox.m_Pos.x = min(m_BoundaryBox.m_Pos.x,pt_edge_mod->m_Start0.x - width);
|
||
m_BoundaryBox.m_Pos.x = min(m_BoundaryBox.m_Pos.x,pt_edge_mod->m_End0.x - width);
|
||
m_BoundaryBox.m_Pos.y = min(m_BoundaryBox.m_Pos.y,pt_edge_mod->m_Start0.y - width);
|
||
m_BoundaryBox.m_Pos.y = min(m_BoundaryBox.m_Pos.y,pt_edge_mod->m_End0.y - width);
|
||
xmax = max(xmax, pt_edge_mod->m_Start0.x + width);
|
||
xmax = max(xmax, pt_edge_mod->m_End0.x + width);
|
||
ymax = max(ymax, pt_edge_mod->m_Start0.y + width);
|
||
ymax = max(ymax, pt_edge_mod->m_End0.y + width);
|
||
break;
|
||
}
|
||
}
|
||
|
||
/* Pads: Recherche des coord min et max et mise a jour du cadre */
|
||
for( pad = m_Pads; pad != NULL; pad = (D_PAD*)pad->Pnext )
|
||
{
|
||
rayon = pad->m_Rayon;
|
||
cx = pad->m_Pos0.x; cy = pad->m_Pos0.y;
|
||
m_BoundaryBox.m_Pos.x = min(m_BoundaryBox.m_Pos.x,cx - rayon);
|
||
m_BoundaryBox.m_Pos.y = min(m_BoundaryBox.m_Pos.y,cy - rayon);
|
||
xmax = max(xmax, cx + rayon);
|
||
ymax = max(ymax, cy + rayon);
|
||
}
|
||
|
||
m_BoundaryBox.SetWidth(xmax - m_BoundaryBox.m_Pos.x);
|
||
m_BoundaryBox.SetHeight(ymax - m_BoundaryBox.m_Pos.y);
|
||
}
|
||
|
||
|
||
|
||
|
||
/****************************************/
|
||
void MODULE::SetRectangleExinscrit(void)
|
||
/****************************************/
|
||
|
||
/* Analogue a MODULE::Set_Rectangle_Encadrement() mais en coord reelles:
|
||
Mise a jour du rectangle d'encadrement reel du module c.a.d en coord PCB
|
||
Entree : pointeur sur module
|
||
Le rectangle d'encadrement est le rectangle comprenant les contours et les
|
||
pads.
|
||
Met egalement a jour la surface (.m_Surface) du module.
|
||
*/
|
||
{
|
||
EDGE_MODULE* EdgeMod;
|
||
D_PAD * Pad;
|
||
int width;
|
||
int cx, cy, uxf, uyf, rayon;
|
||
int xmax, ymax;
|
||
|
||
m_RealBoundaryBox.m_Pos.x = xmax = m_Pos.x;
|
||
m_RealBoundaryBox.m_Pos.y = ymax = m_Pos.y;
|
||
|
||
/* Contours: Recherche des coord min et max et mise a jour du cadre */
|
||
EdgeMod = (EDGE_MODULE*)m_Drawings;
|
||
for( ;EdgeMod != NULL; EdgeMod = (EDGE_MODULE*)EdgeMod->Pnext )
|
||
{
|
||
if( EdgeMod->m_StructType != TYPEEDGEMODULE) continue;
|
||
width = EdgeMod->m_Width / 2;
|
||
switch(EdgeMod->m_Shape)
|
||
{
|
||
case S_ARC:
|
||
case S_CIRCLE:
|
||
{
|
||
cx = EdgeMod->m_Start.x; cy = EdgeMod->m_Start.y ; // centre
|
||
uxf = EdgeMod->m_End.x; uyf = EdgeMod->m_End.y ;
|
||
rayon = (int)hypot((double)(cx-uxf),(double)(cy - uyf) );
|
||
rayon += width;
|
||
m_RealBoundaryBox.m_Pos.x = min(m_RealBoundaryBox.m_Pos.x,cx - rayon);
|
||
m_RealBoundaryBox.m_Pos.y = min(m_RealBoundaryBox.m_Pos.y,cy - rayon);
|
||
xmax = max(xmax,cx + rayon);
|
||
ymax = max(ymax,cy + rayon);
|
||
break;
|
||
}
|
||
|
||
default:
|
||
m_RealBoundaryBox.m_Pos.x = min(m_RealBoundaryBox.m_Pos.x,EdgeMod->m_Start.x - width);
|
||
m_RealBoundaryBox.m_Pos.x = min(m_RealBoundaryBox.m_Pos.x,EdgeMod->m_End.x - width);
|
||
m_RealBoundaryBox.m_Pos.y = min(m_RealBoundaryBox.m_Pos.y,EdgeMod->m_Start.y - width);
|
||
m_RealBoundaryBox.m_Pos.y = min(m_RealBoundaryBox.m_Pos.y,EdgeMod->m_End.y - width);
|
||
xmax = max(xmax,EdgeMod->m_Start.x + width);
|
||
xmax = max(xmax,EdgeMod->m_End.x + width);
|
||
ymax = max(ymax,EdgeMod->m_Start.y + width);
|
||
ymax = max(ymax,EdgeMod->m_End.y + width);
|
||
break;
|
||
}
|
||
}
|
||
|
||
/* Pads: Recherche des coord min et max et mise a jour du cadre */
|
||
for( Pad = m_Pads; Pad != NULL; Pad = (D_PAD*)Pad->Pnext )
|
||
{
|
||
rayon = Pad->m_Rayon;
|
||
cx = Pad->m_Pos.x; cy = Pad->m_Pos.y;
|
||
m_RealBoundaryBox.m_Pos.x = min(m_RealBoundaryBox.m_Pos.x,cx - rayon);
|
||
m_RealBoundaryBox.m_Pos.y = min(m_RealBoundaryBox.m_Pos.y,cy - rayon);
|
||
xmax = max(xmax,cx + rayon);
|
||
ymax = max(ymax,cy + rayon);
|
||
}
|
||
m_RealBoundaryBox.SetWidth(xmax - m_RealBoundaryBox.m_Pos.x);
|
||
m_RealBoundaryBox.SetHeight(ymax - m_RealBoundaryBox.m_Pos.y);
|
||
m_Surface = ABS((float) m_RealBoundaryBox.GetWidth() * m_RealBoundaryBox.GetHeight());
|
||
}
|
||
|
||
|
||
/*******************************************************/
|
||
void MODULE::Display_Infos(WinEDA_BasePcbFrame * frame)
|
||
/*******************************************************/
|
||
{
|
||
int nbpad;
|
||
char bufcar[512], Line[512];
|
||
int pos;
|
||
bool flag = FALSE;
|
||
wxString msg;
|
||
|
||
frame->MsgPanel->EraseMsgBox() ; /* Effacement de la zone message */
|
||
if ( frame->m_Ident != PCB_FRAME ) flag = TRUE;
|
||
pos = 1;
|
||
Affiche_1_Parametre(frame, pos, m_Reference->m_Text, m_Value->m_Text, DARKCYAN);
|
||
|
||
/* Affiche signature temporelle ou date de modif (en edition de modules) */
|
||
pos += 14;
|
||
if ( flag ) // Affichage date de modification (utile en Module Editor)
|
||
{
|
||
strcpy(Line, ctime(&m_LastEdit_Time));
|
||
strtok(Line," \n\r");
|
||
strcpy( bufcar, strtok(NULL," \n\r") ); strcat(bufcar," ");
|
||
strcat( bufcar, strtok(NULL," \n\r") ); strcat(bufcar,", ");
|
||
strtok(NULL," \n\r");
|
||
strcat( bufcar, strtok(NULL," \n\r") );
|
||
msg = CONV_FROM_UTF8(bufcar);
|
||
Affiche_1_Parametre(frame, pos, _("Last Change"), msg, BROWN);
|
||
pos += 4;
|
||
}
|
||
else
|
||
{
|
||
msg.Printf( wxT("%8.8lX"), m_TimeStamp);
|
||
Affiche_1_Parametre(frame, pos, _("TimeStamp"), msg,BROWN);
|
||
}
|
||
|
||
pos += 6;
|
||
Affiche_1_Parametre(frame, pos,_("Layer"),ReturnPcbLayerName(m_Layer),RED) ;
|
||
|
||
pos += 6;
|
||
EDA_BaseStruct * PtStruct = m_Pads;
|
||
nbpad = 0;
|
||
while( PtStruct ) { nbpad ++; PtStruct = PtStruct->Pnext; }
|
||
msg.Printf( wxT("%d"),nbpad);
|
||
Affiche_1_Parametre(frame, pos,_("Pads"), msg,BLUE);
|
||
|
||
pos += 4;
|
||
msg = wxT("..");
|
||
if( m_ModuleStatus & MODULE_is_LOCKED ) msg[0] = 'F';
|
||
if( m_ModuleStatus & MODULE_is_PLACED ) msg[1] = 'P';
|
||
Affiche_1_Parametre(frame, pos,_("Stat"), msg, MAGENTA);
|
||
|
||
pos += 4;
|
||
msg.Printf( wxT("%.1f"),(float)m_Orient / 10 );
|
||
Affiche_1_Parametre(frame, pos,_("Orient"), msg, BROWN);
|
||
|
||
pos += 5;
|
||
Affiche_1_Parametre(frame, pos,_("Module"), m_LibRef, BLUE);
|
||
|
||
pos += 9;
|
||
Affiche_1_Parametre(frame, pos, _("3D-Shape"),
|
||
m_3D_Drawings->m_Shape3DName, RED);
|
||
|
||
pos += 14;
|
||
wxString doc = _("Doc: ") + m_Doc;
|
||
wxString keyword = _("KeyW: ") + m_KeyWord;
|
||
Affiche_1_Parametre(frame, pos, doc, keyword, BLACK);
|
||
|
||
}
|
||
|