410 lines
11 KiB
C++
410 lines
11 KiB
C++
/*********************/
|
||
/* dangling_ends.cpp */
|
||
/*********************/
|
||
|
||
#include "fctsys.h"
|
||
#include "gr_basic.h"
|
||
#include "common.h"
|
||
#include "program.h"
|
||
#include "libcmp.h"
|
||
#include "general.h"
|
||
|
||
#include "netlist.h" /* Definitions generales liees au calcul de netliste */
|
||
#include "protos.h"
|
||
|
||
enum End_Type
|
||
{
|
||
UNKNOWN = 0,
|
||
WIRE_START_END,
|
||
WIRE_END_END,
|
||
BUS_START_END,
|
||
BUS_END_END,
|
||
JUNCTION_END,
|
||
PIN_END,
|
||
LABEL_END,
|
||
ENTRY_END,
|
||
SHEET_LABEL_END
|
||
};
|
||
|
||
class DanglingEndHandle
|
||
{
|
||
public:
|
||
const void * m_Item;
|
||
wxPoint m_Pos;
|
||
int m_Type;
|
||
DanglingEndHandle * m_Pnext;
|
||
|
||
DanglingEndHandle(int type)
|
||
{
|
||
m_Item = NULL;
|
||
m_Type = type;
|
||
m_Pnext = NULL;
|
||
}
|
||
};
|
||
|
||
DanglingEndHandle * ItemList;
|
||
|
||
static void TestWireForDangling(EDA_DrawLineStruct * DrawRef,
|
||
WinEDA_SchematicFrame * frame, wxDC * DC);
|
||
void TestLabelForDangling(DrawTextStruct * label,
|
||
WinEDA_SchematicFrame * frame, wxDC * DC);
|
||
DanglingEndHandle * RebuildEndList(EDA_BaseStruct *DrawList);
|
||
|
||
/**********************************************************/
|
||
bool SegmentIntersect(int Sx1, int Sy1, int Sx2, int Sy2,
|
||
int Px1, int Py1)
|
||
/**********************************************************/
|
||
/* Retourne TRUE si le point P est sur le segment S.
|
||
Le segment est suppose horizontal ou vertical.
|
||
*/
|
||
{
|
||
int Sxmin, Sxmax, Symin, Symax;
|
||
|
||
if (Sx1 == Sx2) /* Line S is vertical. */
|
||
{
|
||
Symin = MIN(Sy1, Sy2); Symax = MAX(Sy1, Sy2);
|
||
if (Px1 != Sx1) return FALSE;
|
||
if (Py1 >= Symin && Py1 <= Symax) return TRUE;
|
||
else return FALSE;
|
||
}
|
||
|
||
else if (Sy1 == Sy2) /* Line S is horizontal. */
|
||
{
|
||
Sxmin = MIN(Sx1, Sx2); Sxmax = MAX(Sx1, Sx2);
|
||
if (Py1 != Sy1) return FALSE;
|
||
if (Px1 >= Sxmin && Px1 <= Sxmax) return TRUE;
|
||
else return FALSE;
|
||
}
|
||
else return FALSE; // Segments quelconques
|
||
}
|
||
|
||
|
||
|
||
/******************************************************************************/
|
||
void WinEDA_SchematicFrame::TestDanglingEnds(EDA_BaseStruct *DrawList, wxDC *DC)
|
||
/******************************************************************************/
|
||
/* Met a jour les membres m_Dangling des wires, bus, labels
|
||
*/
|
||
{
|
||
EDA_BaseStruct * DrawItem;
|
||
const DanglingEndHandle * DanglingItem, * nextitem;
|
||
|
||
if ( ItemList )
|
||
for ( DanglingItem = ItemList; DanglingItem != NULL; DanglingItem = nextitem)
|
||
{
|
||
nextitem = DanglingItem->m_Pnext;
|
||
delete DanglingItem;
|
||
}
|
||
|
||
ItemList = RebuildEndList(DrawList);
|
||
// Controle des elements
|
||
for ( DrawItem = DrawList; DrawItem != NULL; DrawItem= DrawItem->Pnext)
|
||
{
|
||
switch( DrawItem->m_StructType )
|
||
{
|
||
case DRAW_GLOBAL_LABEL_STRUCT_TYPE:
|
||
case DRAW_LABEL_STRUCT_TYPE:
|
||
#undef STRUCT
|
||
#define STRUCT ((DrawLabelStruct*)DrawItem)
|
||
TestLabelForDangling(STRUCT, this, DC);
|
||
break;
|
||
break;
|
||
|
||
case DRAW_SEGMENT_STRUCT_TYPE:
|
||
#undef STRUCT
|
||
#define STRUCT ((EDA_DrawLineStruct*)DrawItem)
|
||
if( STRUCT->m_Layer == LAYER_WIRE)
|
||
{
|
||
TestWireForDangling(STRUCT, this, DC);
|
||
break;
|
||
}
|
||
if( STRUCT->m_Layer == LAYER_NOTES) break;
|
||
if( STRUCT->m_Layer == LAYER_BUS)
|
||
{
|
||
STRUCT->m_StartIsDangling =
|
||
STRUCT->m_EndIsDangling = FALSE;
|
||
break;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
/********************************************************************/
|
||
LibDrawPin * WinEDA_SchematicFrame::LocatePinEnd(EDA_BaseStruct *DrawList,
|
||
const wxPoint & pos)
|
||
/********************************************************************/
|
||
/* Teste si le point de coordonn<6E>es pos est sur l'extr<74>mit<69> d'une PIN
|
||
retourne un pointeur sur la pin
|
||
NULL sinon
|
||
*/
|
||
{
|
||
EDA_SchComponentStruct * DrawLibItem;
|
||
LibDrawPin * Pin;
|
||
wxPoint pinpos;
|
||
|
||
Pin = LocateAnyPin(DrawList,pos, &DrawLibItem);
|
||
if( ! Pin ) return NULL;
|
||
|
||
pinpos = Pin->m_Pos;
|
||
|
||
if(DrawLibItem == NULL ) pinpos.y = -pinpos.y;
|
||
|
||
else
|
||
{
|
||
int x1 = pinpos.x, y1 = pinpos.y;
|
||
pinpos.x = DrawLibItem->m_Pos.x + DrawLibItem->m_Transform[0][0] * x1
|
||
+ DrawLibItem->m_Transform[0][1] * y1;
|
||
pinpos.y = DrawLibItem->m_Pos.y + DrawLibItem->m_Transform[1][0] * x1
|
||
+ DrawLibItem->m_Transform[1][1] * y1;
|
||
}
|
||
|
||
if( (pos.x == pinpos.x) && (pos.y == pinpos.y) ) return Pin;
|
||
return NULL;
|
||
}
|
||
|
||
|
||
/****************************************************************************/
|
||
void TestWireForDangling(EDA_DrawLineStruct * DrawRef,
|
||
WinEDA_SchematicFrame * frame, wxDC * DC)
|
||
/****************************************************************************/
|
||
{
|
||
DanglingEndHandle * terminal_item;
|
||
bool Sdangstate = TRUE, Edangstate = TRUE;
|
||
|
||
for ( terminal_item = ItemList; terminal_item != NULL;
|
||
terminal_item = terminal_item->m_Pnext)
|
||
{
|
||
if ( terminal_item->m_Item == DrawRef ) continue;
|
||
|
||
if ( (DrawRef->m_Start.x == terminal_item->m_Pos.x) &&
|
||
(DrawRef->m_Start.y == terminal_item->m_Pos.y) )
|
||
Sdangstate = FALSE;
|
||
|
||
if ( (DrawRef->m_End.x == terminal_item->m_Pos.x) &&
|
||
(DrawRef->m_End.y == terminal_item->m_Pos.y) )
|
||
Edangstate = FALSE;
|
||
|
||
if ( (Sdangstate == FALSE) && (Edangstate == FALSE) )
|
||
break;
|
||
}
|
||
|
||
if ( (Sdangstate != DrawRef->m_StartIsDangling) ||
|
||
(Edangstate != DrawRef->m_EndIsDangling) )
|
||
{
|
||
if ( DC )
|
||
RedrawOneStruct(frame->DrawPanel,DC, DrawRef, g_XorMode);
|
||
DrawRef->m_StartIsDangling = Sdangstate;
|
||
DrawRef->m_EndIsDangling = Edangstate;
|
||
if ( DC )
|
||
RedrawOneStruct(frame->DrawPanel,DC, DrawRef, GR_DEFAULT_DRAWMODE);
|
||
}
|
||
}
|
||
|
||
/********************************************************/
|
||
void TestLabelForDangling(DrawTextStruct * label,
|
||
WinEDA_SchematicFrame * frame, wxDC * DC)
|
||
/********************************************************/
|
||
{
|
||
DanglingEndHandle * terminal_item;
|
||
bool dangstate = TRUE;
|
||
|
||
for ( terminal_item = ItemList; terminal_item != NULL;
|
||
terminal_item = terminal_item->m_Pnext)
|
||
{
|
||
if ( terminal_item->m_Item == label ) continue;
|
||
switch( terminal_item->m_Type )
|
||
{
|
||
case PIN_END:
|
||
case LABEL_END:
|
||
case SHEET_LABEL_END:
|
||
if ( (label->m_Pos.x == terminal_item->m_Pos.x) &&
|
||
(label->m_Pos.y == terminal_item->m_Pos.y) )
|
||
dangstate = FALSE;
|
||
break;
|
||
|
||
case WIRE_START_END:
|
||
case BUS_START_END:
|
||
dangstate = ! SegmentIntersect(terminal_item->m_Pos.x,
|
||
terminal_item->m_Pos.y,
|
||
terminal_item->m_Pnext->m_Pos.x,
|
||
terminal_item->m_Pnext->m_Pos.y,
|
||
label->m_Pos.x, label->m_Pos.y);
|
||
terminal_item = terminal_item->m_Pnext;
|
||
break;
|
||
|
||
case UNKNOWN:
|
||
case JUNCTION_END:
|
||
case ENTRY_END:
|
||
case WIRE_END_END:
|
||
case BUS_END_END:
|
||
break;
|
||
}
|
||
|
||
if (dangstate == FALSE) break;
|
||
}
|
||
|
||
if ( dangstate != label->m_IsDangling )
|
||
{
|
||
if ( DC )
|
||
RedrawOneStruct(frame->DrawPanel,DC, label, g_XorMode);
|
||
label->m_IsDangling = dangstate;
|
||
if ( DC )
|
||
RedrawOneStruct(frame->DrawPanel,DC, label, GR_DEFAULT_DRAWMODE);
|
||
}
|
||
}
|
||
|
||
|
||
/****************************************************/
|
||
wxPoint ReturnPinPhysicalPosition( LibDrawPin * Pin,
|
||
EDA_SchComponentStruct * DrawLibItem)
|
||
/****************************************************/
|
||
/* Retourne la position physique de la pin, qui d<>pend de l'orientation
|
||
du composant */
|
||
{
|
||
wxPoint PinPos = Pin->m_Pos;
|
||
|
||
if(DrawLibItem == NULL ) PinPos.y = -PinPos.y;
|
||
|
||
else
|
||
{
|
||
int x = Pin->m_Pos.x, y = Pin->m_Pos.y;
|
||
PinPos.x = DrawLibItem->m_Pos.x + DrawLibItem->m_Transform[0][0] * x
|
||
+ DrawLibItem->m_Transform[0][1] * y;
|
||
PinPos.y = DrawLibItem->m_Pos.y + DrawLibItem->m_Transform[1][0] * x
|
||
+ DrawLibItem->m_Transform[1][1] * y;
|
||
}
|
||
|
||
return PinPos;
|
||
}
|
||
|
||
|
||
/***********************************************************/
|
||
DanglingEndHandle * RebuildEndList(EDA_BaseStruct *DrawList)
|
||
/***********************************************************/
|
||
{
|
||
DanglingEndHandle * StartList = NULL, *item, *lastitem = NULL;
|
||
EDA_BaseStruct * DrawItem;
|
||
|
||
for ( DrawItem = DrawList; DrawItem != NULL; DrawItem = DrawItem->Pnext)
|
||
{
|
||
switch( DrawItem->m_StructType )
|
||
{
|
||
case DRAW_LABEL_STRUCT_TYPE:
|
||
break;
|
||
|
||
case DRAW_GLOBAL_LABEL_STRUCT_TYPE:
|
||
#undef STRUCT
|
||
#define STRUCT ((DrawGlobalLabelStruct*)DrawItem)
|
||
item = new DanglingEndHandle(LABEL_END);
|
||
item->m_Item = DrawItem;
|
||
item->m_Pos = STRUCT->m_Pos;
|
||
if ( lastitem ) lastitem->m_Pnext = item;
|
||
else StartList = item;
|
||
lastitem = item;
|
||
break;
|
||
|
||
case DRAW_SEGMENT_STRUCT_TYPE:
|
||
#undef STRUCT
|
||
#define STRUCT ((EDA_DrawLineStruct*)DrawItem)
|
||
if( STRUCT->m_Layer == LAYER_NOTES ) break;
|
||
if( (STRUCT->m_Layer == LAYER_BUS) || (STRUCT->m_Layer == LAYER_WIRE) )
|
||
{
|
||
item = new DanglingEndHandle((STRUCT->m_Layer == LAYER_BUS) ?
|
||
BUS_START_END : WIRE_START_END);
|
||
item->m_Item = DrawItem;
|
||
item->m_Pos = STRUCT->m_Start;
|
||
if ( lastitem ) lastitem->m_Pnext = item;
|
||
else StartList = item;
|
||
lastitem = item;
|
||
item = new DanglingEndHandle((STRUCT->m_Layer == LAYER_BUS) ?
|
||
BUS_END_END : WIRE_END_END);
|
||
item->m_Item = DrawItem;
|
||
item->m_Pos = STRUCT->m_End;
|
||
lastitem->m_Pnext = item;
|
||
lastitem = item;
|
||
}
|
||
break;
|
||
|
||
case DRAW_JUNCTION_STRUCT_TYPE:
|
||
#undef STRUCT
|
||
#define STRUCT ((DrawJunctionStruct*)DrawItem)
|
||
item = new DanglingEndHandle(JUNCTION_END);
|
||
item->m_Item = DrawItem;
|
||
item->m_Pos = STRUCT->m_Pos;
|
||
if ( lastitem ) lastitem->m_Pnext = item;
|
||
else StartList = item;
|
||
lastitem = item;
|
||
break;
|
||
|
||
case DRAW_BUSENTRY_STRUCT_TYPE:
|
||
#undef STRUCT
|
||
#define STRUCT ((DrawBusEntryStruct*)DrawItem)
|
||
item = new DanglingEndHandle(ENTRY_END);
|
||
item->m_Item = DrawItem;
|
||
item->m_Pos = STRUCT->m_Pos;
|
||
if ( lastitem ) lastitem->m_Pnext = item;
|
||
else StartList = item;
|
||
lastitem = item;
|
||
item = new DanglingEndHandle(ENTRY_END);
|
||
item->m_Item = DrawItem;
|
||
item->m_Pos = STRUCT->m_End();
|
||
lastitem->m_Pnext = item;
|
||
lastitem = item;
|
||
break;
|
||
|
||
case DRAW_LIB_ITEM_STRUCT_TYPE:
|
||
{
|
||
#undef STRUCT
|
||
#define STRUCT ((EDA_SchComponentStruct*)DrawItem)
|
||
EDA_LibComponentStruct * Entry;
|
||
Entry = FindLibPart( STRUCT->m_ChipName, wxEmptyString, FIND_ROOT);
|
||
if( Entry == NULL ) break;
|
||
LibEDA_BaseStruct * DrawLibItem = Entry->m_Drawings;
|
||
for ( ; DrawLibItem != NULL; DrawLibItem = DrawLibItem->Next())
|
||
{
|
||
if(DrawLibItem->m_StructType != COMPONENT_PIN_DRAW_TYPE) continue;
|
||
|
||
LibDrawPin * Pin = (LibDrawPin *) DrawLibItem;
|
||
|
||
if( Pin->m_Unit && DrawLibItem->m_Unit &&
|
||
(DrawLibItem->m_Unit != Pin->m_Unit) )
|
||
continue;
|
||
|
||
if( Pin->m_Convert && DrawLibItem->m_Convert &&
|
||
(DrawLibItem->m_Convert != Pin->m_Convert) )
|
||
continue;
|
||
|
||
item = new DanglingEndHandle(PIN_END);
|
||
item->m_Item = Pin;
|
||
item->m_Pos = ReturnPinPhysicalPosition( Pin,STRUCT);
|
||
if ( lastitem ) lastitem->m_Pnext = item;
|
||
else StartList = item;
|
||
lastitem = item;
|
||
}
|
||
break;
|
||
|
||
}
|
||
|
||
case DRAW_SHEET_STRUCT_TYPE:
|
||
{
|
||
#undef STRUCT
|
||
#define STRUCT ((DrawSheetStruct*)DrawItem)
|
||
DrawSheetLabelStruct * pinsheet = STRUCT->m_Label;
|
||
while(pinsheet)
|
||
{
|
||
item = new DanglingEndHandle(SHEET_LABEL_END);
|
||
item->m_Item = pinsheet;
|
||
item->m_Pos = pinsheet->m_Pos;
|
||
if ( lastitem ) lastitem->m_Pnext = item;
|
||
else StartList = item;
|
||
lastitem = item;
|
||
pinsheet = (DrawSheetLabelStruct*)pinsheet->Pnext;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
return StartList;
|
||
}
|