bool SCH_BUS_BUS_ENTRY::IsDanglingStateChanged( std::vector<DANGLING_END_ITEM>& aItemList ) { bool previousStateStart = m_isDanglingStart; bool previousStateEnd = m_isDanglingEnd; m_isDanglingStart = m_isDanglingEnd = true; // Wires and buses are stored in the list as a pair, start and end. This // variable holds the start position from one iteration so it can be used // when the end position is found. wxPoint seg_start; for( DANGLING_END_ITEM& each_item : aItemList ) { if( each_item.GetItem() == this ) continue; switch( each_item.GetType() ) { case BUS_START_END: seg_start = each_item.GetPosition(); break; case BUS_END_END: if( IsPointOnSegment( seg_start, each_item.GetPosition(), m_pos ) ) m_isDanglingStart = false; if( IsPointOnSegment( seg_start, each_item.GetPosition(), m_End() ) ) m_isDanglingEnd = false; break; default: break; } } return (previousStateStart != m_isDanglingStart) || (previousStateEnd != m_isDanglingEnd); }
bool SCH_BUS_ENTRY_BASE::IsDanglingStateChanged( std::vector<DANGLING_END_ITEM>& aItemList ) { bool previousStateStart = m_isDanglingStart; bool previousStateEnd = m_isDanglingEnd; m_isDanglingStart = m_isDanglingEnd = true; // Wires and buses are stored in the list as a pair, start and end. This // variable holds the start position from one iteration so it can be used // when the end position is found. wxPoint seg_start; // Special case: if both items are wires, show as dangling. This is because // a bus entry between two wires will look like a connection, but does NOT // actually represent one. We need to clarify this for the user. bool start_is_wire = false; bool end_is_wire = false; for( DANGLING_END_ITEM& each_item : aItemList ) { if( each_item.GetItem() == this ) continue; switch( each_item.GetType() ) { case WIRE_START_END: case BUS_START_END: seg_start = each_item.GetPosition(); break; case WIRE_END_END: if( IsPointOnSegment( seg_start, each_item.GetPosition(), m_pos ) ) start_is_wire = true; if( IsPointOnSegment( seg_start, each_item.GetPosition(), m_End() ) ) end_is_wire = true; // Fall through case BUS_END_END: if( IsPointOnSegment( seg_start, each_item.GetPosition(), m_pos ) ) m_isDanglingStart = false; if( IsPointOnSegment( seg_start, each_item.GetPosition(), m_End() ) ) m_isDanglingEnd = false; break; default: break; } } // See above: show as dangling if joining two wires if( start_is_wire && end_is_wire ) m_isDanglingStart = m_isDanglingEnd = true; return (previousStateStart != m_isDanglingStart) || (previousStateEnd != m_isDanglingEnd); }
/** * In a contiguous list of wires, remove wires that backtrack over the previous * wire. Example: * * Wire is added: * ----------------------------------------> * * A second wire backtracks over it: * -------------------<====================> * * RemoveBacktracks is called: * -------------------> */ static void RemoveBacktracks( DLIST<SCH_ITEM>& aWires ) { SCH_LINE* last_line = NULL; EDA_ITEM* first = aWires.GetFirst(); for( EDA_ITEM* p = first; p; ) { SCH_LINE *line = dynamic_cast<SCH_LINE*>( p ); if( !line ) { wxFAIL_MSG( "RemoveBacktracks() requires SCH_LINE items" ); break; } p = line->Next(); if( last_line ) { wxASSERT_MSG( last_line->GetEndPoint() == line->GetStartPoint(), "RemoveBacktracks() requires contiguous lines" ); if( IsPointOnSegment( last_line->GetStartPoint(), line->GetStartPoint(), line->GetEndPoint() ) ) { last_line->SetEndPoint( line->GetEndPoint() ); delete s_wires.Remove( line ); } else last_line = line; } else last_line = line; } }
bool Poly::IsPointInside(Vec2 p) { if(!global) // Sprawdzam aktualnoœæ danych calc_glob(); /* Kod z internetu , zoptymalizowany super-mega sztuczkami c++ Ogólna idea to sprawdziæ czy dla ka¿dego boku wielok¹ta , podany punkt znajduje siê potej samej stronie co reszta wierzcho³ków Jeœli dla któregoœ nie to punkt nie nale¿y do wielok¹tu */ for(int i=0 ; i<size;i++) if( IsPointOnSegment(GlobVert[i],GlobVert[(i+1)%size] , p) ) return true; int i, j=size-1 ; bool oddNodes = false; for (i=0; i<size; i++) { if ( (GlobVert[i].y <= p.y && GlobVert[j].y >= p.y || GlobVert[j].y <= p.y && GlobVert[i].y >= p.y ) && (GlobVert[i].x <= p.x || GlobVert[j].x <= p.x) ) { oddNodes^=(GlobVert[i].x + (p.y-GlobVert[i].y)/(GlobVert[j].y-GlobVert[i].y)*(GlobVert[j].x-GlobVert[i].x)<p.x); } j=i; } return oddNodes; }
void SCH_EDIT_FRAME::CheckListConnections( PICKED_ITEMS_LIST& aItemsList, bool aAppend ) { std::vector< wxPoint > pts; std::vector< wxPoint > connections; GetSchematicConnections( connections ); for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ ) { SCH_ITEM* item = (SCH_ITEM*) aItemsList.GetPickedItem( ii ); std::vector< wxPoint > new_pts; if( !item->IsConnectable() ) continue; item->GetConnectionPoints( new_pts ); pts.insert( pts.end(), new_pts.begin(), new_pts.end() ); // If the item is a line, we also add any connection points from the rest of the schematic // that terminate on the line after it is moved. if( item->Type() == SCH_LINE_T ) { SCH_LINE* line = (SCH_LINE*) item; for( auto i : connections ) if( IsPointOnSegment( line->GetStartPoint(), line->GetEndPoint(), i ) ) pts.push_back( i ); } else { // Clean up any wires that short non-wire connections in the list for( auto point = new_pts.begin(); point != new_pts.end(); point++ ) { for( auto second_point = point + 1; second_point != new_pts.end(); second_point++ ) { aAppend |= TrimWire( *point, *second_point, aAppend ); } } } } // We always have some overlapping connection points. Drop duplicates here std::sort( pts.begin(), pts.end(), []( const wxPoint& a, const wxPoint& b ) -> bool { return a.x < b.x || (a.x == b.x && a.y < b.y); } ); pts.erase( unique( pts.begin(), pts.end() ), pts.end() ); for( auto point : pts ) { if( GetScreen()->IsJunctionNeeded( point, true ) ) { AddJunction( point, aAppend ); aAppend = true; } } }
bool SCH_TEXT::IsDanglingStateChanged( std::vector< DANGLING_END_ITEM >& aItemList ) { // Normal text labels cannot be tested for dangling ends. if( Type() == SCH_TEXT_T ) return false; bool previousState = m_isDangling; m_isDangling = true; for( unsigned ii = 0; ii < aItemList.size(); ii++ ) { DANGLING_END_ITEM& item = aItemList[ii]; if( item.GetItem() == this ) continue; switch( item.GetType() ) { case PIN_END: case LABEL_END: case SHEET_LABEL_END: if( m_Pos == item.GetPosition() ) m_isDangling = false; break; case WIRE_START_END: case BUS_START_END: { // These schematic items have created 2 DANGLING_END_ITEM one per end. But being // a paranoid programmer, I'll check just in case. ii++; wxCHECK_MSG( ii < aItemList.size(), previousState != m_isDangling, wxT( "Dangling end type list overflow. Bad programmer!" ) ); DANGLING_END_ITEM & nextItem = aItemList[ii]; m_isDangling = !IsPointOnSegment( item.GetPosition(), nextItem.GetPosition(), m_Pos ); } break; default: break; } if( !m_isDangling ) break; } return previousState != m_isDangling; }
/** * In a contiguous list of wires, remove wires that backtrack over the previous * wire. Example: * * Wire is added: * ----------------------------------------> * * A second wire backtracks over it: * -------------------<====================> * * RemoveBacktracks is called: * -------------------> */ static void RemoveBacktracks( DLIST<SCH_ITEM>& aWires ) { EDA_ITEM* first = aWires.GetFirst(); std::vector<SCH_LINE*> last_lines; for( EDA_ITEM* p = first; p; ) { SCH_LINE *line = static_cast<SCH_LINE*>( p ); p = line->Next(); if( !last_lines.empty() ) { SCH_LINE* last_line = last_lines[last_lines.size() - 1]; bool contiguous = ( last_line->GetEndPoint() == line->GetStartPoint() ); bool backtracks = IsPointOnSegment( last_line->GetStartPoint(), last_line->GetEndPoint(), line->GetEndPoint() ); bool total_backtrack = ( last_line->GetStartPoint() == line->GetEndPoint() ); if( contiguous && backtracks ) { if( total_backtrack ) { delete s_wires.Remove( last_line ); delete s_wires.Remove( line ); last_lines.pop_back(); } else { last_line->SetEndPoint( line->GetEndPoint() ); delete s_wires.Remove( line ); } } else { last_lines.push_back( line ); } } else { last_lines.push_back( line ); } } }
void NETLIST_OBJECT_LIST::segmentToPointConnect( NETLIST_OBJECT* aJonction, bool aIsBus, int aIdxStart ) { for( unsigned i = aIdxStart; i < size(); i++ ) { NETLIST_OBJECT* segment = GetItem( i ); // if different sheets, obviously no physical connection between elements. if( segment->m_SheetPath != aJonction->m_SheetPath ) continue; if( aIsBus == IS_WIRE ) { if( segment->m_Type != NET_SEGMENT ) continue; } else { if( segment->m_Type != NET_BUS ) continue; } if( IsPointOnSegment( segment->m_Start, segment->m_End, aJonction->m_Start ) ) { // Propagation Netcode has all the objects of the same Netcode. if( aIsBus == IS_WIRE ) { if( segment->GetNet() ) propagateNetCode( segment->GetNet(), aJonction->GetNet(), aIsBus ); else segment->SetNet( aJonction->GetNet() ); } else { if( segment->m_BusNetCode ) propagateNetCode( segment->m_BusNetCode, aJonction->m_BusNetCode, aIsBus ); else segment->m_BusNetCode = aJonction->m_BusNetCode; } } } }
bool SCH_BUS_WIRE_ENTRY::IsDanglingStateChanged( std::vector<DANGLING_END_ITEM>& aItemList ) { bool previousStateStart = m_isDanglingStart; bool previousStateEnd = m_isDanglingEnd; m_isDanglingStart = m_isDanglingEnd = true; // Wires and buses are stored in the list as a pair, start and end. This // variable holds the start position from one iteration so it can be used // when the end position is found. wxPoint seg_start; // Store the connection type and state for the start (0) and end (1) bool has_wire[2] = { false }; bool has_bus[2] = { false }; for( DANGLING_END_ITEM& each_item : aItemList ) { if( each_item.GetItem() == this ) continue; switch( each_item.GetType() ) { case WIRE_START_END: case BUS_START_END: seg_start = each_item.GetPosition(); break; case WIRE_END_END: if( IsPointOnSegment( seg_start, each_item.GetPosition(), m_pos ) ) has_wire[0] = true; if( IsPointOnSegment( seg_start, each_item.GetPosition(), m_End() ) ) has_wire[1] = true; break; case BUS_END_END: if( IsPointOnSegment( seg_start, each_item.GetPosition(), m_pos ) ) has_bus[0] = true; if( IsPointOnSegment( seg_start, each_item.GetPosition(), m_End() ) ) has_bus[1] = true; break; default: break; } } /** * A bus-wire entry is connected at both ends if it has a bus and a wire on its * ends. Otherwise, we connect only one end (in the case of a wire-wire or bus-bus) */ if( ( has_wire[0] && has_bus[1] ) || ( has_wire[1] && has_bus[0] ) ) m_isDanglingEnd = m_isDanglingStart = false; else if( has_wire[0] || has_bus[0] ) m_isDanglingStart = false; else if( has_wire[1] || has_bus[1] ) m_isDanglingEnd = false; return (previousStateStart != m_isDanglingStart) || (previousStateEnd != m_isDanglingEnd); }
bool SCH_TEXT::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemList ) { // Normal text labels cannot be tested for dangling ends. if( Type() == SCH_TEXT_T ) return false; bool previousState = m_isDangling; m_isDangling = true; m_connectionType = CONNECTION_NONE; for( unsigned ii = 0; ii < aItemList.size(); ii++ ) { DANGLING_END_ITEM& item = aItemList[ii]; if( item.GetItem() == this ) continue; switch( item.GetType() ) { case PIN_END: case LABEL_END: case SHEET_LABEL_END: case NO_CONNECT_END: if( GetTextPos() == item.GetPosition() ) { m_isDangling = false; if( item.GetType() != PIN_END ) m_connected_items.insert( static_cast< SCH_ITEM* >( item.GetItem() ) ); } break; case BUS_START_END: m_connectionType = CONNECTION_BUS; // fall through case WIRE_START_END: { // These schematic items have created 2 DANGLING_END_ITEM one per end. But being // a paranoid programmer, I'll check just in case. ii++; wxCHECK_MSG( ii < aItemList.size(), previousState != m_isDangling, wxT( "Dangling end type list overflow. Bad programmer!" ) ); DANGLING_END_ITEM & nextItem = aItemList[ii]; m_isDangling = !IsPointOnSegment( item.GetPosition(), nextItem.GetPosition(), GetTextPos() ); if( !m_isDangling ) { if( m_connectionType != CONNECTION_BUS ) m_connectionType = CONNECTION_NET; // Add the line to the connected items, since it won't be picked // up by a search of intersecting connection points auto sch_item = static_cast< SCH_ITEM* >( item.GetItem() ); AddConnectionTo( sch_item ); sch_item->AddConnectionTo( this ); } } break; default: break; } if( !m_isDangling ) break; } if( m_isDangling ) m_connectionType = CONNECTION_NONE; return previousState != m_isDangling; }