Solved netlist problems for multiple parts per package components in complex hierarchies.

B.O.M. generation still have a minor problem wih this.
This commit is contained in:
charras 2008-05-15 11:20:19 +00:00
parent 88055164d5
commit b8ea76fe63
17 changed files with 2804 additions and 2443 deletions

View File

@ -5,6 +5,15 @@ Started 2007-June-11
Please add newer entries at the top, list the date and your name with
email address.
2008-May-15 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
================================================================================
+eeschema:
Solved netlist problems for multiple parts per package components
in complex hierarchies.
B.O.M. generation still have a minor problem wih this.
2008-May-5 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================
+common.c

View File

@ -4,7 +4,6 @@
****************************************************************/
#include "fctsys.h"
#include "gr_basic.h"
#include "common.h"
#include "program.h"
@ -15,8 +14,6 @@
#include "dialog_backanno.cpp"
#include "protos.h"
/**************************************************************/
SCH_COMPONENT * WinEDA_SchematicFrame::FindComponentByRef(
const wxString& reference )

View File

@ -293,9 +293,7 @@ SCH_COMPONENT::SCH_COMPONENT( const wxPoint& aPos ) :
m_Pos = aPos;
//m_FlagControlMulti = 0;
m_UsedOnSheets.Clear();
m_Convert = 0; /* Gestion des mutiples representations (conversion De Morgan) */
m_Convert = 0; /* De Morgan Handling */
/* The rotation/mirror transformation matrix. pos normal*/
m_Transform[0][0] = 1;
@ -469,6 +467,9 @@ void SCH_COMPONENT::ClearAnnotation( DrawSheetPath* aSheet )
defRef.Append( wxT( "?" ) );
wxString multi = wxT( "1" );
if ( KeepMulti ) // We cannot remove all annotations: part selection must be kept
{
wxString NewHref;
wxString path;
if( aSheet )
@ -486,15 +487,20 @@ void SCH_COMPONENT::ClearAnnotation( DrawSheetPath* aSheet )
m_PathsAndReferences[ii] = NewHref;
}
}
}
else
{
m_PathsAndReferences.Empty(); // Empty strings, but does not free memory because a new annotation will reuse it
m_Multi = 1;
}
// These 2 changes do not work in complex hierarchy.
// When a clear annotation is made, the calling function must call a
// UpdateAllScreenReferences for the active sheet.
// But this call does not made here.
// But this call cannot made here.
m_Field[REFERENCE].m_Text = defRef; //for drawing.
if( !KeepMulti )
m_Multi = 1;
}
@ -510,8 +516,6 @@ SCH_COMPONENT* SCH_COMPONENT::GenCopy()
new_item->m_ChipName = m_ChipName;
new_item->m_PrefixString = m_PrefixString;
//new_item->m_FlagControlMulti = m_FlagControlMulti;
new_item->m_UsedOnSheets = m_UsedOnSheets;
new_item->m_Convert = m_Convert;
new_item->m_Transform[0][0] = m_Transform[0][0];
new_item->m_Transform[0][1] = m_Transform[0][1];

View File

@ -100,8 +100,6 @@ public:
* determined, upon file load, by the first non-digits in the reference fields. */
PartTextStruct m_Field[NUMBER_OF_FIELDS];
//int m_FlagControlMulti;
ArrayOfSheetLists m_UsedOnSheets; // Used as flags when calculating netlist
int m_Convert; /* Gestion (management) des mutiples representations (ex: conversion De Morgan) */
int m_Transform[2][2]; /* The rotation/mirror transformation matrix. */

View File

@ -402,7 +402,7 @@ DanglingEndHandle* RebuildEndList( EDA_BaseStruct* DrawList )
#undef STRUCT
#define STRUCT ( (SCH_COMPONENT*) DrawItem )
EDA_LibComponentStruct* Entry;
Entry = FindLibPart( STRUCT->m_ChipName, wxEmptyString, FIND_ROOT );
Entry = FindLibPart( STRUCT->m_ChipName.GetData(), wxEmptyString, FIND_ROOT );
if( Entry == NULL )
break;

View File

@ -691,13 +691,6 @@ void WinEDA_Build_BOM_Frame::GenereListeOfItems( const wxString& FullFileName )
GenListeCmp( List );
#if 0
for( int i = 0; i<NbItems; i++ )
{
printf( "found component: %s\n", List[i].m_Ref );
}
#endif
/* generation du fichier listing */
DateAndTime( Line );
wxString Title = g_Main_Title + wxT( " " ) + GetBuildVersion();
@ -707,13 +700,7 @@ void WinEDA_Build_BOM_Frame::GenereListeOfItems( const wxString& FullFileName )
qsort( List, NbItems, sizeof( ListComponent ),
( int( * ) ( const void*, const void* ) )ListTriComposantByRef );
#if 0
printf( "sorted by reference:\n" );
for( int i = 0; i<NbItems; i++ )
{
printf( "found component: %s\n", List[i].m_Ref );
}
#endif
// if( ! s_ListWithSubCmponents )
if( !m_ListSubCmpItems->GetValue() )
DeleteSubCmp( List, NbItems );
@ -785,20 +772,17 @@ void WinEDA_Build_BOM_Frame::GenereListeOfItems( const wxString& FullFileName )
int GenListeCmp( ListComponent* List )
/****************************************/
/* Routine de generation de la liste des elements utiles du dessin
* Si List == NULL: comptage des elements
* Sinon remplissage de la liste
* Initialise "FlagControlMulti" a SheetNumber pour la sortie des listes
* et m_Father comme pointeur sur la sheet d'appartenance
/* Creates the list of components in the schematic
*
* routine for generating a list of the used components.
* if List == null, just returns the count. if not, fills the list.
* goes through the sheets, not the screens, so that we account for
* multiple instances of a given screen.
* Also Initialise m_Father as pointer pointeur of the SCH_SCREN parent
*/
{
int ItemCount = 0;
EDA_BaseStruct* DrawList;
EDA_BaseStruct* SchItem;
SCH_COMPONENT* DrawLibItem;
DrawSheetPath* sheet;
@ -807,14 +791,13 @@ int GenListeCmp( ListComponent* List )
for( sheet = SheetList.GetFirst(); sheet != NULL; sheet = SheetList.GetNext() )
{
DrawList = sheet->LastDrawList();
while( DrawList )
for ( SchItem = sheet->LastDrawList(); SchItem;SchItem = SchItem->Next() )
{
switch( DrawList->Type() )
{
case TYPE_SCH_COMPONENT:
if( SchItem->Type() != TYPE_SCH_COMPONENT )
continue;
ItemCount++;
DrawLibItem = (SCH_COMPONENT*) DrawList;
DrawLibItem = (SCH_COMPONENT*) SchItem;
DrawLibItem->m_Parent = sheet->LastScreen();
if( List )
{
@ -825,13 +808,6 @@ int GenListeCmp( ListComponent* List )
sizeof( List->m_Ref ) );
List++;
}
break;
default:
break;
}
DrawList = DrawList->Pnext;
}
}

View File

@ -25,17 +25,22 @@ static void WriteGENERICListOfNets( FILE* f, ObjetNetListStruct* ObjNet );
static void AddPinToComponentPinList( SCH_COMPONENT* Component,
DrawSheetPath* sheet,
LibDrawPin* PinEntry );
static void FindOthersUnits( SCH_COMPONENT* Component, DrawSheetPath* Sheet_in);
static void FindAllsInstancesOfComponent( SCH_COMPONENT* Component,
EDA_LibComponentStruct* Entry,
DrawSheetPath* Sheet_in );
static int SortPinsByNum( ObjetNetListStruct** Pin1, ObjetNetListStruct** Pin2 );
static void EraseDuplicatePins( ObjetNetListStruct** TabPin, int NbrPin );
static void ClearUsedFlags( WinEDA_SchematicFrame* frame );
static void ClearUsedFlags( void );
/* Variable locales */
/* Local variables */
static int s_SortedPinCount;
static ObjetNetListStruct** s_SortedComponentPinList;
// list of references arready found for multi part per packages components
// (used to avoid to used more than one time a component)
static wxArrayString s_ReferencesAlreadyFound;
/******************************************************************************/
void WriteNetList( WinEDA_SchematicFrame* frame, const wxString& FileNameNL,
@ -91,7 +96,7 @@ void WriteNetList( WinEDA_SchematicFrame* frame, const wxString& FileNameNL,
/****************************************************************************/
static SCH_COMPONENT* FindNextComponentAndCreatPinList(
EDA_BaseStruct* DrawList, DrawSheetPath* sheet)
EDA_BaseStruct* DrawList, DrawSheetPath* sheet )
/****************************************************************************/
/* Find a "suitable" component from the DrawList
@ -115,15 +120,12 @@ static SCH_COMPONENT* FindNextComponentAndCreatPinList(
continue;
Component = (SCH_COMPONENT*) DrawList;
/* already tested ? : */
bool found = false;
for(unsigned int i =0; i<Component->m_UsedOnSheets.GetCount(); i++){
if( Component->m_UsedOnSheets.Item(i) == *sheet ){
found = true;
break;
}
}
if( found ) continue;
/* Power symbol and other component which have the reference starting by
* "#" are not included in netlist (pseudo or virtual components) */
wxString str = Component->GetRef( sheet );
if( str[0] == '#' ) // ignore it
continue;
//if( Component->m_FlagControlMulti == 1 )
// continue; /* yes */
// removed because with multiple instances of one schematic
@ -133,11 +135,26 @@ static SCH_COMPONENT* FindNextComponentAndCreatPinList(
if( Entry == NULL )
continue;
/* Power symbol and other component which have the reference starting by
* "#" are not included in netlist (pseudo components) */
wxString str = Component->GetRef(sheet);
if( str[0] == '#' )
if( Entry->m_UnitCount > 1 ) // Multi parts per package: test if already visited:
{
bool found = false;
for( unsigned jj = 0; jj < s_ReferencesAlreadyFound.GetCount(); jj++ )
{
if( str == s_ReferencesAlreadyFound[jj] ) // Already visited
{
found = true;
break;
}
}
if( found )
continue;
else
{
s_ReferencesAlreadyFound.Add( str ); // Mark as visited
}
}
/* Create the pin table for this component */
int ii = sizeof(ObjetNetListStruct*) * MAXPIN;
@ -146,12 +163,14 @@ static SCH_COMPONENT* FindNextComponentAndCreatPinList(
memset( s_SortedComponentPinList, 0, ii );
DEntry = Entry->m_Drawings;
if( Entry->m_UnitCount <= 1 ) // One part per package
{
for( ; DEntry != NULL; DEntry = DEntry->Next() )
{
if( DEntry->Type() != COMPONENT_PIN_DRAW_TYPE )
continue;
if( DEntry->m_Unit
&& (DEntry->m_Unit != Component->m_Multi) )
&& ( DEntry->m_Unit != Component->GetUnitSelection( sheet ) ) )
continue;
if( DEntry->m_Convert
&& (DEntry->m_Convert != Component->m_Convert) )
@ -160,18 +179,15 @@ static SCH_COMPONENT* FindNextComponentAndCreatPinList(
AddPinToComponentPinList( Component, sheet, (LibDrawPin*) DEntry );
}
}
}
else // Multiple parts per package: Collect all parts ans pins for this reference
FindAllsInstancesOfComponent( Component, Entry, sheet );
//Component->m_FlagControlMulti = 1;
Component->m_UsedOnSheets.Add(*sheet);
if( Entry->m_UnitCount > 1 )
FindOthersUnits( Component, sheet);
/* Tri sur le numero de Pin de TabListePin */
/* Sort Pins in s_SortedComponentPinList by pin number */
qsort( s_SortedComponentPinList, s_SortedPinCount, sizeof(ObjetNetListStruct*),
( int( * ) ( const void*, const void* ) )SortPinsByNum );
/* Elimination des Pins redondantes du s_SortedComponentPinList */
/* Remove duplicate Pins in s_SortedComponentPinList */
EraseDuplicatePins( s_SortedComponentPinList, s_SortedPinCount );
return Component;
@ -218,10 +234,12 @@ static wxString ReturnPinNetName( ObjetNetListStruct* Pin,
if( !NetName.IsEmpty() )
{
if( g_TabObjNet[jj].m_Type != NET_PINLABEL ){
if( g_TabObjNet[jj].m_Type != NET_PINLABEL )
{
NetName = g_TabObjNet[jj].m_SheetList.PathHumanReadable()
+ NetName;
}
//NetName << wxT("_") << g_TabObjNet[jj].m_SheetList.PathHumanReadable();
}
else
@ -232,6 +250,7 @@ static wxString ReturnPinNetName( ObjetNetListStruct* Pin,
return NetName;
}
/***********************************************************************/
void Write_GENERIC_NetList( WinEDA_SchematicFrame* frame,
const wxString& FullFileName )
@ -239,12 +258,11 @@ void Write_GENERIC_NetList( WinEDA_SchematicFrame* frame,
/* Create a generic netlist, and call an external netlister
* to change the netlist syntax and create the file
* -- does this still work?
*/
{
wxString Line, FootprintName;
DrawSheetPath* sheet;
EDA_BaseStruct* DrawList;
EDA_BaseStruct* SchItem;
SCH_COMPONENT* Component;
wxString netname;
int ii;
@ -260,7 +278,7 @@ void Write_GENERIC_NetList( WinEDA_SchematicFrame* frame,
return;
}
ClearUsedFlags( frame ); /* 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 */
@ -269,9 +287,9 @@ void Write_GENERIC_NetList( WinEDA_SchematicFrame* frame,
for( sheet = SheetList.GetFirst(); sheet != NULL; sheet = SheetList.GetNext() )
{
for( DrawList = sheet->LastDrawList(); DrawList != NULL; DrawList = DrawList->Pnext )
for( SchItem = sheet->LastDrawList(); SchItem != NULL; SchItem = SchItem->Pnext )
{
DrawList = Component = FindNextComponentAndCreatPinList( DrawList, sheet );
SchItem = Component = FindNextComponentAndCreatPinList( SchItem, sheet );
if( Component == NULL )
break; // No component left
@ -286,7 +304,7 @@ void Write_GENERIC_NetList( WinEDA_SchematicFrame* frame,
fprintf( tmpfile, "\n$BeginComponent\n" );
fprintf( tmpfile, "TimeStamp=%8.8lX\n", Component->m_TimeStamp );
fprintf( tmpfile, "Footprint=%s\n", CONV_TO_UTF8( FootprintName ) );
Line = wxT( "Reference=" ) + Component->GetRef(sheet) + wxT( "\n" );
Line = wxT( "Reference=" ) + Component->GetRef( sheet ) + wxT( "\n" );
Line.Replace( wxT( " " ), wxT( "_" ) );
fprintf( tmpfile, CONV_TO_UTF8( Line ) );
@ -346,30 +364,12 @@ void Write_GENERIC_NetList( WinEDA_SchematicFrame* frame,
}
/********************************************************/
static void ClearUsedFlags( WinEDA_SchematicFrame* frame )
/********************************************************/
/**********************************/
static void ClearUsedFlags( void )
/*********************************/
/* Clear flag list, used in netlist generation */
{
SCH_SCREEN* screen;
EDA_BaseStruct* DrawList;
EDA_ScreenList ScreenList;
for( screen = ScreenList.GetFirst(); screen != NULL; screen = ScreenList.GetNext() )
{
DrawList = screen->EEDrawList;
while( DrawList )
{
if( DrawList->Type() == TYPE_SCH_COMPONENT )
{
SCH_COMPONENT* Component = (SCH_COMPONENT*) DrawList;
//Component->m_FlagControlMulti = 0;
Component->m_UsedOnSheets.Clear();
}
DrawList = DrawList->Pnext;
}
}
s_ReferencesAlreadyFound.Clear();
}
@ -384,7 +384,7 @@ static void WriteNetListPspice( WinEDA_SchematicFrame* frame, FILE* f,
* sinon les nodes sont identifies par le netnumber
*
* tous les textes graphiques commen<EFBFBD>ant par [.-+]pspice ou [.-+]gnucap
* sont consid<EFBFBD>r<EFBFBD>s comme des commandes a placer dans la netliste
* sont consideres comme des commandes a placer dans la netliste
* [.-]pspice ou gnucap sont en debut
+pspice et +gnucap sont en fin de netliste
*/
@ -461,7 +461,7 @@ static void WriteNetListPspice( WinEDA_SchematicFrame* frame, FILE* f,
/* Create component list */
ClearUsedFlags( frame ); /* Reset the flags FlagControlMulti in all schematic files*/
ClearUsedFlags(); /* Reset the flags FlagControlMulti in all schematic files*/
for( sheet = SheetList.GetFirst(); sheet != NULL; sheet = SheetList.GetNext() )
{
for( DrawList = sheet->LastDrawList(); DrawList != NULL; DrawList = DrawList->Pnext )
@ -524,7 +524,7 @@ static void WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with
/*****************************************************************************************/
/* Routine de generation du fichier netliste ( Format ORCAD PCB 2 ameliore )
* si with_pcbnew = FALSE
* si with_pcbnew = TRUE
* format PCBNEW (OrcadPcb2 + commentaires et liste des nets)
* si with_pcbnew = FALSE
* Format ORCADPCB2 strict
@ -547,7 +547,7 @@ static void WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with
/* Create netlist module section */
ClearUsedFlags( frame ); /* Reset the flags FlagControlMulti in all schematic files*/
ClearUsedFlags( ); /* Reset the flags FlagControlMulti in all schematic files*/
EDA_SheetList SheetList( NULL );
@ -555,7 +555,7 @@ static void WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with
{
for( DrawList = sheet->LastDrawList(); DrawList != NULL; DrawList = DrawList->Pnext )
{
DrawList = Component = FindNextComponentAndCreatPinList( DrawList, sheet);
DrawList = Component = FindNextComponentAndCreatPinList( DrawList, sheet );
if( Component == NULL )
break;
@ -566,7 +566,8 @@ static void WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with
{
if( Entry->m_FootprintList.GetCount() != 0 ) /* Put in list */
{
if( CmpList == NULL ){
if( CmpList == NULL )
{
CmpList = (ListComponent*)
MyZMalloc( sizeof(ListComponent) * CmpListSize );
}
@ -578,7 +579,7 @@ static void WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with
sizeof(ListComponent) * CmpListSize );
}
CmpList[CmpListCount].m_Comp = Component;
strcpy(CmpList[CmpListCount].m_Ref, Component->GetRef( sheet ).mb_str());
strcpy( CmpList[CmpListCount].m_Ref, Component->GetRef( sheet ).mb_str() );
CmpListCount++;
}
}
@ -591,9 +592,9 @@ static void WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with
else
FootprintName = wxT( "$noname" );
Line = Component->GetRef(sheet);
Line = Component->GetRef( sheet );
fprintf( f, " ( %s %s",
CONV_TO_UTF8(Component->GetPath(sheet)),
CONV_TO_UTF8( Component->GetPath( sheet ) ),
CONV_TO_UTF8( FootprintName ) );
fprintf( f, " %s", CONV_TO_UTF8( Line ) );
@ -640,13 +641,16 @@ static void WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with
{
Component = CmpList[ii].m_Comp;
Entry = FindLibPart( Component->m_ChipName.GetData(), wxEmptyString, FIND_ROOT );
//Line.Printf(_("%s"), CmpList[ii].m_Ref);
//Line.Replace( wxT( " " ), wxT( "_" ) );
unsigned int i;
for(i=0; i<sizeof(CmpList[ii].m_Ref) && CmpList[ii].m_Ref[i]; i++){
if(CmpList[ii].m_Ref[i] == ' ')
for( i = 0; i<sizeof(CmpList[ii].m_Ref) && CmpList[ii].m_Ref[i]; i++ )
{
if( CmpList[ii].m_Ref[i] == ' ' )
CmpList[ii].m_Ref[i] = '_';
}
fprintf( f, "$component %s\n", CmpList[ii].m_Ref );
/* Write the footprint list */
for( unsigned int jj = 0; jj < Entry->m_FootprintList.GetCount(); jj++ )
@ -714,10 +718,12 @@ static void EraseDuplicatePins( ObjetNetListStruct** TabPin, int NbrPin )
/**********************************************************************/
/*
* Routine qui elimine les Pins de meme Numero de la liste des objets
* (Liste des Pins d'un boitier) passee en entree
* Ces pins redondantes proviennent des pins (alims... ) communes a plusieurs
* elements d'un boitier a multiple parts.
* Function to remove duplicate Pins in the TabPin pin list
* (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
* in the list.
*/
{
int ii, jj;
@ -739,56 +745,40 @@ static void EraseDuplicatePins( ObjetNetListStruct** TabPin, int NbrPin )
}
/**********************************************************************/
static void FindOthersUnits( SCH_COMPONENT* Component_in, DrawSheetPath* Sheet_in)
/**********************************************************************/
/**********************************************************************************/
static void FindAllsInstancesOfComponent( SCH_COMPONENT* Component_in,
EDA_LibComponentStruct* Entry,
DrawSheetPath* Sheet_in )
/**********************************************************************************/
/* Recherche les autres parts du boitier auquel appartient la part Component,
* pour les boitiers a parts multiples.
* Appelle AddPinToComponentPinList() pour classer les pins des parts trouvees
/**
* Used for multiple parts per package components
* Search all instances of Component_in,
* Calls AddPinToComponentPinList() to and pins founds to the current component pin list
*/
{
EDA_BaseStruct* DrawList;
EDA_BaseStruct* SchItem;
SCH_COMPONENT* Component2;
EDA_LibComponentStruct* Entry;
LibEDA_BaseStruct* DEntry;
DrawSheetPath* sheet;
wxString str;
wxString str, Reference = Component_in->GetRef( Sheet_in );
EDA_SheetList SheetList( NULL );
unsigned int i;
bool found;
for( sheet = SheetList.GetFirst(); sheet != NULL; sheet = SheetList.GetNext() )
{
DrawList = sheet->LastDrawList();
while( DrawList )
for( SchItem = sheet->LastDrawList(); SchItem; SchItem = SchItem->Pnext )
{
switch( DrawList->Type() )
{
case TYPE_SCH_COMPONENT:
Component2 = (SCH_COMPONENT*) DrawList;
if( SchItem->Type() != TYPE_SCH_COMPONENT )
continue;
found = false;
for( i =0; i<Component2->m_UsedOnSheets.GetCount(); i++){
if( Component2->m_UsedOnSheets.Item(i) == *Sheet_in ){
found = true;
}
}
if( found ) break;
//if( Component2->m_FlagControlMulti == 1 ) //has it been used? (on this sheet?)
// break;
str = Component2->GetRef(sheet);
if( str.CmpNoCase( Component_in->GetRef(Sheet_in) ) != 0 )
break;
Component2 = (SCH_COMPONENT*) SchItem;
Entry = FindLibPart( Component2->m_ChipName.GetData(), wxEmptyString, FIND_ROOT );
if( Entry == NULL )
break;
str = Component2->GetRef( sheet );
if( str.CmpNoCase( Reference ) != 0 )
continue;
if( str[0] == '#' )
break;
if( Entry->m_Drawings != NULL )
if( Entry && Entry->m_Drawings != NULL )
{
DEntry = Entry->m_Drawings;
for( ; DEntry != NULL; DEntry = DEntry->Next() )
@ -796,26 +786,16 @@ static void FindOthersUnits( SCH_COMPONENT* Component_in, DrawSheetPath* Sheet_i
if( DEntry->Type() != COMPONENT_PIN_DRAW_TYPE )
continue;
if( DEntry->m_Unit
&& (DEntry->m_Unit != Component2->m_Multi) )
&& ( DEntry->m_Unit != Component2->GetUnitSelection( sheet ) ) )
continue;
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 );
}
}
}
Component2->m_UsedOnSheets.Add(*Sheet_in);
//Component2->m_FlagControlMulti = 1; //mark it as used..
break;
default:
break;
}
DrawList = DrawList->Pnext;
}
}
}
@ -858,7 +838,7 @@ static void WriteGENERICListOfNets( FILE* f, ObjetNetListStruct* ObjNet )
for( ii = 0; ii < g_NbrObjNet; ii++ )
{
if( (NetCode = ObjNet[ii].GetNet()) != LastNetCode ) // New net found, write net id;
if( ( NetCode = ObjNet[ii].GetNet() ) != LastNetCode ) // New net found, write net id;
{
SameNetcodeCount = 0; // Items count for this net
NetName.Empty();
@ -879,10 +859,12 @@ static void WriteGENERICListOfNets( FILE* f, ObjetNetListStruct* ObjNet )
if( !NetName.IsEmpty() )
{
NetcodeName += NetName;
if( g_TabObjNet[jj].m_Type != NET_PINLABEL ){
if( g_TabObjNet[jj].m_Type != NET_PINLABEL )
{
// usual net name, add in the sheet path
NetcodeName = g_TabObjNet[jj].m_SheetList.PathHumanReadable()
+ NetcodeName;
//NetcodeName << wxT("_") <<
// g_TabObjNet[jj].m_SheetList.PathHumanReadable();
}
@ -895,7 +877,7 @@ static void WriteGENERICListOfNets( FILE* f, ObjetNetListStruct* ObjNet )
continue;
Cmp = (SCH_COMPONENT*) ObjNet[ii].m_Link;
CmpRef = Cmp->GetRef(&ObjNet[ii].m_SheetList); //is this correct?
CmpRef = Cmp->GetRef( &ObjNet[ii].m_SheetList ); //is this correct?
if( CmpRef.StartsWith( wxT( "#" ) ) )
continue; // Pseudo component (Like Power symbol)
@ -971,14 +953,14 @@ static void WriteNetListCADSTAR( WinEDA_SchematicFrame* frame, FILE* f )
fprintf( f, "\n" );
/* Create netlist module section */
ClearUsedFlags( frame ); /* Reset the flags FlagControlMulti in all schematic files*/
ClearUsedFlags( ); /* Reset the flags FlagControlMulti in all schematic files*/
EDA_SheetList SheetList( NULL );
for( sheet = SheetList.GetFirst(); sheet != NULL; sheet = SheetList.GetNext() )
{
for( DrawList = sheet->LastDrawList(); DrawList != NULL; DrawList = DrawList->Pnext )
{
DrawList = Component = FindNextComponentAndCreatPinList( DrawList, sheet);
DrawList = Component = FindNextComponentAndCreatPinList( DrawList, sheet );
if( Component == NULL )
break;
@ -990,7 +972,7 @@ static void WriteNetListCADSTAR( WinEDA_SchematicFrame* frame, FILE* f )
else
FootprintName = wxT( "$noname" );
msg = Component->GetRef(sheet);
msg = Component->GetRef( sheet );
fprintf( f, "%s ", CONV_TO_UTF8( StartCmpDesc ) );
fprintf( f, "%s", CONV_TO_UTF8( msg ) );
@ -1038,7 +1020,7 @@ static void WriteListOfNetsCADSTAR( FILE* f, ObjetNetListStruct* ObjNet )
for( ii = 0; ii < g_NbrObjNet; ii++ )
{
// Get the NetName of the current net :
if( (NetCode = ObjNet[ii].GetNet()) != LastNetCode )
if( ( NetCode = ObjNet[ii].GetNet() ) != LastNetCode )
{
NetName.Empty();
for( jj = 0; jj < g_NbrObjNet; jj++ )
@ -1057,9 +1039,11 @@ static void WriteListOfNetsCADSTAR( FILE* f, ObjetNetListStruct* ObjNet )
if( !NetName.IsEmpty() )
{
NetcodeName += NetName;
if( g_TabObjNet[jj].m_Type != NET_PINLABEL ){
if( g_TabObjNet[jj].m_Type != NET_PINLABEL )
{
NetcodeName = g_TabObjNet[jj].m_SheetList.PathHumanReadable()
+ NetcodeName;
//NetcodeName << wxT("_") <<
// g_TabObjNet[jj].m_SheetList.PathHumanReadable();
}
@ -1079,7 +1063,7 @@ static void WriteListOfNetsCADSTAR( FILE* f, ObjetNetListStruct* ObjNet )
continue;
Cmp = (SCH_COMPONENT*) ObjNet[ii].m_Link;
wxString refstr = Cmp->GetRef(&(ObjNet[ii].m_SheetList));
wxString refstr = Cmp->GetRef( &(ObjNet[ii].m_SheetList) );
if( refstr[0] == '#' )
continue; // Pseudo composant (symboles d'alims)
@ -1129,7 +1113,7 @@ static void WriteListOfNetsCADSTAR( FILE* f, ObjetNetListStruct* ObjNet )
(SCH_COMPONENT*) ObjNet[jj].m_Link;
wxString p = Cmp->GetPath( &( ObjNet[ii].m_SheetList ) );
wxString tstp = tstcmp->GetPath( &( ObjNet[jj].m_SheetList ) );
if( p.Cmp(tstp) != 0 )
if( p.Cmp( tstp ) != 0 )
continue;
if( ObjNet[jj].m_PinNum == ObjNet[ii].m_PinNum )

View File

@ -17,8 +17,7 @@
/* Routines locales */
static void PropageNetCode( int OldNetCode, int NewNetCode, int IsBus );
static void SheetLabelConnect( ObjetNetListStruct* SheetLabel );
static int ListeObjetConnection( WinEDA_SchematicFrame* frame,
DrawSheetPath* sheetlist,
static int ListeObjetConnection( DrawSheetPath* sheetlist,
ObjetNetListStruct* ObjNet );
static int ConvertBusToMembers( ObjetNetListStruct* ObjNet );
static void PointToPointConnect( ObjetNetListStruct* Ref, int IsBus,
@ -165,7 +164,7 @@ void* WinEDA_SchematicFrame::BuildNetListBase()
/* Build the sheet (not screen) list (flattened)*/
EDA_SheetList SheetListList( NULL );
i=0;
/* 1ere passe : Comptage du nombre d'objet de Net */
/* first pass : count objects used in connectivty calculation */
g_NbrObjNet = 0;
g_TabObjNet = NULL; /* Init pour le 1er passage dans ListeObjetConnection */
@ -174,7 +173,7 @@ void* WinEDA_SchematicFrame::BuildNetListBase()
for( sheet = SheetListList.GetFirst(); sheet != NULL; sheet = SheetListList.GetNext() )
{
g_NbrObjNet += ListeObjetConnection( this, sheet, NULL );
g_NbrObjNet += ListeObjetConnection( sheet, NULL );
}
if( g_NbrObjNet == 0 )
@ -188,8 +187,7 @@ void* WinEDA_SchematicFrame::BuildNetListBase()
if( g_TabObjNet == NULL )
return NULL;
/* 2eme passe : Remplissage des champs des structures des objets de Net */
/* second pass: fill the fields of the structures in the Net */
/* second pass: fill the fields of the structures used in connectivty calculation */
s_PassNumber++;
@ -197,15 +195,14 @@ void* WinEDA_SchematicFrame::BuildNetListBase()
for( ObjetNetListStruct* tabObjNet = g_TabObjNet;
sheet != NULL; sheet = SheetListList.GetNext() )
{
tabObjNet += ListeObjetConnection( this, sheet, tabObjNet );
tabObjNet += ListeObjetConnection( sheet, tabObjNet );
}
activity.Empty();
activity << wxT(" ") << _( "NbItems" ) << wxT(" ") << g_NbrObjNet;
SetStatusText( activity );
/* Recherche des connections pour les Segments et les Pins */
/* Tri du Tableau des objets de Net par Sheet */
/* Sort objects by Sheet */
qsort( g_TabObjNet, g_NbrObjNet, sizeof(ObjetNetListStruct), TriBySheet );
@ -363,7 +360,7 @@ void* WinEDA_SchematicFrame::BuildNetListBase()
SheetLabelConnect( g_TabObjNet + i );
}
/* Tri du Tableau des objets de Net par NetCode */
/* Sort objects by NetCode */
qsort( g_TabObjNet, g_NbrObjNet, sizeof(ObjetNetListStruct), TriNetCode );
@ -438,17 +435,14 @@ static void SheetLabelConnect( ObjetNetListStruct* SheetLabel )
}
/*****************************************************************************/
static int ListeObjetConnection( WinEDA_SchematicFrame* frame, DrawSheetPath* sheetlist,
ObjetNetListStruct* ObjNet )
/*****************************************************************************/
/**************************************************************************************/
static int ListeObjetConnection( DrawSheetPath* sheetlist, ObjetNetListStruct* ObjNet )
/**************************************************************************************/
/* Routine generant la liste des objets relatifs aux connection
* entree:
* sheetlist: pointer to a sheetlist.
* ObjNet:
* si NULL: la routine compte seulement le nombre des objets
* sinon: pointe le tableau a remplir
/** Function ListeObjetConnection
* Creates the list of objects related to connections (pins of components, wires, labels, junctions ...)
* @param sheetlist: pointer to a sheetlist.
* @param ObjNet: if NULL, objects count else list to fill
*/
{
int ii, NbrItem = 0;
@ -596,8 +590,7 @@ static int ListeObjetConnection( WinEDA_SchematicFrame* frame, DrawSheetPath* sh
if( DEntry->Type() != COMPONENT_PIN_DRAW_TYPE )
continue;
if( DEntry->m_Unit
&& (DEntry->m_Unit != DrawLibItem->m_Multi) )
if( DEntry->m_Unit && (DEntry->m_Unit != DrawLibItem->GetUnitSelection( sheetlist ) ) )
continue;
if( DEntry->m_Convert
@ -684,7 +677,7 @@ static int ListeObjetConnection( WinEDA_SchematicFrame* frame, DrawSheetPath* sh
break;
case DRAW_HIERARCHICAL_PIN_SHEET_STRUCT_TYPE:
DisplayError( frame, wxT( "Netlist: Type DRAW_SHEETLABEL inattendu" ) );
DisplayError( NULL, wxT( "Netlist: Type DRAW_SHEETLABEL inattendu" ) );
break;
default:
@ -692,7 +685,7 @@ static int ListeObjetConnection( WinEDA_SchematicFrame* frame, DrawSheetPath* sh
wxString msg;
msg.Printf( wxT( "Netlist: unexpected type struct %d" ),
DrawList->Type() );
DisplayError( frame, msg );
DisplayError( NULL, msg );
break;
}
}

View File

@ -26,7 +26,7 @@ typedef enum {
* NET_TYPE_CUSTOM1+CUSTOMPANEL_COUNTMAX-1
* is the last id for user netlist format
*/
NET_TYPE_CUSTOM_MAX = NET_TYPE_CUSTOM1+CUSTOMPANEL_COUNTMAX-1
NET_TYPE_CUSTOM_MAX = NET_TYPE_CUSTOM1 + CUSTOMPANEL_COUNTMAX - 1
} TypeNetForm;
@ -68,7 +68,7 @@ public:
int m_Flag; /* flag pour calculs internes */
DrawSheetPath m_SheetList;
NetObjetType m_Type;
int m_ElectricalType;/* Pour Pins et sheet labels: type electrique */
int m_ElectricalType; /* Pour Pins et sheet labels: type electrique */
private:
int m_NetCode; /* pour elements simples */
public:
@ -94,14 +94,16 @@ public:
typedef struct ListLabel
{
int m_LabelType;
void * m_Label;
void* m_Label;
char m_SheetPath[64];
} ListLabel;
typedef struct ListComponent
{
SCH_COMPONENT * m_Comp;
SCH_COMPONENT* m_Comp;
char m_Ref[32];
//have to store it here since the object refrerences will be duplicated.
//have to store it here since the object references will be duplicated.
DrawSheetPath m_SheetList; //composed of UIDs
} ListComponent;

View File

@ -610,7 +610,7 @@ void WinEDA_SchematicFrame::Process_Special_Functions( wxCommandEvent& event )
{
EDA_LibComponentStruct* LibEntry;
LibEntry = FindLibPart(
( (SCH_COMPONENT*) screen->GetCurItem() )->m_ChipName,
( (SCH_COMPONENT*) screen->GetCurItem() )->m_ChipName.GetData(),
wxEmptyString,
FIND_ALIAS );
if( LibEntry && LibEntry->m_DocFile != wxEmptyString )

View File

@ -253,7 +253,7 @@ wxClientDC dc(DrawPanel);
g_ViewUnit = 1;
g_ViewConvert = 1;
LibEntry = FindLibPart(CmpName,Lib->m_Name, FIND_ALIAS);
LibEntry = FindLibPart(CmpName.GetData(),Lib->m_Name, FIND_ALIAS);
g_CurrentViewComponentName = CmpName;
DisplayLibInfos();
Zoom_Automatique(FALSE);

View File

@ -212,20 +212,20 @@
#include "../bitmaps/annotate_right_down.xpm"
#include "../bitmaps/annotate_down_right.xpm"
#include "../bitmaps/new_sch.xpm"
// #include "../bitmaps/new_sch.xpm"
#include "../bitmaps/Open_Project.xpm"
#include "../bitmaps/new_cvpcb.xpm"
// #include "../bitmaps/new_cvpcb.xpm"
#include "../bitmaps/zip.xpm"
#include "../bitmaps/icon_gerbview_small.xpm"
#include "../bitmaps/zip_tool.xpm"
// #include "../bitmaps/zip_tool.xpm"
#include "../bitmaps/unzip.xpm"
#include "../bitmaps/Browse_Files.xpm"
#include "../bitmaps/New_Project.xpm"
#include "../bitmaps/new_gerb.xpm"
#include "../bitmaps/new_python.xpm"
// #include "../bitmaps/new_gerb.xpm"
// #include "../bitmaps/new_python.xpm"
#include "../bitmaps/icon_cvpcb_small.xpm"
#include "../bitmaps/unknown.xpm"
#include "../bitmaps/new_pcb.xpm"
// #include "../bitmaps/new_pcb.xpm"
#include "../bitmaps/reload.xpm"

View File

@ -280,7 +280,7 @@ int BOARD::ClipAreaPolygon( ZONE_CONTAINER* CurrArea,
{
std::vector<CPolyLine*> * pa = new std::vector<CPolyLine*>;
curr_polygon->Undraw();
int n_poly = CurrArea->m_Poly->NormalizeWithGpc( pa, bRetainArcs );
int n_poly = CurrArea->m_Poly->NormalizeAreaOutlines( pa, bRetainArcs );
if( n_poly > 1 ) // i.e if clipping has created some polygons, we must add these new copper areas
{
ZONE_CONTAINER* NewArea;
@ -310,7 +310,8 @@ int BOARD::ClipAreaPolygon( ZONE_CONTAINER* CurrArea,
* itself and the polygons for any other areas on the same net.
* This may change the number and order of copper areas in the net.
* @param modified_area = area to test
* @param bMessageBox : if true, shows message boxes when clipping occurs.
* @param bMessageBoxInt == true, shows message when clipping occurs.
* @param bMessageBoxArc == true, shows message when clipping can't be done due to arcs.
* @return :
* -1 if arcs intersect other sides, so polygon can't be clipped
* 0 if no intersecting sides
@ -697,8 +698,11 @@ int BOARD::CombineAreas( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_combi
CPolyLine* poly2 = area_to_combine->m_Poly;
std::vector<CArc> arc_array1;
std::vector<CArc> arc_array2;
poly1->MakeGpcPoly( -1, &arc_array1 );
poly2->MakeGpcPoly( -1, &arc_array2 );
poly1->MakePolygonFromAreaOutlines( -1, &arc_array1 );
poly2->MakePolygonFromAreaOutlines( -1, &arc_array2 );
#ifdef USE_GPC_POLY_LIB
int n_ext_cont1 = 0;
for( int ic = 0; ic<poly1->GetGpcPoly()->num_contours; ic++ )
if( !( (poly1->GetGpcPoly()->hole)[ic] ) )
@ -776,7 +780,97 @@ int BOARD::CombineAreas( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_combi
area_ref->m_Poly->Draw();
gpc_free_polygon( union_gpc );
delete union_gpc;
return 1;
#endif
#ifdef USE_GPL_POLY_LIB
//@todo
#warning work in progress
wxString msg;
int n_ext_cont1 = poly1->GetPhpPoly()->m_cnt;
int n_ext_cont2 = poly2->GetPhpPoly()->m_cnt;
polygon* union_polygon = NULL;
union_polygon = poly1->GetPhpPoly()->boolean( poly2->GetPhpPoly(), A_OR_B );
if ( union_polygon == NULL )
return 0;
// get number of outside contours
int n_union_ext_cont = union_polygon->m_cnt;
msg.Printf(wxT("cnt res = %d, pts1,2 = %d,%d"), n_union_ext_cont , n_ext_cont1, n_ext_cont2);
wxMessageBox(msg);
// if no intersection, free new gpc and return
#if 0
if( n_union_ext_cont == n_ext_cont1 + n_ext_cont2 )
{
wxMessageBox(wxT("no change polys"));
delete union_polygon;
return 0;
}
#endif
wxMessageBox(wxT("merge areas"));
// intersection, replace area_ref->m_Poly with combined areas and remove area_to_combine
RemoveArea( area_to_combine );
area_ref->m_Poly->RemoveAllContours();
// create area with external contour
// for( int ic = 0; ic < union_polygon->m_cnt; ic++ )
{
// if( !(union_gpc->hole)[ic] ) // Recreate only area edges, NOT holes (todo..)
{
// external contour, replace this poly
vertex * curr_vertex = union_polygon->getFirst();
for( int ii = 0; ii < union_polygon->m_cnt; ii++ )
{
int x = (int) curr_vertex->X();
int y = (int) curr_vertex->Y();
msg.Printf(wxT("ii = %d, pts = %d,%d, wid = %d"), ii , x, y, curr_vertex->id());
wxMessageBox(msg);
if( ii==0 )
{
area_ref->m_Poly->Start( area_ref->GetLayer(
), x, y, area_ref->m_Poly->GetHatchStyle() );
}
else
area_ref->m_Poly->AppendCorner( x, y );
curr_vertex = curr_vertex->Next();
// if( curr_vertex->id() == union_polygon->getFirst()->id() ) break;
}
area_ref->m_Poly->Close();
}
}
// add holes
#if 0
for( int ic = 0; ic<union_gpc->num_contours; ic++ )
{
if( (union_gpc->hole)[ic] )
{
// hole
for( int i = 0; i<union_gpc->contour[ic].num_vertices; i++ )
{
int x = (int) ( (union_gpc->contour)[ic].vertex )[i].x;
int y = (int) ( (union_gpc->contour)[ic].vertex )[i].y;
area_ref->m_Poly->AppendCorner( x, y );
}
area_ref->m_Poly->Close();
}
}
#endif
area_ref->utility = 1;
area_ref->m_Poly->RestoreArcs( &arc_array1 );
area_ref->m_Poly->RestoreArcs( &arc_array2 );
area_ref->m_Poly->Draw();
delete union_polygon;
return 0;
#endif
}
@ -785,7 +879,7 @@ int BOARD::CombineAreas( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_combi
/**
* Function Is_Area_Inside_Area
* Test a given area to see if it is inside an other area, or an other area is inside the given area
* an area is inside an other are if ALL its corners are inside
* an area is inside an other are if ALL its edges are inside the other area
* @param Area_Ref: the given area to compare with other areas
* used to remove redundant areas
*/

File diff suppressed because it is too large Load Diff

View File

@ -16,6 +16,9 @@
#include <vector>
#define USE_GPC_POLY_LIB
//#define USE_GPL_POLY_LIB
#include "defs-macros.h"
#include "GenericPolygonClipperLibrary.h"
@ -117,22 +120,32 @@ public:
void SetEndContour( int ic, bool end_contour );
void SetSideStyle( int is, int style );
// GPC functions
int MakeGpcPoly( int icontour=0, std::vector<CArc> * arc_array=NULL );
int FreeGpcPoly();
gpc_polygon * GetGpcPoly(){ return m_gpc_poly; };
int NormalizeWithGpc( std::vector<CPolyLine*> * pa=NULL, bool bRetainArcs=FALSE );
int RestoreArcs( std::vector<CArc> * arc_array, std::vector<CPolyLine*> * pa=NULL );
CPolyLine * MakePolylineForPad( int type, int x, int y, int w, int l, int r, int angle );
void AddContourForPadClearance( int type, int x, int y, int w,
int l, int r, int angle, int fill_clearance,
int hole_w, int hole_clearance, bool bThermal=FALSE, int spoke_w=0 );
void ClipGpcPolygon( gpc_op op, CPolyLine * poly );
int MakePolygonFromAreaOutlines( int icontour, std::vector<CArc> * arc_array );
void FreePolygon();
int NormalizeAreaOutlines( std::vector<CPolyLine*> * pa=NULL, bool bRetainArcs=FALSE );
#ifdef USE_GPC_POLY_LIB
// GPC functions
int MakeGpcPoly( int icontour=0, std::vector<CArc> * arc_array=NULL );
void FreeGpcPoly();
gpc_polygon * GetGpcPoly(){ return m_gpc_poly; };
int NormalizeWithGpc( std::vector<CPolyLine*> * pa=NULL, bool bRetainArcs=FALSE );
#endif
// PHP functions
#ifdef USE_GPL_POLY_LIB
int MakePhpPoly();
void FreePhpPoly();
void ClipPhpPolygon( int php_op, CPolyLine * poly );
polygon * GetPhpPoly(){ return m_php_poly; };
#endif
private:
int m_layer; // layer to draw on

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,5 @@
// file php_polygon.h
// See comments in php_polygon.cpp
#ifndef PHP_POLYGON_H
@ -10,50 +11,60 @@ class segment;
#define infinity 100000000 // for places that are far far away
#define PI 3.14159265359
enum{ A_OR_B, A_AND_B, A_MINUS_B, B_MINUS_A };
enum {
A_OR_B,
A_AND_B,
A_MINUS_B,
B_MINUS_A
};
class polygon
{
public:
/*------------------------------------------------------------------------------
** This class manages a doubly linked list of vertex objects that represents
** a polygon. The class consists of basic methods to manage the list
** and methods to implement boolean operations between polygon objects.
*/
vertex * m_first; // Reference to first vertex in the linked list
class polygon
{
public:
vertex* m_first; // Reference to first vertex in the linked list
int m_cnt; // Tracks number of vertices in the polygon
polygon( vertex * first = NULL );
public:
polygon( vertex* first = NULL );
~polygon();
vertex * getFirst();
polygon * NextPoly();
vertex* getFirst();
polygon* NextPoly();
void add( vertex * nv );
void add( vertex* nv );
void addv( double x, double y,
double xc=0, double yc=0, int d=0);
vertex * del( vertex * v );
double xc = 0, double yc = 0, int d = 0 );
vertex* del( vertex* v );
void res();
polygon * copy_poly();
void insertSort( vertex * nv, vertex * s, vertex * e );
vertex * nxt( vertex * v );
polygon* copy_poly();
void insertSort( vertex* nv, vertex* s, vertex* e );
vertex* nxt( vertex* v );
BOOL unckd_remain();
vertex * first_unckd_intersect();
vertex* first_unckd_intersect();
double dist( double x1, double y1, double x2, double y2 );
double angle( double xc, double yc, double x1, double y1 );
double aAlpha( double x1, double y1, double x2, double y2,
double xc, double yc, double xi, double yi, double d );
void perturb( vertex * p1, vertex * p2, vertex * q1, vertex * q2,
void perturb( vertex* p1, vertex* p2, vertex* q1, vertex* q2,
double aP, double aQ );
BOOL ints( vertex * p1, vertex * p2, vertex * q1, vertex * q2,
int * n, double ix[], double iy[], double alphaP[], double alphaQ[] );
BOOL isInside ( vertex * v );
polygon * boolean( polygon * polyB, int oper );
int* n, double ix[], double iy[], double alphaP[], double alphaQ[] );
BOOL isInside( vertex* v );
polygon* boolean( polygon* polyB, int oper );
#if 0
function isPolyInside (p);
function move (dx, dy);
function rotate (xr, yr, a);
function &bRect ();
function isPolyInside( p );
function move( dx, dy );
function rotate( xr, yr, a );
function& bRect();
#endif
}; //end of class polygon