void SCH_REFERENCE_LIST::Annotate( bool aUseSheetNum, int aSheetIntervalId, SCH_MULTI_UNIT_REFERENCE_MAP aLockedUnitMap ) { if ( componentFlatList.size() == 0 ) return; int LastReferenceNumber = 0; int NumberOfUnits, Unit; // Components with an invisible reference (power...) always are re-annotated. ResetHiddenReferences(); /* calculate index of the first component with the same reference prefix * than the current component. All components having the same reference * prefix will receive a reference number with consecutive values: * IC .. will be set to IC4, IC4, IC5 ... */ unsigned first = 0; // calculate the last used number for this reference prefix: #ifdef USE_OLD_ALGO int minRefId = 0; // when using sheet number, ensure ref number >= sheet number* aSheetIntervalId if( aUseSheetNum ) minRefId = componentFlatList[first].m_SheetNum * aSheetIntervalId; LastReferenceNumber = GetLastReference( first, minRefId ); #else int minRefId = 1; // when using sheet number, ensure ref number >= sheet number* aSheetIntervalId if( aUseSheetNum ) minRefId = componentFlatList[first].m_SheetNum * aSheetIntervalId + 1; // This is the list of all Id already in use for a given reference prefix. // Will be refilled for each new reference prefix. std::vector<int>idList; GetRefsInUse( first, idList, minRefId ); #endif for( unsigned ii = 0; ii < componentFlatList.size(); ii++ ) { if( componentFlatList[ii].m_Flag ) continue; // Check whether this component is in aLockedUnitMap. SCH_REFERENCE_LIST* lockedList = NULL; BOOST_FOREACH( SCH_MULTI_UNIT_REFERENCE_MAP::value_type& pair, aLockedUnitMap ) { unsigned n_refs = pair.second.GetCount(); for( unsigned thisRefI = 0; thisRefI < n_refs; ++thisRefI ) { SCH_REFERENCE &thisRef = pair.second[thisRefI]; if( thisRef.IsSameInstance( componentFlatList[ii] ) ) { lockedList = &pair.second; break; } } if( lockedList != NULL ) break; } if( ( componentFlatList[first].CompareRef( componentFlatList[ii] ) != 0 ) || ( aUseSheetNum && ( componentFlatList[first].m_SheetNum != componentFlatList[ii].m_SheetNum ) ) ) { // New reference found: we need a new ref number for this reference first = ii; #ifdef USE_OLD_ALGO minRefId = 0; // when using sheet number, ensure ref number >= sheet number* aSheetIntervalId if( aUseSheetNum ) minRefId = componentFlatList[ii].m_SheetNum * aSheetIntervalId; LastReferenceNumber = componentFlatList.GetLastReference( ii, minRefId ); #else minRefId = 1; // when using sheet number, ensure ref number >= sheet number* aSheetIntervalId if( aUseSheetNum ) minRefId = componentFlatList[ii].m_SheetNum * aSheetIntervalId + 1; GetRefsInUse( first, idList, minRefId ); #endif } // Annotation of one part per package components (trivial case). if( componentFlatList[ii].GetLibComponent()->GetUnitCount() <= 1 ) { if( componentFlatList[ii].m_IsNew ) { #ifdef USE_OLD_ALGO LastReferenceNumber++; #else LastReferenceNumber = CreateFirstFreeRefId( idList, minRefId ); #endif componentFlatList[ii].m_NumRef = LastReferenceNumber; } componentFlatList[ii].m_Unit = 1; componentFlatList[ii].m_Flag = 1; componentFlatList[ii].m_IsNew = false; continue; } // Annotation of multi-unit parts ( n units per part ) (complex case) NumberOfUnits = componentFlatList[ii].GetLibComponent()->GetUnitCount(); if( componentFlatList[ii].m_IsNew ) { #ifdef USE_OLD_ALGO LastReferenceNumber++; #else LastReferenceNumber = CreateFirstFreeRefId( idList, minRefId ); #endif componentFlatList[ii].m_NumRef = LastReferenceNumber; if( !componentFlatList[ii].IsUnitsLocked() ) componentFlatList[ii].m_Unit = 1; componentFlatList[ii].m_Flag = 1; } // If this component is in aLockedUnitMap, copy the annotation to all // components that are not it if( lockedList != NULL ) { unsigned n_refs = lockedList->GetCount(); for( unsigned thisRefI = 0; thisRefI < n_refs; ++thisRefI ) { SCH_REFERENCE &thisRef = (*lockedList)[thisRefI]; if( thisRef.IsSameInstance( componentFlatList[ii] ) ) { // This is the component we're currently annotating. Hold the unit! componentFlatList[ii].m_Unit = thisRef.m_Unit; } if( thisRef.CompareValue( componentFlatList[ii] ) != 0 ) continue; if( thisRef.CompareLibName( componentFlatList[ii] ) != 0 ) continue; // Find the matching component for( unsigned jj = ii + 1; jj < componentFlatList.size(); jj++ ) { if( ! thisRef.IsSameInstance( componentFlatList[jj] ) ) continue; componentFlatList[jj].m_NumRef = componentFlatList[ii].m_NumRef; componentFlatList[jj].m_Unit = thisRef.m_Unit; componentFlatList[jj].m_IsNew = false; componentFlatList[jj].m_Flag = 1; break; } } } else { /* search for others units of this component. * we search for others parts that have the same value and the same * reference prefix (ref without ref number) */ for( Unit = 1; Unit <= NumberOfUnits; Unit++ ) { if( componentFlatList[ii].m_Unit == Unit ) continue; int found = FindUnit( ii, Unit ); if( found >= 0 ) continue; // this unit exists for this reference (unit already annotated) // Search a component to annotate ( same prefix, same value, not annotated) for( unsigned jj = ii + 1; jj < componentFlatList.size(); jj++ ) { if( componentFlatList[jj].m_Flag ) // already tested continue; if( componentFlatList[ii].CompareRef( componentFlatList[jj] ) != 0 ) continue; if( componentFlatList[jj].CompareValue( componentFlatList[ii] ) != 0 ) continue; if( componentFlatList[jj].CompareLibName( componentFlatList[ii] ) != 0 ) continue; if( !componentFlatList[jj].m_IsNew ) continue; // Component without reference number found, annotate it if possible if( !componentFlatList[jj].IsUnitsLocked() || ( componentFlatList[jj].m_Unit == Unit ) ) { componentFlatList[jj].m_NumRef = componentFlatList[ii].m_NumRef; componentFlatList[jj].m_Unit = Unit; componentFlatList[jj].m_Flag = 1; componentFlatList[jj].m_IsNew = false; break; } } } } }
void SCH_REFERENCE_LIST::Annotate( bool aUseSheetNum, int aSheetIntervalId ) { if ( componentFlatList.size() == 0 ) return; int LastReferenceNumber = 0; int NumberOfUnits, Unit; /* Components with an invisible reference (power...) always are re-annotated. */ ResetHiddenReferences(); /* calculate index of the first component with the same reference prefix * than the current component. All components having the same reference * prefix will receive a reference number with consecutive values: * IC .. will be set to IC4, IC4, IC5 ... */ unsigned first = 0; /* calculate the last used number for this reference prefix: */ #ifdef USE_OLD_ALGO int minRefId = 0; // when using sheet number, ensure ref number >= sheet number* aSheetIntervalId if( aUseSheetNum ) minRefId = componentFlatList[first].m_SheetNum * aSheetIntervalId; LastReferenceNumber = GetLastReference( first, minRefId ); #else int minRefId = 1; // when using sheet number, ensure ref number >= sheet number* aSheetIntervalId if( aUseSheetNum ) minRefId = componentFlatList[first].m_SheetNum * aSheetIntervalId + 1; // This is the list of all Id already in use for a given reference prefix. // Will be refilled for each new reference prefix. std::vector<int>idList; GetRefsInUse( first, idList, minRefId ); #endif for( unsigned ii = 0; ii < componentFlatList.size(); ii++ ) { if( componentFlatList[ii].m_Flag ) continue; if( ( componentFlatList[first].CompareRef( componentFlatList[ii] ) != 0 ) || ( aUseSheetNum && ( componentFlatList[first].m_SheetNum != componentFlatList[ii].m_SheetNum ) ) ) { /* New reference found: we need a new ref number for this reference */ first = ii; #ifdef USE_OLD_ALGO minRefId = 0; // when using sheet number, ensure ref number >= sheet number* aSheetIntervalId if( aUseSheetNum ) minRefId = componentFlatList[ii].m_SheetNum * aSheetIntervalId; LastReferenceNumber = componentFlatList.GetLastReference( ii, minRefId ); #else minRefId = 1; // when using sheet number, ensure ref number >= sheet number* aSheetIntervalId if( aUseSheetNum ) minRefId = componentFlatList[ii].m_SheetNum * aSheetIntervalId + 1; GetRefsInUse( first, idList, minRefId ); #endif } // Annotation of one part per package components (trivial case). if( componentFlatList[ii].GetLibComponent()->GetPartCount() <= 1 ) { if( componentFlatList[ii].m_IsNew ) { #ifdef USE_OLD_ALGO LastReferenceNumber++; #else LastReferenceNumber = CreateFirstFreeRefId( idList, minRefId ); #endif componentFlatList[ii].m_NumRef = LastReferenceNumber; } componentFlatList[ii].m_Unit = 1; componentFlatList[ii].m_Flag = 1; componentFlatList[ii].m_IsNew = false; continue; } /* Annotation of multi-part components ( n parts per package ) (complex case) */ NumberOfUnits = componentFlatList[ii].GetLibComponent()->GetPartCount(); if( componentFlatList[ii].m_IsNew ) { #ifdef USE_OLD_ALGO LastReferenceNumber++; #else LastReferenceNumber = CreateFirstFreeRefId( idList, minRefId ); #endif componentFlatList[ii].m_NumRef = LastReferenceNumber; if( !componentFlatList[ii].IsPartsLocked() ) componentFlatList[ii].m_Unit = 1; componentFlatList[ii].m_Flag = 1; } /* search for others units of this component. * we search for others parts that have the same value and the same * reference prefix (ref without ref number) */ for( Unit = 1; Unit <= NumberOfUnits; Unit++ ) { if( componentFlatList[ii].m_Unit == Unit ) continue; int found = FindUnit( ii, Unit ); if( found >= 0 ) continue; /* this unit exists for this reference (unit already annotated) */ /* Search a component to annotate ( same prefix, same value, not annotated) */ for( unsigned jj = ii + 1; jj < componentFlatList.size(); jj++ ) { if( componentFlatList[jj].m_Flag ) // already tested continue; if( componentFlatList[ii].CompareRef( componentFlatList[jj] ) != 0 ) continue; if( componentFlatList[jj].CompareValue( componentFlatList[ii] ) != 0 ) continue; if( componentFlatList[jj].CompareLibName( componentFlatList[ii] ) != 0 ) continue; if( !componentFlatList[jj].m_IsNew ) continue; /* Component without reference number found, annotate it if possible */ if( !componentFlatList[jj].IsPartsLocked() || ( componentFlatList[jj].m_Unit == Unit ) ) { componentFlatList[jj].m_NumRef = componentFlatList[ii].m_NumRef; componentFlatList[jj].m_Unit = Unit; componentFlatList[jj].m_Flag = 1; componentFlatList[jj].m_IsNew = false; break; } } } } }