|
|
/**************************************//* Code to handle schematic clean up. *//**************************************/
#include "fctsys.h"
#include "appl_wxstruct.h"
#include "common.h"
#include "trigo.h"
#include "confirm.h"
#include "macros.h"
#include "program.h"
#include "general.h"
#include "protos.h"
#include "netlist.h"
static int TstAlignSegment( SCH_LINE* RefSegm, SCH_LINE* TstSegm );
/* Routine cleaning:
* - Includes segments or buses aligned in only 1 segment * - Detects identical objects superimposed */bool SCH_SCREEN::SchematicCleanUp( wxDC* DC ){ SCH_ITEM* DrawList, * TstDrawList; int flag; bool Modify = FALSE;
DrawList = EEDrawList; for( ; DrawList != NULL; DrawList = DrawList->Next() ) { if( DrawList->Type() == DRAW_SEGMENT_STRUCT_TYPE ) { TstDrawList = DrawList->Next(); while( TstDrawList ) { if( TstDrawList->Type() == DRAW_SEGMENT_STRUCT_TYPE ) { flag = TstAlignSegment( (SCH_LINE*) DrawList, (SCH_LINE*) TstDrawList ); if( flag ) { /* keep the bits set in .m_Flags, because the deleted
* segment can be flagged */ DrawList->m_Flags |= TstDrawList->m_Flags; EraseStruct( TstDrawList, this ); SetRefreshReq(); TstDrawList = EEDrawList; Modify = TRUE; } else TstDrawList = TstDrawList->Next(); } else TstDrawList = TstDrawList->Next(); } } }
WinEDA_SchematicFrame* frame; frame = (WinEDA_SchematicFrame*) wxGetApp().GetTopWindow(); frame->TestDanglingEnds( EEDrawList, DC );
return Modify;}
/* Routine to start/end segment (BUS or wires) on junctions.
*/void BreakSegmentOnJunction( SCH_SCREEN* Screen ){ SCH_ITEM* DrawList;
if( Screen == NULL ) { DisplayError( NULL, wxT( "BreakSegmentOnJunction() error: NULL screen" ) ); return; }
DrawList = Screen->EEDrawList; while( DrawList ) { switch( DrawList->Type() ) { case DRAW_JUNCTION_STRUCT_TYPE: #undef STRUCT
#define STRUCT ( (SCH_JUNCTION*) DrawList )
BreakSegment( Screen, STRUCT->m_Pos ); break;
case DRAW_BUSENTRY_STRUCT_TYPE: #undef STRUCT
#define STRUCT ( (SCH_BUS_ENTRY*) DrawList )
BreakSegment( Screen, STRUCT->m_Pos ); BreakSegment( Screen, STRUCT->m_End() ); break;
case DRAW_SEGMENT_STRUCT_TYPE: case DRAW_NOCONNECT_STRUCT_TYPE: case TYPE_SCH_LABEL: case TYPE_SCH_GLOBALLABEL: case TYPE_SCH_HIERLABEL: case TYPE_SCH_COMPONENT: case DRAW_POLYLINE_STRUCT_TYPE: case TYPE_SCH_MARKER: case TYPE_SCH_TEXT: case DRAW_SHEET_STRUCT_TYPE: case DRAW_HIERARCHICAL_PIN_SHEET_STRUCT_TYPE: break;
default: break; } DrawList = DrawList->Next(); }}
/* Break a segment ( BUS, WIRE ) int 2 segments at location aBreakpoint,
* if aBreakpoint in on segment segment * ( excluding ends) * fill aPicklist with modified items if non null */void BreakSegment( SCH_SCREEN* aScreen, wxPoint aBreakpoint ){ SCH_LINE* segment, * NewSegment;
for( SCH_ITEM* DrawList = aScreen->EEDrawList; DrawList; DrawList = DrawList->Next() ) { if( DrawList->Type() != DRAW_SEGMENT_STRUCT_TYPE ) continue;
segment = (SCH_LINE*) DrawList;
if( !TestSegmentHit( aBreakpoint, segment->m_Start, segment->m_End, 0 ) ) continue;
/* ???
* Segment connecte: doit etre coupe en 2 si px,py * n'est * pas une extremite */ if( ( segment->m_Start == aBreakpoint ) || ( segment->m_End == aBreakpoint ) ) continue; /* Here we must cut the segment into 2. */ NewSegment = segment->GenCopy(); NewSegment->m_Start = aBreakpoint; segment->m_End = NewSegment->m_Start; NewSegment->SetNext( segment->Next() ); segment->SetNext( NewSegment ); DrawList = NewSegment; }}
/* Search if the 2 segments RefSegm and TstSegm are on a line.
* Return 0 if no * 1 if yes, and RefSegm is modified to be the equivalent segment */static int TstAlignSegment( SCH_LINE* RefSegm, SCH_LINE* TstSegm ){ if( RefSegm == TstSegm ) return 0; if( RefSegm->GetLayer() != TstSegm->GetLayer() ) return 0;
// search for a common end, and modify coordinates to ensure RefSegm->m_End
// == TstSegm->m_Start
if( RefSegm->m_Start == TstSegm->m_Start ) { if( RefSegm->m_End == TstSegm->m_End ) return 1; EXCHG( RefSegm->m_Start, RefSegm->m_End ); } else if( RefSegm->m_Start == TstSegm->m_End ) { EXCHG( RefSegm->m_Start, RefSegm->m_End ); EXCHG( TstSegm->m_Start, TstSegm->m_End ); } else if( RefSegm->m_End == TstSegm->m_End ) { EXCHG( TstSegm->m_Start, TstSegm->m_End ); } else if( RefSegm->m_End != TstSegm->m_Start ) // No common end point, segments cannot be merged.
return 0;
/* Test alignment: */ if( RefSegm->m_Start.y == RefSegm->m_End.y ) // Horizontal segment
{ if( TstSegm->m_Start.y == TstSegm->m_End.y ) { RefSegm->m_End = TstSegm->m_End; return 1; } } else if( RefSegm->m_Start.x == RefSegm->m_End.x ) // Vertical segment
{ if( TstSegm->m_Start.x == TstSegm->m_End.x ) { RefSegm->m_End = TstSegm->m_End; return 1; } } else { if( atan2( (double) ( RefSegm->m_Start.x - RefSegm->m_End.x ), (double) ( RefSegm->m_Start.y - RefSegm->m_End.y ) ) == atan2( (double) ( TstSegm->m_Start.x - TstSegm->m_End.x ), (double) ( TstSegm->m_Start.y - TstSegm->m_End.y ) ) ) { RefSegm->m_End = TstSegm->m_End; return 1; } }
return 0;}
|