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
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
......
......@@ -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 )
......@@ -72,7 +69,7 @@ bool WinEDA_SchematicFrame::ProcessStuffFile( FILE* StuffFile )
continue;
#if defined(DEBUG)
printf( " %s %s\n", CONV_TO_UTF8(Cmp->m_Field[REFERENCE].m_Text),
printf( " %s %s\n", CONV_TO_UTF8(Cmp->m_Field[REFERENCE].m_Text),
CONV_TO_UTF8(Cmp->m_Field[VALUE].m_Text) );
#endif
TextField = &Cmp->m_Field[FOOTPRINT];
......
......@@ -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,32 +467,40 @@ void SCH_COMPONENT::ClearAnnotation( DrawSheetPath* aSheet )
defRef.Append( wxT( "?" ) );
wxString multi = wxT( "1" );
wxString NewHref;
wxString path;
if( aSheet )
path = GetPath( aSheet );;
for( unsigned int ii = 0; ii< m_PathsAndReferences.GetCount(); ii++ )
if ( KeepMulti ) // We cannot remove all annotations: part selection must be kept
{
// Break hierachical reference in path, ref and multi selection:
reference_fields = wxStringTokenize( m_PathsAndReferences[ii], separators );
if( aSheet == NULL || reference_fields[0].Cmp( path ) == 0 )
wxString NewHref;
wxString path;
if( aSheet )
path = GetPath( aSheet );;
for( unsigned int ii = 0; ii< m_PathsAndReferences.GetCount(); ii++ )
{
if( KeepMulti ) // Get and keep part selection
multi = reference_fields[2];
NewHref = reference_fields[0];
NewHref << wxT( " " ) << defRef << wxT( " " ) << multi;
m_PathsAndReferences[ii] = NewHref;
// Break hierachical reference in path, ref and multi selection:
reference_fields = wxStringTokenize( m_PathsAndReferences[ii], separators );
if( aSheet == NULL || reference_fields[0].Cmp( path ) == 0 )
{
if( KeepMulti ) // Get and keep part selection
multi = reference_fields[2];
NewHref = reference_fields[0];
NewHref << wxT( " " ) << defRef << wxT( " " ) << multi;
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];
......
......@@ -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. */
......
......@@ -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;
......
......@@ -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,31 +791,23 @@ 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:
ItemCount++;
DrawLibItem = (SCH_COMPONENT*) DrawList;
DrawLibItem->m_Parent = sheet->LastScreen();
if( List )
{
List->m_Comp = DrawLibItem;
List->m_SheetList = *sheet;
strncpy( List->m_Ref,
CONV_TO_UTF8( DrawLibItem->GetRef( sheet ) ),
sizeof( List->m_Ref ) );
List++;
}
break;
if( SchItem->Type() != TYPE_SCH_COMPONENT )
continue;
default:
break;
ItemCount++;
DrawLibItem = (SCH_COMPONENT*) SchItem;
DrawLibItem->m_Parent = sheet->LastScreen();
if( List )
{
List->m_Comp = DrawLibItem;
List->m_SheetList = *sheet;
strncpy( List->m_Ref,
CONV_TO_UTF8( DrawLibItem->GetRef( sheet ) ),
sizeof( List->m_Ref ) );
List++;
}
DrawList = DrawList->Pnext;
}
}
......
This diff is collapsed.
......@@ -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;
}
}
......
......@@ -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;
......@@ -39,7 +39,7 @@ enum NetObjetType { /* Type des objets de Net */
NET_JONCTION,
NET_LABEL,
NET_GLOBLABEL,
NET_HIERLABEL, //on a screen to indicate connection to a higher-level sheet
NET_HIERLABEL, //on a screen to indicate connection to a higher-level sheet
NET_SHEETLABEL, //on a drawscreen element to indicate connection to a lower-level sheet.
NET_BUSLABELMEMBER,
NET_GLOBBUSLABELMEMBER,
......@@ -51,9 +51,9 @@ enum NetObjetType { /* Type des objets de Net */
};
enum IsConnectType { /* Valeur du Flag de connection */
UNCONNECT, /* Pin ou Label non connecte */
NOCONNECT, /* Pin volontairement non connectee (Symb. NoConnect utilise) */
enum IsConnectType { /* Valeur du Flag de connection */
UNCONNECT, /* Pin ou Label non connecte */
NOCONNECT, /* Pin volontairement non connectee (Symb. NoConnect utilise) */
PAD_CONNECT /* connexion normale */
};
......@@ -62,23 +62,23 @@ enum IsConnectType { /* Valeur du Flag de connection */
class ObjetNetListStruct
{
public:
EDA_BaseStruct* m_Comp; /* Pointeur sur la definition de l'objet */
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 */
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 */
int m_NetCode; /* pour elements simples */
public:
int m_BusNetCode; /* pour connexions type bus */
int m_BusNetCode; /* pour connexions type bus */
int m_Member; /* pour les labels type BUSWIRE ( labels de bus eclate )
* numero de membre */
* numero de membre */
IsConnectType 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 */
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 */
wxPoint m_Start, m_End;
#if defined (DEBUG)
......@@ -93,15 +93,17 @@ public:
/* Structures pour memo et liste des elements */
typedef struct ListLabel
{
int m_LabelType;
void * m_Label;
char m_SheetPath[64];
int m_LabelType;
void* m_Label;
char m_SheetPath[64];
} ListLabel;
typedef struct ListComponent
{
SCH_COMPONENT * m_Comp;
char m_Ref[32];
//have to store it here since the object refrerences will be duplicated.
SCH_COMPONENT* m_Comp;
char m_Ref[32];
//have to store it here since the object references will be duplicated.
DrawSheetPath m_SheetList; //composed of UIDs
} ListComponent;
......@@ -109,19 +111,19 @@ typedef struct ListComponent
struct CmpListStruct
{
public:
SCH_COMPONENT* m_Cmp; /* Pointeur sur le composant */
int m_NbParts; /* Nombre de parts par boitier */
bool m_PartsLocked; // For multi part components: True if the part cannot be changed
int m_Unit; /* Numero de part */
DrawSheetPath m_SheetList;
unsigned long m_TimeStamp; /* unique identification number */
int m_IsNew; /* != 0 pour composants non annotes */
char m_TextValue[32]; /* Valeur */
char m_TextRef[32]; /* Reference ( hors numero ) */
int m_NumRef; /* Numero de reference */
int m_Flag; /* flag pour calculs internes */
wxPoint m_Pos; /* position components */
char m_Path[128]; // the 'path' of the object in the sheet hierarchy.
SCH_COMPONENT* m_Cmp; /* Pointeur sur le composant */
int m_NbParts; /* Nombre de parts par boitier */
bool m_PartsLocked; // For multi part components: True if the part cannot be changed
int m_Unit; /* Numero de part */
DrawSheetPath m_SheetList;
unsigned long m_TimeStamp; /* unique identification number */
int m_IsNew; /* != 0 pour composants non annotes */
char m_TextValue[32]; /* Valeur */
char m_TextRef[32]; /* Reference ( hors numero ) */
int m_NumRef; /* Numero de reference */
int m_Flag; /* flag pour calculs internes */
wxPoint m_Pos; /* position components */
char m_Path[128]; // the 'path' of the object in the sheet hierarchy.
};
......
......@@ -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 )
......
......@@ -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);
......
......@@ -208,24 +208,24 @@
#include "../bitmaps/Auto_track_width.xpm"
#include "../bitmaps/fill_zone.xpm"
#include "../bitmaps/Width_Segment.xpm"
#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"
......
......@@ -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
*/
......@@ -1007,7 +1101,7 @@ int BOARD::Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_E
bool DRC::doEdgeZoneDrc( ZONE_CONTAINER * aArea, int aCornerIndex )
{
wxString str;
wxPoint start = aArea->GetCornerPosition(aCornerIndex);
wxPoint end;
// Search the end point of the edge starting at aCornerIndex
......
This diff is collapsed.
......@@ -5,10 +5,10 @@
// There may be multiple contours in a polyline.
// The last contour may be open or closed, any others must be closed.
// All of the corners and side-styles are concatenated into 2 arrays,
// separated by setting the end_contour flag of the last corner of
// separated by setting the end_contour flag of the last corner of
// each contour.
//
// When used for copper areas, the first contour is the outer edge
// When used for copper areas, the first contour is the outer edge
// of the area, subsequent ones are "holes" in the copper.
#ifndef POLYLINE_H
......@@ -16,6 +16,9 @@
#include <vector>
#define USE_GPC_POLY_LIB
//#define USE_GPL_POLY_LIB
#include "defs-macros.h"
#include "GenericPolygonClipperLibrary.h"
......@@ -37,12 +40,12 @@ public:
};
class CArc {
public:
public:
enum{ MAX_STEP = 50*25400 }; // max step is 20 mils
enum{ MIN_STEPS = 18 }; // min step is 5 degrees
int style;
int xi, yi, xf, yf;
int n_steps; // number of straight-line segments in gpc_poly
int n_steps; // number of straight-line segments in gpc_poly
bool bFound;
};
......@@ -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,
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
......
This diff is collapsed.
// file php_polygon.h
// See comments in php_polygon.cpp
#ifndef PHP_POLYGON_H
......@@ -7,55 +8,65 @@
class vertex;
class segment;
#define infinity 100000000 // for places that are far far away
#define PI 3.14159265359
#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
int m_cnt; // Tracks number of vertices in the polygon
polygon( vertex * first = NULL );
~polygon();
vertex * getFirst();
polygon * NextPoly();
void add( vertex * nv );
void addv( double x, double y,
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 );
BOOL unckd_remain();
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,
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 );
class polygon
{
public:
vertex* m_first; // Reference to first vertex in the linked list
int m_cnt; // Tracks number of vertices in the polygon
public:
polygon( vertex* first = NULL );
~polygon();
vertex* getFirst();
polygon* NextPoly();
void add( vertex* nv );
void addv( double x, double y,
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 );
BOOL unckd_remain();
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,
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 );
#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
#endif // ifndef PHP_POLYGON_H
#endif // ifndef PHP_POLYGON_H
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