bool SCH_SCREEN::BreakSegmentsOnJunctions() { bool brokenSegments = false; for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() ) { if( item->Type() == SCH_JUNCTION_T ) { SCH_JUNCTION* junction = ( SCH_JUNCTION* ) item; if( BreakSegment( junction->GetPosition() ) ) brokenSegments = true; } else { SCH_BUS_ENTRY_BASE* busEntry = dynamic_cast<SCH_BUS_ENTRY_BASE*>( item ); if( busEntry ) { if( BreakSegment( busEntry->GetPosition() ) || BreakSegment( busEntry->m_End() ) ) brokenSegments = true; } } } return brokenSegments; }
SCH_JUNCTION* SCH_EDIT_FRAME::AddJunction( wxDC* aDC, const wxPoint& aPosition, bool aPutInUndoList ) { SCH_JUNCTION* junction = new SCH_JUNCTION( aPosition ); SetRepeatItem( junction ); m_canvas->CrossHairOff( aDC ); // Erase schematic cursor junction->Draw( m_canvas, aDC, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE ); m_canvas->CrossHairOn( aDC ); // Display schematic cursor if( aPutInUndoList ) { GetScreen()->Append( junction ); SaveCopyInUndoList( junction, UR_NEW ); OnModify(); } return junction; }
void SCH_SCREEN::MarkConnections( SCH_LINE* aSegment ) { wxCHECK_RET( (aSegment) && (aSegment->Type() == SCH_LINE_T), wxT( "Invalid object pointer." ) ); for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() ) { if( item->GetFlags() & CANDIDATE ) continue; if( item->Type() == SCH_JUNCTION_T ) { SCH_JUNCTION* junction = (SCH_JUNCTION*) item; if( aSegment->IsEndPoint( junction->GetPosition() ) ) item->SetFlags( CANDIDATE ); continue; } if( item->Type() != SCH_LINE_T ) continue; SCH_LINE* segment = (SCH_LINE*) item; if( aSegment->IsEndPoint( segment->GetStartPoint() ) && !GetPin( segment->GetStartPoint(), NULL, true ) ) { item->SetFlags( CANDIDATE ); MarkConnections( segment ); } if( aSegment->IsEndPoint( segment->GetEndPoint() ) && !GetPin( segment->GetEndPoint(), NULL, true ) ) { item->SetFlags( CANDIDATE ); MarkConnections( segment ); } } }
int SCH_SCREEN::GetConnection( const wxPoint& aPosition, PICKED_ITEMS_LIST& aList, bool aFullConnection ) { SCH_ITEM* item; EDA_ITEM* tmp; EDA_ITEMS list; // Clear flags member for all items. ClearDrawingState(); BreakSegmentsOnJunctions(); if( GetNode( aPosition, list ) == 0 ) return 0; for( size_t i = 0; i < list.size(); i++ ) { item = (SCH_ITEM*) list[ i ]; item->SetFlags( SELECTEDNODE | STRUCT_DELETED ); /* Put this structure in the picked list: */ ITEM_PICKER picker( item, UR_DELETED ); aList.PushItem( picker ); } // Mark all wires, junctions, .. connected to the item(s) found. if( aFullConnection ) { SCH_LINE* segment; for( item = m_drawList.begin(); item; item = item->Next() ) { if( !(item->GetFlags() & SELECTEDNODE) ) continue; if( item->Type() != SCH_LINE_T ) continue; MarkConnections( (SCH_LINE*) item ); } // Search all attached wires (i.e wire with one new dangling end ) for( item = m_drawList.begin(); item; item = item->Next() ) { bool noconnect = false; if( item->GetFlags() & STRUCT_DELETED ) continue; // Already seen if( !(item->GetFlags() & CANDIDATE) ) continue; // not a candidate if( item->Type() != SCH_LINE_T ) continue; item->SetFlags( SKIP_STRUCT ); segment = (SCH_LINE*) item; /* If the wire start point is connected to a wire that was already found * and now is not connected, add the wire to the list. */ for( tmp = m_drawList.begin(); tmp; tmp = tmp->Next() ) { // Ensure tmp is a previously deleted segment: if( ( tmp->GetFlags() & STRUCT_DELETED ) == 0 ) continue; if( tmp->Type() != SCH_LINE_T ) continue; SCH_LINE* testSegment = (SCH_LINE*) tmp; // Test for segment connected to the previously deleted segment: if( testSegment->IsEndPoint( segment->GetStartPoint() ) ) break; } // when tmp != NULL, segment is a new candidate: // put it in deleted list if // the start point is not connected to an other item (like pin) if( tmp && !CountConnectedItems( segment->GetStartPoint(), true ) ) noconnect = true; /* If the wire end point is connected to a wire that has already been found * and now is not connected, add the wire to the list. */ for( tmp = m_drawList.begin(); tmp; tmp = tmp->Next() ) { // Ensure tmp is a previously deleted segment: if( ( tmp->GetFlags() & STRUCT_DELETED ) == 0 ) continue; if( tmp->Type() != SCH_LINE_T ) continue; SCH_LINE* testSegment = (SCH_LINE*) tmp; // Test for segment connected to the previously deleted segment: if( testSegment->IsEndPoint( segment->GetEndPoint() ) ) break; } // when tmp != NULL, segment is a new candidate: // put it in deleted list if // the end point is not connected to an other item (like pin) if( tmp && !CountConnectedItems( segment->GetEndPoint(), true ) ) noconnect = true; item->ClearFlags( SKIP_STRUCT ); if( noconnect ) { item->SetFlags( STRUCT_DELETED ); ITEM_PICKER picker( item, UR_DELETED ); aList.PushItem( picker ); item = m_drawList.begin(); } } // Get redundant junctions (junctions which connect < 3 end wires // and no pin) for( item = m_drawList.begin(); item; item = item->Next() ) { if( item->GetFlags() & STRUCT_DELETED ) continue; if( !(item->GetFlags() & CANDIDATE) ) continue; if( item->Type() != SCH_JUNCTION_T ) continue; SCH_JUNCTION* junction = (SCH_JUNCTION*) item; if( CountConnectedItems( junction->GetPosition(), false ) <= 2 ) { item->SetFlags( STRUCT_DELETED ); ITEM_PICKER picker( item, UR_DELETED ); aList.PushItem( picker ); } } for( item = m_drawList.begin(); item; item = item->Next() ) { if( item->GetFlags() & STRUCT_DELETED ) continue; if( item->Type() != SCH_LABEL_T ) continue; tmp = GetWireOrBus( ( (SCH_TEXT*) item )->GetPosition() ); if( tmp && tmp->GetFlags() & STRUCT_DELETED ) { item->SetFlags( STRUCT_DELETED ); ITEM_PICKER picker( item, UR_DELETED ); aList.PushItem( picker ); } } } ClearDrawingState(); return aList.GetCount(); }