Commit f7265b0a authored by charras's avatar charras

Eeschema: better ERC diags (work in progress)

3D view: fixed: mirrored texts incorrectly drawn
parent 8355c3ad
......@@ -112,7 +112,7 @@ GLuint Pcb3D_GLCanvas::CreateDrawGL_List()
// because all boards thickness no not match with this setup:
//double epoxy_width = 1.6; // epoxy width in mm
g_Parm_3D_Visu.m_Epoxy_Width = pcb->m_BoardSettings->m_LayerThickness
g_Parm_3D_Visu.m_Epoxy_Width = pcb->m_BoardSettings->m_LayerThickness
* g_Parm_3D_Visu.m_BoardScale;
/* calculate z position for each layer */
......@@ -483,6 +483,9 @@ void Pcb3D_GLCanvas::Draw3D_DrawText( TEXTE_PCB* text )
s_Text3DZPos = g_Parm_3D_Visu.m_LayerZcoord[layer];
s_Text3DWidth = text->m_Width * g_Parm_3D_Visu.m_BoardScale;
glNormal3f( 0.0, 0.0, Get3DLayerSide( layer ) );
wxSize size = text->m_Size;
if( text->m_Mirror )
NEGATE(size.x);
if( text->m_MultilineAllowed )
{
wxPoint pos = text->m_Pos;
......@@ -496,7 +499,7 @@ void Pcb3D_GLCanvas::Draw3D_DrawText( TEXTE_PCB* text )
{
wxString txt = list->Item( i );
DrawGraphicText( NULL, NULL, pos, (EDA_Colors) color,
txt, text->m_Orient, text->m_Size,
txt, text->m_Orient, size,
text->m_HJustify, text->m_VJustify,
text->m_Width, text->m_Italic,
true,
......@@ -508,7 +511,7 @@ void Pcb3D_GLCanvas::Draw3D_DrawText( TEXTE_PCB* text )
}
else
DrawGraphicText( NULL, NULL, text->m_Pos, (EDA_Colors) color,
text->m_Text, text->m_Orient, text->m_Size,
text->m_Text, text->m_Orient, size,
text->m_HJustify, text->m_VJustify,
text->m_Width, text->m_Italic,
true,
......
......@@ -272,11 +272,11 @@ void AnnotateComponents( WinEDA_SchematicFrame* parent,
if( repairsTimestamps )
{
int ireplacecount = ReplaceDuplicatedTimeStamps();
if ( ireplacecount )
if( ireplacecount )
{
wxString msg;
msg.Printf(_("%d Duplicate Time stamps replaced"), ireplacecount);
DisplayInfoMessage( NULL, msg, 2);
msg.Printf( _( "%d Duplicate Time stamps replaced" ), ireplacecount );
DisplayInfoMessage( NULL, msg, 2 );
}
}
......@@ -328,7 +328,7 @@ void AnnotateComponents( WinEDA_SchematicFrame* parent,
ReAnnotateComponents( ComponentsList );
/* Final control (just in case ... )*/
CheckAnnotate( parent, !annotateSchematic );
parent->CheckAnnotate( NULL, !annotateSchematic );
parent->DrawPanel->Refresh( true );
}
......@@ -631,9 +631,9 @@ static int ExistUnit( int aObjet, int Unit,
}
/*******************************************************************/
int CheckAnnotate( WinEDA_SchematicFrame* frame, bool oneSheetOnly )
/*******************************************************************/
/***************************************************************************************/
int WinEDA_SchematicFrame::CheckAnnotate( wxTextCtrl* aMessageList, bool aOneSheetOnly )
/***************************************************************************************/
/**
* Function CheckAnnotate
......@@ -644,7 +644,8 @@ int CheckAnnotate( WinEDA_SchematicFrame* frame, bool oneSheetOnly )
* part number > number of parts
* different values between parts
* @return errors count
* @param oneSheetOnly : true = search is made only in the current sheet
* @param aMessageList = a wxTextCtrl to display merssages. If NULL, they are displyed in a wxMessageBox
* @param aOneSheetOnly : true = search is made only in the current sheet
* false = search in whole hierarchy (usual search).
*/
{
......@@ -657,17 +658,15 @@ int CheckAnnotate( WinEDA_SchematicFrame* frame, bool oneSheetOnly )
std::vector <OBJ_CMP_TO_LIST> ComponentsList;
g_RootSheet->m_AssociatedScreen->SetModify();
/* Build the list of components */
if( !oneSheetOnly )
if( !aOneSheetOnly )
{
DrawSheetPath* sheet;
for( sheet = SheetList.GetFirst(); sheet != NULL; sheet = SheetList.GetNext() )
AddComponentsInSheetToList( ComponentsList, sheet );
}
else
AddComponentsInSheetToList( ComponentsList, frame->GetSheet() );
AddComponentsInSheetToList( ComponentsList, GetSheet() );
sort( ComponentsList.begin(), ComponentsList.end(), AnnotateByValue );
......@@ -699,7 +698,13 @@ int CheckAnnotate( WinEDA_SchematicFrame* frame, bool oneSheetOnly )
Buff.Printf( _( "( unit %d)" ), ComponentsList[ii].m_Unit );
msg << Buff;
}
DisplayError( frame, msg );
if( aMessageList )
{
aMessageList->AppendText( msg );
aMessageList->AppendText( wxT( "\n" ) );
}
else
DisplayError( NULL, msg );
error++;
break;
}
......@@ -719,7 +724,13 @@ int CheckAnnotate( WinEDA_SchematicFrame* frame, bool oneSheetOnly )
Buff.Printf( _( " unit %d and no more than %d parts" ),
ComponentsList[ii].m_Unit, ComponentsList[ii].m_Entry->m_UnitCount );
msg << Buff;
DisplayError( frame, msg );
if( aMessageList )
{
aMessageList->AppendText( msg );
aMessageList->AppendText( wxT( "\n" ) );
}
else
DisplayError( NULL, msg );
error++;
break;
}
......@@ -756,7 +767,13 @@ int CheckAnnotate( WinEDA_SchematicFrame* frame, bool oneSheetOnly )
Buff.Printf( _( " (unit %d)" ), ComponentsList[ii].m_Unit );
msg << Buff;
}
DisplayError( frame, msg );
if( aMessageList )
{
aMessageList->AppendText( msg );
aMessageList->AppendText( wxT( "\n" ) );
}
else
DisplayError( NULL, msg );
error++;
continue;
}
......@@ -780,7 +797,13 @@ int CheckAnnotate( WinEDA_SchematicFrame* frame, bool oneSheetOnly )
msg << Buff;
}
DisplayError( frame, msg );
if( aMessageList )
{
aMessageList->AppendText( msg );
aMessageList->AppendText( wxT( "\n" ) );
}
else
DisplayError( NULL, msg );
error++;
}
......@@ -811,7 +834,13 @@ int CheckAnnotate( WinEDA_SchematicFrame* frame, bool oneSheetOnly )
ComponentsList[next].m_Value->GetData() );
#endif
DisplayError( frame, msg );
if( aMessageList )
{
aMessageList->AppendText( msg );
aMessageList->AppendText( wxT( "\n" ) );
}
else
DisplayError( NULL, msg );
error++;
}
}
......@@ -836,7 +865,13 @@ int CheckAnnotate( WinEDA_SchematicFrame* frame, bool oneSheetOnly )
full_path.GetData(),
cmpref.GetData(), ComponentsList[ii].m_NumRef,
nextcmpref.GetData(), ComponentsList[ii + 1].m_NumRef );
DisplayError( frame, msg );
if( aMessageList )
{
aMessageList->AppendText( msg );
aMessageList->AppendText( wxT( "\n" ) );
}
else
DisplayError( NULL, msg );
error++;
}
......@@ -852,14 +887,14 @@ static bool SortItemByTimeStamp( const SCH_ITEM* item1, const SCH_ITEM* item2 )
int ii = item1->m_TimeStamp - item2->m_TimeStamp;
/* if same time stamp, compare type, in order to have
* first : component
* after : sheet
* because this is the first item that have its time stamp changed
* and changing the time stamp of a sheet can loose annotation
*/
if( ii == 0 && ( item1->Type() != item2->Type()) )
if ( item1->Type() == DRAW_SHEET_STRUCT_TYPE )
* first : component
* after : sheet
* because this is the first item that have its time stamp changed
* and changing the time stamp of a sheet can loose annotation
*/
if( ii == 0 && ( item1->Type() != item2->Type() ) )
if( item1->Type() == DRAW_SHEET_STRUCT_TYPE )
ii = -1;
return ii < 0;
......@@ -906,9 +941,11 @@ int ReplaceDuplicatedTimeStamps()
if( item->m_TimeStamp == nextitem->m_TimeStamp )
{
errcount++;
// for a component, update its Time stamp and its paths (m_PathsAndReferences field)
if (item->Type() == TYPE_SCH_COMPONENT )
((SCH_COMPONENT*) item)->SetTimeStamp( GetTimeStamp());
if( item->Type() == TYPE_SCH_COMPONENT )
( (SCH_COMPONENT*) item )->SetTimeStamp( GetTimeStamp() );
// for a sheet, update only its time stamp (annotation of its components will be lost)
// TODO: see how to change sheet paths for its cmp list (can be possible in most cases)
else
......
......@@ -966,18 +966,31 @@ int LibDrawPin::ReturnPinDrawOrient( const int TransMat[2][2] )
/** Function ReturnPinStringNum
* fill the buffer with pin num as a wxString
* Pin num is coded as a long
* fill a buffer with pin num as a wxString
* Pin num is coded as a long or 4 ascii chars
* Used to print/draw the pin num
* @param aStringBuffer = the wxString to store the pin num as an unicode string
*/
void LibDrawPin::ReturnPinStringNum( wxString& buffer ) const
void LibDrawPin::ReturnPinStringNum( wxString& aStringBuffer ) const
{
aStringBuffer = ReturnPinStringNum( m_PinNum );
}
/** Function ReturnPinStringNum (static function)
* Pin num is coded as a long or 4 ascii chars
* @param aPinNum = a long containing a pin num
* @return aStringBuffer = the wxString to store the pin num as an unicode string
*/
wxString LibDrawPin::ReturnPinStringNum( long aPinNum )
{
char ascii_buf[5];
memcpy( ascii_buf, &m_PinNum, 4 );
memcpy( ascii_buf, &aPinNum, 4 );
ascii_buf[4] = 0;
buffer = CONV_FROM_UTF8( ascii_buf );
wxString buffer = CONV_FROM_UTF8( ascii_buf );
return buffer;
}
......
......@@ -265,7 +265,22 @@ public:
wxPoint ReturnPinEndPoint();
int ReturnPinDrawOrient( const int TransMat[2][2] );
void ReturnPinStringNum( wxString& buffer ) const;
/** Function ReturnPinStringNum
* fill a buffer with pin num as a wxString
* Pin num is coded as a long or 4 ascii chars
* Used to print/draw the pin num
* @param aStringBuffer = the wxString to store the pin num as an unicode string
*/
void ReturnPinStringNum( wxString& aStringBuffer ) const;
/** Function ReturnPinStringNum (static function)
* Pin num is coded as a long or 4 ascii chars
* @param aPinNum = a long containing a pin num
* @return aStringBuffer = the wxString to store the pin num as an unicode string
*/
static wxString ReturnPinStringNum( long aPinNum );
void SetPinNumFromString( wxString& buffer );
/** Function GetPenSize
......
......@@ -60,14 +60,13 @@ void DIALOG_ERC::Init()
num.Printf(wxT("%d"), g_EESchemaVar.NbWarningErc);
m_LastWarningCount->SetLabel(num);
DisplayERC_MarkersList( );
// Init Panel Matrix
ReBuildMatrixPanel();
}
/*!
* wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_ERASE_DRC_MARKERS
*/
/* wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_ERASE_DRC_MARKERS */
void DIALOG_ERC::OnEraseDrcMarkersClick( wxCommandEvent& event )
/* Delete the old ERC markers, over the whole hierarchy
*/
......@@ -77,30 +76,21 @@ void DIALOG_ERC::OnEraseDrcMarkersClick( wxCommandEvent& event )
m_Parent->DrawPanel->Refresh();
}
/*!
* wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_CANCEL
*/
/* wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_CANCEL */
void DIALOG_ERC::OnCancelClick( wxCommandEvent& event )
{
EndModal(0);
}
/*!
* wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_RESET_MATRIX
*/
/* wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_RESET_MATRIX */
void DIALOG_ERC::OnResetMatrixClick( wxCommandEvent& event )
{
ResetDefaultERCDiag(event);
}
/*!
* wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_ERC_CMP
*/
/* wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_ERC_CMP */
void DIALOG_ERC::OnErcCmpClick( wxCommandEvent& event )
{
m_MessagesList->Clear();
......@@ -113,7 +103,7 @@ void DIALOG_ERC::OnErcCmpClick( wxCommandEvent& event )
void DIALOG_ERC::ReBuildMatrixPanel()
/*********************************************/
/* Build or rebuild the panel showing the ERC matrix
/* Build or rebuild the panel showing the ERC confict matrix
*/
{
int ii, jj, event_id, text_height;
......
/////////////////////////////////////////////////////////////////////////////
// Name: dialog_erc.h
// Author: jean-pierre Charras
// Licence: GPL
// Licence: GPL
/////////////////////////////////////////////////////////////////////////////
#ifndef _DIALOG_ERC_H_
......@@ -31,7 +31,7 @@ extern const wxChar* CommentERC_V[];
*/
class DIALOG_ERC: public DIALOG_ERC_BASE
{
{
DECLARE_EVENT_TABLE()
private:
......@@ -58,6 +58,7 @@ public:
void OnResetMatrixClick( wxCommandEvent& event );
void TestErc( wxTextCtrl* aMessagesList );
void DisplayERC_MarkersList( );
void SelLocal(wxCommandEvent& event);
void SelNewCmp(wxCommandEvent& event);
void ResetDefaultERCDiag(wxCommandEvent& event);
......
......@@ -163,7 +163,7 @@ void DIALOG_ERC::TestErc( wxTextCtrl* aMessagesList )
WriteFichierERC = m_WriteResultOpt->GetValue();
ReAnnotatePowerSymbolsOnly();
if( CheckAnnotate( m_Parent, 0 ) )
if( m_Parent->CheckAnnotate( aMessagesList, false ) )
{
if ( aMessagesList )
{
......@@ -173,7 +173,7 @@ void DIALOG_ERC::TestErc( wxTextCtrl* aMessagesList )
return;
}
/* Effacement des anciens marqueurs DRC */
/* Erase all DRC markers */
DeleteAllMarkers( MARQ_ERC );
g_EESchemaVar.NbErrorErc = 0;
......@@ -237,7 +237,7 @@ void DIALOG_ERC::TestErc( wxTextCtrl* aMessagesList )
/* Analyse de la table des connexions : */
Lim = g_TabObjNet + g_NbrObjNet;
/* Reset du flag m_FlagOfConnection, utilise par la suite */
/* Reset the flag m_FlagOfConnection, that will be used next, in calculations */
for( NetItemRef = g_TabObjNet; NetItemRef < Lim; NetItemRef++ )
NetItemRef->m_FlagOfConnection = UNCONNECTED;
......@@ -264,24 +264,30 @@ void DIALOG_ERC::TestErc( wxTextCtrl* aMessagesList )
case NET_LABEL:
case NET_BUSLABELMEMBER:
case NET_PINLABEL:
case NET_GLOBLABEL: //not sure how to handle global labels -- they should be treated like other nets (just global!0
case NET_GLOBLABEL:
case NET_GLOBBUSLABELMEMBER:
// These items do not create erc problems
break;
case NET_HIERLABEL:
case NET_HIERBUSLABELMEMBER:
case NET_SHEETLABEL:
case NET_SHEETBUSLABELMEMBER:
// ERC problems when pin sheets do not match hierachical labels.
// Each pin sheet must match a hierachical label
// Each hierachicallabel must match a pin sheet
TestLabel( m_Parent->DrawPanel, NetItemRef, StartNet );
break;
case NET_NOCONNECT:
// ERC problems when a noconnect symbol is connected to more than one pin.
MinConn = NET_NC;
if( NetNbItems != 0 )
Diagnose( m_Parent->DrawPanel,NetItemRef, NULL, MinConn, UNC );
break;
case NET_PIN:
// Look for ERC problems between pins:
TestOthersItems( m_Parent->DrawPanel,
NetItemRef, StartNet, &NetNbItems, &MinConn );
break;
......@@ -292,6 +298,7 @@ void DIALOG_ERC::TestErc( wxTextCtrl* aMessagesList )
FreeTabNetList( g_TabObjNet, g_NbrObjNet );
// Displays global results:
wxString num;
num.Printf( wxT( "%d" ), g_EESchemaVar.NbErrorErc );
m_TotalErrCount->SetLabel( num );
......@@ -303,30 +310,12 @@ void DIALOG_ERC::TestErc( wxTextCtrl* aMessagesList )
m_LastWarningCount->SetLabel( num );
// Display diags:
EDA_SheetList SheetList;
for( DrawSheetPath * Sheet = SheetList.GetFirst(); Sheet != NULL; Sheet = SheetList.GetNext() )
{
SCH_ITEM * DrawStruct = Sheet->LastDrawList();
for( ; DrawStruct != NULL; DrawStruct = DrawStruct->Next() )
{
if( DrawStruct->Type() != DRAW_MARKER_STRUCT_TYPE )
continue;
/* Marqueur trouve */
DrawMarkerStruct* Marker = (DrawMarkerStruct*) DrawStruct;
if( Marker->m_Type != MARQ_ERC )
continue;
/* Display diag */
wxString msg;
msg.Printf(_("sheet %s: %s\n"),
Sheet->PathHumanReadable().GetData(),
Marker->GetComment().GetData() );
m_MessagesList->AppendText( msg );
}
}
DisplayERC_MarkersList( );
if ( m_TotalErrCount == 0 )
m_MessagesList->AppendText( _("ERC finished, no error\n"));
// Display new markers:
m_Parent->DrawPanel->Refresh();
/* Generation ouverture fichier diag */
......@@ -352,6 +341,34 @@ void DIALOG_ERC::TestErc( wxTextCtrl* aMessagesList )
}
/** Function DisplayERC_MarkersList
* read the schematic and display the list of ERC markers
*/
void DIALOG_ERC::DisplayERC_MarkersList( )
{
EDA_SheetList SheetList;
for( DrawSheetPath * Sheet = SheetList.GetFirst(); Sheet != NULL; Sheet = SheetList.GetNext() )
{
SCH_ITEM * DrawStruct = Sheet->LastDrawList();
for( ; DrawStruct != NULL; DrawStruct = DrawStruct->Next() )
{
if( DrawStruct->Type() != DRAW_MARKER_STRUCT_TYPE )
continue;
/* Marqueur trouve */
DrawMarkerStruct* Marker = (DrawMarkerStruct*) DrawStruct;
if( Marker->m_Type != MARQ_ERC )
continue;
/* Display diag */
wxString msg;
msg.Printf(_("sheet %s: %s\n"),
Sheet->PathHumanReadable().GetData(),
Marker->GetComment().GetData() );
m_MessagesList->AppendText( msg );
}
}
}
/**************************************************************/
void DIALOG_ERC::ResetDefaultERCDiag( wxCommandEvent& event )
......@@ -417,13 +434,14 @@ void DIALOG_ERC::ChangeErrorLevel( wxCommandEvent& event )
/********************************************************/
static void Diagnose( WinEDA_DrawPanel* panel,
ObjetNetListStruct* NetItemRef,
ObjetNetListStruct* NetItemTst,
int MinConn, int Diag )
static void Diagnose( WinEDA_DrawPanel* aPanel,
ObjetNetListStruct* aNetItemRef,
ObjetNetListStruct* aNetItemTst,
int aMinConn, int aDiag )
/********************************************************/
/* Creates an ERC marker to show the ERC problem between NetItemRef and NetItemTst
/* Creates an ERC marker to show the ERC problem about aNetItemRef
* or between aNetItemRef and aNetItemTst
* if MinConn < 0: this is an error on labels
*/
{
......@@ -432,78 +450,79 @@ static void Diagnose( WinEDA_DrawPanel* panel,
SCH_SCREEN* screen;
int ii, jj;
if( Diag == OK )
if( aDiag == OK )
return;
/* Creation du nouveau marqueur type Erreur ERC */
Marker = new DrawMarkerStruct( NetItemRef->m_Start, wxEmptyString );
Marker = new DrawMarkerStruct( aNetItemRef->m_Start, wxEmptyString );
Marker->m_Type = MARQ_ERC;
Marker->m_MarkFlags = WAR;
screen = NetItemRef->m_SheetList.LastScreen();
screen = aNetItemRef->m_SheetList.LastScreen();
Marker->SetNext( screen->EEDrawList );
screen->EEDrawList = Marker;
g_EESchemaVar.NbErrorErc++;
g_EESchemaVar.NbWarningErc++;
if( MinConn < 0 ) // Traitement des erreurs sur labels
if( aMinConn < 0 ) // Traitement des erreurs sur labels
{
if( (NetItemRef->m_Type == NET_HIERLABEL)
|| (NetItemRef->m_Type == NET_HIERBUSLABELMEMBER) )
if( (aNetItemRef->m_Type == NET_HIERLABEL)
|| (aNetItemRef->m_Type == NET_HIERBUSLABELMEMBER) )
{
Marker->m_Comment.Printf( _( "Warning HLabel %s not connected to SheetLabel" ),
NetItemRef->m_Label->GetData() );
aNetItemRef->m_Label->GetData() );
}
else
Marker->m_Comment.Printf( _( "Warning SheetLabel %s not connected to HLabel" ),
NetItemRef->m_Label->GetData() );
aNetItemRef->m_Label->GetData() );
return;
}
ii = NetItemRef->m_ElectricalType;
ii = aNetItemRef->m_ElectricalType;
wxString string_pinnum, cmp_ref;
char ascii_buf[5];
ascii_buf[4] = 0;
memcpy( ascii_buf, &NetItemRef->m_PinNum, 4 );
memcpy( ascii_buf, &aNetItemRef->m_PinNum, 4 );
string_pinnum = CONV_FROM_UTF8( ascii_buf );
cmp_ref = wxT("?");
if ( aNetItemRef->m_Type == NET_PIN && aNetItemRef->m_Link )
cmp_ref = ((SCH_COMPONENT*)aNetItemRef->m_Link)->GetRef( &aNetItemRef->m_SheetList );
if( NetItemTst == NULL )
if( aNetItemTst == NULL )
{
if( MinConn == NOC ) /* 1 seul element dans le net */
if( aMinConn == NOC ) /* 1 seul element dans le net */
{
if ( NetItemRef->m_Type == NET_PIN && NetItemRef->m_Link )
cmp_ref = ((SCH_COMPONENT*)NetItemRef->m_Link)->GetRef( &NetItemRef->m_SheetList );
Marker->m_Comment.Printf( _( "Warning Cmp %s, Pin %s (%s) Unconnected" ),
cmp_ref.GetData(), string_pinnum.GetData(), MsgPinElectricType[ii] );
return;
}
if( MinConn == NOD ) /* pas de pilotage du net */
if( aMinConn == NOD ) /* pas de pilotage du net */
{
if ( NetItemRef->m_Type == NET_PIN && NetItemRef->m_Link )
cmp_ref = ((SCH_COMPONENT*)NetItemRef->m_Link)->GetRef( &NetItemRef->m_SheetList );
if ( aNetItemRef->m_Type == NET_PIN && aNetItemRef->m_Link )
cmp_ref = ((SCH_COMPONENT*)aNetItemRef->m_Link)->GetRef( &aNetItemRef->m_SheetList );
Marker->m_Comment.Printf(
_( "Warning Cmp %s, Pin %s (%s) not driven (Net %d)" ),
cmp_ref.GetData(), string_pinnum.GetData(),
MsgPinElectricType[ii], NetItemRef->GetNet() );
MsgPinElectricType[ii], aNetItemRef->GetNet() );
return;
}
if( Diag == UNC )
if( aDiag == UNC )
{
Marker->m_Comment.Printf(
_( "Warning More than 1 Pin connected to UnConnect symbol" ) );
_( "Warning More than 1 Pin connected to UnConnect symbol @X=%f"", Y=%f""" ),
(float)Marker->m_Pos.x/1000, (float)Marker->m_Pos.y/1000);
return;
}
}
if( NetItemTst ) /* Erreur entre 2 pins */
if( aNetItemTst ) /* Erreur entre 2 pins */
{
jj = NetItemTst->m_ElectricalType;
jj = aNetItemTst->m_ElectricalType;
DiagLevel = _( "Warning" );
if( Diag == ERR )
if( aDiag == ERR )
{
DiagLevel = _( "Error" );
Marker->m_MarkFlags = ERR;
......@@ -511,15 +530,16 @@ static void Diagnose( WinEDA_DrawPanel* panel,
}
wxString alt_string_pinnum, alt_cmp;
memcpy( ascii_buf, &NetItemTst->m_PinNum, 4 );
memcpy( ascii_buf, &aNetItemTst->m_PinNum, 4 );
alt_string_pinnum = CONV_FROM_UTF8( ascii_buf );
alt_cmp = wxT("?");
if ( NetItemTst->m_Type == NET_PIN && NetItemTst->m_Link )
alt_cmp = ((SCH_COMPONENT*)NetItemTst->m_Link)->GetRef( &NetItemTst->m_SheetList );
if ( aNetItemTst->m_Type == NET_PIN && aNetItemTst->m_Link )
alt_cmp = ((SCH_COMPONENT*)aNetItemTst->m_Link)->GetRef( &aNetItemTst->m_SheetList );
Marker->m_Comment.Printf( _("%s: Cmp %s, Pin %s (%s) connected to Cmp %s, Pin %s (%s) (net %d)" ),
DiagLevel.GetData(),
cmp_ref.GetData(), string_pinnum.GetData(), MsgPinElectricType[ii],
alt_cmp.GetData(), alt_string_pinnum.GetData(),MsgPinElectricType[jj], NetItemRef->GetNet() );
alt_cmp.GetData(), alt_string_pinnum.GetData(),MsgPinElectricType[jj],
aNetItemRef->GetNet() );
}
}
......
......@@ -54,7 +54,7 @@ void WriteNetList( WinEDA_SchematicFrame* frame, const wxString& FileNameNL,
* bool use_netnames is used only for Spice netlist
*/
{
FILE* f = NULL;
FILE* f = NULL;
if( frame->m_NetlistFormat < NET_TYPE_CUSTOM1 )
{
......@@ -241,8 +241,9 @@ static wxString ReturnPinNetName( ObjetNetListStruct* Pin,
{
wxString lnet = NetName;
NetName = g_TabObjNet[jj].m_SheetList.PathHumanReadable();
// If sheet path is too long, use the time stamp name insteed
if ( NetName.Length() > 32 )
if( NetName.Length() > 32 )
NetName = g_TabObjNet[jj].m_SheetList.Path();
NetName += lnet;
}
......@@ -283,7 +284,7 @@ void Write_GENERIC_NetList( WinEDA_SchematicFrame* frame,
return;
}
ClearUsedFlags( ); /* Reset the flags FlagControlMulti in all schematic files*/
ClearUsedFlags(); /* Reset the flags FlagControlMulti in all schematic files*/
fprintf( tmpfile, "$BeginNetlist\n" );
/* Create netlist module section */
......@@ -553,7 +554,7 @@ static void WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with
/* Create netlist module section */
ClearUsedFlags( ); /* Reset the flags FlagControlMulti in all schematic files*/
ClearUsedFlags(); /* Reset the flags FlagControlMulti in all schematic files*/
EDA_SheetList SheetList;
......@@ -580,7 +581,7 @@ static void WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with
if( CmpListCount >= CmpListSize )
{
CmpListSize += 1000;
CmpList = (OBJ_CMP_TO_LIST*) realloc(
CmpList = (OBJ_CMP_TO_LIST*) realloc(
CmpList,
sizeof(OBJ_CMP_TO_LIST) * CmpListSize );
}
......@@ -647,7 +648,7 @@ static void WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with
for( ii = 0; ii < CmpListCount; ii++ )
{
Component = CmpList[ii].m_RootCmp;
Entry = FindLibPart( Component->m_ChipName.GetData(), wxEmptyString, FIND_ROOT );
Entry = FindLibPart( Component->m_ChipName.GetData(), wxEmptyString, FIND_ROOT );
//Line.Printf(_("%s"), CmpList[ii].m_Ref);
//Line.Replace( wxT( " " ), wxT( "_" ) );
......@@ -729,24 +730,39 @@ static void EraseDuplicatePins( ObjetNetListStruct** TabPin, int NbrPin )
* (This is a list of pins found in the whole schematic, for a given component)
* These duplicate pins were put in list because some pins (powers... )
* are found more than one time when we have a multiple parts per package component
* for instance, a 74ls00 has 4 parts, and therefor the VCC pin and GND pin apperas 4 times
* for instance, a 74ls00 has 4 parts, and therefore the VCC pin and GND pin appears 4 times
* in the list.
*/
{
int ii, jj;
for( ii = 0; ii < NbrPin - 1; ii++ )
for( int ii = 0; ii < NbrPin - 1; ii++ )
{
if( TabPin[ii] == NULL )
continue; /* Deja supprime */
continue; /* already deleted */
if( TabPin[ii]->m_PinNum != TabPin[ii + 1]->m_PinNum )
continue;
/* 2 Pins doublees */
for( jj = ii + 1; jj < NbrPin; jj++ )
/* Duplicated Pins
* remove duplicates. The priority is keep connected pins and remove unconnected
* So this allows (for instance when using multi op amps per package
* to connect only one op amp to power
*/
int idxref = ii;
for( int jj = ii + 1; jj < NbrPin; jj++ )
{
if( TabPin[ii]->m_PinNum != TabPin[jj]->m_PinNum )
if( TabPin[idxref]->m_PinNum != TabPin[jj]->m_PinNum )
break;
TabPin[jj] = NULL;
if ( TabPin[idxref]->GetNet() )
TabPin[jj] = NULL;
else
{ /* the refernce pin is not connected: remove this pin if the other pin is connected */
if ( TabPin[jj]->GetNet() )
{
TabPin[idxref] = NULL;
idxref = jj;
}
else // the 2 pins are not connected: remove the tested pin, and continue ...
TabPin[jj] = NULL;
}
}
}
}
......@@ -798,6 +814,7 @@ static void FindAllsInstancesOfComponent( SCH_COMPONENT* Component_in,
if( DEntry->m_Convert
&& (DEntry->m_Convert != Component2->m_Convert) )
continue;
// A suitable pin in found: add it to the current list
AddPinToComponentPinList( Component2, sheet, (LibDrawPin*) DEntry );
}
......@@ -858,7 +875,8 @@ static void WriteGENERICListOfNets( FILE* f, ObjetNetListStruct* ObjNet )
&& ( ObjNet[jj].m_Type != NET_PINLABEL) )
continue;
NetName = *g_TabObjNet[jj].m_Label; break;
NetName = *g_TabObjNet[jj].m_Label;
break;
}
NetcodeName.Printf( wxT( "Net %d " ), NetCode );
......@@ -873,6 +891,7 @@ static void WriteGENERICListOfNets( FILE* f, ObjetNetListStruct* ObjNet )
NetcodeName += NetName;
}
NetcodeName += wxT( "\"" );
// Add the netname without prefix, in cases we need only the "short" netname
NetcodeName += wxT( " \"" ) + NetName + wxT( "\"" );
LastNetCode = NetCode;
......@@ -958,7 +977,7 @@ static void WriteNetListCADSTAR( WinEDA_SchematicFrame* frame, FILE* f )
fprintf( f, "\n" );
/* Create netlist module section */
ClearUsedFlags( ); /* Reset the flags FlagControlMulti in all schematic files*/
ClearUsedFlags(); /* Reset the flags FlagControlMulti in all schematic files*/
EDA_SheetList SheetList;
for( sheet = SheetList.GetFirst(); sheet != NULL; sheet = SheetList.GetNext() )
......
......@@ -210,8 +210,6 @@ void* WinEDA_SchematicFrame::BuildNetListBase()
g_TabObjNet = NULL; /* Init pour le 1er passage dans ListeObjetConnection */
/* count nelist items */
g_RootSheet->m_AssociatedScreen->SetModify();
for( sheet = SheetListList.GetFirst(); sheet != NULL; sheet = SheetListList.GetNext() )
{
g_NbrObjNet += ListeObjetConnection( sheet, NULL );
......
......@@ -30,7 +30,8 @@ enum TypeNetForm {
/* Max pin number per component and footprint */
#define MAXPIN 5000
enum NetObjetType { /* Type des objets de Net */
enum NetObjetType {
/* Type des objets de Net */
NET_SEGMENT,
NET_BUS,
NET_JONCTION,
......@@ -48,7 +49,8 @@ enum NetObjetType { /* Type des objets de Net */
};
enum ConnectType { /* Valeur du Flag de connection */
enum ConnectType {
/* Valeur du Flag de connection */
UNCONNECTED = 0, /* Pin ou Label non connecte */
NOCONNECT, /* Pin volontairement non connectee (Symb. NoConnect utilise) */
PAD_CONNECT /* connexion normale */
......@@ -59,26 +61,31 @@ enum ConnectType { /* Valeur du Flag de connection */
class ObjetNetListStruct
{
public:
EDA_BaseStruct* m_Comp; /* Pointeur sur la definition de l'objet */
void* m_Link; /* Pour SheetLabelStruct: Pointeur sur la feuille de hierarchie
* Pour les Pins: pointeur sur le composant */
int m_Flag; /* flag pour calculs internes */
NetObjetType m_Type; // Type of this item (see NetObjetType enum)
EDA_BaseStruct* m_Comp; /* Pointer on the schematic item that created this net object (the parent)*/
void* m_Link; /* For Hierarchical_PIN_Sheet_Struct:
* Pointer to the hierarchy sheet that contains this Hierarchical_PIN_Sheet_Struct
* For Pins: pointer to the component that contains this pin
*/
int m_Flag; /* flag used in calculations */
DrawSheetPath m_SheetList;
NetObjetType m_Type;
int m_ElectricalType; /* Pour Pins et sheet labels: type electrique */
int m_ElectricalType; /* Has meaning only for Pins and hierachical pins: electrical type */
private:
int m_NetCode; /* pour elements simples */
int m_NetCode; /* net code for all items except BUS labels because a BUS label has
* as many net codes as bus members
*/
public:
int m_BusNetCode; /* pour connexions type bus */
int m_Member; /* pour les labels type BUSWIRE ( labels de bus eclate )
* numero de membre */
int m_BusNetCode; /* Used for BUS connections */
int m_Member; /* for labels type NET_BUSLABELMEMBER ( bus member created from the BUS label )
* member number
*/
ConnectType m_FlagOfConnection;
DrawSheetPath m_SheetListInclude; /* sheet that the hierarchal label connects to.*/
long m_PinNum; /* numero de pin( 4 octets -> 4 codes ascii) */
const wxString* m_Label; /* Tous types Labels:pointeur sur la wxString definissant le label */
const wxString* m_Label; /* For all labels:pointer on the text label */
wxPoint m_Start, m_End;
#if defined (DEBUG)
#if defined(DEBUG)
void Show( std::ostream& out, int ndx );
#endif
......@@ -97,29 +104,29 @@ public:
class OBJ_CMP_TO_LIST
{
public:
SCH_COMPONENT* m_RootCmp; // the component in schematic
SCH_COMPONENT* m_RootCmp; // the component in schematic
EDA_LibComponentStruct* m_Entry; // the source component in library
int m_Unit; /* Selected part (For multi parts per package) depending on sheet path */
DrawSheetPath m_SheetPath; /* the sheet path for this component */
unsigned long m_TimeStamp; /* unique identification number depending on sheet path */
bool m_IsNew; /* true for not yet annotated components */
wxString* m_Value; /* Component value (same for all instances) */
char m_Reference[32]; /* Component reference prefix, without number (for IC1, this is IC) ) */
int m_NumRef; /* Reference number (for IC1, this is 1) ) depending on sheet path*/
int m_Flag; /* flag for computations */
int m_Unit; /* Selected part (For multi parts per package) depending on sheet path */
DrawSheetPath m_SheetPath; /* the sheet path for this component */
unsigned long m_TimeStamp; /* unique identification number depending on sheet path */
bool m_IsNew; /* true for not yet annotated components */
wxString* m_Value; /* Component value (same for all instances) */
char m_Reference[32]; /* Component reference prefix, without number (for IC1, this is IC) ) */
int m_NumRef; /* Reference number (for IC1, this is 1) ) depending on sheet path*/
int m_Flag; /* flag for computations */
public:
OBJ_CMP_TO_LIST()
{
m_RootCmp = NULL;
m_Entry = NULL;
m_Unit = 0;
m_TimeStamp = 0;
m_IsNew = false;
m_Value = NULL;
m_RootCmp = NULL;
m_Entry = NULL;
m_Unit = 0;
m_TimeStamp = 0;
m_IsNew = false;
m_Value = NULL;
m_Reference[0] = 0;
m_NumRef = 0;
m_Flag = 0;
m_NumRef = 0;
m_Flag = 0;
}
......@@ -134,24 +141,24 @@ public:
return strnicmp( m_Reference, item.m_Reference, 32 );
}
bool IsPartsLocked( )
bool IsPartsLocked()
{
return m_Entry->m_UnitSelectionLocked;
}
};
/* Global Variables */
extern int g_NbrObjNet;
extern ObjetNetListStruct* g_TabObjNet;
/* Prototypes: */
void WriteNetList( WinEDA_SchematicFrame* frame,
const wxString& FileNameNL,
bool use_netnames );
void FreeTabNetList( ObjetNetListStruct* TabNetItems, int NbrNetItems );
void WriteNetList( WinEDA_SchematicFrame* frame,
const wxString& FileNameNL,
bool use_netnames );
void FreeTabNetList( ObjetNetListStruct* TabNetItems, int NbrNetItems );
/** Function ReturnUserNetlistTypeName
* to retrieve user netlist type names
......@@ -160,7 +167,7 @@ void FreeTabNetList( ObjetNetListStruct* TabNetItems, int NbrNetItems );
* this function must be called first with "first_item" = true
* and after with "first_item" = false to get all the other existing netlist names
*/
wxString ReturnUserNetlistTypeName( bool first_item );
wxString ReturnUserNetlistTypeName( bool first_item );
#endif
......@@ -486,7 +486,7 @@ void WinEDA_NetlistFrame::GenNetlist( wxCommandEvent& event )
m_Parent->MsgPanel->EraseMsgBox();
ReAnnotatePowerSymbolsOnly();
if( CheckAnnotate( m_Parent, 0 ) )
if( m_Parent->CheckAnnotate( NULL, 0 ) )
{
if( !IsOK( this, _( "Must be Annotated, Continue ?" ) ) )
return;
......
......@@ -235,11 +235,6 @@ int IsBusLabel(const wxString & LabelDrawList);
/***************/
void ReAnnotatePowerSymbolsOnly();
int CheckAnnotate(WinEDA_SchematicFrame * frame, bool OneSheetOnly);
/* Retourne le nombre de composants non annotes ou erron�s
Si OneSheetOnly : recherche sur le schema courant
else: recherche sur toute la hierarchie */
/************/
/* PLOT.CPP */
......
......@@ -333,10 +333,7 @@ private:
Hierarchical_PIN_Sheet_Struct* Import_PinSheet( DrawSheetStruct* Sheet, wxDC* DC );
public:
void DeleteSheetLabel(
bool aRedraw,
Hierarchical_PIN_Sheet_Struct*
aSheetLabelToDel );
void DeleteSheetLabel( bool aRedraw, Hierarchical_PIN_Sheet_Struct* aSheetLabelToDel );
private:
......@@ -396,6 +393,23 @@ public:
void TestDanglingEnds( SCH_ITEM* DrawList, wxDC* DC );
LibDrawPin* LocatePinEnd( SCH_ITEM* DrawList, const wxPoint& pos );
// ERC:
/**
* Function CheckAnnotate
* Check errors relatives to annotation:
* components not annotated
* components having the same reference (duplicates)
* for multiple parts per package components :
* part number > number of parts
* different values between parts
* @return errors count
* @param aMessageList = a wxTextCtrl to display merssages. If NULL, they are displyed in a wxMessageBox
* @param aOneSheetOnly : true = search is made only in the current sheet
* false = search in whole hierarchy (usual search).
*/
int CheckAnnotate( wxTextCtrl * aMessageList, bool aOneSheetOnly );
DECLARE_EVENT_TABLE()
};
......
......@@ -13,14 +13,6 @@
#include "protos.h"
/* Sometimes Pcbnew crashes when calculating net info (Heap Error)
* gen_rats_block_to_block() seems the culprit, but because this is a memory allocation error, it is not sure.
* define DBG_BUILD_NETINFO diplays som diags.
* All code between #define DBG_BUILD_NETINFO and #endif will be removed when ths issue will be solved
* Comment this next line for normal use
* JP Charras
*/
//#define DBG_BUILD_NETINFO
/* local variables */
static std::vector <D_PAD*> s_localPadBuffer; // for local ratsnest calculations when moving a footprint: buffer of pads to consider
......@@ -115,10 +107,6 @@ void WinEDA_BasePcbFrame::Compile_Ratsnest( wxDC* DC, bool display_status_pcb )
GetBoard()->m_Status_Pcb = 0; /* we want a full ratnest computation, from the scratch */
MsgPanel->EraseMsgBox();
#ifdef DBG_BUILD_NETINFO
wxSafeYield();
#endif
// Rebuild the full pads and net info list
RecalculateAllTracksNetcode();
......@@ -134,9 +122,6 @@ void WinEDA_BasePcbFrame::Compile_Ratsnest( wxDC* DC, bool display_status_pcb )
msg.Printf( wxT( " %d" ), m_Pcb->m_NetInfo->GetNetsCount() );
Affiche_1_Parametre( this, 8, wxT( "Nets" ), msg, CYAN );
}
#ifdef DBG_BUILD_NETINFO
wxSafeYield();
#endif
/* Compute the full ratsnest
* which can be see like all the possible links or logical connections.
......@@ -144,34 +129,17 @@ void WinEDA_BasePcbFrame::Compile_Ratsnest( wxDC* DC, bool display_status_pcb )
* This full ratsnest is not modified by track editing.
* It changes only when a netlist is read, or footprints are modified
*/
#ifdef DBG_BUILD_NETINFO
Affiche_Message( wxT( "Build Board Ratsnest" ) );
wxSafeYield();
#endif
Build_Board_Ratsnest( DC );
/* Compute the pad connections due to the existing tracks (physical connections)*/
#ifdef DBG_BUILD_NETINFO
Affiche_Message( wxT( "testconnexions" ) );
wxSafeYield();
#endif
test_connexions( DC );
/* Compute the active ratsnest, i.e. the unconnected links
* it is faster than Build_Board_Ratsnest()
* because many optimisations and computations are already made
*/
#ifdef DBG_BUILD_NETINFO
Affiche_Message( wxT( "Tst Ratsnest" ) );
wxSafeYield();
#endif
Tst_Ratsnest( DC, 0 );
#ifdef DBG_BUILD_NETINFO
Affiche_Message( wxT( "End Tst Ratsnest" ) );
wxSafeYield();
#endif
// Redraw the active ratsnest ( if enabled )
if( g_Show_Ratsnest && DC )
DrawGeneralRatsnest( DC, 0 );
......@@ -244,10 +212,6 @@ static int gen_rats_block_to_block( std::vector<RATSNEST_ITEM>& aRatsnestBuffer,
for( unsigned ii = aPadIdxStart; ii < aPadIdxMax; ii++ )
{
D_PAD* ref_pad = aPadBuffer[ii];
#ifdef DBG_BUILD_NETINFO
if( ref_pad->Type() != TYPE_PAD )
wxMessageBox( wxT( "gen_rats_block_to_block() err: ref_pad is not a D_PAD" ) );
#endif
/* search a pad which is in the block 1 */
if( ref_pad->GetSubRatsnest() != 1 )
......@@ -462,10 +426,6 @@ void WinEDA_BasePcbFrame::Build_Board_Ratsnest( wxDC* DC )
unsigned current_net_code = 1; // 1er net_code a analyser (net_code = 0 -> no connect)
noconn = 0;
#ifdef DBG_BUILD_NETINFO
Affiche_Message( wxT( "Build Board Ratsnest - 1" ) );
wxSafeYield();
#endif
for( ; current_net_code < m_Pcb->m_NetInfo->GetNetsCount(); current_net_code++ )
{
......@@ -476,14 +436,6 @@ void WinEDA_BasePcbFrame::Build_Board_Ratsnest( wxDC* DC )
return;
}
net->m_RatsnestStartIdx = m_Pcb->GetRatsnestsCount();
#ifdef DBG_BUILD_NETINFO
wxString msg;
msg.Printf( wxT(
"Build Board Ratsnest net %d/%d start" ), current_net_code,
m_Pcb->m_NetInfo->GetNetsCount() );
Affiche_Message( msg );
wxSafeYield();
#endif
// Search for the last subratsnest already in use
int num_block = 0;
......@@ -495,13 +447,6 @@ void WinEDA_BasePcbFrame::Build_Board_Ratsnest( wxDC* DC )
}
/* Compute the ratsnest relative to the current net */
#ifdef DBG_BUILD_NETINFO
msg.Printf( wxT(
"Build Board Ratsnest net %d/%d first pass" ), current_net_code,
m_Pcb->m_NetInfo->GetNetsCount() );
Affiche_Message( msg );
wxSafeYield();
#endif
/* a - first pass : create the blocks from not already in block pads */
int icnt = gen_rats_pad_to_pad( m_Pcb->m_FullRatsnest,
......@@ -510,13 +455,6 @@ void WinEDA_BasePcbFrame::Build_Board_Ratsnest( wxDC* DC )
net->m_ListPad.size(),
num_block );
#ifdef DBG_BUILD_NETINFO
msg.Printf( wxT( "Build Board Ratsnest net (%s) %d/%d iteration" ),
m_Pcb->FindNet( current_net_code )->GetNetname().GetData(),
current_net_code, m_Pcb->m_NetInfo->GetNetsCount() );
Affiche_Message( msg );
wxSafeYield();
#endif
/* b - blocks connection (Iteration) */
while( icnt > 1 )
{
......@@ -527,13 +465,6 @@ void WinEDA_BasePcbFrame::Build_Board_Ratsnest( wxDC* DC )
net->m_RatsnestEndIdx = m_Pcb->GetRatsnestsCount();
#ifdef DBG_BUILD_NETINFO
msg.Printf( wxT(
"Build Board Ratsnest net %d/%d sort" ), current_net_code,
m_Pcb->m_NetInfo->GetNetsCount() );
Affiche_Message( msg );
wxSafeYield();
#endif
/* sort by lenght */
net = m_Pcb->FindNet( current_net_code );
if( (net->m_RatsnestEndIdx - net->m_RatsnestStartIdx) > 1 )
......@@ -545,10 +476,6 @@ void WinEDA_BasePcbFrame::Build_Board_Ratsnest( wxDC* DC )
}
}
#ifdef DBG_BUILD_NETINFO
Affiche_Message( wxT( "Build Board Ratsnest - 2" ) );
wxSafeYield();
#endif
m_Pcb->m_NbNoconnect = noconn;
m_Pcb->m_Status_Pcb |= LISTE_RATSNEST_ITEM_OK;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment