Commit b8ea76fe authored by charras's avatar charras

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

B.O.M. generation still have a minor problem wih this.
parent 88055164
...@@ -5,6 +5,15 @@ Started 2007-June-11 ...@@ -5,6 +5,15 @@ Started 2007-June-11
Please add newer entries at the top, list the date and your name with Please add newer entries at the top, list the date and your name with
email address. 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> 2008-May-5 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================ ================================================================================
+common.c +common.c
......
...@@ -4,7 +4,6 @@ ...@@ -4,7 +4,6 @@
****************************************************************/ ****************************************************************/
#include "fctsys.h" #include "fctsys.h"
#include "gr_basic.h"
#include "common.h" #include "common.h"
#include "program.h" #include "program.h"
...@@ -15,8 +14,6 @@ ...@@ -15,8 +14,6 @@
#include "dialog_backanno.cpp" #include "dialog_backanno.cpp"
#include "protos.h"
/**************************************************************/ /**************************************************************/
SCH_COMPONENT * WinEDA_SchematicFrame::FindComponentByRef( SCH_COMPONENT * WinEDA_SchematicFrame::FindComponentByRef(
const wxString& reference ) const wxString& reference )
......
...@@ -293,9 +293,7 @@ SCH_COMPONENT::SCH_COMPONENT( const wxPoint& aPos ) : ...@@ -293,9 +293,7 @@ SCH_COMPONENT::SCH_COMPONENT( const wxPoint& aPos ) :
m_Pos = aPos; m_Pos = aPos;
//m_FlagControlMulti = 0; m_Convert = 0; /* De Morgan Handling */
m_UsedOnSheets.Clear();
m_Convert = 0; /* Gestion des mutiples representations (conversion De Morgan) */
/* The rotation/mirror transformation matrix. pos normal*/ /* The rotation/mirror transformation matrix. pos normal*/
m_Transform[0][0] = 1; m_Transform[0][0] = 1;
...@@ -469,6 +467,9 @@ void SCH_COMPONENT::ClearAnnotation( DrawSheetPath* aSheet ) ...@@ -469,6 +467,9 @@ void SCH_COMPONENT::ClearAnnotation( DrawSheetPath* aSheet )
defRef.Append( wxT( "?" ) ); defRef.Append( wxT( "?" ) );
wxString multi = wxT( "1" ); wxString multi = wxT( "1" );
if ( KeepMulti ) // We cannot remove all annotations: part selection must be kept
{
wxString NewHref; wxString NewHref;
wxString path; wxString path;
if( aSheet ) if( aSheet )
...@@ -486,15 +487,20 @@ void SCH_COMPONENT::ClearAnnotation( DrawSheetPath* aSheet ) ...@@ -486,15 +487,20 @@ void SCH_COMPONENT::ClearAnnotation( DrawSheetPath* aSheet )
m_PathsAndReferences[ii] = NewHref; 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. // These 2 changes do not work in complex hierarchy.
// When a clear annotation is made, the calling function must call a // When a clear annotation is made, the calling function must call a
// UpdateAllScreenReferences for the active sheet. // 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. m_Field[REFERENCE].m_Text = defRef; //for drawing.
if( !KeepMulti )
m_Multi = 1;
} }
...@@ -510,8 +516,6 @@ SCH_COMPONENT* SCH_COMPONENT::GenCopy() ...@@ -510,8 +516,6 @@ SCH_COMPONENT* SCH_COMPONENT::GenCopy()
new_item->m_ChipName = m_ChipName; new_item->m_ChipName = m_ChipName;
new_item->m_PrefixString = m_PrefixString; 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_Convert = m_Convert;
new_item->m_Transform[0][0] = m_Transform[0][0]; new_item->m_Transform[0][0] = m_Transform[0][0];
new_item->m_Transform[0][1] = m_Transform[0][1]; new_item->m_Transform[0][1] = m_Transform[0][1];
......
...@@ -100,8 +100,6 @@ public: ...@@ -100,8 +100,6 @@ public:
* determined, upon file load, by the first non-digits in the reference fields. */ * determined, upon file load, by the first non-digits in the reference fields. */
PartTextStruct m_Field[NUMBER_OF_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_Convert; /* Gestion (management) des mutiples representations (ex: conversion De Morgan) */
int m_Transform[2][2]; /* The rotation/mirror transformation matrix. */ int m_Transform[2][2]; /* The rotation/mirror transformation matrix. */
......
...@@ -402,7 +402,7 @@ DanglingEndHandle* RebuildEndList( EDA_BaseStruct* DrawList ) ...@@ -402,7 +402,7 @@ DanglingEndHandle* RebuildEndList( EDA_BaseStruct* DrawList )
#undef STRUCT #undef STRUCT
#define STRUCT ( (SCH_COMPONENT*) DrawItem ) #define STRUCT ( (SCH_COMPONENT*) DrawItem )
EDA_LibComponentStruct* Entry; EDA_LibComponentStruct* Entry;
Entry = FindLibPart( STRUCT->m_ChipName, wxEmptyString, FIND_ROOT ); Entry = FindLibPart( STRUCT->m_ChipName.GetData(), wxEmptyString, FIND_ROOT );
if( Entry == NULL ) if( Entry == NULL )
break; break;
......
...@@ -691,13 +691,6 @@ void WinEDA_Build_BOM_Frame::GenereListeOfItems( const wxString& FullFileName ) ...@@ -691,13 +691,6 @@ void WinEDA_Build_BOM_Frame::GenereListeOfItems( const wxString& FullFileName )
GenListeCmp( List ); 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 */ /* generation du fichier listing */
DateAndTime( Line ); DateAndTime( Line );
wxString Title = g_Main_Title + wxT( " " ) + GetBuildVersion(); wxString Title = g_Main_Title + wxT( " " ) + GetBuildVersion();
...@@ -707,13 +700,7 @@ void WinEDA_Build_BOM_Frame::GenereListeOfItems( const wxString& FullFileName ) ...@@ -707,13 +700,7 @@ void WinEDA_Build_BOM_Frame::GenereListeOfItems( const wxString& FullFileName )
qsort( List, NbItems, sizeof( ListComponent ), qsort( List, NbItems, sizeof( ListComponent ),
( int( * ) ( const void*, const void* ) )ListTriComposantByRef ); ( 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( ! s_ListWithSubCmponents )
if( !m_ListSubCmpItems->GetValue() ) if( !m_ListSubCmpItems->GetValue() )
DeleteSubCmp( List, NbItems ); DeleteSubCmp( List, NbItems );
...@@ -785,20 +772,17 @@ void WinEDA_Build_BOM_Frame::GenereListeOfItems( const wxString& FullFileName ) ...@@ -785,20 +772,17 @@ void WinEDA_Build_BOM_Frame::GenereListeOfItems( const wxString& FullFileName )
int GenListeCmp( ListComponent* List ) int GenListeCmp( ListComponent* List )
/****************************************/ /****************************************/
/* Routine de generation de la liste des elements utiles du dessin /* Creates the list of components in the schematic
* 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
* *
* routine for generating a list of the used components. * routine for generating a list of the used components.
* if List == null, just returns the count. if not, fills the list. * if List == null, just returns the count. if not, fills the list.
* goes through the sheets, not the screens, so that we account for * goes through the sheets, not the screens, so that we account for
* multiple instances of a given screen. * multiple instances of a given screen.
* Also Initialise m_Father as pointer pointeur of the SCH_SCREN parent
*/ */
{ {
int ItemCount = 0; int ItemCount = 0;
EDA_BaseStruct* DrawList; EDA_BaseStruct* SchItem;
SCH_COMPONENT* DrawLibItem; SCH_COMPONENT* DrawLibItem;
DrawSheetPath* sheet; DrawSheetPath* sheet;
...@@ -807,14 +791,13 @@ int GenListeCmp( ListComponent* List ) ...@@ -807,14 +791,13 @@ int GenListeCmp( ListComponent* List )
for( sheet = SheetList.GetFirst(); sheet != NULL; sheet = SheetList.GetNext() ) for( sheet = SheetList.GetFirst(); sheet != NULL; sheet = SheetList.GetNext() )
{ {
DrawList = sheet->LastDrawList(); for ( SchItem = sheet->LastDrawList(); SchItem;SchItem = SchItem->Next() )
while( DrawList )
{ {
switch( DrawList->Type() ) if( SchItem->Type() != TYPE_SCH_COMPONENT )
{ continue;
case TYPE_SCH_COMPONENT:
ItemCount++; ItemCount++;
DrawLibItem = (SCH_COMPONENT*) DrawList; DrawLibItem = (SCH_COMPONENT*) SchItem;
DrawLibItem->m_Parent = sheet->LastScreen(); DrawLibItem->m_Parent = sheet->LastScreen();
if( List ) if( List )
{ {
...@@ -825,13 +808,6 @@ int GenListeCmp( ListComponent* List ) ...@@ -825,13 +808,6 @@ int GenListeCmp( ListComponent* List )
sizeof( List->m_Ref ) ); sizeof( List->m_Ref ) );
List++; List++;
} }
break;
default:
break;
}
DrawList = DrawList->Pnext;
} }
} }
......
This diff is collapsed.
...@@ -17,8 +17,7 @@ ...@@ -17,8 +17,7 @@
/* Routines locales */ /* Routines locales */
static void PropageNetCode( int OldNetCode, int NewNetCode, int IsBus ); static void PropageNetCode( int OldNetCode, int NewNetCode, int IsBus );
static void SheetLabelConnect( ObjetNetListStruct* SheetLabel ); static void SheetLabelConnect( ObjetNetListStruct* SheetLabel );
static int ListeObjetConnection( WinEDA_SchematicFrame* frame, static int ListeObjetConnection( DrawSheetPath* sheetlist,
DrawSheetPath* sheetlist,
ObjetNetListStruct* ObjNet ); ObjetNetListStruct* ObjNet );
static int ConvertBusToMembers( ObjetNetListStruct* ObjNet ); static int ConvertBusToMembers( ObjetNetListStruct* ObjNet );
static void PointToPointConnect( ObjetNetListStruct* Ref, int IsBus, static void PointToPointConnect( ObjetNetListStruct* Ref, int IsBus,
...@@ -165,7 +164,7 @@ void* WinEDA_SchematicFrame::BuildNetListBase() ...@@ -165,7 +164,7 @@ void* WinEDA_SchematicFrame::BuildNetListBase()
/* Build the sheet (not screen) list (flattened)*/ /* Build the sheet (not screen) list (flattened)*/
EDA_SheetList SheetListList( NULL ); EDA_SheetList SheetListList( NULL );
i=0; i=0;
/* 1ere passe : Comptage du nombre d'objet de Net */ /* first pass : count objects used in connectivty calculation */
g_NbrObjNet = 0; g_NbrObjNet = 0;
g_TabObjNet = NULL; /* Init pour le 1er passage dans ListeObjetConnection */ g_TabObjNet = NULL; /* Init pour le 1er passage dans ListeObjetConnection */
...@@ -174,7 +173,7 @@ void* WinEDA_SchematicFrame::BuildNetListBase() ...@@ -174,7 +173,7 @@ void* WinEDA_SchematicFrame::BuildNetListBase()
for( sheet = SheetListList.GetFirst(); sheet != NULL; sheet = SheetListList.GetNext() ) for( sheet = SheetListList.GetFirst(); sheet != NULL; sheet = SheetListList.GetNext() )
{ {
g_NbrObjNet += ListeObjetConnection( this, sheet, NULL ); g_NbrObjNet += ListeObjetConnection( sheet, NULL );
} }
if( g_NbrObjNet == 0 ) if( g_NbrObjNet == 0 )
...@@ -188,8 +187,7 @@ void* WinEDA_SchematicFrame::BuildNetListBase() ...@@ -188,8 +187,7 @@ void* WinEDA_SchematicFrame::BuildNetListBase()
if( g_TabObjNet == NULL ) if( g_TabObjNet == NULL )
return NULL; return NULL;
/* 2eme passe : Remplissage des champs des structures des objets de Net */ /* second pass: fill the fields of the structures used in connectivty calculation */
/* second pass: fill the fields of the structures in the Net */
s_PassNumber++; s_PassNumber++;
...@@ -197,15 +195,14 @@ void* WinEDA_SchematicFrame::BuildNetListBase() ...@@ -197,15 +195,14 @@ void* WinEDA_SchematicFrame::BuildNetListBase()
for( ObjetNetListStruct* tabObjNet = g_TabObjNet; for( ObjetNetListStruct* tabObjNet = g_TabObjNet;
sheet != NULL; sheet = SheetListList.GetNext() ) sheet != NULL; sheet = SheetListList.GetNext() )
{ {
tabObjNet += ListeObjetConnection( this, sheet, tabObjNet ); tabObjNet += ListeObjetConnection( sheet, tabObjNet );
} }
activity.Empty(); activity.Empty();
activity << wxT(" ") << _( "NbItems" ) << wxT(" ") << g_NbrObjNet; activity << wxT(" ") << _( "NbItems" ) << wxT(" ") << g_NbrObjNet;
SetStatusText( activity ); SetStatusText( activity );
/* Recherche des connections pour les Segments et les Pins */ /* Sort objects by Sheet */
/* Tri du Tableau des objets de Net par Sheet */
qsort( g_TabObjNet, g_NbrObjNet, sizeof(ObjetNetListStruct), TriBySheet ); qsort( g_TabObjNet, g_NbrObjNet, sizeof(ObjetNetListStruct), TriBySheet );
...@@ -363,7 +360,7 @@ void* WinEDA_SchematicFrame::BuildNetListBase() ...@@ -363,7 +360,7 @@ void* WinEDA_SchematicFrame::BuildNetListBase()
SheetLabelConnect( g_TabObjNet + i ); 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 ); qsort( g_TabObjNet, g_NbrObjNet, sizeof(ObjetNetListStruct), TriNetCode );
...@@ -438,17 +435,14 @@ static void SheetLabelConnect( ObjetNetListStruct* SheetLabel ) ...@@ -438,17 +435,14 @@ static void SheetLabelConnect( ObjetNetListStruct* SheetLabel )
} }
/*****************************************************************************/ /**************************************************************************************/
static int ListeObjetConnection( WinEDA_SchematicFrame* frame, DrawSheetPath* sheetlist, static int ListeObjetConnection( DrawSheetPath* sheetlist, ObjetNetListStruct* ObjNet )
ObjetNetListStruct* ObjNet ) /**************************************************************************************/
/*****************************************************************************/
/* Routine generant la liste des objets relatifs aux connection /** Function ListeObjetConnection
* entree: * Creates the list of objects related to connections (pins of components, wires, labels, junctions ...)
* sheetlist: pointer to a sheetlist. * @param sheetlist: pointer to a sheetlist.
* ObjNet: * @param ObjNet: if NULL, objects count else list to fill
* si NULL: la routine compte seulement le nombre des objets
* sinon: pointe le tableau a remplir
*/ */
{ {
int ii, NbrItem = 0; int ii, NbrItem = 0;
...@@ -596,8 +590,7 @@ static int ListeObjetConnection( WinEDA_SchematicFrame* frame, DrawSheetPath* sh ...@@ -596,8 +590,7 @@ static int ListeObjetConnection( WinEDA_SchematicFrame* frame, DrawSheetPath* sh
if( DEntry->Type() != COMPONENT_PIN_DRAW_TYPE ) if( DEntry->Type() != COMPONENT_PIN_DRAW_TYPE )
continue; continue;
if( DEntry->m_Unit if( DEntry->m_Unit && (DEntry->m_Unit != DrawLibItem->GetUnitSelection( sheetlist ) ) )
&& (DEntry->m_Unit != DrawLibItem->m_Multi) )
continue; continue;
if( DEntry->m_Convert if( DEntry->m_Convert
...@@ -684,7 +677,7 @@ static int ListeObjetConnection( WinEDA_SchematicFrame* frame, DrawSheetPath* sh ...@@ -684,7 +677,7 @@ static int ListeObjetConnection( WinEDA_SchematicFrame* frame, DrawSheetPath* sh
break; break;
case DRAW_HIERARCHICAL_PIN_SHEET_STRUCT_TYPE: case DRAW_HIERARCHICAL_PIN_SHEET_STRUCT_TYPE:
DisplayError( frame, wxT( "Netlist: Type DRAW_SHEETLABEL inattendu" ) ); DisplayError( NULL, wxT( "Netlist: Type DRAW_SHEETLABEL inattendu" ) );
break; break;
default: default:
...@@ -692,7 +685,7 @@ static int ListeObjetConnection( WinEDA_SchematicFrame* frame, DrawSheetPath* sh ...@@ -692,7 +685,7 @@ static int ListeObjetConnection( WinEDA_SchematicFrame* frame, DrawSheetPath* sh
wxString msg; wxString msg;
msg.Printf( wxT( "Netlist: unexpected type struct %d" ), msg.Printf( wxT( "Netlist: unexpected type struct %d" ),
DrawList->Type() ); DrawList->Type() );
DisplayError( frame, msg ); DisplayError( NULL, msg );
break; break;
} }
} }
......
...@@ -26,7 +26,7 @@ typedef enum { ...@@ -26,7 +26,7 @@ typedef enum {
* NET_TYPE_CUSTOM1+CUSTOMPANEL_COUNTMAX-1 * NET_TYPE_CUSTOM1+CUSTOMPANEL_COUNTMAX-1
* is the last id for user netlist format * 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; } TypeNetForm;
...@@ -68,7 +68,7 @@ public: ...@@ -68,7 +68,7 @@ public:
int m_Flag; /* flag pour calculs internes */ int m_Flag; /* flag pour calculs internes */
DrawSheetPath m_SheetList; DrawSheetPath m_SheetList;
NetObjetType m_Type; NetObjetType m_Type;
int m_ElectricalType;/* Pour Pins et sheet labels: type electrique */ int m_ElectricalType; /* Pour Pins et sheet labels: type electrique */
private: private:
int m_NetCode; /* pour elements simples */ int m_NetCode; /* pour elements simples */
public: public:
...@@ -94,14 +94,16 @@ public: ...@@ -94,14 +94,16 @@ public:
typedef struct ListLabel typedef struct ListLabel
{ {
int m_LabelType; int m_LabelType;
void * m_Label; void* m_Label;
char m_SheetPath[64]; char m_SheetPath[64];
} ListLabel; } ListLabel;
typedef struct ListComponent typedef struct ListComponent
{ {
SCH_COMPONENT * m_Comp; SCH_COMPONENT* m_Comp;
char m_Ref[32]; 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 DrawSheetPath m_SheetList; //composed of UIDs
} ListComponent; } ListComponent;
......
...@@ -610,7 +610,7 @@ void WinEDA_SchematicFrame::Process_Special_Functions( wxCommandEvent& event ) ...@@ -610,7 +610,7 @@ void WinEDA_SchematicFrame::Process_Special_Functions( wxCommandEvent& event )
{ {
EDA_LibComponentStruct* LibEntry; EDA_LibComponentStruct* LibEntry;
LibEntry = FindLibPart( LibEntry = FindLibPart(
( (SCH_COMPONENT*) screen->GetCurItem() )->m_ChipName, ( (SCH_COMPONENT*) screen->GetCurItem() )->m_ChipName.GetData(),
wxEmptyString, wxEmptyString,
FIND_ALIAS ); FIND_ALIAS );
if( LibEntry && LibEntry->m_DocFile != wxEmptyString ) if( LibEntry && LibEntry->m_DocFile != wxEmptyString )
......
...@@ -253,7 +253,7 @@ wxClientDC dc(DrawPanel); ...@@ -253,7 +253,7 @@ wxClientDC dc(DrawPanel);
g_ViewUnit = 1; g_ViewUnit = 1;
g_ViewConvert = 1; g_ViewConvert = 1;
LibEntry = FindLibPart(CmpName,Lib->m_Name, FIND_ALIAS); LibEntry = FindLibPart(CmpName.GetData(),Lib->m_Name, FIND_ALIAS);
g_CurrentViewComponentName = CmpName; g_CurrentViewComponentName = CmpName;
DisplayLibInfos(); DisplayLibInfos();
Zoom_Automatique(FALSE); Zoom_Automatique(FALSE);
......
...@@ -212,20 +212,20 @@ ...@@ -212,20 +212,20 @@
#include "../bitmaps/annotate_right_down.xpm" #include "../bitmaps/annotate_right_down.xpm"
#include "../bitmaps/annotate_down_right.xpm" #include "../bitmaps/annotate_down_right.xpm"
#include "../bitmaps/new_sch.xpm" // #include "../bitmaps/new_sch.xpm"
#include "../bitmaps/Open_Project.xpm" #include "../bitmaps/Open_Project.xpm"
#include "../bitmaps/new_cvpcb.xpm" // #include "../bitmaps/new_cvpcb.xpm"
#include "../bitmaps/zip.xpm" #include "../bitmaps/zip.xpm"
#include "../bitmaps/icon_gerbview_small.xpm" #include "../bitmaps/icon_gerbview_small.xpm"
#include "../bitmaps/zip_tool.xpm" // #include "../bitmaps/zip_tool.xpm"
#include "../bitmaps/unzip.xpm" #include "../bitmaps/unzip.xpm"
#include "../bitmaps/Browse_Files.xpm" #include "../bitmaps/Browse_Files.xpm"
#include "../bitmaps/New_Project.xpm" #include "../bitmaps/New_Project.xpm"
#include "../bitmaps/new_gerb.xpm" // #include "../bitmaps/new_gerb.xpm"
#include "../bitmaps/new_python.xpm" // #include "../bitmaps/new_python.xpm"
#include "../bitmaps/icon_cvpcb_small.xpm" #include "../bitmaps/icon_cvpcb_small.xpm"
#include "../bitmaps/unknown.xpm" #include "../bitmaps/unknown.xpm"
#include "../bitmaps/new_pcb.xpm" // #include "../bitmaps/new_pcb.xpm"
#include "../bitmaps/reload.xpm" #include "../bitmaps/reload.xpm"
......
...@@ -280,7 +280,7 @@ int BOARD::ClipAreaPolygon( ZONE_CONTAINER* CurrArea, ...@@ -280,7 +280,7 @@ int BOARD::ClipAreaPolygon( ZONE_CONTAINER* CurrArea,
{ {
std::vector<CPolyLine*> * pa = new std::vector<CPolyLine*>; std::vector<CPolyLine*> * pa = new std::vector<CPolyLine*>;
curr_polygon->Undraw(); 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 if( n_poly > 1 ) // i.e if clipping has created some polygons, we must add these new copper areas
{ {
ZONE_CONTAINER* NewArea; ZONE_CONTAINER* NewArea;
...@@ -310,7 +310,8 @@ int BOARD::ClipAreaPolygon( ZONE_CONTAINER* CurrArea, ...@@ -310,7 +310,8 @@ int BOARD::ClipAreaPolygon( ZONE_CONTAINER* CurrArea,
* itself and the polygons for any other areas on the same net. * 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. * This may change the number and order of copper areas in the net.
* @param modified_area = area to test * @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 : * @return :
* -1 if arcs intersect other sides, so polygon can't be clipped * -1 if arcs intersect other sides, so polygon can't be clipped
* 0 if no intersecting sides * 0 if no intersecting sides
...@@ -697,8 +698,11 @@ int BOARD::CombineAreas( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_combi ...@@ -697,8 +698,11 @@ int BOARD::CombineAreas( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_combi
CPolyLine* poly2 = area_to_combine->m_Poly; CPolyLine* poly2 = area_to_combine->m_Poly;
std::vector<CArc> arc_array1; std::vector<CArc> arc_array1;
std::vector<CArc> arc_array2; 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; int n_ext_cont1 = 0;
for( int ic = 0; ic<poly1->GetGpcPoly()->num_contours; ic++ ) for( int ic = 0; ic<poly1->GetGpcPoly()->num_contours; ic++ )
if( !( (poly1->GetGpcPoly()->hole)[ic] ) ) if( !( (poly1->GetGpcPoly()->hole)[ic] ) )
...@@ -776,7 +780,97 @@ int BOARD::CombineAreas( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_combi ...@@ -776,7 +780,97 @@ int BOARD::CombineAreas( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_combi
area_ref->m_Poly->Draw(); area_ref->m_Poly->Draw();
gpc_free_polygon( union_gpc ); gpc_free_polygon( union_gpc );
delete union_gpc; delete union_gpc;
return 1; 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 ...@@ -785,7 +879,7 @@ int BOARD::CombineAreas( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_combi
/** /**
* Function Is_Area_Inside_Area * 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 * 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 * @param Area_Ref: the given area to compare with other areas
* used to remove redundant areas * used to remove redundant areas
*/ */
......
This diff is collapsed.
...@@ -16,6 +16,9 @@ ...@@ -16,6 +16,9 @@
#include <vector> #include <vector>
#define USE_GPC_POLY_LIB
//#define USE_GPL_POLY_LIB
#include "defs-macros.h" #include "defs-macros.h"
#include "GenericPolygonClipperLibrary.h" #include "GenericPolygonClipperLibrary.h"
...@@ -117,22 +120,32 @@ public: ...@@ -117,22 +120,32 @@ public:
void SetEndContour( int ic, bool end_contour ); void SetEndContour( int ic, bool end_contour );
void SetSideStyle( int is, int style ); 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 ); 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 ); 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, void AddContourForPadClearance( int type, int x, int y, int w,
int l, int r, int angle, int fill_clearance, int l, int r, int angle, int fill_clearance,
int hole_w, int hole_clearance, bool bThermal=FALSE, int spoke_w=0 ); 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 // PHP functions
#ifdef USE_GPL_POLY_LIB
int MakePhpPoly(); int MakePhpPoly();
void FreePhpPoly(); void FreePhpPoly();
void ClipPhpPolygon( int php_op, CPolyLine * poly ); void ClipPhpPolygon( int php_op, CPolyLine * poly );
polygon * GetPhpPoly(){ return m_php_poly; };
#endif
private: private:
int m_layer; // layer to draw on int m_layer; // layer to draw on
......
This diff is collapsed.
// file php_polygon.h // file php_polygon.h
// See comments in php_polygon.cpp // See comments in php_polygon.cpp
#ifndef PHP_POLYGON_H #ifndef PHP_POLYGON_H
...@@ -10,50 +11,60 @@ class segment; ...@@ -10,50 +11,60 @@ class segment;
#define infinity 100000000 // for places that are far far away #define infinity 100000000 // for places that are far far away
#define PI 3.14159265359 #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 ** This class manages a doubly linked list of vertex objects that represents
** a polygon. The class consists of basic methods to manage the list ** a polygon. The class consists of basic methods to manage the list
** and methods to implement boolean operations between polygon objects. ** 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 int m_cnt; // Tracks number of vertices in the polygon
polygon( vertex * first = NULL ); public:
polygon( vertex* first = NULL );
~polygon(); ~polygon();
vertex * getFirst(); vertex* getFirst();
polygon * NextPoly(); polygon* NextPoly();
void add( vertex * nv ); void add( vertex* nv );
void addv( double x, double y, void addv( double x, double y,
double xc=0, double yc=0, int d=0); double xc = 0, double yc = 0, int d = 0 );
vertex * del( vertex * v ); vertex* del( vertex* v );
void res(); void res();
polygon * copy_poly(); polygon* copy_poly();
void insertSort( vertex * nv, vertex * s, vertex * e ); void insertSort( vertex* nv, vertex* s, vertex* e );
vertex * nxt( vertex * v ); vertex* nxt( vertex* v );
BOOL unckd_remain(); BOOL unckd_remain();
vertex * first_unckd_intersect(); vertex* first_unckd_intersect();
double dist( double x1, double y1, double x2, double y2 ); double dist( double x1, double y1, double x2, double y2 );
double angle( double xc, double yc, double x1, double y1 ); double angle( double xc, double yc, double x1, double y1 );
double aAlpha( double x1, double y1, double x2, double y2, double aAlpha( double x1, double y1, double x2, double y2,
double xc, double yc, double xi, double yi, double d ); 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 ); double aP, double aQ );
BOOL ints( vertex * p1, vertex * p2, vertex * q1, vertex * q2, BOOL ints( vertex * p1, vertex * p2, vertex * q1, vertex * q2,
int * n, double ix[], double iy[], double alphaP[], double alphaQ[] ); int* n, double ix[], double iy[], double alphaP[], double alphaQ[] );
BOOL isInside ( vertex * v ); BOOL isInside( vertex* v );
polygon * boolean( polygon * polyB, int oper ); polygon* boolean( polygon* polyB, int oper );
#if 0 #if 0
function isPolyInside (p); function isPolyInside( p );
function move (dx, dy); function move( dx, dy );
function rotate (xr, yr, a); function rotate( xr, yr, a );
function &bRect (); function& bRect();
#endif #endif
}; //end of class polygon }; //end of class polygon
......
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