diff --git a/Scripts - PCB/DiffPairFinder/DiffPair_Finder.PrjScr b/Scripts - PCB/DiffPairFinder/DiffPair_Finder.PrjScr new file mode 100644 index 00000000..3c292e86 --- /dev/null +++ b/Scripts - PCB/DiffPairFinder/DiffPair_Finder.PrjScr @@ -0,0 +1,1017 @@ +[Design] +Version=1.0 +HierarchyMode=0 +ChannelRoomNamingStyle=0 +ReleasesFolder= +ChannelDesignatorFormatString=$Component_$RoomName +ChannelRoomLevelSeperator=_ +OpenOutputs=1 +ArchiveProject=0 +TimestampOutput=0 +SeparateFolders=0 +TemplateLocationPath= +PinSwapBy_Netlabel=1 +PinSwapBy_Pin=1 +AllowPortNetNames=0 +AllowSheetEntryNetNames=1 +AppendSheetNumberToLocalNets=0 +NetlistSinglePinNets=0 +DefaultConfiguration=Default - All Constraints +UserID=0xFFFFFFFF +DefaultPcbProtel=1 +DefaultPcbPcad=0 +ReorderDocumentsOnCompile=1 +NameNetsHierarchically=0 +PowerPortNamesTakePriority=0 +AutoSheetNumbering=0 +NewIndexingOfSheetSymbols=1 +PushECOToAnnotationFile=1 +DItemRevisionGUID= +ReportSuppressedErrorsInMessages=0 +FSMCodingStyle=eFMSDropDownList_OneProcess +FSMEncodingStyle=eFMSDropDownList_OneHot +IsProjectConflictPreventionWarningsEnabled=1 +ConstraintManagerFlow=0 +IsVirtualBomDocumentRemoved=0 +OutputPath= +LogFolderPath= +ManagedProjectGUID= +IncludeDesignInRelease=0 +CrossRefSheetStyle=2 +CrossRefLocationStyle=1 +CrossRefPorts=3 +CrossRefCrossSheets=1 +CrossRefSheetEntries=0 +CrossRefFollowFromMainSettings=1 + +[Preferences] +PrefsVaultGUID= +PrefsRevisionGUID= + +[Document1] +DocumentPath=DiffPair_Finder.pas +AnnotationEnabled=1 +AnnotateStartValue=1 +AnnotationIndexControlEnabled=0 +AnnotateSuffix= +AnnotateScope=All +AnnotateOrder=-1 +DoLibraryUpdate=1 +DoDatabaseUpdate=1 +ClassGenCCAutoEnabled=1 +ClassGenCCAutoRoomEnabled=0 +ClassGenNCAutoScope=None +DItemRevisionGUID= +GenerateClassCluster=0 +DocumentUniqueId= + +[OutputGroup1] +Name=Netlist Outputs +Description= +TargetPrinter=\\NDG-PC-SVR-03\Brother DCP-L2540DW series +PrinterOptions=Record=PrinterOptions|Copies=1|Duplex=1|TrueTypeOptions=3|Collate=1|PrintJobKind=1|PrintWhat=1 +OutputType1=CadnetixNetlist +OutputName1=Cadnetix Netlist +OutputDocumentPath1= +OutputVariantName1= +OutputDefault1=0 +OutputType2=CalayNetlist +OutputName2=Calay Netlist +OutputDocumentPath2= +OutputVariantName2= +OutputDefault2=0 +OutputType3=EDIF +OutputName3=EDIF for PCB +OutputDocumentPath3= +OutputVariantName3= +OutputDefault3=0 +OutputType4=EESofNetlist +OutputName4=EESof Netlist +OutputDocumentPath4= +OutputVariantName4= +OutputDefault4=0 +OutputType5=IntergraphNetlist +OutputName5=Intergraph Netlist +OutputDocumentPath5= +OutputVariantName5= +OutputDefault5=0 +OutputType6=MentorBoardStationNetlist +OutputName6=Mentor BoardStation Netlist +OutputDocumentPath6= +OutputVariantName6= +OutputDefault6=0 +OutputType7=MultiWire +OutputName7=MultiWire +OutputDocumentPath7= +OutputVariantName7= +OutputDefault7=0 +OutputType8=OrCadPCB2Netlist +OutputName8=Orcad/PCB2 Netlist +OutputDocumentPath8= +OutputVariantName8= +OutputDefault8=0 +OutputType9=PADSNetlist +OutputName9=PADS ASCII Netlist +OutputDocumentPath9= +OutputVariantName9= +OutputDefault9=0 +OutputType10=Pcad +OutputName10=Pcad for PCB +OutputDocumentPath10= +OutputVariantName10= +OutputDefault10=0 +OutputType11=PCADNetlist +OutputName11=PCAD Netlist +OutputDocumentPath11= +OutputVariantName11= +OutputDefault11=0 +OutputType12=PCADnltNetlist +OutputName12=PCADnlt Netlist +OutputDocumentPath12= +OutputVariantName12= +OutputDefault12=0 +OutputType13=Protel2Netlist +OutputName13=Protel2 Netlist +OutputDocumentPath13= +OutputVariantName13= +OutputDefault13=0 +OutputType14=ProtelNetlist +OutputName14=Protel +OutputDocumentPath14= +OutputVariantName14= +OutputDefault14=0 +OutputType15=RacalNetlist +OutputName15=Racal Netlist +OutputDocumentPath15= +OutputVariantName15= +OutputDefault15=0 +OutputType16=RINFNetlist +OutputName16=RINF Netlist +OutputDocumentPath16= +OutputVariantName16= +OutputDefault16=0 +OutputType17=SciCardsNetlist +OutputName17=SciCards Netlist +OutputDocumentPath17= +OutputVariantName17= +OutputDefault17=0 +OutputType18=TangoNetlist +OutputName18=Tango Netlist +OutputDocumentPath18= +OutputVariantName18= +OutputDefault18=0 +OutputType19=TelesisNetlist +OutputName19=Telesis Netlist +OutputDocumentPath19= +OutputVariantName19= +OutputDefault19=0 +OutputType20=WireListNetlist +OutputName20=WireList Netlist +OutputDocumentPath20= +OutputVariantName20= +OutputDefault20=0 + +[OutputGroup2] +Name=Simulator Outputs +Description= +TargetPrinter=\\NDG-PC-SVR-03\Brother DCP-L2540DW series +PrinterOptions=Record=PrinterOptions|Copies=1|Duplex=1|TrueTypeOptions=3|Collate=1|PrintJobKind=1|PrintWhat=1 + +[OutputGroup3] +Name=Documentation Outputs +Description= +TargetPrinter=Virtual Printer +PrinterOptions=Record=PrinterOptions|Copies=1|Duplex=1|TrueTypeOptions=3|Collate=1|PrintJobKind=1|PrintWhat=1 +OutputType1=Composite +OutputName1=Composite Drawing +OutputDocumentPath1= +OutputVariantName1=[No Variations] +OutputDefault1=0 +PageOptions1=Record=PageOptions|CenterHorizontal=True|CenterVertical=True|PrintScale=1.00|XCorrection=1.00|YCorrection=1.00|PrintKind=1|BorderSize=5000000|LeftOffset=0|BottomOffset=0|Orientation=2|PaperLength=1000|PaperWidth=1000|Scale=100|PaperSource=7|PrintQuality=-3|MediaType=1|DitherType=10|PrintScaleMode=1|PaperKind=Letter|PaperIndex=1 +OutputType2=PCB 3D Print +OutputName2=PCB 3D Print +OutputDocumentPath2= +OutputVariantName2=[No Variations] +OutputDefault2=0 +PageOptions2=Record=PageOptions|CenterHorizontal=True|CenterVertical=True|PrintScale=1.00|XCorrection=1.00|YCorrection=1.00|PrintKind=1|BorderSize=5000000|LeftOffset=0|BottomOffset=0|Orientation=2|PaperLength=1000|PaperWidth=1000|Scale=100|PaperSource=7|PrintQuality=-3|MediaType=1|DitherType=10|PrintScaleMode=1|PaperKind=Letter|PaperIndex=1 +OutputType3=PCB 3D Video +OutputName3=PCB 3D Video +OutputDocumentPath3= +OutputVariantName3=[No Variations] +OutputDefault3=0 +PageOptions3=Record=PageOptions|CenterHorizontal=True|CenterVertical=True|PrintScale=1.00|XCorrection=1.00|YCorrection=1.00|PrintKind=1|BorderSize=5000000|LeftOffset=0|BottomOffset=0|Orientation=2|PaperLength=1000|PaperWidth=1000|Scale=100|PaperSource=7|PrintQuality=-3|MediaType=1|DitherType=10|PrintScaleMode=1|PaperKind=Letter|PaperIndex=1 +OutputType4=PCB Print +OutputName4=PCB Prints +OutputDocumentPath4= +OutputVariantName4=[No Variations] +OutputDefault4=0 +PageOptions4=Record=PageOptions|CenterHorizontal=True|CenterVertical=True|PrintScale=1.00|XCorrection=1.00|YCorrection=1.00|PrintKind=1|BorderSize=5000000|LeftOffset=0|BottomOffset=0|Orientation=2|PaperLength=1000|PaperWidth=1000|Scale=100|PaperSource=7|PrintQuality=-3|MediaType=1|DitherType=10|PrintScaleMode=1|PaperKind=Letter|PaperIndex=1 +OutputType5=PCBDrawing +OutputName5=Draftsman +OutputDocumentPath5= +OutputVariantName5=[No Variations] +OutputDefault5=0 +PageOptions5=Record=PageOptions|CenterHorizontal=True|CenterVertical=True|PrintScale=1.00|XCorrection=1.00|YCorrection=1.00|PrintKind=1|BorderSize=5000000|LeftOffset=0|BottomOffset=0|Orientation=2|PaperLength=1000|PaperWidth=1000|Scale=100|PaperSource=7|PrintQuality=-3|MediaType=1|DitherType=10|PrintScaleMode=1|PaperKind=Letter|PaperIndex=1 +OutputType6=PCBLIB Print +OutputName6=PCBLIB Prints +OutputDocumentPath6= +OutputVariantName6=[No Variations] +OutputDefault6=0 +PageOptions6=Record=PageOptions|CenterHorizontal=True|CenterVertical=True|PrintScale=1.00|XCorrection=1.00|YCorrection=1.00|PrintKind=1|BorderSize=5000000|LeftOffset=0|BottomOffset=0|Orientation=2|PaperLength=1000|PaperWidth=1000|Scale=100|PaperSource=7|PrintQuality=-3|MediaType=1|DitherType=10|PrintScaleMode=1|PaperKind=Letter|PaperIndex=1 +OutputType7=PDF3D +OutputName7=PDF3D +OutputDocumentPath7= +OutputVariantName7=[No Variations] +OutputDefault7=0 +PageOptions7=Record=PageOptions|CenterHorizontal=True|CenterVertical=True|PrintScale=1.00|XCorrection=1.00|YCorrection=1.00|PrintKind=1|BorderSize=5000000|LeftOffset=0|BottomOffset=0|Orientation=2|PaperLength=1000|PaperWidth=1000|Scale=100|PaperSource=7|PrintQuality=-3|MediaType=1|DitherType=10|PrintScaleMode=1|PaperKind=Letter|PaperIndex=1 +OutputType8=Report Print +OutputName8=Report Prints +OutputDocumentPath8= +OutputVariantName8= +OutputDefault8=0 +PageOptions8=Record=PageOptions|CenterHorizontal=True|CenterVertical=True|PrintScale=1.00|XCorrection=1.00|YCorrection=1.00|PrintKind=1|BorderSize=5000000|LeftOffset=0|BottomOffset=0|Orientation=2|PaperLength=1000|PaperWidth=1000|Scale=100|PaperSource=7|PrintQuality=-3|MediaType=1|DitherType=10|PrintScaleMode=1|PaperKind=Letter|PaperIndex=1 +OutputType9=Schematic Print +OutputName9=Schematic Prints +OutputDocumentPath9= +OutputVariantName9= +OutputDefault9=0 +PageOptions9=Record=PageOptions|CenterHorizontal=True|CenterVertical=True|PrintScale=1.00|XCorrection=1.00|YCorrection=1.00|PrintKind=1|BorderSize=5000000|LeftOffset=0|BottomOffset=0|Orientation=2|PaperLength=1000|PaperWidth=1000|Scale=100|PaperSource=7|PrintQuality=-3|MediaType=1|DitherType=10|PrintScaleMode=1|PaperKind=Letter|PaperIndex=1 +OutputType10=SimView Print +OutputName10=SimView Prints +OutputDocumentPath10= +OutputVariantName10= +OutputDefault10=0 +PageOptions10=Record=PageOptions|CenterHorizontal=True|CenterVertical=True|PrintScale=1.00|XCorrection=1.00|YCorrection=1.00|PrintKind=1|BorderSize=5000000|LeftOffset=0|BottomOffset=0|Orientation=2|PaperLength=1000|PaperWidth=1000|Scale=100|PaperSource=7|PrintQuality=-3|MediaType=1|DitherType=10|PrintScaleMode=1|PaperKind=Letter|PaperIndex=1 +OutputType11=Harness Layout Drawing Print +OutputName11=Harness Layout Drawing Prints +OutputDocumentPath11= +OutputVariantName11= +OutputDefault11=0 +PageOptions11=Record=PageOptions|CenterHorizontal=True|CenterVertical=True|PrintScale=1.00|XCorrection=1.00|YCorrection=1.00|PrintKind=1|BorderSize=5000000|LeftOffset=0|BottomOffset=0|Orientation=2|PaperLength=1000|PaperWidth=1000|Scale=100|PaperSource=7|PrintQuality=-3|MediaType=1|DitherType=10|PrintScaleMode=1|PaperKind=Letter|PaperIndex=1 +OutputType12=Harness Wiring Diagram Print +OutputName12=Harness Wiring Diagram Prints +OutputDocumentPath12= +OutputVariantName12= +OutputDefault12=0 +PageOptions12=Record=PageOptions|CenterHorizontal=True|CenterVertical=True|PrintScale=1.00|XCorrection=1.00|YCorrection=1.00|PrintKind=1|BorderSize=5000000|LeftOffset=0|BottomOffset=0|Orientation=2|PaperLength=1000|PaperWidth=1000|Scale=100|PaperSource=7|PrintQuality=-3|MediaType=1|DitherType=10|PrintScaleMode=1|PaperKind=Letter|PaperIndex=1 +OutputType13=PDF3D MBA +OutputName13=PDF3D MBA +OutputDocumentPath13= +OutputVariantName13= +OutputDefault13=0 +PageOptions13=Record=PageOptions|CenterHorizontal=True|CenterVertical=True|PrintScale=1.00|XCorrection=1.00|YCorrection=1.00|PrintKind=1|BorderSize=5000000|LeftOffset=0|BottomOffset=0|Orientation=2|PaperLength=1000|PaperWidth=1000|Scale=100|PaperSource=7|PrintQuality=-3|MediaType=1|DitherType=10|PrintScaleMode=1|PaperKind=Letter|PaperIndex=1 + +[OutputGroup4] +Name=Assembly Outputs +Description= +TargetPrinter=\\NDG-PC-SVR-03\Brother DCP-L2540DW series +PrinterOptions=Record=PrinterOptions|Copies=1|Duplex=1|TrueTypeOptions=3|Collate=1|PrintJobKind=1|PrintWhat=1 +OutputType1=Assembly +OutputName1=Assembly Drawings +OutputDocumentPath1= +OutputVariantName1=[No Variations] +OutputDefault1=0 +PageOptions1=Record=PageOptions|CenterHorizontal=True|CenterVertical=True|PrintScale=1.00|XCorrection=1.00|YCorrection=1.00|PrintKind=1|BorderSize=5000000|LeftOffset=0|BottomOffset=0|Orientation=2|PaperLength=1000|PaperWidth=1000|Scale=100|PaperSource=7|PrintQuality=-3|MediaType=1|DitherType=10|PrintScaleMode=1|PaperKind=Letter|PaperIndex=1 +OutputType2=Pick Place +OutputName2=Generates pick and place files +OutputDocumentPath2= +OutputVariantName2=[No Variations] +OutputDefault2=0 +OutputType3=Test Points For Assembly +OutputName3=Test Point Report +OutputDocumentPath3= +OutputVariantName3=[No Variations] +OutputDefault3=0 +OutputType4=Wire Bonding Table +OutputName4=Wire Bonding Table Report +OutputDocumentPath4= +OutputVariantName4=[No Variations] +OutputDefault4=0 + +[OutputGroup5] +Name=Fabrication Outputs +Description= +TargetPrinter=\\NDG-PC-SVR-03\Brother DCP-L2540DW series +PrinterOptions=Record=PrinterOptions|Copies=1|Duplex=1|TrueTypeOptions=3|Collate=1|PrintJobKind=1|PrintWhat=1 +OutputType1=Board Stack Report +OutputName1=Report Board Stack +OutputDocumentPath1= +OutputVariantName1= +OutputDefault1=0 +PageOptions1=Record=PageOptions|CenterHorizontal=True|CenterVertical=True|PrintScale=1.00|XCorrection=1.00|YCorrection=1.00|PrintKind=1|BorderSize=5000000|LeftOffset=0|BottomOffset=0|Orientation=2|PaperLength=1000|PaperWidth=1000|Scale=100|PaperSource=7|PrintQuality=-3|MediaType=1|DitherType=10|PrintScaleMode=1|PaperKind=Letter|PaperIndex=1 +OutputType2=CompositeDrill +OutputName2=Composite Drill Drawing +OutputDocumentPath2= +OutputVariantName2=[No Variations] +OutputDefault2=0 +PageOptions2=Record=PageOptions|CenterHorizontal=True|CenterVertical=True|PrintScale=1.00|XCorrection=1.00|YCorrection=1.00|PrintKind=1|BorderSize=5000000|LeftOffset=0|BottomOffset=0|Orientation=2|PaperLength=1000|PaperWidth=1000|Scale=100|PaperSource=7|PrintQuality=-3|MediaType=1|DitherType=10|PrintScaleMode=1|PaperKind=Letter|PaperIndex=1 +OutputType3=Drill +OutputName3=Drill Drawing/Guides +OutputDocumentPath3= +OutputVariantName3=[No Variations] +OutputDefault3=0 +PageOptions3=Record=PageOptions|CenterHorizontal=True|CenterVertical=True|PrintScale=1.00|XCorrection=1.00|YCorrection=1.00|PrintKind=1|BorderSize=5000000|LeftOffset=0|BottomOffset=0|Orientation=2|PaperLength=1000|PaperWidth=1000|Scale=100|PaperSource=7|PrintQuality=-3|MediaType=1|DitherType=10|PrintScaleMode=1|PaperKind=Letter|PaperIndex=1 +OutputType4=Final +OutputName4=Final Artwork Prints +OutputDocumentPath4= +OutputVariantName4=[No Variations] +OutputDefault4=0 +PageOptions4=Record=PageOptions|CenterHorizontal=True|CenterVertical=True|PrintScale=1.00|XCorrection=1.00|YCorrection=1.00|PrintKind=1|BorderSize=5000000|LeftOffset=0|BottomOffset=0|Orientation=2|PaperLength=1000|PaperWidth=1000|Scale=100|PaperSource=7|PrintQuality=-3|MediaType=1|DitherType=10|PrintScaleMode=1|PaperKind=Letter|PaperIndex=1 +OutputType5=Gerber +OutputName5=Gerber Files +OutputDocumentPath5= +OutputVariantName5=[No Variations] +OutputDefault5=0 +OutputType6=Gerber X2 +OutputName6=Gerber X2 Files +OutputDocumentPath6= +OutputVariantName6=[No Variations] +OutputDefault6=0 +OutputType7=IPC2581 +OutputName7=IPC-2581 Files +OutputDocumentPath7= +OutputVariantName7=[No Variations] +OutputDefault7=0 +OutputType8=Mask +OutputName8=Solder/Paste Mask Prints +OutputDocumentPath8= +OutputVariantName8=[No Variations] +OutputDefault8=0 +PageOptions8=Record=PageOptions|CenterHorizontal=True|CenterVertical=True|PrintScale=1.00|XCorrection=1.00|YCorrection=1.00|PrintKind=1|BorderSize=5000000|LeftOffset=0|BottomOffset=0|Orientation=2|PaperLength=1000|PaperWidth=1000|Scale=100|PaperSource=7|PrintQuality=-3|MediaType=1|DitherType=10|PrintScaleMode=1|PaperKind=Letter|PaperIndex=1 +OutputType9=NC Drill +OutputName9=NC Drill Files +OutputDocumentPath9= +OutputVariantName9= +OutputDefault9=0 +OutputType10=ODB +OutputName10=ODB++ Files +OutputDocumentPath10= +OutputVariantName10=[No Variations] +OutputDefault10=0 +OutputType11=Plane +OutputName11=Power-Plane Prints +OutputDocumentPath11= +OutputVariantName11=[No Variations] +OutputDefault11=0 +PageOptions11=Record=PageOptions|CenterHorizontal=True|CenterVertical=True|PrintScale=1.00|XCorrection=1.00|YCorrection=1.00|PrintKind=1|BorderSize=5000000|LeftOffset=0|BottomOffset=0|Orientation=2|PaperLength=1000|PaperWidth=1000|Scale=100|PaperSource=7|PrintQuality=-3|MediaType=1|DitherType=10|PrintScaleMode=1|PaperKind=Letter|PaperIndex=1 +OutputType12=Test Points +OutputName12=Test Point Report +OutputDocumentPath12= +OutputVariantName12= +OutputDefault12=0 + +[OutputGroup6] +Name=Report Outputs +Description= +TargetPrinter=\\NDG-PC-SVR-03\Brother DCP-L2540DW series +PrinterOptions=Record=PrinterOptions|Copies=1|Duplex=1|TrueTypeOptions=3|Collate=1|PrintJobKind=1|PrintWhat=1 +OutputType1=BOM_PartType +OutputName1=Bill of Materials +OutputDocumentPath1= +OutputVariantName1=[No Variations] +OutputDefault1=0 +PageOptions1=Record=PageOptions|CenterHorizontal=True|CenterVertical=True|PrintScale=1.00|XCorrection=1.00|YCorrection=1.00|PrintKind=1|BorderSize=5000000|LeftOffset=0|BottomOffset=0|Orientation=2|PaperLength=1000|PaperWidth=1000|Scale=100|PaperSource=7|PrintQuality=-3|MediaType=1|DitherType=10|PrintScaleMode=1|PaperKind=Letter|PaperIndex=1 +OutputType2=ComponentCrossReference +OutputName2=Component Cross Reference Report +OutputDocumentPath2= +OutputVariantName2=[No Variations] +OutputDefault2=0 +OutputType3=ReportHierarchy +OutputName3=Report Project Hierarchy +OutputDocumentPath3= +OutputVariantName3=[No Variations] +OutputDefault3=0 +OutputType4=Script +OutputName4=Script Output +OutputDocumentPath4= +OutputVariantName4=[No Variations] +OutputDefault4=0 +OutputType5=SimpleBOM +OutputName5=Simple BOM +OutputDocumentPath5= +OutputVariantName5=[No Variations] +OutputDefault5=0 +OutputType6=SinglePinNetReporter +OutputName6=Report Single Pin Nets +OutputDocumentPath6= +OutputVariantName6=[No Variations] +OutputDefault6=0 +OutputType7=BOM_ReportCompare +OutputName7=BOM Compare +OutputDocumentPath7= +OutputVariantName7=[No Variations] +OutputDefault7=0 +PageOptions7=Record=PageOptions|CenterHorizontal=True|CenterVertical=True|PrintScale=1.00|XCorrection=1.00|YCorrection=1.00|PrintKind=1|BorderSize=5000000|LeftOffset=0|BottomOffset=0|Orientation=2|PaperLength=1000|PaperWidth=1000|Scale=100|PaperSource=7|PrintQuality=-3|MediaType=1|DitherType=10|PrintScaleMode=1|PaperKind=Letter|PaperIndex=1 +OutputType8=Export Comments +OutputName8=Export Comments +OutputDocumentPath8= +OutputVariantName8=[No Variations] +OutputDefault8=0 +PageOptions8=Record=PageOptions|CenterHorizontal=True|CenterVertical=True|PrintScale=1.00|XCorrection=1.00|YCorrection=1.00|PrintKind=1|BorderSize=5000000|LeftOffset=0|BottomOffset=0|Orientation=2|PaperLength=1000|PaperWidth=1000|Scale=100|PaperSource=7|PrintQuality=-3|MediaType=1|DitherType=10|PrintScaleMode=1|PaperKind=Letter|PaperIndex=1 +OutputType9=Project History +OutputName9=Project History +OutputDocumentPath9= +OutputVariantName9=[No Variations] +OutputDefault9=0 +PageOptions9=Record=PageOptions|CenterHorizontal=True|CenterVertical=True|PrintScale=1.00|XCorrection=1.00|YCorrection=1.00|PrintKind=1|BorderSize=5000000|LeftOffset=0|BottomOffset=0|Orientation=2|PaperLength=1000|PaperWidth=1000|Scale=100|PaperSource=7|PrintQuality=-3|MediaType=1|DitherType=10|PrintScaleMode=1|PaperKind=Letter|PaperIndex=1 + +[OutputGroup7] +Name=Other Outputs +Description= +TargetPrinter=\\NDG-PC-SVR-03\Brother DCP-L2540DW series +PrinterOptions=Record=PrinterOptions|Copies=1|Duplex=1|TrueTypeOptions=3|Collate=1|PrintJobKind=1|PrintWhat=1 +OutputType1=Text Print +OutputName1=Text Print +OutputDocumentPath1= +OutputVariantName1= +OutputDefault1=0 +PageOptions1=Record=PageOptions|CenterHorizontal=True|CenterVertical=True|PrintScale=1.00|XCorrection=1.00|YCorrection=1.00|PrintKind=1|BorderSize=5000000|LeftOffset=0|BottomOffset=0|Orientation=2|PaperLength=1000|PaperWidth=1000|Scale=100|PaperSource=7|PrintQuality=-3|MediaType=1|DitherType=10|PrintScaleMode=1|PaperKind=Letter|PaperIndex=1 + +[OutputGroup8] +Name=Validation Outputs +Description= +TargetPrinter=\\NDG-PC-SVR-03\Brother DCP-L2540DW series +PrinterOptions=Record=PrinterOptions|Copies=1|Duplex=1|TrueTypeOptions=3|Collate=1|PrintJobKind=1|PrintWhat=1 +OutputType1=Component states check +OutputName1=Vault's components states check +OutputDocumentPath1= +OutputVariantName1= +OutputDefault1=0 +OutputType2=Configuration compliance +OutputName2=Environment configuration compliance check +OutputDocumentPath2= +OutputVariantName2= +OutputDefault2=0 +OutputType3=Design Rules Check +OutputName3=Design Rules Check +OutputDocumentPath3= +OutputVariantName3= +OutputDefault3=0 +PageOptions3=Record=PageOptions|CenterHorizontal=True|CenterVertical=True|PrintScale=1.00|XCorrection=1.00|YCorrection=1.00|PrintKind=1|BorderSize=5000000|LeftOffset=0|BottomOffset=0|Orientation=2|PaperLength=1000|PaperWidth=1000|Scale=100|PaperSource=7|PrintQuality=-3|MediaType=1|DitherType=10|PrintScaleMode=1|PaperKind=Letter|PaperIndex=1 +OutputType4=Differences Report +OutputName4=Differences Report +OutputDocumentPath4= +OutputVariantName4= +OutputDefault4=0 +PageOptions4=Record=PageOptions|CenterHorizontal=True|CenterVertical=True|PrintScale=1.00|XCorrection=1.00|YCorrection=1.00|PrintKind=1|BorderSize=5000000|LeftOffset=0|BottomOffset=0|Orientation=2|PaperLength=1000|PaperWidth=1000|Scale=100|PaperSource=7|PrintQuality=-3|MediaType=1|DitherType=10|PrintScaleMode=1|PaperKind=Letter|PaperIndex=1 +OutputType5=Electrical Rules Check +OutputName5=Electrical Rules Check +OutputDocumentPath5= +OutputVariantName5= +OutputDefault5=0 +PageOptions5=Record=PageOptions|CenterHorizontal=True|CenterVertical=True|PrintScale=1.00|XCorrection=1.00|YCorrection=1.00|PrintKind=1|BorderSize=5000000|LeftOffset=0|BottomOffset=0|Orientation=2|PaperLength=1000|PaperWidth=1000|Scale=100|PaperSource=7|PrintQuality=-3|MediaType=1|DitherType=10|PrintScaleMode=1|PaperKind=Letter|PaperIndex=1 +OutputType6=Footprint Comparison Report +OutputName6=Footprint Comparison Report +OutputDocumentPath6= +OutputVariantName6= +OutputDefault6=0 +OutputType7=BOM_Violations +OutputName7=BOM Checks Report +OutputDocumentPath7= +OutputVariantName7= +OutputDefault7=0 + +[OutputGroup9] +Name=Export Outputs +Description= +TargetPrinter=\\NDG-PC-SVR-03\Brother DCP-L2540DW series +PrinterOptions=Record=PrinterOptions|Copies=1|Duplex=1|TrueTypeOptions=3|Collate=1|PrintJobKind=1|PrintWhat=1 +OutputType1=AutoCAD dwg/dxf PCB +OutputName1=AutoCAD dwg/dxf File PCB +OutputDocumentPath1= +OutputVariantName1= +OutputDefault1=0 +OutputType2=AutoCAD dwg/dxf Schematic +OutputName2=AutoCAD dwg/dxf File Schematic +OutputDocumentPath2= +OutputVariantName2= +OutputDefault2=0 +OutputType3=ExportIDF +OutputName3=Export IDF +OutputDocumentPath3= +OutputVariantName3= +OutputDefault3=0 +OutputType4=ExportSTEP +OutputName4=Export STEP +OutputDocumentPath4= +OutputVariantName4=[No Variations] +OutputDefault4=0 +OutputType5=ExportPARASOLID +OutputName5=Export PARASOLID +OutputDocumentPath5= +OutputVariantName5=[No Variations] +OutputDefault5=0 +OutputType6=ExportVRML +OutputName6=Export VRML +OutputDocumentPath6= +OutputVariantName6=[No Variations] +OutputDefault6=0 +OutputType7=MBAExportPARASOLID +OutputName7=Export PARASOLID +OutputDocumentPath7= +OutputVariantName7= +OutputDefault7=0 +OutputType8=MBAExportSTEP +OutputName8=Export STEP +OutputDocumentPath8= +OutputVariantName8= +OutputDefault8=0 +OutputType9=Save As/Export PCB +OutputName9=Save As/Export PCB +OutputDocumentPath9= +OutputVariantName9= +OutputDefault9=0 +OutputType10=Save As/Export Schematic +OutputName10=Save As/Export Schematic +OutputDocumentPath10= +OutputVariantName10= +OutputDefault10=0 +OutputType11=Specctra Design PCB +OutputName11=Specctra Design PCB +OutputDocumentPath11= +OutputVariantName11= +OutputDefault11=0 +OutputType12=Web ReviewOutputName +OutputName12=Web Review Data +OutputDocumentPath12= +OutputVariantName12= +OutputDefault12=0 + +[OutputGroup10] +Name=PostProcess Outputs +Description= +TargetPrinter=\\NDG-PC-SVR-03\Brother DCP-L2540DW series +PrinterOptions=Record=PrinterOptions|Copies=1|Duplex=1|TrueTypeOptions=3|Collate=1|PrintJobKind=1|PrintWhat=1 +OutputType1=Copy Files +OutputName1=Copy Files +OutputDocumentPath1= +OutputVariantName1= +OutputDefault1=0 + +[Modification Levels] +Type1=1 +Type2=1 +Type3=1 +Type4=1 +Type5=1 +Type6=1 +Type7=1 +Type8=1 +Type9=1 +Type10=1 +Type11=1 +Type12=1 +Type13=1 +Type14=1 +Type15=1 +Type16=1 +Type17=1 +Type18=1 +Type19=1 +Type20=1 +Type21=1 +Type22=1 +Type23=1 +Type24=1 +Type25=1 +Type26=1 +Type27=1 +Type28=1 +Type29=1 +Type30=1 +Type31=1 +Type32=1 +Type33=1 +Type34=1 +Type35=1 +Type36=1 +Type37=1 +Type38=1 +Type39=1 +Type40=1 +Type41=1 +Type42=1 +Type43=1 +Type44=1 +Type45=1 +Type46=1 +Type47=1 +Type48=1 +Type49=1 +Type50=1 +Type51=1 +Type52=1 +Type53=1 +Type54=1 +Type55=1 +Type56=1 +Type57=1 +Type58=1 +Type59=1 +Type60=1 +Type61=1 +Type62=1 +Type63=1 +Type64=1 +Type65=1 +Type66=1 +Type67=1 +Type68=1 +Type69=1 +Type70=1 +Type71=1 +Type72=1 +Type73=1 +Type74=1 +Type75=1 +Type76=1 +Type77=1 +Type78=1 +Type79=1 +Type80=1 +Type81=1 +Type82=1 +Type83=1 +Type84=1 +Type85=1 +Type86=1 +Type87=1 +Type88=1 +Type89=1 +Type90=1 +Type91=1 +Type92=1 +Type93=1 +Type94=1 +Type95=1 +Type96=1 +Type97=1 +Type98=1 +Type99=1 +Type100=1 +Type101=1 +Type102=1 +Type103=1 +Type104=1 +Type105=1 +Type106=1 +Type107=1 +Type108=1 +Type109=1 +Type110=1 +Type111=1 +Type112=1 +Type113=1 +Type114=1 +Type115=1 +Type116=1 +Type117=1 +Type118=1 +Type119=1 +Type120=1 +Type121=1 +Type122=1 +Type123=1 +Type124=1 +Type125=1 +Type126=1 +Type127=1 +Type128=1 +Type129=1 +Type130=1 +Type131=1 +Type132=1 +Type133=1 +Type134=1 +Type135=1 +Type136=1 +Type137=1 +Type138=1 +Type139=1 +Type140=1 +Type141=1 +Type142=1 +Type143=1 +Type144=1 +Type145=1 +Type146=1 +Type147=1 +Type148=1 +Type149=1 +Type150=1 + +[Difference Levels] +Type1=1 +Type2=1 +Type3=1 +Type4=1 +Type5=1 +Type6=1 +Type7=1 +Type8=1 +Type9=1 +Type10=1 +Type11=1 +Type12=1 +Type13=1 +Type14=1 +Type15=1 +Type16=1 +Type17=1 +Type18=1 +Type19=1 +Type20=1 +Type21=1 +Type22=1 +Type23=1 +Type24=1 +Type25=1 +Type26=1 +Type27=1 +Type28=1 +Type29=1 +Type30=1 +Type31=1 +Type32=1 +Type33=1 +Type34=1 +Type35=1 +Type36=1 +Type37=1 +Type38=1 +Type39=1 +Type40=1 +Type41=1 +Type42=1 +Type43=1 +Type44=1 +Type45=1 +Type46=1 +Type47=1 +Type48=1 +Type49=1 +Type50=1 +Type51=1 +Type52=1 +Type53=1 +Type54=1 +Type55=1 +Type56=1 +Type57=1 +Type58=1 +Type59=1 +Type60=1 +Type61=1 +Type62=1 +Type63=1 +Type64=1 +Type65=1 +Type66=1 +Type67=1 +Type68=1 +Type69=1 +Type70=1 +Type71=1 +Type72=1 +Type73=1 +Type74=1 +Type75=1 +Type76=1 +Type77=1 +Type78=1 +Type79=1 +Type80=1 +Type81=1 + +[Electrical Rules Check] +Type1=1 +Type2=1 +Type3=2 +Type4=1 +Type5=2 +Type6=2 +Type7=0 +Type8=1 +Type9=1 +Type10=1 +Type11=2 +Type12=2 +Type13=2 +Type14=1 +Type15=1 +Type16=1 +Type17=1 +Type18=1 +Type19=1 +Type20=0 +Type21=0 +Type22=0 +Type23=0 +Type24=1 +Type25=2 +Type26=0 +Type27=2 +Type28=1 +Type29=1 +Type30=1 +Type31=1 +Type32=2 +Type33=0 +Type34=2 +Type35=1 +Type36=2 +Type37=1 +Type38=2 +Type39=2 +Type40=2 +Type41=0 +Type42=2 +Type43=1 +Type44=0 +Type45=0 +Type46=0 +Type47=0 +Type48=0 +Type49=0 +Type50=2 +Type51=0 +Type52=0 +Type53=1 +Type54=1 +Type55=1 +Type56=2 +Type57=1 +Type58=1 +Type59=2 +Type60=0 +Type61=0 +Type62=0 +Type63=0 +Type64=0 +Type65=2 +Type66=3 +Type67=2 +Type68=2 +Type69=2 +Type70=2 +Type71=2 +Type72=2 +Type73=2 +Type74=1 +Type75=2 +Type76=1 +Type77=1 +Type78=1 +Type79=1 +Type80=2 +Type81=3 +Type82=3 +Type83=3 +Type84=3 +Type85=3 +Type86=2 +Type87=2 +Type88=2 +Type89=1 +Type90=1 +Type91=3 +Type92=3 +Type93=2 +Type94=2 +Type95=2 +Type96=2 +Type97=2 +Type98=0 +Type99=1 +Type100=2 +Type101=0 +Type102=2 +Type103=2 +Type104=1 +Type105=2 +Type106=2 +Type107=2 +Type108=2 +Type109=1 +Type110=1 +Type111=1 +Type112=1 +Type113=1 +Type114=2 +Type115=2 +Type116=2 +Type117=3 +Type118=3 +Type119=3 +MultiChannelAlternate=0 +AlternateItemFail=3 +Type122=2 +Type123=1 +Type124=1 +Type125=1 +Type126=1 +Type127=1 +Type128=2 +Type129=2 +Type130=2 +Type131=2 +Type132=2 +Type133=2 +Type134=2 +Type135=2 +Type136=2 +Type137=2 +Type138=1 +Type139=1 +Type140=1 +Type141=1 +Type142=1 +Type143=1 +Type144=1 +Type145=1 +Type146=1 +Type147=2 +Type148=2 +Type149=2 +Type150=2 +Type151=2 +Type152=1 +Type153=1 +Type154=0 + +[ERC Connection Matrix] +L1=NNNNNNNNNNNWNNNWW +L2=NNWNNNNWWWNWNWNWN +L3=NWEENEEEENEWNEEWN +L4=NNENNNWEENNWNENWN +L5=NNNNNNNNNNNNNNNNN +L6=NNENNNNEENNWNENWN +L7=NNEWNNWEENNWNENWN +L8=NWEENEENEEENNEENN +L9=NWEENEEEENEWNEEWW +L10=NWNNNNNENNEWNNEWN +L11=NNENNNNEEENWNENWN +L12=WWWWNWWNWWWNWWWNN +L13=NNNNNNNNNNNWNNNWW +L14=NWEENEEEENEWNEEWW +L15=NNENNNNEEENWNENWW +L16=WWWWNWWNWWWNWWWNW +L17=WNNNNNNNWNNNWWWWN + +[Annotate] +SortOrder=3 +SortLocation=0 +ReplaceSubparts=0 +MatchParameter1=Comment +MatchStrictly1=1 +MatchParameter2=Library Reference +MatchStrictly2=1 +PhysicalNamingFormat=$Component_$RoomName +GlobalIndexSortOrder=3 +GlobalIndexSortLocation=0 + +[PrjClassGen] +CompClassManualEnabled=0 +CompClassManualRoomEnabled=0 +NetClassAutoBusEnabled=1 +NetClassAutoCompEnabled=0 +NetClassAutoNamedHarnessEnabled=0 +NetClassManualEnabled=1 +NetClassSeparateForBusSections=0 + +[LibraryUpdateOptions] +SelectedOnly=0 +UpdateVariants=1 +UpdateToLatestRevision=1 +PartTypes=0 +FullReplace=1 +UpdateDesignatorLock=1 +UpdatePartIDLock=1 +PreserveParameterLocations=1 +PreserveParameterVisibility=1 +DoGraphics=1 +DoParameters=1 +DoModels=1 +AddParameters=0 +RemoveParameters=0 +AddModels=1 +RemoveModels=1 +UpdateCurrentModels=1 + +[DatabaseUpdateOptions] +SelectedOnly=0 +UpdateVariants=1 +UpdateToLatestRevision=1 +PartTypes=0 + +[Comparison Options] +ComparisonOptions0=Kind=Net|MinPercent=75|MinMatch=3|ShowMatch=-1|UseName=-1|InclAllRules=0 +ComparisonOptions1=Kind=Net Class|MinPercent=75|MinMatch=3|ShowMatch=-1|UseName=-1|InclAllRules=0 +ComparisonOptions2=Kind=Component Class|MinPercent=75|MinMatch=3|ShowMatch=-1|UseName=-1|InclAllRules=0 +ComparisonOptions3=Kind=Rule|MinPercent=75|MinMatch=3|ShowMatch=-1|UseName=-1|InclAllRules=0 +ComparisonOptions4=Kind=Differential Pair|MinPercent=50|MinMatch=1|ShowMatch=0|UseName=0|InclAllRules=0 +ComparisonOptions5=Kind=Structure Class|MinPercent=75|MinMatch=3|ShowMatch=-1|UseName=-1|InclAllRules=0 + +[SmartPDF] +PageOptions=Record=PageOptions|CenterHorizontal=True|CenterVertical=True|PrintScale=1.00|XCorrection=1.00|YCorrection=1.00|PrintKind=1|BorderSize=5000000|LeftOffset=0|BottomOffset=0|Orientation=2|PaperLength=1000|PaperWidth=1000|Scale=100|PaperSource=7|PrintQuality=-3|MediaType=1|DitherType=10|PrintScaleMode=1|PaperKind=Letter|PaperIndex=1 + diff --git a/Scripts - PCB/DiffPairFinder/DiffPair_Finder.dfm b/Scripts - PCB/DiffPairFinder/DiffPair_Finder.dfm new file mode 100644 index 00000000..099bc689 --- /dev/null +++ b/Scripts - PCB/DiffPairFinder/DiffPair_Finder.dfm @@ -0,0 +1,79 @@ +object Form1: TForm1 + Left = 0 + Top = 0 + Caption = 'Differential Pair Finder' + ClientHeight = 679 + ClientWidth = 930 + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + OldCreateOrder = False + DesignSize = ( + 930 + 679) + PixelsPerInch = 96 + TextHeight = 13 + object Label1: TLabel + Left = 8 + Top = 608 + Width = 166 + Height = 13 + Caption = 'Hold SHIFT to select multiple pairs.' + end + object StringGrid: TStringGrid + Left = 8 + Top = 8 + Width = 912 + Height = 592 + Anchors = [akLeft, akTop, akRight] + ColCount = 3 + DefaultColWidth = 300 + Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goRangeSelect, goColSizing, goRowSelect, goFixedColClick] + ScrollBars = ssVertical + TabOrder = 0 + ColWidths = ( + 300 + 300 + 300) + RowHeights = ( + 24 + 24 + 24 + 24 + 24) + end + object btnAddDiffPairs: TButton + Left = 744 + Top = 640 + Width = 176 + Height = 25 + Anchors = [akRight, akBottom] + Caption = 'Add Selected To DiffPair Class' + TabOrder = 1 + OnClick = btnAddDiffPairsClick + end + object cbDiffPairClasses: TComboBox + Left = 744 + Top = 608 + Width = 177 + Height = 21 + Anchors = [akRight, akBottom] + TabOrder = 2 + Text = 'Select DiffPair Class' + end + object cbHideExisting: TCheckBox + Left = 8 + Top = 648 + Width = 97 + Height = 17 + Anchors = [akLeft, akBottom] + Caption = 'Hide Existing' + Checked = True + State = cbChecked + TabOrder = 3 + OnClick = cbHideExistingClick + end +end diff --git a/Scripts - PCB/DiffPairFinder/DiffPair_Finder.pas b/Scripts - PCB/DiffPairFinder/DiffPair_Finder.pas new file mode 100644 index 00000000..6fa2c962 --- /dev/null +++ b/Scripts - PCB/DiffPairFinder/DiffPair_Finder.pas @@ -0,0 +1,1180 @@ +// References: Altium Examples CreateAVia.pas +// PCB_Class_Generator_Form.pas +// ChatGPT 4o + +var + Board : IPCB_Board; + GlbDiffPairs : TStringList; + +Function DiffPolarity(txt: String): Integer; +var + polarity : Integer; + t : String; + isIn : Boolean; +Begin + result := 0; + + t := LowerCase(txt); + + // If Else to Force priority ordering + If AnsiEndsStr('_dp', t) Then + Begin + result := 1; + End + Else If AnsiEndsStr('_dn', t) Then + Begin + result := -1; + End + Else If AnsiEndsStr('_dm', t) Then + Begin + result := -1; + End + Else If AnsiEndsStr('-dp', t) Then + Begin + result := 1; + End + Else If AnsiEndsStr('-dn', t) Then + Begin + result := -1; + End + Else If AnsiEndsStr('-dm', t) Then + Begin + result := -1; + End + Else If AnsiEndsStr('_p', t) Then + Begin + result := 1; + End + Else If AnsiEndsStr('_n', t) Then + Begin + result := -1; + End + Else If AnsiEndsStr('-p', t) Then + Begin + result := 1; + End + Else If AnsiEndsStr('-n', t) Then + Begin + result := -1; + End + Else If AnsiEndsStr('dp', t) Then + Begin + result := 1; + End + Else If AnsiEndsStr('dn', t) Then + Begin + result := -1; + End + Else If AnsiEndsStr('dm', t) Then + Begin + result := -1; + End + Else If AnsiEndsStr('_h', t) Then + Begin + result := 1; + End + Else If AnsiEndsStr('_l', t) Then + Begin + result := -1; + End + Else If AnsiEndsStr('-h', t) Then + Begin + result := 1; + End + Else If AnsiEndsStr('-l', t) Then + Begin + result := -1; + End + Else If AnsiEndsStr('+', t) Then + Begin + result := 1; + End + Else If AnsiEndsStr('-', t) Then + Begin + result := -1; + End + Else If ContainsText(t, '_dp') Then + Begin + result := 1; + End + Else If ContainsText(t, '_dn') Then + Begin + result := -1; + End + Else If ContainsText(t, '_dm') Then + Begin + result := -1; + End + Else If ContainsText(t, '-dp') Then + Begin + result := 1; + End + Else If ContainsText(t, '-dn') Then + Begin + result := -1; + End + Else If ContainsText(t, '-dm') Then + Begin + result := -1; + End + Else If ContainsText(t, '_p') Then + Begin + result := 1; + End + Else If ContainsText(t, '_n') Then + Begin + result := -1; + End + Else If ContainsText(t, '-p') Then + Begin + result := 1; + End + Else If ContainsText(t, '-n') Then + Begin + result := -1; + End + Else If ContainsText(t, '+') And Not(AnsiStartsStr('+', t)) Then + Begin + result := 1; + End + Else If ContainsText(t, 'dp') And Not(AnsiStartsStr('dp', t)) Then + Begin + result := 1; + End + Else If ContainsText(t, 'dn') And Not(AnsiStartsStr('dn', t)) Then + Begin + result := -1; + End + Else If ContainsText(t, 'dm') And Not(AnsiStartsStr('dm', t)) Then + Begin + result := -1; + End + Else If ContainsText(t, 'p_') Then + Begin + result := 1; + End + Else If ContainsText(t, 'n_') Then + Begin + result := -1; + End + Else If ContainsText(t, '_h') Then + Begin + result := 1; + End + Else If ContainsText(t, '_l') Then + Begin + result := -1; + End + Else If ContainsText(t, '-h') Then + Begin + result := 1; + End + Else If ContainsText(t, '-l') Then + Begin + result := -1; + End + Else If ContainsText(t, 'h_') Then + Begin + result := 1; + End + Else If ContainsText(t, 'l_') Then + Begin + result := -1; + End + Else If ContainsText(t, 'p-') Then + Begin + result := 1; + End + Else If ContainsText(t, 'n-') Then + Begin + result := -1; + End + Else If ContainsText(t, 'h-') Then + Begin + result := 1; + End + Else If ContainsText(t, 'l-') Then + Begin + result := -1; + End; +End; + +Function IsPotentialDiffPair(txt: String): Boolean; +var + polarity : Integer; + t : String; + isIn : Boolean; +Begin + result := False; + + t := LowerCase(txt); + + if Not(AnsiStartsStr('net', t)) and (txt <> 'gnd') then + Begin + polarity := DiffPolarity(txt); + if (polarity = -1) or (polarity = 1) then + begin + result := True; + end; + End; +End; + +Function GetAllPinsSortedByComponent(Dummy): TStringList; // Dummy hides visibility. Use Nil in call. +Var + Iterator : IPCB_BoardIterator; + GrpIter : IPCB_GroupIterator; + Cmp : IPCB_Component; + Pad : IPCB_Pad; + cmps : TStringList; + CmpDes, NetName, PinDes, Value, FirstEntry : String; +Begin + cmps := TStringList.Create; + cmps.NameValueSeparator := '='; + + Iterator := Board.BoardIterator_Create; + Iterator.AddFilter_ObjectSet(MkSet(eComponentObject)); + Iterator.AddFilter_IPCB_LayerSet(LayerSet.AllLayers); + Iterator.AddFilter_Method(eProcessAll); + + Cmp := Iterator.FirstPCBObject; + While (Cmp <> Nil) Do + Begin + CmpDes := Cmp.Name.Text; + + FirstEntry := ''; + + GrpIter := Cmp.GroupIterator_Create; + GrpIter.SetState_FilterAll; + GrpIter.AddFilter_ObjectSet(MkSet(ePadObject)); + + Pad := GrpIter.FirstPCBObject; + While Pad <> Nil Do + Begin + If Pad.InComponent Then + Begin + If Pad.Net <> Nil Then + Begin + NetName := Pad.Net.Name; + Value := cmps.Values[CmpDes]; + + // If NetName not already in list and is a potential DiffPair + If Not(ContainsText(FirstEntry+Value, NetName)) And IsPotentialDiffPair(NetName) Then + Begin + + // If CmpDes Key already exists + If cmps.IndexOfName(CmpDes) >= 0 Then + Begin + cmps.Values[CmpDes] := Value + ';' + NetName; + End + // If Key doesn't exist, but this is the first entry, don't add because we don't want single net entries + Else If FirstEntry = '' Then + Begin + //cmps.Add(CmpDes + '=' + NetName); + FirstEntry := CmpDes + '=' + NetName; + End + // Once we have at least 2 nets ready to add then add first entry at CmpDes Key + // After this, the key will exist so only the first if should be valid + Else + Begin + cmps.Add(FirstEntry + ';' + NetName); + End; + + End; + End; + End; + + Pad := GrpIter.NextPCBObject; + End; + Cmp.GroupIterator_Destroy(GrpIter); + + Cmp := Iterator.NextPCBObject; + End; + + Board.BoardIterator_Destroy(Iterator); + + result := cmps; +End; + +function AlphaOnly(const InputStr: String): String; +var + I: Integer; +begin + Result := ''; + // Iterate through each character in the input string + for I := 1 to Length(InputStr) do + begin + // Check if the character is alphabetic (A-Z, a-z) + if ((InputStr[I] >= 'A') and (InputStr[I] <= 'Z')) or + ((InputStr[I] >= 'a') and (InputStr[I] <= 'z')) then + begin + Result := Result + InputStr[I]; // Add the character to the result + end; + end; +end; + +function IsNonAlphaNumeric(const Ch: Char): Boolean; +begin + // Check if the character is not alphanumeric + Result := not ((Ch >= '0') and (Ch <= '9') or + (Ch >= 'A') and (Ch <= 'Z') or + (Ch >= 'a') and (Ch <= 'z')); +end; + +function TrimNonAlphaNumeric(const InputStr: String): String; +var + Len: Integer; +begin + Result := InputStr; + Len := Length(Result); + + // Loop to remove non-alphanumeric characters from the end + while (Len > 0) and IsNonAlphaNumeric(Result[Len]) do + begin + Delete(Result, Len, 1); // Remove the last character + Len := Len - 1; // Update the length + end; +end; + +Function IsOffByNChar(txt1: String, txt2: String, n: Integer, var diffName : String): Boolean; +Var + i, matchCnt, digCnt : Integer; + ch1, ch2, prev : Char; + ch1Valid, ch2Valid: Boolean; +Begin + result := False; + ch1Valid := False; + ch2Valid := False; + diffName := ''; + + matchCnt := 0; + digCnt := 0; + For i := 1 to Length(txt1) Do + Begin + ch1 := LowerCase(txt1[i]); + ch2 := LowerCase(txt2[i]); + + If ch1 = ch2 Then + Begin + Inc(matchCnt); + If Not(IsNonAlphaNumeric(ch1) And IsNonAlphaNumeric(prev)) Then + Begin + diffName := diffName+ch1; + prev := ch1; + End; + End + Else + Begin + If (ch1 = 'p') or (ch1 = 'n') or (ch1 = 'm') or (ch1 = '+') or (ch1 = '-') or (ch1 = 'h') or (ch1 = 'l') Then ch1Valid := True; + If (ch2 = 'p') or (ch2 = 'n') or (ch2 = 'm') or (ch2 = '+') or (ch2 = '-') or (ch2 = 'h') or (ch2 = 'l') Then ch2Valid := True; + End; + + End; + + + + if (matchCnt >= Length(txt1)-n) and ch1Valid and ch2Valid Then + Begin + result := True; + End; + + diffName := UpperCase(TrimNonAlphaNumeric(diffName)); +End; + +Function CompareSameLenNets(matches: TStringList, cnts: TStringList): TStringList; +Var + cnt, viewed : TStringList; + i, j, cntIdx, cntsLen, cntLen, polarity: Integer; + net1, net2, diffName : String; + IsMatch : Boolean; +Begin + cnt := TStringList.Create; + cnt.Delimiter := ';'; + cnt.StrictDelimiter := True; + + viewed := TStringList.Create; + viewed.Sorted := True; + viewed.Duplicates := dupIgnore; + + cntsLen := cnts.Count; + + for cntIdx := 0 to cnts.Count-1 do + begin + cnt.DelimitedText := cnts.ValueFromIndex[cntIdx]; + + if cnt.Count <= 1 then continue; + + for i := 0 to cnt.Count - 1 do + begin + net1 := cnt[i]; + + for j := 0 to cnt.Count - 1 do + begin + + // Don't compare the same net against itself + if i <> j then + begin + net2 := cnt[j]; + + // previously viewed can be skipped + if viewed.IndexOf(net1 + net2) = -1 then + begin + IsMatch := IsOffByNChar(net1, net2, 1, diffName); + + If IsMatch Then + Begin + polarity := DiffPolarity(net1); + if polarity = 1 then + begin + matches.Add(diffName+'='+net1+';'+net2); + end + else + begin + matches.Add(diffName+'='+net2+';'+net1); + end; + End; + + viewed.Add(net1+net2); + viewed.Add(net2+net1); + end; + end; + end; + end; + viewed.Clear; + end; + + cnt.Free; + viewed.Free; +End; + +Function FindDiffPairCandidates(cmps: TStringList): TStringList; +Const + pIdx = 0; + nIdx = 1; +Var + pinStr, netStr, cmpDes: String; + cmpIdx, netIdx, pinsCnt, pinCnt, len: Integer; + nets, cnts, tmp, matches: TStringList; + doCompare : Boolean; +Begin + nets := TStringList.Create; + nets.Delimiter := ';'; + nets.StrictDelimiter := True; + + tmp := TStringList.Create; + tmp.Delimiter := ';'; + tmp.StrictDelimiter := True; + + cnts := TStringList.Create; + cnts.NameValueSeparator := '='; + + matches := TStringList.Create; + matches.Sorted := True; + matches.Duplicates := dupIgnore; + matches.NameValueSeparator := '='; + + // Build a dictionary of dict[StringLength] = DelimitedNetList + // For each component, build a cnts dictionary that holds the length of + // each string as a key + for cmpIdx := 0 to cmps.Count-1 do + begin + nets.DelimitedText := cmps.ValueFromIndex[cmpIdx]; + + doCompare := False; // Reset for each component + + for netIdx := 0 to nets.Count - 1 do + begin + netStr := nets[netIdx]; + + // Filter out all other nets for speed + If IsPotentialDiffPair(netStr) Then + Begin + len := IntToStr(Length(netStr)); + + If cnts.IndexOfName(len) >= 0 Then + Begin + tmp.DelimitedText := cnts.Values[len]; + If tmp.IndexOf(netStr) = -1 Then + Begin + cnts.Values[len] := cnts.Values[len] + ';' + netStr; + doCompare := True; // There is at least one set of matching lengths worth checking + End; + End + Else + Begin + cnts.Add(len + '=' + netStr); + End; + + End; + + end; + + If doCompare Then CompareSameLenNets(matches, cnts); // Iterate Same Length Strings and compare + cnts.Clear; + end; + + nets.Free; + cnts.Free; + tmp.Free; + + result := matches; +End; + +Function GetNetObject(NetName: String): IPCB_Net; +Var + Iterator : IPCB_BoardIterator; + Net : IPCB_Net; +Begin + result := Nil; + + Iterator := Board.BoardIterator_Create; + Iterator.AddFilter_ObjectSet(MkSet(eNetObject)); + Iterator.AddFilter_LayerSet(AllLayers); + Iterator.AddFilter_Method(eProcessAll); + + Net := Iterator.FirstPCBObject; + While (Net <> Nil) Do + Begin + If Net.Name = NetName Then + Begin + result := Net; + Break; + End; + + Net := Iterator.NextPCBObject; + End; + Board.BoardIterator_Destroy(Iterator); +End; + +Function GetExistingDiffPairs(Dummy): TStringList; +Var + Iterator : IPCB_BoardIterator; + Existing : TStringList; + Diff : IPCB_DifferentialPair; +Begin + Existing := TStringList.Create; + + Iterator := Board.BoardIterator_Create; + Iterator.AddFilter_ObjectSet(MkSet(eDifferentialPairObject)); + Iterator.AddFilter_LayerSet(AllLayers); + Iterator.AddFilter_Method(eProcessAll); + + Diff := Iterator.FirstPCBObject; + While (Diff <> Nil) Do + Begin + If (Diff.PositiveNet <> Nil) And (Diff.NegativeNet <> Nil) Then + Begin + Existing.Add(LowerCase(Diff.PositiveNet.Name)); + Existing.Add(LowerCase(Diff.NegativeNet.Name)); + End; + + Diff := Iterator.NextPCBObject; + End; + Board.BoardIterator_Destroy(Iterator); + + result := Existing; +End; + +Function AddDiffPairClass(ClassName: String): IPCB_ObjectClass; +Var + DiffClass : IPCB_ObjectClass; +Begin + PCBServer.PreProcess; // Initialize the systems in the PCB Editor. + + DiffClass := PCBServer.PCBClassFactoryByClassMember(eClassMemberKind_DifferentialPair); + DiffClass.SuperClass := False; + DiffClass.Name := ClassName; + + Board.AddPCBObject(DiffClass); + + // Update the Undo System in DXP that a new object has been added to the board + PCBServer.SendMessageToRobots(Board .I_ObjectAddress, c_Broadcast, PCBM_BoardRegisteration, DiffClass.I_ObjectAddress); + + PCBServer.PostProcess; // Finalize the systems in the PCB Editor. + + result := DiffClass; +End; + +Function AddDiffPair(DiffClass: IPCB_ObjectClass, ExistingPairs: TStringList, DiffPairName: String, PositiveNet: String, NegativeNet: String); +Var + DiffPair : IPCB_DifferentialPair; + pLow, nLow : String; + pGood, nGood : Boolean; +Begin + + // Check if Diff pair positive or negative net name already exists + If (ExistingPairs.IndexOf(LowerCase(PositiveNet)) <> -1) Or (ExistingPairs.IndexOf(LowerCase(NegativeNet)) <> -1) Then Exit; + + PCBServer.PreProcess; // Initialize the systems in the PCB Editor. + + DiffPair := PCBServer.PCBObjectFactory(eDifferentialPairObject, eNoDimension, eCreate_Default); + + DiffPair.PositiveNet := GetNetObject(PositiveNet); + DiffPair.NegativeNet := GetNetObject(NegativeNet); + + DiffPair.Name := DiffPairName; + + Board.AddPCBObject(DiffPair); + + // Update the Undo System in DXP that a new object has been added to the board + PCBServer.SendMessageToRobots(Board .I_ObjectAddress, c_Broadcast, PCBM_BoardRegisteration, DiffPair.I_ObjectAddress); + + // Class was specified, add to specific class. + If DiffClass <> Nil Then + Begin + DiffClass.AddMemberByName(DiffPair.Name); + End; + + PCBServer.PostProcess; // Finalize the systems in the PCB Editor. +End; + +Function AddDiffPairs(DiffClass: IPCB_ObjectClass, diffs: TStringList); +Const + pIdx = 0; + nIdx = 1; +Var + i, pairCnt : Integer; + pair, existingPairs : TStringList; + diffName, pStr, nStr, pairStr : String; +Begin + pair := TStringList.Create; + pair.Delimiter := ';'; + pair.StrictDelimiter := True; + + existingPairs := GetExistingDiffPairs(Nil); // Get existing differential pairs + + For i := 0 to diffs.Count - 1 do + Begin + diffName := diffs.Names[i]; + pairStr := diffs.ValueFromIndex[i]; + pair.DelimitedText := pairStr; + + pairCnt := pair.Count; + + if pairCnt = 2 Then + Begin + pStr := pair[pIdx]; + nStr := pair[nIdx]; + + AddDiffPair(DiffClass, existingPairs, diffName, pStr, nStr); + + existingPairs.Add(LowerCase(pStr)); + existingPairs.Add(LowerCase(nStr)); + End; + End; + + existingPairs.Free; +End; + +Function ValidComponent(Cmp: IPCB_Component, NetName: String): Boolean; +Var + GrpIter : IPCB_GroupIterator; + Pad : IPCB_Pad; + Cnt : Integer; + HasNet : Boolean; +Begin + result := False; + HasNet := False; + + GrpIter := Cmp.GroupIterator_Create; + GrpIter.SetState_FilterAll; + GrpIter.AddFilter_ObjectSet(MkSet(ePadObject)); + + Cnt := 0; + + Pad := GrpIter.FirstPCBObject; + While Pad <> Nil Do + Begin + If (Pad.InComponent) And (Pad.Net <> Nil) Then + Begin + Inc(Cnt); + + If LowerCase(Pad.Net.Name) = LowerCase(NetName) Then HasNet := True; + + If Cnt > 2 Then Break; + End; + + Pad := GrpIter.NextPCBObject; + End; + Cmp.GroupIterator_Destroy(GrpIter); + + If (Cnt = 2) And (HasNet) Then result := True; +End; + +Function GetConnectedNetName(Cmp: IPCB_Component, NetName: String): String; +Var + GrpIter : IPCB_GroupIterator; + Pad : IPCB_Pad; + conName, CmpDes : String; +Begin + result := ''; + + CmpDes := Cmp.Name.Text; + + GrpIter := Cmp.GroupIterator_Create; + GrpIter.SetState_FilterAll; + GrpIter.AddFilter_ObjectSet(MkSet(ePadObject)); + + Pad := GrpIter.FirstPCBObject; + While Pad <> Nil Do + Begin + If Pad.InComponent Then + Begin + If Pad.Net <> Nil Then + Begin + conName := Pad.Net.Name; + If (LowerCase(conName) <> LowerCase(NetName)) And Not(ContainsText(LowerCase(conName), 'gnd')) Then + Begin + result := conName; + Exit; + End; + End; + End; + + Pad := GrpIter.NextPCBObject; + End; + Cmp.GroupIterator_Destroy(GrpIter); +End; + +Function IsConnectedDiffPair(cwn: TStringList, pStr: String, nStr: String, var pCon: String, var nCon: String): Boolean; +Var + Iterator : IPCB_BoardIterator; + Cmp : IPCB_Component; + inCmps : TStringList; + CmpDes, test : String; + i : Integer; +Begin + inCmps := TStringList.Create; + + result := False; + pCon := ''; + nCon := ''; + + If (cwn.IndexOfName(pStr) = -1) or (cwn.IndexOfName(nStr) = -1) Then Exit; + + inCmps.DelimitedText := cwn.Values[pStr]; + // TODO: How to handle if net has multiple connected R's or C's? + if inCmps.Count > 1 then + begin + ShowMessage(pStr + ' is connected to ' + IntToStr(inCmps.Count) + '2-pin components. Skipping...'); + Exit; + end; + + for i:=0 to inCmps.Count - 1 do + begin + CmpDes := inCmps[i]; + Cmp := Board.GetPcbComponentByRefDes(CmpDes); + + pCon := GetConnectedNetName(Cmp, pStr); + If pCon <> '' Then Break; + end; + + inCmps.DelimitedText := cwn.Values[nStr]; + for i:=0 to inCmps.Count - 1 do + begin + CmpDes := inCmps[i]; + Cmp := Board.GetPcbComponentByRefDes(CmpDes); + + nCon := GetConnectedNetName(Cmp, pStr); + If nCon <> '' Then Break; + end; + + inCmps.Free; + + If (pCon <> '') And (nCon <> '') Then + Begin + result := True; + End; + + Board.BoardIterator_Destroy(Iterator); +End; + +function RemovePrefix(const InputStr, Prefix: String): String; +var + LowerInput, LowerPrefix: String; +begin + // Convert both the input string and the prefix to lowercase for case-insensitive comparison + LowerInput := AnsiLowerCase(InputStr); + LowerPrefix := AnsiLowerCase(Prefix); + + // Check if the input string starts with the specified prefix + if Copy(LowerInput, 1, Length(LowerPrefix)) = LowerPrefix then + Result := Copy(InputStr, Length(LowerPrefix) + 1, Length(InputStr)) + else + Result := InputStr; // Return the original string if no match +end; + +Function FlattenDiffsToNetList(diffs: TStringList): TStringList; +Const + pIdx = 0; + nIdx = 1; +Var + i, pairCnt : Integer; + pair, flat : TStringList; + pairStr : String; +Begin + flat := TStringList.Create; + flat.Delimiter := ','; + flat.StrictDelimiter := True; + + pair := TStringList.Create; + pair.Delimiter := ';'; + pair.StrictDelimiter := True; + + For i := 0 to diffs.Count - 1 do + Begin + pairStr := diffs.ValueFromIndex[i]; + pair.DelimitedText := pairStr; + + pairCnt := pair.Count; + + if pairCnt = 2 Then + Begin + flat.Add(pair[pIdx]); + flat.Add(pair[nIdx]); + End; + End; + + result := flat; +End; + +Function CreateCmpsWithNetsList(nets: TStringList): TStringList; +Var + Iterator : IPCB_BoardIterator; + GrpIter : IPCB_GroupIterator; + Cmp : IPCB_Component; + Pad : IPCB_Pad; + cwn : TStringList; + CmpDes : String; +Begin + cwn := TStringList.Create; + cwn.Duplicates := dupIgnore; + cwn.NameValueSeparator := '='; + + Iterator := Board.BoardIterator_Create; + Iterator.AddFilter_ObjectSet(MkSet(eComponentObject)); + Iterator.AddFilter_IPCB_LayerSet(LayerSet.AllLayers); + Iterator.AddFilter_Method(eProcessAll); + + Cmp := Iterator.FirstPCBObject; + While (Cmp <> Nil) Do + Begin + CmpDes := Cmp.Name.Text; + + // Only consider Resistors and Capacitors + If AnsiStartsStr('R', CmpDes) Or AnsiStartsStr('C', CmpDes) Then + Begin + GrpIter := Cmp.GroupIterator_Create; + GrpIter.SetState_FilterAll; + GrpIter.AddFilter_ObjectSet(MkSet(ePadObject)); + + Pad := GrpIter.FirstPCBObject; + While Pad <> Nil Do + Begin + If Pad.InComponent Then + Begin + If Pad.Net <> Nil Then + Begin + If nets.IndexOf(Pad.Net.Name) >= 0 Then + Begin + cwn.Add(Pad.Net.Name+'='+CmpDes); + End; + End; + End; + + Pad := GrpIter.NextPCBObject; + End; + Cmp.GroupIterator_Destroy(GrpIter); + End; + + Cmp := Iterator.NextPCBObject; + End; + Board.BoardIterator_Destroy(Iterator); + + result := cwn; +End; + +Function GetConnectedDiffPairs(diffs: TStringList, alreadyFound: TStringList): TStringList; +Const + pIdx = 0; + nIdx = 1; +Var + i, pairCnt : Integer; + pair, cwn, newDiffs : TStringList; + diffName, conName, pStr, nStr, pairStr, pConnect, nConnect, suffix : String; +Begin + newDiffs := TStringList.Create; + + pair := TStringList.Create; + pair.Delimiter := ';'; + pair.StrictDelimiter := True; + + cwn := CreateCmpsWithNetsList(alreadyFound); // Components with nets + + For i := 0 to diffs.Count - 1 do + Begin + diffName := diffs.Names[i]; + pairStr := diffs.ValueFromIndex[i]; + pair.DelimitedText := pairStr; + + pairCnt := pair.Count; + + if pairCnt = 2 Then + Begin + pStr := pair[pIdx]; + nStr := pair[nIdx]; + + If IsConnectedDiffPair(cwn, pStr, nStr, pConnect, nConnect) Then + Begin + // New name is old name + designator prefix, unless that already exists, then it is full refDes + suffix := RemovePrefix(pConnect, 'net'); + conName := diffName + '-' + AlphaOnly(suffix); + If (diffs.IndexOf(conName) <> -1) or (newDiffs.IndexOf(conName) <> -1) Then conName := diffName + '-' + suffix; + + If (alreadyFound.IndexOf(pConnect) = -1) and (alreadyFound.IndexOf(nConnect) = -1) Then + Begin + newDiffs.Add(conName+'='+pConnect+';'+nConnect); + + alreadyFound.Add(pConnect); + alreadyFound.Add(nConnect); + End; + End; + End; + End; + + result := newDiffs; +End; + +Procedure AddDiffPairClassesToComboBox(Dummy); +Var + i : Integer; + ClassIterator : IPCB_BoardIterator; + ClassList : TStringList; + DiffClass : IPCB_ObjectClass; + Name : String; +Begin + ClassList := TStringList.Create; + + ClassIterator := Board.BoardIterator_Create; + ClassIterator.SetState_FilterAll; + ClassIterator.AddFilter_ObjectSet(MkSet(eClassObject)); + DiffClass := ClassIterator.FirstPCBObject; + i := 0; + While DiffClass <> Nil Do + Begin + Inc(i); + If DiffClass.MemberKind = eClassMemberKind_DifferentialPair Then + Begin + Name := DiffClass.Name; + //cbDiffPairClasses.items.AddObject(DiffClass.Name, DiffClass); + cbDiffPairClasses.AddItem(DiffClass.Name, DiffClass); + //IPCB_ObjectClass.MemberName[0]; + ClassList.Add(DiffClass.Name); + End; + DiffClass := ClassIterator.NextPCBObject; + End; + cbDiffPairClasses.SetItemIndex(0); + Board.BoardIterator_Destroy(ClassIterator); +End; + +procedure ResetStringGrid(Grid: TStringGrid); +var + Row, Col: Integer; +begin + // Clear all cell contents + for Row := 0 to Grid.RowCount - 1 do + for Col := 0 to Grid.ColCount - 1 do + Grid.Cells[Col, Row] := ''; + + // Reset the grid dimensions + Grid.RowCount := 1; // Keep only one row + Grid.ColCount := 1; // Keep only one column + + // Optionally, reset headers if needed + Grid.Cells[0, 0] := ''; // Clear the header cell or set initial text +end; + +Function AddKeysToStringGrid(list: TStringList, HideExisting: Boolean); +Var + i, RowIdx : Integer; + DiffPairName, pStr, nStr : String; + Row, existing: TStringList; +Begin + Row := TStringList.Create; + Row.Delimiter := ';'; + + existing := GetExistingDiffPairs(Nil); + + // Start adding from the last row + RowIdx := StringGrid.RowCount; // Get current row count + + For i := 0 to list.Count - 1 do + begin + Row.DelimitedText := list.ValueFromIndex[i]; + DiffPairName := list.Names[i]; + pStr := LowerCase(Row[0]); + nStr := LowerCase(Row[1]); + + If (HideExisting) And ((existing.IndexOf(pStr) <> -1) Or (existing.IndexOf(nStr) <> -1)) Then continue; + + // Add a new row if necessary + if RowIdx >= StringGrid.RowCount then + StringGrid.RowCount := StringGrid.RowCount + 1; + + StringGrid.Cells[0, RowIdx] := DiffPairName; // DiffPairName + StringGrid.Cells[1, RowIdx] := Row[0]; // PositiveNetName + StringGrid.Cells[2, RowIdx] := Row[1]; // NegativeNetName + + Inc(RowIdx); + end; +End; + +Function InitStringGrid(diffs: TStringList); +Begin + // Set up StringGrid columns and headers + StringGrid.RowCount := 1; // Add 1 for header row + StringGrid.Cells[0, 0] := 'Diff Pair Name'; + StringGrid.Cells[1, 0] := 'Positive Net Name'; + StringGrid.Cells[2, 0] := 'Negative Net Name'; + + StringGrid.FixedCols := 0; + + AddKeysToStringGrid(diffs, cbHideExisting.Checked); +End; + +{..............................................................................} +Procedure Run(UseGUI : Boolean); +Const + MAX_CONNECTIONS = 3; +Var + cmps : TStringList; + diffs, newDiffs, alreadyFound : TStringList; + DiffClass : IPCB_ObjectClass; + i, idx, cnt : Integer; +Begin + // Retrieve the current board + Board := PCBServer.GetCurrentPCBBoard; + If Board = Nil Then Exit; + + // 1. Get All nets for each pin in a component + cmps := GetAllPinsSortedByComponent(Nil); + + // 2. For given component, if nets' chars all match except 1 char + // add pos/neg net string to TStringList. + // Format: DiffPairName=PositiveNetName;NegativeNetName, ... + diffs := FindDiffPairCandidates(cmps); + cmps.Free; + + // 3. Find all DiffPair Candidates that go through 2 pin components + // and add their nets as well + // Iterate until no new connected pairs are found or max + For i := 0 to MAX_CONNECTIONS - 1 Do + Begin + alreadyFound := FlattenDiffsToNetList(diffs); + newDiffs := GetConnectedDiffPairs(diffs, alreadyFound); + if newDiffs.Count <= 0 then break; + + diffs.AddStrings(newDiffs); // Append new diff pairs list + End; + + GlbDiffPairs := diffs; + + // TODO: Run until no new pairs are found + //newDiffs := GetConnectedDiffPairs(newDiffs); + //diffs.AddStrings(newDiffs); // Append new diff pairs list + + if UseGUI = True then + begin + AddDiffPairClassesToComboBox(Nil); + InitStringGrid(diffs); + + Form1.ShowModal; + end + else + begin + // 4. Create diff pairs in layout + AddDiffPairs(Nil, diffs); + end; +End; +{..............................................................................} + +Procedure RunWithGUI; +Begin + Run(True); +End; + +Procedure RunNoGUI; +Begin + Run(False); +End; + + +Function GetSelectedDiffPairs(Grid: TStringGrid): TStringList; +var + DiffPairs: TStringList; + Row: Integer; + Key, Value: String; + Selection: TGridRect; +begin + DiffPairs := TStringList.Create; + DiffPairs.Sorted := True; + DiffPairs.Duplicates := dupIgnore; + DiffPairs.NameValueSeparator := '='; + + // Get the selection rectangle + Selection := Grid.Selection; + + // Iterate through the rows in the selected range + for Row := Selection.Top to Selection.Bottom do + begin + // Ensure the row is valid (in case of invalid selections) + if (Row >= 0) and (Row < Grid.RowCount) then + begin + // Construct the dictionary key and value + Key := Grid.Cells[0, Row]; // Column 1 + Value := Grid.Cells[1, Row] + ';' + Grid.Cells[2, Row]; // Columns 2 and 3 + + // Add the entry to the TStringList dictionary + DiffPairs.Add(Key + '=' + Value); + end; + end; + + Result := DiffPairs; // Return the resulting TStringList +end; + + + +procedure TForm1.btnAddDiffPairsClick(Sender: TObject); +var + idx : Integer; + ClassObj: IPCB_ObjectClass; + SelectedDiffPairs: StringList; +begin + // Get ComboBox selection index + idx := cbDiffPairClasses.GetItemIndex(); + + // Add Differential Pairs to New Class + if idx < 0 then + begin + ClassObj := AddDiffPairClass(cbDiffPairClasses.Text); + end + // Add Differential Pairs to Existing Class + else + begin + ClassObj := cbDiffPairClasses.Items.Objects[idx]; + end; + + // Get selected diff pairs from String Grid + SelectedDiffPairs := GetSelectedDiffPairs(StringGrid); + + // 4. Create diff pairs in layout + AddDiffPairs(ClassObj, SelectedDiffPairs); + + InitStringGrid(GlbDiffPairs); // Refresh String Grid +end; + + +procedure TForm1.cbHideExistingClick(Sender: TObject); +begin + InitStringGrid(GlbDiffPairs); +end; + diff --git a/Scripts - PCB/DiffPairFinder/README.md b/Scripts - PCB/DiffPairFinder/README.md new file mode 100644 index 00000000..d6d7627d --- /dev/null +++ b/Scripts - PCB/DiffPairFinder/README.md @@ -0,0 +1,16 @@ +### [DOWNLOAD](https://altium-designer-addons.github.io/DownGit/#/home?url=https://github.com/Altium-Designer-addons/scripts-libraries/tree/master/Scripts%20-%20PCB/DiffPairFinder) + +# Differential Pair Finder + +## Overview +Finds diff pairs in layout by filtering through net names. It will also find non-obvious nets by looking for pairs that connect through resistors and capacitors. + +## Usage +Run with or without a GUI. In GUI mode, you can add pairs to a selected class or enter a new class name. If you run without a GUI it will just add all pairs to the `All Differential Pairs` class. + +![GUI](gui.jpg) + +## Credits +- Created by Stephen Thompson +- From the Altium Script Examples: Matt Berggren & David Parker's PCB_Class_Generator_Form.pas on how to add classes and nets to classes +- GPT4o \ No newline at end of file diff --git a/Scripts - PCB/DiffPairFinder/gui.jpg b/Scripts - PCB/DiffPairFinder/gui.jpg new file mode 100644 index 00000000..2e4c03d3 Binary files /dev/null and b/Scripts - PCB/DiffPairFinder/gui.jpg differ diff --git a/Scripts - PCB/README.md b/Scripts - PCB/README.md index bf50b820..e759e14d 100644 --- a/Scripts - PCB/README.md +++ b/Scripts - PCB/README.md @@ -17,6 +17,7 @@ CopyTracesRadial | [download](https://altium-designer-addons.github.io/DownGit/# CurrentCalculator | [download](https://altium-designer-addons.github.io/DownGit/#/home?url=https://github.com/Altium-Designer-addons/scripts-libraries/tree/master/Scripts+-+PCB/CurrentCalculator) | PCB script that gives the user a dialog box with current (Amperes) handling calculations for a selected track. The script determines if the track is on an internal or external layer, and provides current calculations for 1, 5, and 10°C rise above ambient DeleteInvalidPCBObjects | [download](https://altium-designer-addons.github.io/DownGit/#/home?url=https://github.com/Altium-Designer-addons/scripts-libraries/tree/master/Scripts+-+PCB/DeleteInvalidPCBObjects) | Cleans a PCB documents of some current invalid objects. Checks for invalid regions or polygons and deletes them DeleteSelectedSplit | [download](https://altium-designer-addons.github.io/DownGit/#/home?url=https://github.com/Altium-Designer-addons/scripts-libraries/tree/master/Scripts+-+PCB/DeleteSelectedSplit) | Script that can be used to delete selected split plane. It actually creates region based on selected split plane, with holes inside, so no copper will appear on that place +DiffPairFinder | [download](https://altium-designer-addons.github.io/DownGit/#/home?url=https://github.com/Altium-Designer-addons/scripts-libraries/tree/master/Scripts+-+PCB/DiffPairFinder) | Find differential pairs by net name in layout and also nets connected across components Distribute | [download](https://altium-designer-addons.github.io/DownGit/#/home?url=https://github.com/Altium-Designer-addons/scripts-libraries/tree/master/Scripts+-+PCB/Distribute) | script that distributes distance between selected lines Fillet | [download](https://altium-designer-addons.github.io/DownGit/#/home?url=https://github.com/Altium-Designer-addons/scripts-libraries/tree/master/Scripts+-+PCB/Fillet) | Script that places arcs to corners of selected tracks (Fillet command) FilletWithRadius | [download](https://altium-designer-addons.github.io/DownGit/#/home?url=https://github.com/Altium-Designer-addons/scripts-libraries/tree/master/Scripts+-+PCB/FilletWithRadius) | script that rounds connection on horizontaland vertical lines by fixed radius value (superseded by Fillet script)