From 360ff0424e1a2f0e57cad41c8b72bacc3a4b5110 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Tue, 9 Mar 2010 15:24:29 +0000 Subject: [PATCH] * ./hurricane/src/hviewer, ./coriolis/src/crlcore, ./coriolis/src/knik, ./coriolis/src/katabatic, ./coriolis/src/kite, ./coriolis/src/equinox, ./coriolis/src/solstice, ./coriolis/src/ispd: - SVN MOVE: Source tree simplification & uniformisation. Now all tools are at the same level, directly under the root of the repository. No more "coriolis/src". --- katabatic/CMakeLists.txt | 48 + katabatic/cmake_modules/CMakeLists.txt | 1 + katabatic/cmake_modules/FindKATABATIC.cmake | 47 + katabatic/doc/ASIM-bigfonts.css | 353 +++ katabatic/doc/ASIM.css | 485 +++ katabatic/doc/AutoContact.dox | 364 +++ katabatic/doc/AutoSegment.dox | 677 +++++ katabatic/doc/CMakeLists.txt | 12 + katabatic/doc/GCell.dox | 179 ++ katabatic/doc/GCellGrid.dox | 21 + katabatic/doc/Grid.dox | 114 + katabatic/doc/KatabaticEngine.dox | 202 ++ katabatic/doc/LayerAssign.dox | 143 + katabatic/doc/LoadGrByNet.dox | 27 + katabatic/doc/NetConstraints.dox | 128 + katabatic/doc/NetOptimals.dox | 59 + katabatic/doc/Session.dox | 153 + katabatic/doc/asimbook.cls | 798 +++++ katabatic/doc/customHierarchy.html | 110 + katabatic/doc/customSummary.html | 77 + katabatic/doc/doxyfile | 275 ++ katabatic/doc/footer.html | 16 + katabatic/doc/header.html | 22 + katabatic/doc/header.tex | 47 + katabatic/doc/html.entry | 1 + katabatic/doc/images/AutoContact-1.fig | 107 + katabatic/doc/images/AutoContact-1.pdf | Bin 0 -> 5370 bytes katabatic/doc/images/AutoContact-1.png | Bin 0 -> 7696 bytes katabatic/doc/images/AutoContact-10.fig | 72 + katabatic/doc/images/AutoContact-10.pdf | Bin 0 -> 3592 bytes katabatic/doc/images/AutoContact-10.png | Bin 0 -> 4398 bytes katabatic/doc/images/AutoContact-11.fig | 68 + katabatic/doc/images/AutoContact-11.pdf | Bin 0 -> 3584 bytes katabatic/doc/images/AutoContact-11.png | Bin 0 -> 4470 bytes katabatic/doc/images/AutoContact-12.fig | 91 + katabatic/doc/images/AutoContact-12.pdf | Bin 0 -> 5463 bytes katabatic/doc/images/AutoContact-12.png | Bin 0 -> 5260 bytes katabatic/doc/images/AutoContact-13.fig | 104 + katabatic/doc/images/AutoContact-13.pdf | Bin 0 -> 6277 bytes katabatic/doc/images/AutoContact-13.png | Bin 0 -> 5843 bytes katabatic/doc/images/AutoContact-14.fig | 79 + katabatic/doc/images/AutoContact-14.pdf | Bin 0 -> 4502 bytes katabatic/doc/images/AutoContact-14.png | Bin 0 -> 4875 bytes katabatic/doc/images/AutoContact-15.fig | 73 + katabatic/doc/images/AutoContact-15.pdf | Bin 0 -> 4217 bytes katabatic/doc/images/AutoContact-15.png | Bin 0 -> 4517 bytes katabatic/doc/images/AutoContact-2.fig | 43 + katabatic/doc/images/AutoContact-2.pdf | Bin 0 -> 6625 bytes katabatic/doc/images/AutoContact-2.png | Bin 0 -> 1851 bytes katabatic/doc/images/AutoContact-3.fig | 54 + katabatic/doc/images/AutoContact-3.pdf | Bin 0 -> 7314 bytes katabatic/doc/images/AutoContact-3.png | Bin 0 -> 2267 bytes katabatic/doc/images/AutoContactG1-1.fig | 33 + katabatic/doc/images/AutoContactG1-1.pdf | 78 + katabatic/doc/images/AutoContactG1-1.png | Bin 0 -> 1637 bytes katabatic/doc/images/AutoContactG2-1.fig | 75 + katabatic/doc/images/AutoContactG2-1.pdf | Bin 0 -> 1928 bytes katabatic/doc/images/AutoContactG2-1.png | Bin 0 -> 2823 bytes katabatic/doc/images/AutoContactG3-1.fig | 89 + katabatic/doc/images/AutoContactG3-1.pdf | Bin 0 -> 1938 bytes katabatic/doc/images/AutoContactG3-1.png | Bin 0 -> 3093 bytes katabatic/doc/images/AutoContactG3-2.fig | 91 + katabatic/doc/images/AutoContactG3-2.pdf | Bin 0 -> 1984 bytes katabatic/doc/images/AutoContactG3-2.png | Bin 0 -> 3030 bytes katabatic/doc/images/AutoContactG3-3.fig | 124 + katabatic/doc/images/AutoContactG3-3.pdf | Bin 0 -> 10770 bytes katabatic/doc/images/AutoContactG3-3.png | Bin 0 -> 9777 bytes katabatic/doc/images/AutoContactG3-4.fig | 146 + katabatic/doc/images/AutoContactG3-4.pdf | Bin 0 -> 10548 bytes katabatic/doc/images/AutoContactG3-4.png | Bin 0 -> 10669 bytes katabatic/doc/images/AutoContactG4-1.fig | 111 + katabatic/doc/images/AutoContactG4-1.pdf | Bin 0 -> 1999 bytes katabatic/doc/images/AutoContactG4-1.png | Bin 0 -> 3151 bytes katabatic/doc/images/AutoContactG4-2.fig | 109 + katabatic/doc/images/AutoContactG4-2.pdf | Bin 0 -> 1986 bytes katabatic/doc/images/AutoContactG4-2.png | Bin 0 -> 3075 bytes katabatic/doc/images/AutoContactG4-3.fig | 109 + katabatic/doc/images/AutoContactG4-3.pdf | Bin 0 -> 2028 bytes katabatic/doc/images/AutoContactG4-3.png | Bin 0 -> 3237 bytes katabatic/doc/images/AutoContactG4-4.fig | 108 + katabatic/doc/images/AutoContactG4-4.pdf | Bin 0 -> 8358 bytes katabatic/doc/images/AutoContactG4-4.png | Bin 0 -> 8623 bytes katabatic/doc/images/AutoContactG4-5.fig | 151 + katabatic/doc/images/AutoContactG4-5.pdf | Bin 0 -> 10707 bytes katabatic/doc/images/AutoContactG4-5.png | Bin 0 -> 10108 bytes katabatic/doc/images/AutoInvalidate-1.fig | 66 + katabatic/doc/images/AutoInvalidate-1.pdf | Bin 0 -> 2090 bytes katabatic/doc/images/AutoInvalidate-1.png | Bin 0 -> 8075 bytes .../doc/images/AutoSegmentCollapse-1.fig | 87 + .../doc/images/AutoSegmentCollapse-1.pdf | Bin 0 -> 2887 bytes .../doc/images/AutoSegmentCollapse-1.png | Bin 0 -> 4922 bytes .../doc/images/AutoSegmentCollapse-2.fig | 87 + .../doc/images/AutoSegmentCollapse-2.pdf | Bin 0 -> 3025 bytes .../doc/images/AutoSegmentCollapse-2.png | Bin 0 -> 4504 bytes .../doc/images/AutoSegmentCollapse-3.fig | 85 + .../doc/images/AutoSegmentCollapse-3.pdf | Bin 0 -> 2973 bytes .../doc/images/AutoSegmentCollapse-3.png | Bin 0 -> 4580 bytes .../doc/images/AutoSegmentCollapse-4.fig | 90 + .../doc/images/AutoSegmentCollapse-4.pdf | Bin 0 -> 2401 bytes .../doc/images/AutoSegmentCollapse-4.png | Bin 0 -> 4270 bytes .../doc/images/AutoSegmentCollapse-5.fig | 81 + .../doc/images/AutoSegmentCollapse-5.pdf | Bin 0 -> 2327 bytes .../doc/images/AutoSegmentCollapse-5.png | Bin 0 -> 4828 bytes .../doc/images/AutoSegmentCollapse-6.fig | 82 + .../doc/images/AutoSegmentCollapse-6.pdf | Bin 0 -> 2299 bytes .../doc/images/AutoSegmentCollapse-6.png | Bin 0 -> 4436 bytes katabatic/doc/images/GCellConfiguration-1.fig | 65 + katabatic/doc/images/GCellConfiguration-1.pdf | Bin 0 -> 7042 bytes katabatic/doc/images/GCellConfiguration-1.png | Bin 0 -> 4901 bytes .../doc/images/GCellConfiguration-10.fig | 20 + .../doc/images/GCellConfiguration-10.pdf | Bin 0 -> 2058 bytes .../doc/images/GCellConfiguration-10.png | Bin 0 -> 1198 bytes .../doc/images/GCellConfiguration-11.fig | 24 + .../doc/images/GCellConfiguration-11.pdf | Bin 0 -> 2160 bytes .../doc/images/GCellConfiguration-11.png | Bin 0 -> 1496 bytes .../doc/images/GCellConfiguration-12.fig | 31 + .../doc/images/GCellConfiguration-12.pdf | Bin 0 -> 2887 bytes .../doc/images/GCellConfiguration-12.png | Bin 0 -> 1374 bytes .../doc/images/GCellConfiguration-13.fig | 29 + .../doc/images/GCellConfiguration-13.pdf | Bin 0 -> 2884 bytes .../doc/images/GCellConfiguration-13.png | Bin 0 -> 1809 bytes .../doc/images/GCellConfiguration-14.fig | 76 + .../doc/images/GCellConfiguration-14.pdf | Bin 0 -> 4434 bytes .../doc/images/GCellConfiguration-14.png | Bin 0 -> 4002 bytes .../doc/images/GCellConfiguration-15.fig | 22 + .../doc/images/GCellConfiguration-15.pdf | Bin 0 -> 1433 bytes .../doc/images/GCellConfiguration-15.png | Bin 0 -> 1378 bytes .../doc/images/GCellConfiguration-16.fig | 22 + .../doc/images/GCellConfiguration-16.pdf | 72 + .../doc/images/GCellConfiguration-16.png | Bin 0 -> 1393 bytes .../doc/images/GCellConfiguration-17.fig | 458 +++ .../doc/images/GCellConfiguration-17.pdf | Bin 0 -> 19884 bytes .../doc/images/GCellConfiguration-17.png | Bin 0 -> 33690 bytes .../doc/images/GCellConfiguration-18.fig | 123 + .../doc/images/GCellConfiguration-18.pdf | Bin 0 -> 12457 bytes .../doc/images/GCellConfiguration-18.png | Bin 0 -> 7459 bytes .../doc/images/GCellConfiguration-19.fig | 119 + .../doc/images/GCellConfiguration-19.pdf | Bin 0 -> 12318 bytes .../doc/images/GCellConfiguration-19.png | Bin 0 -> 7305 bytes katabatic/doc/images/GCellConfiguration-2.fig | 70 + katabatic/doc/images/GCellConfiguration-2.pdf | Bin 0 -> 7556 bytes katabatic/doc/images/GCellConfiguration-2.png | Bin 0 -> 5373 bytes .../doc/images/GCellConfiguration-20.fig | 66 + .../doc/images/GCellConfiguration-20.pdf | Bin 0 -> 5147 bytes .../doc/images/GCellConfiguration-20.png | Bin 0 -> 4960 bytes .../doc/images/GCellConfiguration-21.fig | 92 + .../doc/images/GCellConfiguration-21.pdf | Bin 0 -> 5770 bytes .../doc/images/GCellConfiguration-21.png | Bin 0 -> 5770 bytes .../doc/images/GCellConfiguration-22.fig | 96 + .../doc/images/GCellConfiguration-22.pdf | Bin 0 -> 5039 bytes .../doc/images/GCellConfiguration-22.png | Bin 0 -> 5871 bytes .../doc/images/GCellConfiguration-23.fig | 91 + .../doc/images/GCellConfiguration-23.pdf | Bin 0 -> 5104 bytes .../doc/images/GCellConfiguration-23.png | Bin 0 -> 6440 bytes .../doc/images/GCellConfiguration-24.fig | 45 + .../doc/images/GCellConfiguration-24.pdf | Bin 0 -> 3111 bytes .../doc/images/GCellConfiguration-24.png | Bin 0 -> 3471 bytes katabatic/doc/images/GCellConfiguration-3.fig | 171 ++ katabatic/doc/images/GCellConfiguration-3.pdf | Bin 0 -> 9296 bytes katabatic/doc/images/GCellConfiguration-3.png | Bin 0 -> 6878 bytes .../doc/images/GCellConfiguration-30.fig | 128 + .../doc/images/GCellConfiguration-30.pdf | Bin 0 -> 7433 bytes .../doc/images/GCellConfiguration-30.png | Bin 0 -> 6285 bytes .../doc/images/GCellConfiguration-31.fig | 133 + .../doc/images/GCellConfiguration-31.pdf | Bin 0 -> 7305 bytes .../doc/images/GCellConfiguration-31.png | Bin 0 -> 5662 bytes .../doc/images/GCellConfiguration-32.fig | 133 + .../doc/images/GCellConfiguration-32.pdf | Bin 0 -> 7374 bytes .../doc/images/GCellConfiguration-32.png | Bin 0 -> 6092 bytes .../doc/images/GCellConfiguration-33.fig | 74 + .../doc/images/GCellConfiguration-33.pdf | Bin 0 -> 4457 bytes .../doc/images/GCellConfiguration-33.png | Bin 0 -> 4107 bytes .../doc/images/GCellConfiguration-34.fig | 67 + .../doc/images/GCellConfiguration-34.pdf | Bin 0 -> 4406 bytes .../doc/images/GCellConfiguration-34.png | Bin 0 -> 3617 bytes .../doc/images/GCellConfiguration-35.fig | 111 + .../doc/images/GCellConfiguration-35.pdf | Bin 0 -> 7051 bytes .../doc/images/GCellConfiguration-35.png | Bin 0 -> 4676 bytes .../doc/images/GCellConfiguration-36.fig | 64 + .../doc/images/GCellConfiguration-36.pdf | Bin 0 -> 4374 bytes .../doc/images/GCellConfiguration-36.png | Bin 0 -> 3372 bytes katabatic/doc/images/GCellConfiguration-4.fig | 86 + katabatic/doc/images/GCellConfiguration-4.pdf | Bin 0 -> 5337 bytes katabatic/doc/images/GCellConfiguration-4.png | Bin 0 -> 6126 bytes .../doc/images/GCellConfiguration-40.fig | 81 + .../doc/images/GCellConfiguration-40.pdf | Bin 0 -> 5061 bytes .../doc/images/GCellConfiguration-40.png | Bin 0 -> 4425 bytes .../doc/images/GCellConfiguration-41.fig | 98 + .../doc/images/GCellConfiguration-41.pdf | Bin 0 -> 5322 bytes .../doc/images/GCellConfiguration-41.png | Bin 0 -> 5532 bytes .../doc/images/GCellConfiguration-42.fig | 104 + .../doc/images/GCellConfiguration-42.pdf | Bin 0 -> 5290 bytes .../doc/images/GCellConfiguration-42.png | Bin 0 -> 5438 bytes .../doc/images/GCellConfiguration-43.fig | 104 + .../doc/images/GCellConfiguration-43.pdf | Bin 0 -> 5388 bytes .../doc/images/GCellConfiguration-43.png | Bin 0 -> 5923 bytes .../doc/images/GCellConfiguration-44.fig | 60 + .../doc/images/GCellConfiguration-44.pdf | Bin 0 -> 3443 bytes .../doc/images/GCellConfiguration-44.png | Bin 0 -> 3750 bytes .../doc/images/GCellConfiguration-45.fig | 50 + .../doc/images/GCellConfiguration-45.pdf | Bin 0 -> 3266 bytes .../doc/images/GCellConfiguration-45.png | Bin 0 -> 3064 bytes katabatic/doc/images/GCellConfiguration-5.fig | 90 + katabatic/doc/images/GCellConfiguration-5.pdf | Bin 0 -> 5081 bytes katabatic/doc/images/GCellConfiguration-5.png | Bin 0 -> 5643 bytes katabatic/doc/images/GCellConfiguration-6.fig | 656 ++++ katabatic/doc/images/GCellConfiguration-6.pdf | Bin 0 -> 32998 bytes katabatic/doc/images/GCellConfiguration-6.png | Bin 0 -> 42039 bytes katabatic/doc/images/GCellConfiguration-7.fig | 106 + katabatic/doc/images/GCellConfiguration-7.pdf | Bin 0 -> 6966 bytes katabatic/doc/images/GCellConfiguration-7.png | Bin 0 -> 6465 bytes katabatic/doc/images/LegalConstruct-1.fig | 136 + katabatic/doc/images/LegalConstruct-1.pdf | Bin 0 -> 8118 bytes katabatic/doc/images/LegalConstruct-1.png | Bin 0 -> 11193 bytes katabatic/doc/images/LegalConstruct-2.fig | 151 + katabatic/doc/images/LegalConstruct-2.pdf | Bin 0 -> 9839 bytes katabatic/doc/images/LegalConstruct-2.png | Bin 0 -> 12317 bytes katabatic/doc/images/LegalConstruct-3.fig | 55 + katabatic/doc/images/LegalConstruct-3.pdf | Bin 0 -> 4307 bytes katabatic/doc/images/LegalConstruct-3.png | Bin 0 -> 5196 bytes katabatic/doc/images/LegalConstruct-4.fig | 91 + katabatic/doc/images/LegalConstruct-4.pdf | Bin 0 -> 7490 bytes katabatic/doc/images/LegalConstruct-4.png | Bin 0 -> 9533 bytes katabatic/doc/images/LegalConstruct-5.fig | 94 + katabatic/doc/images/LegalConstruct-5.pdf | Bin 0 -> 8269 bytes katabatic/doc/images/LegalConstruct-5.png | Bin 0 -> 9308 bytes katabatic/doc/images/LegalConstruct-6.fig | 59 + katabatic/doc/images/LegalConstruct-6.pdf | Bin 0 -> 5668 bytes katabatic/doc/images/LegalConstruct-6.png | Bin 0 -> 5490 bytes katabatic/doc/images/Makefile.am | 65 + katabatic/doc/images/Makefile.in | 403 +++ katabatic/doc/images/NetConstraints-1.fig | 78 + katabatic/doc/images/NetConstraints-1.pdf | Bin 0 -> 3062 bytes katabatic/doc/images/NetConstraints-1.png | Bin 0 -> 5012 bytes katabatic/doc/images/NetConstraints-2.fig | 75 + katabatic/doc/images/NetConstraints-2.pdf | Bin 0 -> 3016 bytes katabatic/doc/images/NetConstraints-2.png | Bin 0 -> 4416 bytes katabatic/doc/images/NetConstraints-3.fig | 72 + katabatic/doc/images/NetConstraints-3.pdf | Bin 0 -> 3119 bytes katabatic/doc/images/NetConstraints-3.png | Bin 0 -> 4505 bytes katabatic/doc/images/NetConstraints-4.fig | 68 + katabatic/doc/images/NetConstraints-4.pdf | Bin 0 -> 2614 bytes katabatic/doc/images/NetConstraints-4.png | Bin 0 -> 3861 bytes katabatic/doc/images/NetOptimals-1.fig | 146 + katabatic/doc/images/NetOptimals-1.pdf | Bin 0 -> 6987 bytes katabatic/doc/images/NetOptimals-1.png | Bin 0 -> 7610 bytes katabatic/doc/images/NetOptimals-2.fig | 80 + katabatic/doc/images/NetOptimals-2.pdf | Bin 0 -> 2075 bytes katabatic/doc/images/NetOptimals-2.png | Bin 0 -> 6781 bytes katabatic/doc/images/NetOptimals-3.fig | 109 + katabatic/doc/images/NetOptimals-3.pdf | Bin 0 -> 3836 bytes katabatic/doc/images/NetOptimals-3.png | Bin 0 -> 7141 bytes katabatic/doc/images/PerpandicularState-1.fig | 102 + katabatic/doc/images/PerpandicularState-1.pdf | Bin 0 -> 2618 bytes katabatic/doc/images/PerpandicularState-1.png | Bin 0 -> 5749 bytes katabatic/doc/images/PerpandicularState-2.fig | 113 + katabatic/doc/images/PerpandicularState-2.pdf | Bin 0 -> 2827 bytes katabatic/doc/images/PerpandicularState-2.png | Bin 0 -> 6862 bytes katabatic/doc/images/PerpandicularState-3.fig | 108 + katabatic/doc/images/PerpandicularState-3.pdf | Bin 0 -> 2802 bytes katabatic/doc/images/PerpandicularState-3.png | Bin 0 -> 6112 bytes katabatic/doc/images/PerpandicularState-4.fig | 108 + katabatic/doc/images/PerpandicularState-4.pdf | Bin 0 -> 2773 bytes katabatic/doc/images/PerpandicularState-4.png | Bin 0 -> 5896 bytes katabatic/doc/images/SplitAutoContact-1.fig | 58 + katabatic/doc/images/SplitAutoContact-1.pdf | Bin 0 -> 4926 bytes katabatic/doc/images/SplitAutoContact-1.png | Bin 0 -> 4239 bytes katabatic/doc/images/SplitAutoContact-2.fig | 53 + katabatic/doc/images/SplitAutoContact-2.pdf | Bin 0 -> 4153 bytes katabatic/doc/images/SplitAutoContact-2.png | Bin 0 -> 4049 bytes katabatic/doc/images/SplitAutoContact-3.fig | 48 + katabatic/doc/images/SplitAutoContact-3.pdf | Bin 0 -> 3383 bytes katabatic/doc/images/SplitAutoContact-3.png | Bin 0 -> 3916 bytes katabatic/doc/images/SplitAutoContact-4.fig | 46 + katabatic/doc/images/SplitAutoContact-4.pdf | Bin 0 -> 4064 bytes katabatic/doc/images/SplitAutoContact-4.png | Bin 0 -> 3934 bytes katabatic/doc/images/SplitAutoContact-5.fig | 46 + katabatic/doc/images/SplitAutoContact-5.pdf | Bin 0 -> 4064 bytes katabatic/doc/images/SplitAutoContact-5.png | Bin 0 -> 3844 bytes katabatic/doc/images/SplitAutoContact-6.fig | 36 + katabatic/doc/images/SplitAutoContact-6.pdf | Bin 0 -> 3183 bytes katabatic/doc/images/SplitAutoContact-6.png | Bin 0 -> 3474 bytes katabatic/doc/mkDoc.sh | 10 + katabatic/src/AutoContact.cpp | 2686 +++++++++++++++++ katabatic/src/AutoContacts.cpp | 140 + katabatic/src/AutoHorizontal.cpp | 807 +++++ katabatic/src/AutoSegment.cpp | 1877 ++++++++++++ katabatic/src/AutoSegments.cpp | 656 ++++ katabatic/src/AutoVertical.cpp | 704 +++++ katabatic/src/CMakeLists.txt | 60 + katabatic/src/Configuration.cpp | 165 + katabatic/src/GCell.cpp | 999 ++++++ katabatic/src/GCellGrid.cpp | 229 ++ katabatic/src/GraphicKatabaticEngine.cpp | 229 ++ katabatic/src/Grid.cpp | 134 + katabatic/src/KatabaticEngine.cpp | 913 ++++++ katabatic/src/LayerAssign.cpp | 282 ++ katabatic/src/LoadGrByNet.cpp | 2378 +++++++++++++++ katabatic/src/NetConstraints.cpp | 367 +++ katabatic/src/NetOptimals.cpp | 105 + katabatic/src/PowerRails.cpp | 513 ++++ katabatic/src/Session.cpp | 438 +++ katabatic/src/katabatic/AutoContact.h | 359 +++ katabatic/src/katabatic/AutoContacts.h | 165 + katabatic/src/katabatic/AutoHorizontal.h | 119 + katabatic/src/katabatic/AutoSegment.h | 478 +++ katabatic/src/katabatic/AutoSegments.h | 471 +++ katabatic/src/katabatic/AutoVertical.h | 119 + katabatic/src/katabatic/Configuration.h | 132 + katabatic/src/katabatic/ContactWrapper.h | 113 + katabatic/src/katabatic/GCell.h | 254 ++ katabatic/src/katabatic/GCellGrid.h | 90 + katabatic/src/katabatic/GCells.h | 63 + .../src/katabatic/GraphicKatabaticEngine.h | 105 + katabatic/src/katabatic/Grid.h | 340 +++ katabatic/src/katabatic/GridBox.h | 240 ++ katabatic/src/katabatic/GridCollections.h | 602 ++++ katabatic/src/katabatic/KatabaticEngine.h | 258 ++ katabatic/src/katabatic/SegmentWrapper.h | 110 + katabatic/src/katabatic/Session.h | 227 ++ 320 files changed, 31026 insertions(+) create mode 100644 katabatic/CMakeLists.txt create mode 100644 katabatic/cmake_modules/CMakeLists.txt create mode 100644 katabatic/cmake_modules/FindKATABATIC.cmake create mode 100644 katabatic/doc/ASIM-bigfonts.css create mode 100644 katabatic/doc/ASIM.css create mode 100644 katabatic/doc/AutoContact.dox create mode 100644 katabatic/doc/AutoSegment.dox create mode 100644 katabatic/doc/CMakeLists.txt create mode 100644 katabatic/doc/GCell.dox create mode 100644 katabatic/doc/GCellGrid.dox create mode 100644 katabatic/doc/Grid.dox create mode 100644 katabatic/doc/KatabaticEngine.dox create mode 100644 katabatic/doc/LayerAssign.dox create mode 100644 katabatic/doc/LoadGrByNet.dox create mode 100644 katabatic/doc/NetConstraints.dox create mode 100644 katabatic/doc/NetOptimals.dox create mode 100644 katabatic/doc/Session.dox create mode 100644 katabatic/doc/asimbook.cls create mode 100644 katabatic/doc/customHierarchy.html create mode 100644 katabatic/doc/customSummary.html create mode 100644 katabatic/doc/doxyfile create mode 100644 katabatic/doc/footer.html create mode 100644 katabatic/doc/header.html create mode 100644 katabatic/doc/header.tex create mode 100644 katabatic/doc/html.entry create mode 100644 katabatic/doc/images/AutoContact-1.fig create mode 100644 katabatic/doc/images/AutoContact-1.pdf create mode 100644 katabatic/doc/images/AutoContact-1.png create mode 100644 katabatic/doc/images/AutoContact-10.fig create mode 100644 katabatic/doc/images/AutoContact-10.pdf create mode 100644 katabatic/doc/images/AutoContact-10.png create mode 100644 katabatic/doc/images/AutoContact-11.fig create mode 100644 katabatic/doc/images/AutoContact-11.pdf create mode 100644 katabatic/doc/images/AutoContact-11.png create mode 100644 katabatic/doc/images/AutoContact-12.fig create mode 100644 katabatic/doc/images/AutoContact-12.pdf create mode 100644 katabatic/doc/images/AutoContact-12.png create mode 100644 katabatic/doc/images/AutoContact-13.fig create mode 100644 katabatic/doc/images/AutoContact-13.pdf create mode 100644 katabatic/doc/images/AutoContact-13.png create mode 100644 katabatic/doc/images/AutoContact-14.fig create mode 100644 katabatic/doc/images/AutoContact-14.pdf create mode 100644 katabatic/doc/images/AutoContact-14.png create mode 100644 katabatic/doc/images/AutoContact-15.fig create mode 100644 katabatic/doc/images/AutoContact-15.pdf create mode 100644 katabatic/doc/images/AutoContact-15.png create mode 100644 katabatic/doc/images/AutoContact-2.fig create mode 100644 katabatic/doc/images/AutoContact-2.pdf create mode 100644 katabatic/doc/images/AutoContact-2.png create mode 100644 katabatic/doc/images/AutoContact-3.fig create mode 100644 katabatic/doc/images/AutoContact-3.pdf create mode 100644 katabatic/doc/images/AutoContact-3.png create mode 100644 katabatic/doc/images/AutoContactG1-1.fig create mode 100644 katabatic/doc/images/AutoContactG1-1.pdf create mode 100644 katabatic/doc/images/AutoContactG1-1.png create mode 100644 katabatic/doc/images/AutoContactG2-1.fig create mode 100644 katabatic/doc/images/AutoContactG2-1.pdf create mode 100644 katabatic/doc/images/AutoContactG2-1.png create mode 100644 katabatic/doc/images/AutoContactG3-1.fig create mode 100644 katabatic/doc/images/AutoContactG3-1.pdf create mode 100644 katabatic/doc/images/AutoContactG3-1.png create mode 100644 katabatic/doc/images/AutoContactG3-2.fig create mode 100644 katabatic/doc/images/AutoContactG3-2.pdf create mode 100644 katabatic/doc/images/AutoContactG3-2.png create mode 100644 katabatic/doc/images/AutoContactG3-3.fig create mode 100644 katabatic/doc/images/AutoContactG3-3.pdf create mode 100644 katabatic/doc/images/AutoContactG3-3.png create mode 100644 katabatic/doc/images/AutoContactG3-4.fig create mode 100644 katabatic/doc/images/AutoContactG3-4.pdf create mode 100644 katabatic/doc/images/AutoContactG3-4.png create mode 100644 katabatic/doc/images/AutoContactG4-1.fig create mode 100644 katabatic/doc/images/AutoContactG4-1.pdf create mode 100644 katabatic/doc/images/AutoContactG4-1.png create mode 100644 katabatic/doc/images/AutoContactG4-2.fig create mode 100644 katabatic/doc/images/AutoContactG4-2.pdf create mode 100644 katabatic/doc/images/AutoContactG4-2.png create mode 100644 katabatic/doc/images/AutoContactG4-3.fig create mode 100644 katabatic/doc/images/AutoContactG4-3.pdf create mode 100644 katabatic/doc/images/AutoContactG4-3.png create mode 100644 katabatic/doc/images/AutoContactG4-4.fig create mode 100644 katabatic/doc/images/AutoContactG4-4.pdf create mode 100644 katabatic/doc/images/AutoContactG4-4.png create mode 100644 katabatic/doc/images/AutoContactG4-5.fig create mode 100644 katabatic/doc/images/AutoContactG4-5.pdf create mode 100644 katabatic/doc/images/AutoContactG4-5.png create mode 100644 katabatic/doc/images/AutoInvalidate-1.fig create mode 100644 katabatic/doc/images/AutoInvalidate-1.pdf create mode 100644 katabatic/doc/images/AutoInvalidate-1.png create mode 100644 katabatic/doc/images/AutoSegmentCollapse-1.fig create mode 100644 katabatic/doc/images/AutoSegmentCollapse-1.pdf create mode 100644 katabatic/doc/images/AutoSegmentCollapse-1.png create mode 100644 katabatic/doc/images/AutoSegmentCollapse-2.fig create mode 100644 katabatic/doc/images/AutoSegmentCollapse-2.pdf create mode 100644 katabatic/doc/images/AutoSegmentCollapse-2.png create mode 100644 katabatic/doc/images/AutoSegmentCollapse-3.fig create mode 100644 katabatic/doc/images/AutoSegmentCollapse-3.pdf create mode 100644 katabatic/doc/images/AutoSegmentCollapse-3.png create mode 100644 katabatic/doc/images/AutoSegmentCollapse-4.fig create mode 100644 katabatic/doc/images/AutoSegmentCollapse-4.pdf create mode 100644 katabatic/doc/images/AutoSegmentCollapse-4.png create mode 100644 katabatic/doc/images/AutoSegmentCollapse-5.fig create mode 100644 katabatic/doc/images/AutoSegmentCollapse-5.pdf create mode 100644 katabatic/doc/images/AutoSegmentCollapse-5.png create mode 100644 katabatic/doc/images/AutoSegmentCollapse-6.fig create mode 100644 katabatic/doc/images/AutoSegmentCollapse-6.pdf create mode 100644 katabatic/doc/images/AutoSegmentCollapse-6.png create mode 100644 katabatic/doc/images/GCellConfiguration-1.fig create mode 100644 katabatic/doc/images/GCellConfiguration-1.pdf create mode 100644 katabatic/doc/images/GCellConfiguration-1.png create mode 100644 katabatic/doc/images/GCellConfiguration-10.fig create mode 100644 katabatic/doc/images/GCellConfiguration-10.pdf create mode 100644 katabatic/doc/images/GCellConfiguration-10.png create mode 100644 katabatic/doc/images/GCellConfiguration-11.fig create mode 100644 katabatic/doc/images/GCellConfiguration-11.pdf create mode 100644 katabatic/doc/images/GCellConfiguration-11.png create mode 100644 katabatic/doc/images/GCellConfiguration-12.fig create mode 100644 katabatic/doc/images/GCellConfiguration-12.pdf create mode 100644 katabatic/doc/images/GCellConfiguration-12.png create mode 100644 katabatic/doc/images/GCellConfiguration-13.fig create mode 100644 katabatic/doc/images/GCellConfiguration-13.pdf create mode 100644 katabatic/doc/images/GCellConfiguration-13.png create mode 100644 katabatic/doc/images/GCellConfiguration-14.fig create mode 100644 katabatic/doc/images/GCellConfiguration-14.pdf create mode 100644 katabatic/doc/images/GCellConfiguration-14.png create mode 100644 katabatic/doc/images/GCellConfiguration-15.fig create mode 100644 katabatic/doc/images/GCellConfiguration-15.pdf create mode 100644 katabatic/doc/images/GCellConfiguration-15.png create mode 100644 katabatic/doc/images/GCellConfiguration-16.fig create mode 100644 katabatic/doc/images/GCellConfiguration-16.pdf create mode 100644 katabatic/doc/images/GCellConfiguration-16.png create mode 100644 katabatic/doc/images/GCellConfiguration-17.fig create mode 100644 katabatic/doc/images/GCellConfiguration-17.pdf create mode 100644 katabatic/doc/images/GCellConfiguration-17.png create mode 100644 katabatic/doc/images/GCellConfiguration-18.fig create mode 100644 katabatic/doc/images/GCellConfiguration-18.pdf create mode 100644 katabatic/doc/images/GCellConfiguration-18.png create mode 100644 katabatic/doc/images/GCellConfiguration-19.fig create mode 100644 katabatic/doc/images/GCellConfiguration-19.pdf create mode 100644 katabatic/doc/images/GCellConfiguration-19.png create mode 100644 katabatic/doc/images/GCellConfiguration-2.fig create mode 100644 katabatic/doc/images/GCellConfiguration-2.pdf create mode 100644 katabatic/doc/images/GCellConfiguration-2.png create mode 100644 katabatic/doc/images/GCellConfiguration-20.fig create mode 100644 katabatic/doc/images/GCellConfiguration-20.pdf create mode 100644 katabatic/doc/images/GCellConfiguration-20.png create mode 100644 katabatic/doc/images/GCellConfiguration-21.fig create mode 100644 katabatic/doc/images/GCellConfiguration-21.pdf create mode 100644 katabatic/doc/images/GCellConfiguration-21.png create mode 100644 katabatic/doc/images/GCellConfiguration-22.fig create mode 100644 katabatic/doc/images/GCellConfiguration-22.pdf create mode 100644 katabatic/doc/images/GCellConfiguration-22.png create mode 100644 katabatic/doc/images/GCellConfiguration-23.fig create mode 100644 katabatic/doc/images/GCellConfiguration-23.pdf create mode 100644 katabatic/doc/images/GCellConfiguration-23.png create mode 100644 katabatic/doc/images/GCellConfiguration-24.fig create mode 100644 katabatic/doc/images/GCellConfiguration-24.pdf create mode 100644 katabatic/doc/images/GCellConfiguration-24.png create mode 100644 katabatic/doc/images/GCellConfiguration-3.fig create mode 100644 katabatic/doc/images/GCellConfiguration-3.pdf create mode 100644 katabatic/doc/images/GCellConfiguration-3.png create mode 100644 katabatic/doc/images/GCellConfiguration-30.fig create mode 100644 katabatic/doc/images/GCellConfiguration-30.pdf create mode 100644 katabatic/doc/images/GCellConfiguration-30.png create mode 100644 katabatic/doc/images/GCellConfiguration-31.fig create mode 100644 katabatic/doc/images/GCellConfiguration-31.pdf create mode 100644 katabatic/doc/images/GCellConfiguration-31.png create mode 100644 katabatic/doc/images/GCellConfiguration-32.fig create mode 100644 katabatic/doc/images/GCellConfiguration-32.pdf create mode 100644 katabatic/doc/images/GCellConfiguration-32.png create mode 100644 katabatic/doc/images/GCellConfiguration-33.fig create mode 100644 katabatic/doc/images/GCellConfiguration-33.pdf create mode 100644 katabatic/doc/images/GCellConfiguration-33.png create mode 100644 katabatic/doc/images/GCellConfiguration-34.fig create mode 100644 katabatic/doc/images/GCellConfiguration-34.pdf create mode 100644 katabatic/doc/images/GCellConfiguration-34.png create mode 100644 katabatic/doc/images/GCellConfiguration-35.fig create mode 100644 katabatic/doc/images/GCellConfiguration-35.pdf create mode 100644 katabatic/doc/images/GCellConfiguration-35.png create mode 100644 katabatic/doc/images/GCellConfiguration-36.fig create mode 100644 katabatic/doc/images/GCellConfiguration-36.pdf create mode 100644 katabatic/doc/images/GCellConfiguration-36.png create mode 100644 katabatic/doc/images/GCellConfiguration-4.fig create mode 100644 katabatic/doc/images/GCellConfiguration-4.pdf create mode 100644 katabatic/doc/images/GCellConfiguration-4.png create mode 100644 katabatic/doc/images/GCellConfiguration-40.fig create mode 100644 katabatic/doc/images/GCellConfiguration-40.pdf create mode 100644 katabatic/doc/images/GCellConfiguration-40.png create mode 100644 katabatic/doc/images/GCellConfiguration-41.fig create mode 100644 katabatic/doc/images/GCellConfiguration-41.pdf create mode 100644 katabatic/doc/images/GCellConfiguration-41.png create mode 100644 katabatic/doc/images/GCellConfiguration-42.fig create mode 100644 katabatic/doc/images/GCellConfiguration-42.pdf create mode 100644 katabatic/doc/images/GCellConfiguration-42.png create mode 100644 katabatic/doc/images/GCellConfiguration-43.fig create mode 100644 katabatic/doc/images/GCellConfiguration-43.pdf create mode 100644 katabatic/doc/images/GCellConfiguration-43.png create mode 100644 katabatic/doc/images/GCellConfiguration-44.fig create mode 100644 katabatic/doc/images/GCellConfiguration-44.pdf create mode 100644 katabatic/doc/images/GCellConfiguration-44.png create mode 100644 katabatic/doc/images/GCellConfiguration-45.fig create mode 100644 katabatic/doc/images/GCellConfiguration-45.pdf create mode 100644 katabatic/doc/images/GCellConfiguration-45.png create mode 100644 katabatic/doc/images/GCellConfiguration-5.fig create mode 100644 katabatic/doc/images/GCellConfiguration-5.pdf create mode 100644 katabatic/doc/images/GCellConfiguration-5.png create mode 100644 katabatic/doc/images/GCellConfiguration-6.fig create mode 100644 katabatic/doc/images/GCellConfiguration-6.pdf create mode 100644 katabatic/doc/images/GCellConfiguration-6.png create mode 100644 katabatic/doc/images/GCellConfiguration-7.fig create mode 100644 katabatic/doc/images/GCellConfiguration-7.pdf create mode 100644 katabatic/doc/images/GCellConfiguration-7.png create mode 100644 katabatic/doc/images/LegalConstruct-1.fig create mode 100644 katabatic/doc/images/LegalConstruct-1.pdf create mode 100644 katabatic/doc/images/LegalConstruct-1.png create mode 100644 katabatic/doc/images/LegalConstruct-2.fig create mode 100644 katabatic/doc/images/LegalConstruct-2.pdf create mode 100644 katabatic/doc/images/LegalConstruct-2.png create mode 100644 katabatic/doc/images/LegalConstruct-3.fig create mode 100644 katabatic/doc/images/LegalConstruct-3.pdf create mode 100644 katabatic/doc/images/LegalConstruct-3.png create mode 100644 katabatic/doc/images/LegalConstruct-4.fig create mode 100644 katabatic/doc/images/LegalConstruct-4.pdf create mode 100644 katabatic/doc/images/LegalConstruct-4.png create mode 100644 katabatic/doc/images/LegalConstruct-5.fig create mode 100644 katabatic/doc/images/LegalConstruct-5.pdf create mode 100644 katabatic/doc/images/LegalConstruct-5.png create mode 100644 katabatic/doc/images/LegalConstruct-6.fig create mode 100644 katabatic/doc/images/LegalConstruct-6.pdf create mode 100644 katabatic/doc/images/LegalConstruct-6.png create mode 100644 katabatic/doc/images/Makefile.am create mode 100644 katabatic/doc/images/Makefile.in create mode 100644 katabatic/doc/images/NetConstraints-1.fig create mode 100644 katabatic/doc/images/NetConstraints-1.pdf create mode 100644 katabatic/doc/images/NetConstraints-1.png create mode 100644 katabatic/doc/images/NetConstraints-2.fig create mode 100644 katabatic/doc/images/NetConstraints-2.pdf create mode 100644 katabatic/doc/images/NetConstraints-2.png create mode 100644 katabatic/doc/images/NetConstraints-3.fig create mode 100644 katabatic/doc/images/NetConstraints-3.pdf create mode 100644 katabatic/doc/images/NetConstraints-3.png create mode 100644 katabatic/doc/images/NetConstraints-4.fig create mode 100644 katabatic/doc/images/NetConstraints-4.pdf create mode 100644 katabatic/doc/images/NetConstraints-4.png create mode 100644 katabatic/doc/images/NetOptimals-1.fig create mode 100644 katabatic/doc/images/NetOptimals-1.pdf create mode 100644 katabatic/doc/images/NetOptimals-1.png create mode 100644 katabatic/doc/images/NetOptimals-2.fig create mode 100644 katabatic/doc/images/NetOptimals-2.pdf create mode 100644 katabatic/doc/images/NetOptimals-2.png create mode 100644 katabatic/doc/images/NetOptimals-3.fig create mode 100644 katabatic/doc/images/NetOptimals-3.pdf create mode 100644 katabatic/doc/images/NetOptimals-3.png create mode 100644 katabatic/doc/images/PerpandicularState-1.fig create mode 100644 katabatic/doc/images/PerpandicularState-1.pdf create mode 100644 katabatic/doc/images/PerpandicularState-1.png create mode 100644 katabatic/doc/images/PerpandicularState-2.fig create mode 100644 katabatic/doc/images/PerpandicularState-2.pdf create mode 100644 katabatic/doc/images/PerpandicularState-2.png create mode 100644 katabatic/doc/images/PerpandicularState-3.fig create mode 100644 katabatic/doc/images/PerpandicularState-3.pdf create mode 100644 katabatic/doc/images/PerpandicularState-3.png create mode 100644 katabatic/doc/images/PerpandicularState-4.fig create mode 100644 katabatic/doc/images/PerpandicularState-4.pdf create mode 100644 katabatic/doc/images/PerpandicularState-4.png create mode 100644 katabatic/doc/images/SplitAutoContact-1.fig create mode 100644 katabatic/doc/images/SplitAutoContact-1.pdf create mode 100644 katabatic/doc/images/SplitAutoContact-1.png create mode 100644 katabatic/doc/images/SplitAutoContact-2.fig create mode 100644 katabatic/doc/images/SplitAutoContact-2.pdf create mode 100644 katabatic/doc/images/SplitAutoContact-2.png create mode 100644 katabatic/doc/images/SplitAutoContact-3.fig create mode 100644 katabatic/doc/images/SplitAutoContact-3.pdf create mode 100644 katabatic/doc/images/SplitAutoContact-3.png create mode 100644 katabatic/doc/images/SplitAutoContact-4.fig create mode 100644 katabatic/doc/images/SplitAutoContact-4.pdf create mode 100644 katabatic/doc/images/SplitAutoContact-4.png create mode 100644 katabatic/doc/images/SplitAutoContact-5.fig create mode 100644 katabatic/doc/images/SplitAutoContact-5.pdf create mode 100644 katabatic/doc/images/SplitAutoContact-5.png create mode 100644 katabatic/doc/images/SplitAutoContact-6.fig create mode 100644 katabatic/doc/images/SplitAutoContact-6.pdf create mode 100644 katabatic/doc/images/SplitAutoContact-6.png create mode 100644 katabatic/doc/mkDoc.sh create mode 100644 katabatic/src/AutoContact.cpp create mode 100644 katabatic/src/AutoContacts.cpp create mode 100644 katabatic/src/AutoHorizontal.cpp create mode 100644 katabatic/src/AutoSegment.cpp create mode 100644 katabatic/src/AutoSegments.cpp create mode 100644 katabatic/src/AutoVertical.cpp create mode 100644 katabatic/src/CMakeLists.txt create mode 100644 katabatic/src/Configuration.cpp create mode 100644 katabatic/src/GCell.cpp create mode 100644 katabatic/src/GCellGrid.cpp create mode 100644 katabatic/src/GraphicKatabaticEngine.cpp create mode 100644 katabatic/src/Grid.cpp create mode 100644 katabatic/src/KatabaticEngine.cpp create mode 100644 katabatic/src/LayerAssign.cpp create mode 100644 katabatic/src/LoadGrByNet.cpp create mode 100644 katabatic/src/NetConstraints.cpp create mode 100644 katabatic/src/NetOptimals.cpp create mode 100644 katabatic/src/PowerRails.cpp create mode 100644 katabatic/src/Session.cpp create mode 100644 katabatic/src/katabatic/AutoContact.h create mode 100644 katabatic/src/katabatic/AutoContacts.h create mode 100644 katabatic/src/katabatic/AutoHorizontal.h create mode 100644 katabatic/src/katabatic/AutoSegment.h create mode 100644 katabatic/src/katabatic/AutoSegments.h create mode 100644 katabatic/src/katabatic/AutoVertical.h create mode 100644 katabatic/src/katabatic/Configuration.h create mode 100644 katabatic/src/katabatic/ContactWrapper.h create mode 100644 katabatic/src/katabatic/GCell.h create mode 100644 katabatic/src/katabatic/GCellGrid.h create mode 100644 katabatic/src/katabatic/GCells.h create mode 100644 katabatic/src/katabatic/GraphicKatabaticEngine.h create mode 100644 katabatic/src/katabatic/Grid.h create mode 100644 katabatic/src/katabatic/GridBox.h create mode 100644 katabatic/src/katabatic/GridCollections.h create mode 100644 katabatic/src/katabatic/KatabaticEngine.h create mode 100644 katabatic/src/katabatic/SegmentWrapper.h create mode 100644 katabatic/src/katabatic/Session.h diff --git a/katabatic/CMakeLists.txt b/katabatic/CMakeLists.txt new file mode 100644 index 00000000..d51483b8 --- /dev/null +++ b/katabatic/CMakeLists.txt @@ -0,0 +1,48 @@ +PROJECT(KATABATIC) + +OPTION(BUILD_DOC "Build the documentation (doxygen)" OFF) +OPTION(CHECK_DATABASE "Run database in full check mode (very slow)" OFF) + +CMAKE_MINIMUM_REQUIRED(VERSION 2.4.0) + +SET(CMAKE_C_FLAGS_DEBUG "-g -Wall" CACHE STRING "Debug options." FORCE) +SET(CMAKE_CXX_FLAGS_DEBUG "-g -Wall" CACHE STRING "Debug options." FORCE) +#SET(CMAKE_LINKER_FLAGS_DEBUG "-pg" CACHE STRING "Debug options." FORCE) +#SET(CMAKE_SHARED_LINKER_FLAGS_DEBUG "-pg" CACHE STRING "Debug options." FORCE) +#SET(CMAKE_MODULE_LINKER_FLAGS_DEBUG "-pg" CACHE STRING "Debug options." FORCE) +#SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "-pg" CACHE STRING "Debug options." FORCE) +SET(CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG -Wall" CACHE STRING "Release options." FORCE) +SET(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG -Wall" CACHE STRING "Release options." FORCE) + +IF(COMMAND CMAKE_POLICY) + CMAKE_POLICY(SET CMP0003 NEW) +ENDIF(COMMAND CMAKE_POLICY) + +SET(CMAKE_MODULE_PATH "$ENV{HURRICANE_TOP}/share/cmake_modules/") + +SET(QT_USE_QTXML "true") + +IF(BUILD_DOC) + FIND_PACKAGE(Doxygen) +ENDIF(BUILD_DOC) +FIND_PACKAGE(Qt4 REQUIRED) # find and setup Qt4 for this project +FIND_PACKAGE(HURRICANE REQUIRED) +FIND_PACKAGE(CORIOLIS REQUIRED) +FIND_PACKAGE(KNIK REQUIRED) + +SET_LIB_LINK_MODE() + +ADD_SUBDIRECTORY(src) +ADD_SUBDIRECTORY(cmake_modules) +IF(BUILD_DOC AND DOXYGEN_FOUND) + ADD_SUBDIRECTORY(doc) +ENDIF(BUILD_DOC AND DOXYGEN_FOUND) + +IF(CHECK_DATABASE) + ADD_DEFINITIONS(-DCHECK_DATABASE) + MESSAGE(STATUS "Checking database enabled (very slow).") +ENDIF(CHECK_DATABASE) +IF(CHECK_DETERMINISM) + ADD_DEFINITIONS(-DCHECK_DETERMINISM) + MESSAGE(STATUS "Checking determinism enabled.") +ENDIF(CHECK_DETERMINISM) diff --git a/katabatic/cmake_modules/CMakeLists.txt b/katabatic/cmake_modules/CMakeLists.txt new file mode 100644 index 00000000..774ac201 --- /dev/null +++ b/katabatic/cmake_modules/CMakeLists.txt @@ -0,0 +1 @@ +install ( FILES FindKATABATIC.cmake DESTINATION /share/cmake_modules ) diff --git a/katabatic/cmake_modules/FindKATABATIC.cmake b/katabatic/cmake_modules/FindKATABATIC.cmake new file mode 100644 index 00000000..987c7a5e --- /dev/null +++ b/katabatic/cmake_modules/FindKATABATIC.cmake @@ -0,0 +1,47 @@ +# - Find the Katabatic includes and libraries. +# The following variables are set if Coriolis is found. If KATABATIC is not +# found, KATABATIC_FOUND is set to false. +# KATABATIC_FOUND - True when the Coriolis include directory is found. +# KATABATIC_INCLUDE_DIR - the path to where the Coriolis include files are. +# KATABATIC_LIBRARIES - The path to where the Coriolis library files are. + + +SET(KATABATIC_INCLUDE_PATH_DESCRIPTION "directory containing the Katabatic include files. E.g /usr/local/include/coriolis or /asim/coriolis/include/coriolis") + +SET(KATABATIC_DIR_MESSAGE "Set the KATABATIC_INCLUDE_DIR cmake cache entry to the ${KATABATIC_INCLUDE_PATH_DESCRIPTION}") + +# don't even bother under WIN32 +IF(UNIX) + + SET(KATABATIC_DIR_SEARCH $ENV{CORIOLIS_TOP} $ENV{HURRICANE_TOP}) + # + # Look for an installation. + # + FIND_PATH(KATABATIC_INCLUDE_PATH NAMES katabatic/KatabaticEngine.h PATHS + # Look in other places. + ${KATABATIC_DIR_SEARCH} + PATH_SUFFIXES include/coriolis + # Help the user find it if we cannot. + DOC "The ${KATABATIC_INCLUDE_PATH_DESCRIPTION}" + ) + + FIND_LIBRARY(KATABATIC_LIBRARY_PATH + NAMES katabatic + PATHS ${KATABATIC_DIR_SEARCH} + PATH_SUFFIXES lib + # Help the user find it if we cannot. + DOC "The ${KATABATIC_INCLUDE_PATH_DESCRIPTION}" + ) + + FIND_LIBRARY(KATABATIC_STATIC_LIBRARY_PATH + NAMES katabatic-static + PATHS ${KATABATIC_DIR_SEARCH} + PATH_SUFFIXES lib + # Help the user find it if we cannot. + DOC "The ${KATABATIC_INCLUDE_PATH_DESCRIPTION}" + ) + + SET_LIBRARIES_PATH(KATABATIC KATABATIC) + HURRICANE_CHECK_LIBRARIES(KATABATIC) + +ENDIF(UNIX) diff --git a/katabatic/doc/ASIM-bigfonts.css b/katabatic/doc/ASIM-bigfonts.css new file mode 100644 index 00000000..f8ec6823 --- /dev/null +++ b/katabatic/doc/ASIM-bigfonts.css @@ -0,0 +1,353 @@ + + +/* + * x-----------------------------------------------------------------x + * | HTML Standart Tags | + * x-----------------------------------------------------------------x + */ + + html, body, th, td, tr, p, li, h1, h2, h3, h4, h5, h6 { + font-size: 100%; + font-family: verdana, sans-serif; + } + + body { + color: black; + background: white; + background-color: white; + background-position: top left; + background-attachment: fixed; + background-repeat: no-repeat; + margin-top: 2em; + margin-right: 10%; + margin-left: 10%; + } + + hr { + height: 1px; + border: 0; + color: #004400; + background-color: #004400; + } + + + h1, h2, h3, h4, h5, h6 { + font-family: verdana, sans-serif; + } + + h1 { text-align: center; } + h2, h3, h4, h5, h6 { text-align: left; + padding-top: 2em; + } + h1, h2, h3 { font-family: "Trebuchet MS", sans-serif; + color: #09550B; + } + h1 { font-weight: bold; font-size: 170%; } + h2 { font-weight: bold; font-size: 140%; } + h3 { font-weight: bold; font-size: 118%; } + h4 { font-weight: bold; font-size: 100%; } + h5 { font-style: italic; font-size: 100%; } + h6 { font-variant: small-caps; font-size: 100%; } + + .hide { + display: none; + color: white; + } + + + p { + margin-top: 0.6em; + margin-bottom: 0.6em; + margin-left: 0.0em; + margin-right: 0.0em; + } + + + address { + text-align: right; + font-weight: bold; + font-style: italic; + font-size: 80%; + } + + + caption { font-weight: bold } + + + blockquote { + margin-left: 4em; + margin-right: 4em; + margin-top: 0.8em; + margin-bottom: 0.8em; + font-style: italic; + color: #003300; + } + + blockquote p { + margin-bottom: 0; + } + + blockquote address { + margin: 0; + } + + + table { + border-collapse: collapse; + } + + dt, dd { margin-top: 0; margin-bottom: 0; } + dt { font-weight: bold; } + + + pre, tt, code { + font-family: "andale mono", monospace; + font-size: 100%; + white-space: pre; + } + + pre { + font-size: 80%; + border: solid; + border-width: thin; + border-color: #003300; + background-color: #EEEEEE; + padding: 0.5em; + margin-left: 2em; + margin-right: 2em + } + + tt { color: green; } + em { font-style: italic; font-weight: bold; } + strong { font-weight: bold; } + + span.textit { font-style: italic; } + span.textbf { font-weight: bold; } + + .small { font-size: 90%; } + .white { color: #FFFFFF; } + + + ul.toc { + list-style: disc; + list-style: none; + } + + + a:link img, a:visited img { border-style: none; } + a img { color: white; } + + a:link, a:active, a:visited { + color: #09550B; + text-decoration: none; + } + + a:hover, a:focus { + color: #FF9900; + text-decoration: underline; + } + + + + +/* + * x-----------------------------------------------------------------x + * | Doxygen Specific Classes | + * x-----------------------------------------------------------------x + */ + + +/* ------------------------------------------------------------------- + * Header & Footer Classes (customized top page navigation bar). + */ + + table.header { + width: 100%; + /*background-color: #EEEEEE;*/ + background-color: #CCE6CA; + } + + h1.header { + font-family: times, verdana, sans-serif; + } + + td.header { + /*width: 14%;*/ + text-align: center; + font-weight: bold; + font-family: verdana, sans-serif; + } + + table.footer { + width: 100%; + } + + td.leftFoot1, td.leftFoot2 { + text-align: left; + } + + td.rightFoot1, td.rightFoot2 { + text-align: right; + } + + td.leftFoot2 { + font-family: time; + font-weight: bold; + } + + td.rightFoot2 { + font-weight: bold; + } + + div.ah { + font-family: time; + font-size: 250%; + } + + +/* ------------------------------------------------------------------- + * Quick Index Class (top page navigation bar). + */ + + div.qindex, div.nav { + width: 100%; + /*background-color: #DADAEF;*/ + /*background-color: #eeeeff;*/ + /*background-color: #EEEEEE;*/ + background-color: #CCE6CA; + border: 1px solid #003300; + text-align: center; + margin: 2px; + padding: 2px; + line-height: 140%; + } + + a.qindex, a.qindex:visited, a.qindex:hover, a.qindexHL, a.el, a.elRef { + text-decoration: none; + font-weight: bold; + } + + a.qindex, a.qindex:visited { + color: #09550B; + } + + a.qindex:hover { + background-color: #ddddff; + } + + a.qindexHL, a.qindexHL:hover, a.qindexHL:visited { + background-color: #0c780c; + color: #ffffff; + border: 1px double #9295C2; + } + + a.code:link, a.code:visited, a.codeRef:link, a.codeRef:visited { + text-decoration: none; + font-weight: normal; + color: #0000ff; + } + + .indexkey { + background-color: #eeeeff; + border: 1px solid #b0b0b0; + padding: 2px 15px; + } + + .indexkey, .indexvalue { + background-color: #eeeeff; + border: 1px solid #b0b0b0; + padding: 2px 15px; + } + + .indexkey { + width: 40%; + } + + .indexvalue { + width: 80%; + } + + +/* ------------------------------------------------------------------- + * Verbatim Source Code / Examples. + */ + + pre.fragment { background-color: #EEEEEE; } + + span.keyword { color: #008000 } + span.keywordtype { color: #604020 } + span.keywordflow { color: #e08000 } + span.comment { color: #800000 } + span.preprocessor { color: #806020 } + span.stringliteral { color: #002080 } + span.charliteral { color: #008080 } + + +/* ------------------------------------------------------------------- + * Attributes Listing. + */ + + .mdTable { + /*border: 1px solid #868686;*/ + /*background-color: #DADAEF;*/ + /*background-color: #F4F4FB;*/ + border: 1px none #868686; + /*background-color: #B8E6B8;*/ + background-color: #CCE6CA; + margin-top: 25px; + } + + .mdRow { + padding: 5px 10px; + } + + /* This Mozilla/Firefox bug has been corrected from v1.5. + * .mdname1 { + * padding: 3px 0px 0px 0px; + * } + */ + + .mdescLeft, .mdescRight { + padding: 0px 8px 4px 8px; + font-size: 12px; + font-style: italic; + /*background-color: #FAFAFA;*/ + border-top: 1px none #E0E0E0; + border-right: 1px none #E0E0E0; + border-bottom: 1px none #E0E0E0; + border-left: 1px none #E0E0E0; + margin: 0px; + } + + .memItemLeft, .memItemRight, .memTemplItemLeft { + padding: 1px 0px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #0c0c0c; + border-right-color: #0c0c0c; + border-bottom-color: #0c0c0c; + border-left-color: #0c0c0c; + border-top-style: solid; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + /*background-color: #DADAEF;*/ + /*background-color: #eeeeff;*/ + /*background-color: #EEEEEE;*/ + background-color: #CCE6CA; + } + + .memItemLeft { font-size: 12px; } + .memItemRight { font-size: 13px; } + .memTemplItemLeft { font-size: 12px; } + .memTemplItemRight { font-size: 13px; } + + .memTemplParams { + color: #606060; + background-color: #DADAEF; + font-size: 12px; + } + diff --git a/katabatic/doc/ASIM.css b/katabatic/doc/ASIM.css new file mode 100644 index 00000000..6d92a0c5 --- /dev/null +++ b/katabatic/doc/ASIM.css @@ -0,0 +1,485 @@ + + +/* + * x-----------------------------------------------------------------x + * | HTML Standart Tags | + * x-----------------------------------------------------------------x + */ + + html, body, th, td, tr, p, li, h1, h2, h3, h4, h5, h6 { + font-size: 96%; + font-family: verdana, sans-serif; + } + + body { + color: black; + background: white; + background-color: white; + background-position: top left; + background-attachment: fixed; + background-repeat: no-repeat; + margin-top: 2em; + margin-right: 8%; + margin-left: 8%; + } + + hr { + height: 1px; + border: 0; + color: #004400; + background-color: #004400; + } + + + h1, h2, h3, h4, h5, h6 { + font-family: verdana, sans-serif; + } + + h1 { text-align: center; } + h2, h3, h4, h5, h6 { text-align: left; + padding-top: 2em; + } + h1, h2, h3 { font-family: "Trebuchet MS", sans-serif; + color: #09550B; + } + h1 { font-weight: bold; font-size: 170%; } + h2 { font-weight: bold; font-size: 140%; } + h3 { font-weight: bold; font-size: 118%; } + h4 { font-weight: bold; font-size: 100%; } + h5 { font-style: italic; font-size: 100%; } + h6 { font-variant: small-caps; font-size: 100%; } + + h2.classHierarchy { + /*border: 1px none #008500;*/ + border: 1px none #000000; + border-top-width: 2px; + border-top-style: solid; + padding-top: 1em; + } + + + .hide { + display: none; + color: white; + } + + + p { + margin-top: 0.6em; + margin-bottom: 0.6em; + margin-left: 0.0em; + margin-right: 0.0em; + } + + + address { + text-align: right; + font-weight: bold; + font-style: italic; + font-size: 80%; + } + + + caption { font-weight: bold } + + + blockquote { + margin-left: 4em; + margin-right: 4em; + margin-top: 0.8em; + margin-bottom: 0.8em; + font-style: italic; + color: #003300; + } + + blockquote p { + margin-bottom: 0; + } + + blockquote address { + margin: 0; + } + + + table { + border-collapse: collapse; + } + + dt, dd { margin-top: 0; margin-bottom: 0; } + dt { font-weight: bold; } + + + pre, tt, code { + font-family: "andale mono", monospace; + font-size: 100%; + white-space: pre; + } + + pre { + font-size: 80%; + border: dashed; + border-width: thin; + border-color: #003300; + /* + background-color: #EEEEEE; + */ + background-color: #FCFCE1; + padding: 0.5em; + margin-left: 2em; + margin-right: 2em + } + + tt { color: green; } + em { font-style: italic; + font-weight: bold; } + strong { font-weight: bold; } + + span.textit { font-style: italic; } + span.textbf { font-weight: bold; } + + .small { font-size: 90%; } + .white { color: #FFFFFF; } + + + ul.toc { + list-style: disc; + list-style: none; + } + + + a:link img, a:visited img { border-style: none; } + a img { color: white; } + + a:link, a:active, a:visited { + color: #09550B; + text-decoration: none; + } + + a:hover, a:focus { + color: #FF9900; + text-decoration: underline; + } + + + + +/* + * x-----------------------------------------------------------------x + * | Doxygen Specific Classes | + * x-----------------------------------------------------------------x + */ + + +/* ------------------------------------------------------------------- + * Header & Footer Classes (customized top page navigation bar). + */ + + h1.header { + font-size: 200%; + font-family: times, verdana, sans-serif; + } + + center.header { + background-color: #CCE6CA; + } + + table.header { + /*width: 100%;*/ + /*background-color: #EEEEEE;*/ + background-color: #CCE6CA; + } + + table.header td { + padding: 2px 14px; + text-align: center; + font-weight: bold; + font-family: verdana, sans-serif; + font-size: 110%; + } + + table.footer1, table.footer2 { width: 100%; } + td.LFooter { text-align: left; } + td.RFooter { text-align: right; } + td.CFooter { text-align: center;} + table.footer2 td.RFooter { font-weight: bold; width: 35% } + table.footer2 td.CFooter { width: 30% } + table.footer2 td.LFooter { font-weight: bold; width: 35%; font-family: time; } + + table.classHierarchy { + border-collapse: separate; + border-spacing: 5px; + font-size: 110%; + } + + table.classHierarchy tr { + border: 1px solid blue; + } + + table.classHierarchy td.normal { + border: 1px solid #CCE6CA; + width: 140pt; + text-align: center; + font-weight: bold; + background-color: #CCE6CA; + } + + table.classHierarchy td.virtual { + border: 1px solid black; + width: 140pt; + text-align: center; + font-weight: bold; + } + + table.classHierarchy td.wnormal { + border: 1px solid #CCE6CA; + width: 240pt; + text-align: center; + font-weight: bold; + background-color: #CCE6CA; + } + + table.classHierarchy td.wvirtual { + border: 1px solid black; + width: 240pt; + text-align: center; + font-weight: bold; + } + + div.ah { + font-family: time; + font-size: 250%; + } + + +/* ------------------------------------------------------------------- + * Quick Index Class (top page navigation bar). + */ + + div.qindex, div.nav { + width: 100%-4px; + /*background-color: #DADAEF;*/ + /*background-color: #eeeeff;*/ + /*background-color: #EEEEEE;*/ + background-color: #CCE6CA; + border: 0px solid #003300; + text-align: center; + margin: 0px; + padding: 2px; + line-height: 140%; + } + + a.qindex, a.qindex:visited, a.qindex:hover, a.qindexHL, a.el, a.elRef { + text-decoration: none; + font-weight: bold; + } + + a.qindex, a.qindex:visited { + color: #09550B; + } + + a.qindex:hover { + background-color: #ddddff; + } + + a.qindexHL, a.qindexHL:hover, a.qindexHL:visited { + background-color: #0c780c; + color: #ffffff; + border: 1px double #9295C2; + } + + a.code:link, a.code:visited, a.codeRef:link, a.codeRef:visited { + text-decoration: none; + font-weight: normal; + color: #0000ff; + } + + .indexkey { + background-color: #eeeeff; + border: 1px solid #b0b0b0; + padding: 2px 15px; + } + + .indexkey, .indexvalue { + background-color: #eeeeff; + border: 1px solid #b0b0b0; + padding: 2px 15px; + } + + .indexkey { + width: 40%; + } + + .indexvalue { + width: 80%; + } + + h3 a[name="index__"], + h3 a[name="index_a"], + h3 a[name="index_b"], + h3 a[name="index_c"], + h3 a[name="index_d"], + h3 a[name="index_e"], + h3 a[name="index_f"], + h3 a[name="index_g"], + h3 a[name="index_h"], + h3 a[name="index_i"], + h3 a[name="index_j"], + h3 a[name="index_k"], + h3 a[name="index_l"], + h3 a[name="index_m"], + h3 a[name="index_n"], + h3 a[name="index_o"], + h3 a[name="index_p"], + h3 a[name="index_q"], + h3 a[name="index_r"], + h3 a[name="index_s"], + h3 a[name="index_t"], + h3 a[name="index_u"], + h3 a[name="index_v"], + h3 a[name="index_w"], + h3 a[name="index_x"], + h3 a[name="index_y"], + h3 a[name="index_z"], + h3 a[name="index_0"], + h3 a[name="index_1"], + h3 a[name="index_2"], + h3 a[name="index_3"], + h3 a[name="index_4"], + h3 a[name="index_5"], + h3 a[name="index_6"], + h3 a[name="index_7"], + h3 a[name="index_8"], + h3 a[name="index_9"] + { + font-family: time; + font-size: 250%; + } + + +/* ------------------------------------------------------------------- + * Verbatim Source Code / Examples. + */ + + /* pre.fragment { background-color: #EEEEEE; } */ + + span.keyword { color: #008000 } + span.keywordtype { color: #604020 } + span.keywordflow { color: #e08000 } + span.comment { color: #800000 } + span.preprocessor { color: #806020 } + span.stringliteral { color: #002080 } + span.charliteral { color: #008080 } + + +/* ------------------------------------------------------------------- + * Attributes Listing. + */ + + .mdTable { + /*border: 1px solid #868686;*/ + /*background-color: #DADAEF;*/ + /*background-color: #F4F4FB;*/ + border: 1px none #008500; + border-left-width: 1px; + border-left-style: solid; + /*background-color: #B8E6B8;*/ + /*background-color: #CCE6CA;*/ + margin-top: 25px; + font-size: 105%; + } + + .mdRow { + padding: 5px 10px; + } + + /* This Mozilla/Firefox bug has been corrected from v1.5. + * .mdname1 { + * padding: 3px 0px 0px 0px; + * } + */ + + .mdescLeft, .mdescRight { + padding: 0px 8px 4px 8px; + font-size: 11px; + font-style: italic; + /*background-color: #FAFAFA;*/ + border-top: 1px none #E0E0E0; + border-right: 1px none #E0E0E0; + border-bottom: 1px none #E0E0E0; + border-left: 1px none #E0E0E0; + margin: 0px; + } + + .memitem { + margin-bottom: 30px; + border: 1px none #008500; + } + + .memproto { + background-color: #CCE6CA; + border-left-width: 4px; + border-left-style: solid; + border-color: #008500; + } + + .memname { + white-space: nowrap; + padding-left: 5px; + font-size: 105%; + } + + + .memdoc{ + padding-left: 5px; + /*margin-top: -8px;*/ + border-left-width: 1px; + border-left-style: solid; + border-color: #008500; + } + + .memItemLeft, .memItemRight, .memTemplItemLeft, .memTemplItemRight { + padding: 1px 0px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #0c0c0c; + border-right-color: #0c0c0c; + border-bottom-color: #0c0c0c; + border-left-color: #0c0c0c; + border-top-style: solid; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + /*background-color: #DADAEF;*/ + /*background-color: #eeeeff;*/ + /*background-color: #EEEEEE;*/ + background-color: #CCE6CA; + } + + .memTemplItemLeft, .memTemplItemRight { + border-bottom-width: 2px; + border-bottom-style: solid; + font-weight: bold; + } + + .memItemLeft { font-size: 11px; } + .memItemRight { font-size: 12px; } + .memTemplItemLeft { font-size: 11px; } + .memTemplItemRight { font-size: 12px; } + + .memTemplParams { + color: #FFFFFF; + background-color: #000000; + font-size: 11px; + font-weight: bold; + } + + .groupText, .groupHeader { + color: #09550B; + margin-top: 15px; + font-size: 130%; + font-weight: bold; + } + diff --git a/katabatic/doc/AutoContact.dox b/katabatic/doc/AutoContact.dox new file mode 100644 index 00000000..71c49147 --- /dev/null +++ b/katabatic/doc/AutoContact.dox @@ -0,0 +1,364 @@ + + // -*- C++ -*- + + + namespace Katabatic { + + /*! \class AutoContact + * \brief Self-sizing Contact (\b API). + * + * \see \ref buildRules. + * + * \section secAutoContactSplitting AutoContact splitting mechanism + * + * An AutoContact splitting occurs when more than two layers connects + * to a single AutoContact. + * + * General Case + * + *
    + *
  1. Create a \b secondary contact, so that both the original + * and the secondary abide by the two layers rule. + *
  2. Create new AutoSegments to connect original to secondary. + * There could be one or two segments created according to + * the layers distance. + *
  3. Re-attach the AutoSegments to the right AutoContact. + * The rule being that an AutoSegment is attached to the + * lowest AutoContact containing it's Layer. + *
  4. The orignal & secondary contact are passed trough + * the connexity restauration procedure. + *
+ * + * Importants Points + * + * + * + * Special Cases + * + * + * \image html AutoContact-12.png + * \image html AutoContact-13.png + * \image html AutoContact-14.png + * \image html AutoContact-15.png + * \image latex AutoContact-12.pdf + * \image latex AutoContact-13.pdf + * \image latex AutoContact-14.pdf + * \image latex AutoContact-15.pdf + */ + + /* \var GCell* AutoContact::_gcell + * \brief The GCell into which the AutoContact is located. + */ + + /*! \function AutoContact* AutoContact::fromRp ( GCell* gcell, RoutingPad* routingPad, const Layer* layer, Point point, DbU::Unit width, DbU::Unit height, bool fixed=false ); + * \param gcell The GCell in which to create the AutoContact. + * \param routingPad The RoutingPad on which to anchor the AutoContact. + * \param layer The AutoContact's layer. + * \param point The absolute position of the AutoContact. + * \param width AutoContact's width. + * \param height AutoContact's height. + * \param fixed The AutoContact cannot be moved. + * \return Newly created AutoContact. + * + * create an AutoContact anchored on a \c RoutingPad. The AutoContact can + * be moved along the \c RoutingPad but not outside it. + * + * A remark on the \c point parameter : it must be absolute coordinates, but + * as we uses the \c RoutingPad as an anchor they are translated into an + * offset from the \c RoutingPad (see how \c Hurricane handles coordinates + * through anchoring). It is also assumed that the AutoContact is to be + * electrically connected to the \c RoutingPad (no disconnection). + * So, we will faces three cases, depending on the \c RoutingPad + * underlying \c Entity : + * + */ + + /*! \function AutoContact* AutoContact::create ( GCell* gcell, Net* net, const Layer* layer, bool hAlignate=false, bool vAlignate=false ) + * \param gcell The GCell into which the AutoContact will be put. + * \param net The AutoContact's owner Net. + * \param layer The AutoContact's layer. + * \param hAlignate Keeps alignate (all) horizontal segments. + * \param vAlignate Keeps alignate (all) vertical segments. + * \return A new AutoContact. + * + * As AutoContact are Contacts restricted to, at best, two adjacent + * routing layers, the layer argument is either a single routing + * contact or a two metals only VIA. + */ + + /*! \function AutoContact* AutoContact::create ( GCell* gcell, RoutingPad* rp, const Layer* layer, const DbU::Unit dx, const DbU::Unit dy, const DbU::Unit width, const DbU::Unit height, bool hAlignate=false, bool vAlignate=false, bool fixed=false ); + * \param gcell The GCell into which the AutoContact will be put. + * \param rp The RoutingPad anchor. + * \param layer The AutoContact's layer. + * \param dx Horizontal offset to the component. + * \param dy Vertical offset to the component. + * \param width Width of the AutoContact. + * \param height Height of the AutoContact. + * \param hAlignate Keeps alignate (all) horizontal segments. + * \param vAlignate Keeps alignate (all) vertical segments. + * \param fixed The AutoContact cannot be moved. + * \return A new AutoContact. + * + * create an AutoContact anchored on a component : the component must + * be a \RoutingPad, sets the isTerminal() flag. + * + * As AutoContact are Contacts restricted to, at best, two adjacent + * routing layers, the layer argument is either a single routing + * contact or a two metals only VIA. + */ + + /*! \function GCell* AutoContact::getGCell() const + * \brief Returns the GCell into which the AutoContact is located. + */ + + /*! \function void AutoContact::updateGeometry() + * \brief Perform the segment resizing. + * + * As it will resizes Hurricane components, this function call must + * be enclosed into an updateSession. + */ + + /*! \function AutoContacts AutoContact::getCollapseds ( unsigned int direction ); + * \param direction restrict the search to that direction. + * \return The \c Collection of AutoContact that are collapsed on this one, + * that is, linked through collapsed AutoSegment of type + * \c direction. + */ + + /*! \function bool AutoContact::isTerminal () const; + * \return \true if the AutoContact is anchored on a terminal. + */ + + /*! \function bool AutoContact::isHAlignate () const; + * \return \true if the horizontal AutoSegment anchored on the AutoContact + * must be kept aligned. + * \see \ref collapseCanonical + */ + + /*! \function bool AutoContact::isVAlignate () const; + * \return \true if the vertical AutoSegment anchored on the AutoContact + * must be kept aligned. + * \see \ref collapseCanonical + */ + + /*! \function void AutoContact::getLengths ( DbU::Unit* lengths, set& segments ); + * \return Increment the table of lengths for the lengths of segments of + * this AutoContact and inside it's owning GCell. + */ + + /*! \function void AutoContact::setTerminal ( bool isTerminal ); + * \param isTerminal set the terminal flag. + */ + + /*! \function bool AutoContact::isHExtended (); + * \return \true if the \b privileged direction of the AutoContact is horizontal. + * + * To be privileged in horizontal direction means that the \c Y coordinates + * of all horizontals of the AutoContact are the same and imposed in either + * of the following ways: + * + * \note An AutoContact can be neither horizontally extended nor vertically + * extended. In which case it is punctual. + * + * \image html AutoContact-10.png + * \image latex AutoContact-10.pdf + */ + + /*! \function bool AutoContact::isVExtended (); + * \return \true if the \b privileged direction of the AutoContact is vertical. + * + * To be privileged in vertical direction means that the \c X coordinates + * of all verticals of the AutoContact are the same and imposed in either + * the following way: + * + * \note An AutoContact can be neither horizontally extended nor vertically + * extended. In which case it is punctual. + * + * \image html AutoContact-11.png + * \image latex AutoContact-11.pdf + */ + + /*! \function void AutoContact::setHAlignate ( bool hAlignate ); + * \param hAlignate The new horizontal alignement mode. + * + * When horizontal aligment mode is active, all horizontals of the + * AutoContact are kept aligned (on the same \b Y coordinate). + * \see \ref collapseCanonical + */ + + /*! \function void AutoContact::setVAlignate ( bool vAlignate ); + * \param vAlignate The new vertical alignement mode. + * + * When vertical aligment mode is active, all verticals of the + * AutoContact are kept aligned (on the same \b X coordinate). + * \see \ref collapseCanonical + */ + + /*! \function void AutoContact::restoreHConnexity ( DbU::Unit y, bool split=false ); + * \param y When splitting, the coordinate of the vertical strap segments. + * \param split Wether to separate the various horizontals or not. + * + * Ensure that there is no gap between horizontals of this AutoContact. + * + * In case of splitting, all the verticals are kept on the original AutoContact. + */ + + /*! \function void AutoContact::restoreVConnexity ( DbU::Unit x, bool split=false ); + * \param x When splitting, the coordinate of the horizontal strap segments. + * \param split Wether to separate the various verticals or not. + * + * Ensure that there is no gap between verticals of this AutoContact. + * + * In case of splitting, all the horizontals are kept on the original AutoContact. + */ + + /*! \function void AutoContact::invalidate (); + * Put this AutoContact into the invalidated set (see \ref katabaticSession). + */ + + + //! \addtogroup katabaticSession + //! \{ + + /*! \function bool AutoContact::isInvalidated () const; + * \return \True if the AutoContact is invalidated, i.e. in the + * Katabatic Session, one or more of it's anchored AutoSegment + * being moved. + * + * \see autoInvalidate(). + */ + + /*! \function bool AutoContact::setInvalidated ( bool state ); + * \param state set the state of the AutoContact regarding the + * Katabatic Session. + * + * \see autoInvalidate(). + */ + + /*! \function Box AutoContact::getNativeConstraintBox () const; + * Return the native constraint box, that is, the \Box of the + * owning GCell or the bounding box of the terminal it's anchored + * upon. + */ + + /*! \function DbU::Unit AutoContact::getCBXMin () const; + * \return The X coordinate of the lower left corner. + */ + + /*! \function DbU::Unit AutoContact::getCBYMin () const; + * \return The Y coordinate of the lower left corner. + */ + + /*! \function DbU::Unit AutoContact::getCBXMax () const; + * \return The X coordinate of the upper right corner. + */ + + /*! \function DbU::Unit AutoContact::getCBYMax () const; + * \return The Y coordinate of the upper right corner. + */ + + /*! \function Box AutoContact::getConstraintBox () const; + * \return The current constraint box. + */ + + /*! \function Box& AutoContact::intersectConstraintBox ( Box& box ) const; + * \param box The box to intersect width. + * \return A reference on the the box given as argument. + * + * Do the intersection of the constraint box and the one given + * as argument. Store the result in place. + */ + + /*! \function void AutoContact::restoreNativeConstraintBox (); + * reset the constraint box to the native constraint box. + */ + + /*! \function void AutoContact::setConstraintBox ( const Box& box ); + * \param box The new constraint box. + * + * sets the constraint box. + */ + + /*! \function void AutoContact::restrictConstraintBox ( DbU::Unit constraintMin, DbU::Unit constraintMax, unsigned int direction ); + * \param constraintMin The constraint lower bound. + * \param constraintMax The constraint upper bound. + * \param direction The direction into which apply the constraint. + * + * restrict the constraint box in one direction. + */ + + /*! \function void AutoContact::setCBXMin ( DbU::Unit xMin ); + * \param xMin The X cooordinate of the lower left corner. + * + * sets the X coordinate of the lower left corner. + */ + + /*! \function void AutoContact::setCBYMin ( DbU::Unit yMin ); + * \param yMin The Y cooordinate of the lower left corner. + * + * sets the Y coordinate of the lower left corner. + */ + + /*! \function void AutoContact::setCBXMax ( DbU::Unit xMax ); + * \param xMax The X cooordinate of the upper right corner. + * + * sets the X coordinate of the upper right corner. + */ + + /*! \function void AutoContact::setCBYMax ( DbU::Unit yMax ); + * \param yMax The Y cooordinate of the upper right corner. + * + * sets the Y coordinate of the upper right corner. + */ + + //! \} + + } + + + namespace { + + } diff --git a/katabatic/doc/AutoSegment.dox b/katabatic/doc/AutoSegment.dox new file mode 100644 index 00000000..ae35d17c --- /dev/null +++ b/katabatic/doc/AutoSegment.dox @@ -0,0 +1,677 @@ + + // -*- C++ -*- + + + namespace Katabatic { + + /*! \class AutoSegment + * \brief Self-sizing segment (\b API). + * + * AutoSegment provide an uniform way of accessing AutoHorizontal + * and AutoVertical self-sizing segments. AutoSegments mainly contains + * a pointer to the associated Horizontal/Vertical Hurricane segment. + * This is the Hurricane segment which is part of the ring of the + * AutoContact. Thus we can directly access the Hurricane segment + * from the AutoSegment, but for the othey around we uses a lookup + * table in the Katabatic \c ToolEngine (see the + * Katabatic::_Lookup() member function). + * + * In order to inform the router of an AutoSegment state change, + * a callback function SegmentRevalidateCB can be positionned. + * + * \c Segment associated to AutoSegment are automatically oriented + * in such a way that the source \c Hook is always \e lower than + * the target \c hook. For an Horizontal segment it means that + * the abcissa of the source is inferior to the abcsissa of the + * target. It goes the same way for Vertical segment with the + * ordinate. + * + * KatabaticSession mechanism : this is fairly similar to the + * \c Hurricane updateSession one. When a segment is either moved + * by the router or resized by it's AutoContact it is invalidated + * with autoInvalidate() and put into the set of invalidated + * segments. When the KatabaticSession is closed the onRevalidate() + * member function is called on each segment, which in turn calls + * the router's callback. See Session::open(), Session::revalidate(), + * Session::close() and \ref katabaticSession. + * + * \remark As this object uses the decorator Design Pattern, almost all + * functions are pure virtuals. Implementation take place in a + * derived class \c AutoSegmentConcrete which is not documented, + * (same specifications as AutoSegment). + * + * \see AutoSegmentDecorator class. + */ + + /*! \typedef AutoSegment::RevalidateCb_t ( AutoSegment* ) + * Function type for the router callback. See AutoSegment::setRevalidateCb(). + */ + + /* \function static AutoSegment::RevalidateCb_t* AutoSegment::setRevalidateCb ( RevalidateCb_t* cb ); + * \param cb The new router callback to install. + * \return The previous router callback. + * + * Install the callback to call when an AutoSegment is revalidated, + * The callback is called by onRevalidate() on closing the Katabatic + * update session. + */ + + /*! \function bool AutoSegment::isHorizontal () const; + * \return \true if the AutoSegment is horizontal. + */ + + /*! \function bool AutoSegment::isVertical () const; + * \return \true if the AutoSegment is vertical. + */ + + /*! \function bool AutoSegment::isGlobal () const; + * \return \true if the AutoSegment is global : source and target + * AutoContact are not in the same GCell. + */ + + /*! \function bool AutoSegment::isLocal () const; + * \return \true if the AutoSegment is local : source and target + * belongs to the same GCell. + */ + + /*! \function bool AutoSegment::isTerminal () const; + * \return \true if the AutoSegment is terminal : the only way + * to access a terminal AutoContact (may not be directly + * achored on that terminal). + */ + + /*! \function bool AutoSegment::isCollapsed () const; + * \return \true if the AutoSegment is collapsed : kept to zero-length. + */ + + /*! \function bool AutoSegment::isCanonical () const; + * \return \true if the AutoSegment is canonical that is, the leftmost + * (for horizontal) or lowest (for vertical) segment of a set + * of collapsed segments. The canonical segment must be used + * as the unique representant for the collapsed set. + */ + + /*! \function bool AutoSegment::isFixed () const; + * \return \true if the AutoSegment cannot be moved (through setAxis()). + */ + + /*! \function bool AutoSegment::isAccountable () const; + * \return \true if the AutoSegment is canonical and not collapsed. + * Normally those flags are mutually exclusives, but better safe + * than sorry. + * + */ + + /*! \function virtual GCell* AutoSegment::getGCell () const; + * \return The GCell owning the source AutoContact. + */ + + /*! \function Net* AutoSegment::getNet () const; + * \return The net this AutoSegment is part of. + */ + + /*! \function Layer* AutoSegment::getLayer () const; + * \return The layer of the AutoSegment. + */ + + /*! \function virtual Segment* AutoSegment::getSegment (); + * \return The associated \c Hurricane segment. + */ + + /*! \function virtual Segment* AutoSegment::getSegment () const; + * \return The associated \c Hurricane segment. + * + * This function is for use in const members. + */ + + /*! \function virtual Segment* AutoSegment::getHorizontal (); + * \return If the the associated segment is horizontal, returns it. + * Otherwise (vertical) returns \c NULL. + */ + + /*! \function virtual Segment* AutoSegment::getVertical (); + * \return If the the associated segment is vertical, returns it. + * Otherwise (horizontal) returns \c NULL. + */ + + /*! \function DbU::Unit AutoSegment::getAxis () const; + * \return The segment axis : Y for horizontals and X for verticals. + */ + + /*! \function AutoContact* AutoSegment::getSource () const; + * \return The source AutoContact. + */ + + /*! \function AutoContact* AutoSegment::getTarget () const; + * \return The target AutoContact. + */ + + /*! \function DbU::Unit AutoSegment::getSourcePosition () const; + * \return The lower bound of the segment into the routing track, equal + * the source coordinate minus the half pitch. + */ + + /*! \function DbU::Unit AutoSegment::getTargetPosition () const; + * \return The upper bound of the segment into the routing track, equal + * the target coordinate plus the half pitch. + */ + + /*! \function virtual void AutoSegment::setAxis ( DbU::Unit axis, bool realignate=false, set* processeds=NULL ); + * \param axis New coordinate of the axis. For an horizontal segment + * it will change the Y coordinate and for a vertical, + * the X coordinate. + * \param realignate It set to true, the new axis position will be propagated + * to all collapsed segments, even if the current AutoSegment + * don't need to be moved. + * \param processeds The set of already processeds aligneds AutoSegments. + * + * setAxis is the API frontend to the alignate function. It actually + * only checks if the segment has to be moved and if the move is to + * be propagated to the aligned AutoSegments. + */ + + /*! \function virtual void AutoSegment::orient (); + * sets the source and target \c Hook of the Hurricane segment so + * the source is always lower than the target. + */ + + /*! \function virtual void AutoSegment::invalidate (); + * adds the AutoSegment to the invalidate session. This will happens + * whenever a segment is moved by the router through setAxis() or + * resized by it's AutoContact. + */ + + /* \function virtual void AutoSegment::onRevalidate (); + * This function is called at the time the AutoUpdate session is closed + * and calls the router's callback. + */ + + /*! \function virtual void AutoSegment::getConstraints ( DbU::Unit& constraintMin, DbU::Unit& constraintMax ) const; + * \param constraintMin Where to store the constraint lower bound. + * \param constraintMax Where to store the constraint upper bound. + * \return Always \true (don't remember why...). + * + * Constraints are deduced from the constraint box of the source + * AutoContact. + * + * \see \ref NetConstraints + */ + + /*! \function virtual void AutoSegment::getConstraints ( Interval& i ) const; + * \param i The constraint interval. + * \return Always \true (don't remember why...). + * + * \see getConstraints(), \ref NetConstraints + */ + + /*! \function DbU::Unit AutoSegment::getSlack () const; + * \return The length of the constraint interval. + * + * \see \ref NetOptimals + */ + + /*! \function DbU::Unit AutoSegment::getOptimalMin () const; + * \return The lower bound of the optimal interval. + * + * \see \ref NetOptimals + */ + + /*! \function DbU::Unit AutoSegment::getOptimalMax () const; + * \return The upper bound of the optimal interval. + * + * \see \ref NetOptimals + */ + + /*! \function Interval& AutoSegment::getOptimal ( Interval& i ) const; + * \param i The optimal interval. + * \return The interval given as argument. + * + * \see \ref NetOptimals + */ + + /*! \function DbU::Unit AutoSegment::getCost ( DbU::Unit axis ) const; + * \param axis An axis coordinate. + * \return The distance from the nearest optimal interval bound. + * + * \see \ref NetOptimals + */ + + /*! \function AutoSegment* AutoSegment::getCanonical ( DbU::Unit& sourcePosition, DbU::Unit& targetPosition ); + * \param sourcePosition Lower bound of the super-AutoSegment. + * \param targetPosition Upper bound of the super-AutoSegment. + * \return The canonical AutoSegment of the super-AutoSegment. + * + * A super-AutoSegment is the set of all AutoSegment which have been + * bound together through (perpandicular) collapsed AutoSegment. + * They behave like one big AutoSegment. For algorithmic purpose we + * needs a canonical representant : it will be the lower AutoSegment + * (the one with the lower source coordinates). + * We also needs to know the real extend of the super-AutoSegment : it's + * returned through \c sourcePosition and \c targetPosition parameters. + */ + + /*! \function AutoSegment* AutoSegment::getCanonical ( Interval& i ); + * \param i interval of the super-AutoSegment. + * \return The canonical AutoSegment of the super-AutoSegment. + * + * \see AutoSegment::getCanonical(). + */ + + /*! \function AutoSegments AutoSegment::getCollapseds ( bool withPerpand=false ); + * \return The \Collection of AutoSegment that are collapsed to this one + * (i.e. linked through perpandicual collapsed ones). Together + * they forms one big virtual AutoSegment. + */ + + /*! \function AutoSegments AutoSegment::getCollapsedPerpandiculars (); + * \return The \Collection of AutoSegment that are perpandicular to this + * one and it's collapsed fellows. + * + * Note that this \Collection contains only \b GLOBAL perpandicular + * AutoSegment and \b Terminal perpandicular AutoSegment. + */ + + /*! \function void AutoSegment::setCanonical ( bool state ); + * \param state sets the isCanonical() flag to this value. + */ + + /*! \function void AutoSegment::setTerminal ( bool state ); + * \param state sets the isTerminal() flag to this value. + */ + + /*! \function void AutoSegment::setLayer ( const Layer* layer ); + * \param layer Changes the \Hurricane segment layer. + */ + + /*! \function void AutoSegment::setPositions (); + * compute the positions of the AutoSegment into the routing track, + * from the \Hurricane segment extentions and the half-pitch. + * + * \see getSourcePosition() & getTargetPosition(). + */ + + /*! \function void AutoSegment::collapse (); + * sets the AutoSegment into collapsed state (zero-length). + */ + + /*! \function void AutoSegment::expand (); + * Uncollapse the AutoSegment, re-compute the constraints on + * the splitted sets. + */ + + /*! \function bool AutoSegment::toConstraintAxis ( set* processeds=NULL ); + * \return \True if the AutoSegment axis has been moved. + * + * If the segment axis is outside the constraint interval, set it + * the nearest constraint interval bound. + */ + + /*! \function bool AutoSegment::toOptimalAxis ( set* processeds=NULL ); + * \return \True if the AutoSegment axis has been moved. + * + * If the segment axis is outside the optimal interval, set it + * the nearest optimal interval bound. + */ + + /*! \function void AutoSegment::alignate ( DbU::Unit axis ); + * \param axis New axis's coordinate. + * + * Move the segment axis to a new position. Adjust positions + * of the supporting Contact whenever they are anchored on terminals + * (i.e. RoutingPad). + * This function is atomic and should not be called directly + * but rather through setAxis(). It's implemented in the + * derived classes AutoHorizontal & AutoVertical. + */ + + /*! \function void AutoSegment::setOptimalMin ( DbU::Unit oMin ); + * \param oMin sets the lower bound of the optimal interval. + * + * \see getOptimalMin(), getOptimalMax(), getCost(). + */ + + /*! \function void AutoSegment::setOptimalMax ( DbU::Unit oMin ); + * \param oMin sets the upper bound of the optimal interval. + * + * \see getOptimalMin(), getOptimalMax(), getCost(). + */ + + /*! \function void AutoSegment::checkPositions () const; + * check the coherency between the locally shadowed values + * of source \& target position and the real ones. If a discrepancy + * is found issue an error (but do not stop the program). + * + * Note that discrepancies are legal while the AutoSegment is + * invalidated (see \ref katabaticSession). + */ + + /*! \function void AutoSegment::checkInvalidated () const; + * issue an error if the AutoSegment is invalidated. Mainly used + * to debug the Katabatic Session mechanism (\ref katabaticSession). + */ + + + //! \addtogroup NetOptimals + //! \{ + + /*! \function virtual void AutoSegment::computeOptimal ( set* processeds=NULL ); + * compute the AutoSegment optimal position interval. + */ + + /*! \function virtual DbU::Unit AutoSegment::getOrigin () const; + * \return The lower bound of the GCell in which the AutoSegment is + * (\c YMin for horizontals, \c XMin for verticals). + */ + + /*! \function virtual DbU::Unit AutoSegment::getExtremity () const; + * \return The upper bound of the GCell in which the AutoSegment is + * (\c YMax for horizontals, \c XMax for verticals). + */ + + //! \} + + + //! \addtogroup katabaticSession + //! \{ + + /*! \function bool AutoSegment::isInvalidated () const; + * \return \True if the AutoSegment is invalidated, i.e. in the + * Katabatic Session, it's axis having being moved by the + * router. + * + * \see autoInvalidate(). + */ + + /*! \function bool AutoSegment::setInvalidated ( bool state ); + * \param state set the state of the AutoSegment regarding the + * Katabatic Session. + * + * \see autoInvalidate(). + */ + + //! \} + + + /*! \class AutoHorizontal + * \brief Horizontal AutoSegment (\b API). + */ + + /*! \function static AutoHorizontal* AutoHorizontal::create ( Horizontal* horizontal, int type, bool terminal=false, bool collapsed=false ); + * \param horizontal The associated \c Hurricane segment. + * \param type Global, local or guessed kind. + * \param terminal Whether the segment is tightly linked to a terminal. + * \param collapsed Whether the segment must be kept of null length. + * \return The newly created AutoSegment. + */ + + /*! \function static AutoHorizontal* AutoHorizontal::create ( AutoContact* source, AutoContact* target, const Layer* layer, DbU::Unit y, DbU::Unit width, int type, bool terminal=false, bool collapsed=false ); + * \param source The source \c Component. + * \param target The target \c Component. + * \param layer The segment's layer. + * \param y The segment's Y coordinate. + * \param width The segment's width. + * \param type Global, local or guessed kind. + * \param terminal Whether the segment is tightly linked to a terminal. + * \param collapsed Whether the segment must be kept of null length. + * \return The newly created AutoSegment. + * + * Allocate both \c Hurricane segment and Katabatic AutoSegment. + */ + + + /*! \class AutoVertical + * \brief Vertical AutoSegment (\b API). + */ + + /*! \function static AutoVertical* AutoVertical::create ( Vertical* vertical, int type, bool terminal=false, bool collapsed=false ); + * \param vertical The associated \c Hurricane segment. + * \param type Global, local or guessed kind. + * \param terminal Whether the segment is tightly linked to a terminal. + * \param collapsed Whether the segment must be kept of null length. + * \return The newly created AutoSegment. + */ + + /*! \function static AutoVertical* AutoVertical::create ( AutoContact* source, AutoContact* target, const Layer* layer, DbU::Unit x, DbU::Unit width, int type, bool terminal=false, bool collapsed=false ); + * \param source The source \c Component. + * \param target The target \c Component. + * \param layer The segment's layer. + * \param x The segment's X coordinate. + * \param width The segment's width. + * \param type Global, local or guessed kind. + * \param terminal Whether the segment is tightly linked to a terminal. + * \param collapsed Whether the segment must be kept of null length. + * \return The newly created AutoSegment. + * + * Allocate both \c Hurricane segment and Katabatic AutoSegment. + */ + + + /*! \function AutoSegment* AutoSegment::create ( AutoContact* source, AutoContact* target, unsigned int dir, int type, bool terminal=false, bool collapsed=false ); + * \param source The source AutoContact. + * \param target The target AutoContact. + * \param dir The AutoSegment direction (\b H / \b V). + * \param type Whether the AutoSegment is \b LOCAL, \b GLOBAL or must be guessed. + * \param terminal The AutoSegment is used to connect a terminal. + * \param collapsed The AutoSegment is collapsed. + * \return A new AutoSegment. + * + * create the AutoSegment between \c source and \c target, update the GCell + * density if needed. + * + * If the \c dir parameter do not contains the \b HORIZONTAL or \b VERTICAL + * boolean flags an error will be thrown. + */ + + + /*! \enum AutoSegment::Type + * This enumeration is used to hints AutoSegment constructor about + * the kind of segment we are about to create. Once created, the + * kind of AutoSegment is stored in a single boolean telling + * wether it's \b GLOBAL or \b LOCAL (see AutoSegment::isGlobal()). + * + * It is always best to avoid using AutoSegment::Guess as it implies findind + * and checking source and target anchors (through ring access). + * And in most cases we already known the kind of segment because + * we created the source and target AutoContact just before... + * See GCellConfiguration related functions. + */ + + /*! \var AutoSegment::Global + * The AutosSegment crosses at least one GCell boundary (i.e. + * source and target AutoContact do not belong to the same GCell). + */ + + /*! \var AutoSegment::Local + * The AutoSegment is fully included in one GCell. + */ + + /*! \var AutoSegment::Guess + * The AutoSegment constructor will guess the kind of AutoSegment + * by examining source and target anchors. + */ + + /*! \defgroup collapseCanonical 3. AutoSegment collapse & Canonical (internal) + * + * \section AlignedAS Collapsing AutoSegment + * + * A set of AutoSegment can be aligned together. The set will + * behave like one big AutoSegment, especially, moving one + * AutoSegment through setAxis() will move the whole set. + * + * For each set of aligned AutoSegment, we provide a canonical + * AutoSegment : the leftmost (for horizontal) or lowermost for + * verticals. + * + * There are two ways AutoSegments could be aligned : + *
    + *
  • Through a collapsed perpandicular AutoSegment. + *
  • Through a locked AutoContact. + *
+ * + * \subsection AlignedByCollapsed Aligned through collapsed AutoSegment + * + * When an AutoSegment is collapsed, all perpandicular AutoSegment + * to it's source and target AutoContact are aligneds. Collapsing + * an AutoSegment means that it should be kept to zero length and + * thus not managed by the overlying router. + * + * \image html AutoSegmentCollapse-5.png "collapse by AutoSegment" + * \image latex AutoSegmentCollapse-5.pdf "collapse by AutoSegment" width=0.4\textwidth + * + * \subsection AlignedByAutoContact Aligned through collapsed AutoContact + * + * With the setHAlignate() and setVAlignate() the alignment of + * horizontal (resp. vertical) AutoSegment of an AutoContact can be + * forced. + * + * \image html AutoSegmentCollapse-6.png "collapse by AutoContact" + * \image latex AutoSegmentCollapse-6.pdf "collapse by AutoContact" width=0.4\textwidth + * + * \subsection collapsedExample An example of collapse/alignment + * + * \image html AutoSegmentCollapse-1.png "collapse - Step 1" + * \image latex AutoSegmentCollapse-1.pdf "collapse - Step 1" width=0.4\textwidth + * + * \image html AutoSegmentCollapse-2.png "collapse - Step 2" + * \image latex AutoSegmentCollapse-2.pdf "collapse - Step 2" width=0.4\textwidth + * + * \image html AutoSegmentCollapse-3.png "collapse - Step 3" + * \image latex AutoSegmentCollapse-3.pdf "collapse - Step 3" width=0.4\textwidth + * + * \image html AutoSegmentCollapse-4.png "collapse - Step 4" + * \image latex AutoSegmentCollapse-4.pdf "collapse - Step 4" width=0.4\textwidth + */ + + + //! \addtogroup collapseCanonical + //! \{ + + /*! \enum AutoSegment::PerpandicularState + * set of flags used to build the state of two AutoSegment. + * \see getPerpandicularState(). + */ + + /*! \var AutoSegment::PerpandicularAny + * The \e current AutoSegment is perpandicular to the \e master. + * May it be or not through collapsed perpandiculars. + */ + + /*! \var AutoSegment::PerpandicularIndirect + * The \e current AutoSegment is perpandicular to the \e master + * through at least one collapsed perpandicular. + */ + + /*! \var AutoSegment::ParallelOrExpanded + * The \e current AutoSegment is not part of the aligned set, + * it's either parallel but not aligned (no constraint on the + * AutoContact) or perpandicular and not collapsed. + */ + + /*! \var AutoSegment::ParallelAndLayerChange + * The \e current AutoSegment is parallel to the master but not on + * the same layer as the \e source (the \e master by transitivity). + */ + + /*! \function unsigned int AutoSegment::getPerpandicularState ( AutoContact* contact, AutoSegment* source, AutoSegment* current, bool isHorizontalMaster, const Layer* masterLayer=NULL ) + * \param contact The AutoContact shared by source \& current. + * \param source The AutoSegment from where we came. + * \param current The AutoSegment we are exploring. + * \param isHorizontalMaster The direction of the reference AutoSegment. + * \param masterLayer The \Layer of the reference AutoSegment. + * \return A composite value telling the position of current relative to + * source and reference. + * + * Locators of \Collections like AutoSegment::getCollapseds() or + * AutoSegment::getCollapsedPerpandiculars() are built on this + * function. Any \Collection manipulating aligned sets must uses + * this function which is the keystone of the aligned set walk-through. + * + * The return value is a combination of binary flags from the + * AutoSegment::PerpandicularState enumeration. The function + * compute the following boolean values : + *
    + *
  • \e sourcePerpandicular : \True if the \e source is perpandicular + * to the \e master AutoSegment. + *
  • \e currentPerpandicular : \True if the \e current is perpandicular + * to the \e master AutoSegment. + *
  • \e contactAlignate : \True if the alignment constraint on the + * AutoContact (if any) applies to \e source \& \e current. For instance + * it will be \True if both source and current are horizontal + * \b and AutoContact::isHAlignate() is \True. + *
+ * Then the return value is computed as follow : + *
    + *
  1. If \e current is parallel to \e master \b but not on the same + * layer. + * + * sets the AutoSegment::AutoSegment::ParallelAndLayerChange flag. + *
  2. If \e current is perpandicular to \e master \b and not + * collapsed, it is perpandicular to the aligned set of the + * \e master. + * + * sets the AutoSegment::AutoSegment::PerpandicularAny flag. + *
  3. \e source is perpandicular to \e master. There is an implicit + * context : the only way a perpandicular segment gets took into + * account, is to be collapsed. Then if the \e current AutoSegment + * is also perpandicular \b and \b not collapsed, it means + * that it's a perpandicular to the aligned set of the \e master, + * The difference with the previous case, is that it's through at + * least one collapsed perpandicular. + * + * sets the AutoSegment::AutoSegment::PerpandicularIndirect flag. + *
  4. \e source is parallel to \e master. Then we check for + * disconnection in the aligned set. Disconnection arises + * if the \e contactAlignate flag is \false (either no + * alignment constraint on the AutoContact or different + * directions), \b and the \e current segment is not a + * collapsed perpandicular. + * + * sets the AutoSegment::AutoSegment::ParallelOrExpanded flag. + *
+ * The \b zero return value means that the \e current AutoSegment + * belong to the same aligned set as the \e master \b or is a + * perpandicular collapsed AutoSegment. + * + * The figures below demonstrate all thoses case : + * + * \image html PerpandicularState-1.png "Simple Perpandicular (case 2)" + * \image latex PerpandicularState-1.pdf "Simple Perpandicular (case 2)" width=0.8\textwidth + * + * \image html PerpandicularState-2.png "Indirect Perpandicular (case 3)" + * \image latex PerpandicularState-2.pdf "Indirect Perpandicular (case 3)" width=0.8\textwidth + * + * \image html PerpandicularState-3.png "Parallel (case 4.1)" + * \image latex PerpandicularState-3.pdf "Parallel (case 4.1)" width=0.8\textwidth + * + * \image html PerpandicularState-4.png "Aligned through AutoContact (case 4.2)" + * \image latex PerpandicularState-4.pdf "Aligned through AutoContact (case 4.2)" width=0.8\textwidth + */ + + /*! \function unsigned int AutoSegment::getPerpandicularState ( AutoContact* contact, AutoSegment* source, AutoSegment* current, AutoSegment* master ) + * \param contact The AutoContact shared by source \& current. + * \param source The AutoSegment from where we came. + * \param current The AutoSegment we are exploring. + * \param master The reference AutoSegment. + * \return A composite value telling the position of current relative to + * source and reference. + */ + + /*! \function bool AutoSegment::arePerpandiculars ( AutoSegment* a, AutoSegment* b ); + * \param a First AutoSegment. + * \param b Second AutoSegment. + * \return true if a \& b have perpandicular directions. + */ + + /*! \function bool AutoSegment::areAligneds ( AutoSegment* a, AutoSegment* b ); + * \param a First AutoSegment. + * \param b Second AutoSegment. + * \return true if a \& b have same directions. + */ + + /*! \function bool AutoSegment::arePerpandiculars ( bool isHorizontalA, AutoSegment* b ); + * \param isHorizontalA is the A AutoSegment horizontal. + * \param b Second AutoSegment. + * \return true if a \& have perpandicular directions. + */ + + } diff --git a/katabatic/doc/CMakeLists.txt b/katabatic/doc/CMakeLists.txt new file mode 100644 index 00000000..75bc8217 --- /dev/null +++ b/katabatic/doc/CMakeLists.txt @@ -0,0 +1,12 @@ + + set ( htmlInstallDir /share/doc/en/html/katabatic ) + set ( latexInstallDir /share/doc/en/latex/katabatic ) + + add_custom_target ( doc ALL cd ${KATABATIC_SOURCE_DIR}/doc && ${DOXYGEN_EXECUTABLE} doxyfile ) + + install ( DIRECTORY html/ DESTINATION ${htmlInstallDir} ) + install ( FILES customHierarchy.html DESTINATION ${htmlInstallDir} ) + install ( FILES customSummary.html DESTINATION ${htmlInstallDir} ) + + install ( DIRECTORY latex/ DESTINATION ${latexInstallDir} ) + install ( FILES asimbook.cls DESTINATION ${latexInstallDir} ) diff --git a/katabatic/doc/GCell.dox b/katabatic/doc/GCell.dox new file mode 100644 index 00000000..64d9433a --- /dev/null +++ b/katabatic/doc/GCell.dox @@ -0,0 +1,179 @@ + + // -*- C++ -*- + + + namespace Katabatic { + + /*! \class GCell + * \brief Global Routing cell (\b API). + * + * \attention This class can only be allocated through a GCellGrid thus + * Constructors/Destructors are protecteds. + * + * \remark As this object uses the decorator Design Pattern, almost all + * functions are pure virtuals. Implementation take place in a + * derived class \c GCellConcrete which is not documented, + * (same specifications as GCell). + * + * \see GCellDecorator class. + */ + + /*! \function GCellGrid* GCell::getGCellGrid () const; + * \return The GCellGrid to which the GCell belongs. + */ + + /*! \function unsigned int GCell::getIndex () const; + * \return The linear index of this GCell inside the GCellGrid GCell table. + */ + + /*! \function unsigned int GCell::getRow () const; + * \return The GCell's row inside the GCellGrid (this is a Y coordinate). + */ + + /*! \function unsigned int GCell::getColumn () const; + * \return The GCell's row inside the GCellGrid (this is a X coordinate). + */ + + /*! \function Point GCell::getCenter () const; + * \return The center of the GCell. + */ + + /*! \function DbU::Unit GCell::getX () const; + * \return The X coordinate of the GCell's lower left corner (\b XMin). + */ + + /*! \function DbU::Unit GCell::getY () const; + * \return The Y coordinate of the GCell's lower left corner (\b YMin). + */ + + /*! \function DbU::Unit GCell::getXMax () const; + * \return The X coordinate of the GCell's upper right corner. + */ + + /*! \function DbU::Unit GCell::getYMax () const; + * \return The Y coordinate of the GCell's lower upper right corner. + */ + + /*! \function Box GCell::getBoundingBox () const; + * \return The GCell bounding box. + */ + + /*! \function GCell* GCell::getLeft () const; + * \return The CCell's left neighbour (may be \c NULL if first of the row). + */ + + /*! \function GCell* GCell::getRight () const; + * \return The CCell's right neighbour (may be \c NULL if last of the row). + */ + + /*! \function GCell* GCell::getUp () const; + * \return The CCell's up neighbour (may be \c NULL if top of the column). + */ + + /*! \function GCell* GCell::getDown () const; + * \return The CCell's down neighbour (may be \c NULL if bottom of the column). + */ + + /*! \function unsigned int GCell::getDensity ( unsigned int depth ) const; + * \return The density of vertical wires going through this GCell. + * \see updateDensity() + */ + + /*! \function unsigned int GCell::getCDensity () const; + * \return The AutoContact density. + * \see updateDensity() + */ + + /*! \function unsigned int GCell::getDensity () const; + * \return The average of horizontal and vertical density. + * \see updateDensity() + */ + + /*! \function vector* GCell::getVSegments (); + * \return All vertical AutoSegment, starting, ending or crossing this GCell. + */ + + /*! \function vector* GCell::getHSegments (); + * \return All horizontal AutoSegment, starting, ending or crossing this GCell. + */ + + /*! \function vector* GCell::getContacts (); + * \return All AutoContact belonging to this GCell. + */ + + /*! \function AutoSegments GCell::getVStartSegments (); + * \return All vertical AutoSegment starting from this GCell. + */ + + /*! \function AutoSegments GCell::getHStartSegments (); + * \return All horizontal AutoSegment starting from this GCell. + */ + + /*! \function AutoSegments GCell::getVStopSegments (); + * \return All vertical AutoSegment ending in this GCell. + */ + + /*! \function AutoSegments GCell::getHStopSegments (); + * \return All horizontal AutoSegment ending in this GCell. + */ + + /*! \function AutoSegments GCell::getStartSegments ( unsigned int direction ); + * \param direction The selected direction. + * \return All AutoSegment starting from this GCell in \b direction. + */ + + /*! \function AutoSegments GCell::getStopSegments ( unsigned int direction ); + * \param direction The selected direction. + * \return All AutoSegment ending in this GCell in \b direction. + */ + + /*! \function void GCell::addVSegment ( AutoSegment* segment ); + * \param segment A vertical AutoSegment. + * + * Indicate that the vertical \c segment is going straigh through this + * GCell (no AutoContact). + */ + + /*! \function void GCell::addHSegment ( AutoSegment* segment ); + * \param segment An horizontal AutoSegment. + * + * Indicate that the horizontal \c segment is going straigh through this + * GCell (no AutoContact). + */ + + /*! \function void GCell::addContact ( AutoContact* contact ); + * \param contact An AutoContact. + * + * Indicate that the \c contact is owned by this GCell. This means that + * either it's a branching point or there are terminals in the GCell. + * The AutoContact is geometrically bound by the GCell bounding box. + */ + + /*! \function void GCell::updateContacts (); + * Force the geometrical recalculation of all AutoContact owned by + * this GCell. + */ + + /*! \function void GCell::updateDensity (); + * Recompute the horizontal, vertical, global and contact of + * this GCell. + * + * The horizontal density is computed as follow : the sum of the length + * of all horizontal wires divided by the the total length of horizontal + * wires (the width of the GCell times the number of horizontal tracks). + * A density equal to one means a totally saturated GCell, and greater + * than one an overloaded GCell (unroutable). + * + * The vertical density is computed in a similar way to the horizontal + * one. + * + * The global density is the average of horizontal and vertical + * density. + * + * AutoContact density is the ratio of number of contact with length of + * the diagonal of the GCell multiplied by two. This is a rough approximate. + * + * \see GCellGrid::updateDensity(). + */ + + } diff --git a/katabatic/doc/GCellGrid.dox b/katabatic/doc/GCellGrid.dox new file mode 100644 index 00000000..d8fa9960 --- /dev/null +++ b/katabatic/doc/GCellGrid.dox @@ -0,0 +1,21 @@ + + // -*- C++ -*- + + + namespace Katabatic { + + /*! \class GCellGrid + * \brief Routing Grid (\b API). + * + * \attention This class is can only be allocated through a Katabatic + * \c ToolEngine thus Constructors/Destructors are protecteds. + * + * \section GCellGridImplementation GCellGrid Implementation Details + */ + + /*! \function void GCellGrid::updateDensity (); + * \return Recompute the density of each GCell in the grid. + * \see GCell::updateDensity(). + */ + + } diff --git a/katabatic/doc/Grid.dox b/katabatic/doc/Grid.dox new file mode 100644 index 00000000..49da96dd --- /dev/null +++ b/katabatic/doc/Grid.dox @@ -0,0 +1,114 @@ + + // -*- C++ -*- + + + namespace Katabatic { + + /*! \class BaseGrid + * \brief Grid Common Skeleton (\b API). + * + * \attention Provide a non-template common skeleton for the Grid class + * template. Specifically manage the axis graduation, the geometric + * search functions and the indexes computation (assuming a linear + * storage of the grid elements). + * + * + * \section BaseGridImplementation Grid Implementation Details + * + * The matrix of GCell is stored in a linear vector of GCell's pointer, + * row by row. The Grid class provide convenient functions to + * convert a linear index into row / column and the other way around. + */ + + /*! \function unsigned int BaseGrid::getColumns () const; + * \return The number of columns of the GCell matrix. + */ + + /*! \function unsigned int BaseGrid::getRows () const; + * \return The number of rows of the GCell matrix. + */ + + /*! \function unsigned int BaseGrid::getRawSize () const; + * \return The size of the vector holding the GCell matrix. + */ + + /*! \function unsigned int BaseGrid::getIndex ( unsigned int column, unsigned int row ) const; + * \param column The GCell's column. + * \param row The GCell's row. + * \return The linear index of the GCell at (column,row). + */ + + /*! \function unsigned int BaseGrid::getRow ( unsigned int index ) const; + * \param index A linear index. + * \return extract the row number from the linear index. + */ + + /*! \function unsigned int BaseGrid::getColumn ( unsigned int index ) const; + * \param index A linear index. + * \return extract the column number from the linear index. + */ + + /*! \class Grid + * \brief Routing Grid (\b API). + * + * \attention This class is can only be allocated through a Katabatic + * \c ToolEngine thus Constructors/Destructors are protecteds. + * + * \section GridImplementation Grid Implementation Details + * + * The matrix of GCell is stored in a linear vector of GCell's pointer, + * row by row. The Grid class provide convenient functions to + * convert a linear index into row / column and the other way around. + */ + + + /*! \function GCell* Grid::getGCell ( const Point p1, const Point p2 ) const; + * \param p1 First point. + * \param p2 Second point. + * \return Returns the GCell enclosing both points. + * + * When we build a Net's routing wires, and the Net span more than one + * GCell, we can always find the appropriate GCell through the + * \c Hook, \c GCell and GCell association. + * + * Problem arises for a Net fully contained inside one GCell, in this + * case there is no SplitterContact telling us where we are. We have + * to guess the GCell by only using RoutingPad's positions. And unfortunatly + * \c RoutingPad can be on the edge of one GCell so we cannot tell if + * it belongs to the left or the right. To solve this problem we guess + * the GCell from two (different) \c RoutingPad positions. + * + * Note that if there is only one \c RoutingPad, there is no problem at + * all : we are dealing with a one \c Plug \c Net... + * + * If points do not belongs to one GCell (too far appart), strange + * results may occurs. + */ + + /*! \function GCell* Grid::getGCell ( unsigned int index ) const; + * \param index A linear index. + * \return The GCell at the given index. + * + * Be aware that no check is performed if the index is out of bound, + * this may leads to catastrophic results. + */ + + /*! \function vector Grid::getGCellVector (); + * \return The \vector holding all GCells. + */ + + /*! \function GCells Grid::getGCellsColumn ( unsigned int column, unsigned int rowStart, unsigned int rowStop ); + * \param column The column index. + * \param rowStart The start row index inside the column. + * \param rowStop The stop row index inside the column. + * \return The \c Collection of a partial row. + */ + + /*! \function GCells Grid::getGCellsRow ( unsigned int row, unsigned int columnStart, unsigned int columnStop ); + * \param row The row index. + * \param columnStart The start column index inside the row. + * \param columnStop The stop column index inside the row. + * \return The \c Collection of a partial column. + */ + + } diff --git a/katabatic/doc/KatabaticEngine.dox b/katabatic/doc/KatabaticEngine.dox new file mode 100644 index 00000000..7e09fa3e --- /dev/null +++ b/katabatic/doc/KatabaticEngine.dox @@ -0,0 +1,202 @@ + + // -*- C++ -*- + + + namespace Katabatic { + + /*! \mainpage Routing Toolbox Documentation + * + * This documentation adresses two level of explanations : + * + *
    + *
  • The \b API description which explains how to use Katabatic, + * thoses parts as flagged as \b API. + *
  • The internal description which details how Katabatic do + * things. It's mostly intended for myself to help me not to + * forget how I've done things when debug time will come... + * It may also be valuable to people who may want to use + * or patch Katabatic for their own purpose (my secret hope). + *
+ */ + + + /*! \namespace Katabatic + * \brief The namespace dedicated to Katabatic. + */ + /*! \enum LoadGRMethod + * Lists all avalaible global routing loading methods for + * loadGlobalRouting(). + */ + /*! \var LoadGRMethod LoadGrByNet + * The global routing will be loaded net by net. + */ + /*! \var LoadGRMethod LoadGrByGCell + * The global routing will be loaded GCell by GCell. + */ + + + /*! \class KatabaticEngine + * \brief The Katabatic ToolEngine, routing toolbox (\b API). + */ + + /*! \function KatabaticEngine* KatabaticEngine::create ( const RoutingGauge* gauge, Cell* cell, vector& nets ); + * \param gauge The RoutingGauge to use. + * \param cell The \Cell to be routed. + * \param nets The subset of \Nets to be routeds. Note that the vector is + * copied inside the KatabaticEngine object, so there's no need to keep + * the parameter. + * + * creates a new KatabaticEngine object. Should never be used, as Katabatic + * must be used as the base class for any router, and therefore + * created through it. Still avalaible for debugging purposes. + */ + + /* \function void KatabaticEngine::destroy (); + * Cleanly destruct the data-base, saves the routing wires in + * the \Hurricane data-base (really a call to _preDestroy()). + * + * \see _saveNet(). + */ + + /*! \function GCellGrid* KatabaticEngine::getGCellGrid () const; + * \return The associated GCellGrid. + */ + + /*! \function const vector& KatabaticEngine::getRoutingNets () const; + * \return The subset of \Nets that are to be routed. + */ + + /*! \function void KatabaticEngine::loadGlobalRouting ( unsigned int method ) + * \param method to specify the algorithm used to perform the loading. + * + * translates a global routing created by Tornado (GCell/GCell data-base) + * into an initial detailed routing. Two algorithms are currently + * avalaibles : + *
    + *
  • LoadGrByNet : load global routing net by net. + *
  • LoadGrByGCell : load global routing GCell by GCell. + *
+ * + * This method is essentially a switch which calls the appropriate sub-method + * _loadGrByNet() or _LoadGRbyGCell(). It relies on the presence of a Nimbus + * ToolEngine, if not found, throws an error. + */ + + /*! \function void KatabaticEngine::setGlobalThreshold ( DbU::Unit threshold ); + * \param threshold The global routing threshold. + * + * The length (in DbU::Unit) from which an AutoSegment will be considered to be + * global. + * + * \see layerAssign(), getGlobalThresold(). + */ + + /*! \function DbU::Unit KatabaticEngine::getGlobalThreshold () const; + * \return The value of the global routing thresold. + * + * \see setGlobalThresold(). + */ + + /*! \function void KatabaticEngine::_computeNetConstraints ( Net* ); + * computes the \c AutoSegment constraints (see \ref NetConstraints). + */ + + /*! \function void KatabaticEngine::_computeNetOptimals ( Net* ); + * computes the \c AutoSegment optimal positions (see \ref NetOptimals). + */ + + /*! \function AutoSegment* KatabaticEngine::_lookup ( Segment* segment ) const; + * \param segment The \c Hurricane segment. + * + * Finds the Katabatic AutoSegment associated to \c segment. + * For this function to work, a Katabatic update session must be open. + * If not, an exception will be thrown. + */ + + /*! \function void KatabaticEngine::_link ( AutoSegment* autoSegment ); + * adds \b autoSegment to the AutoSegment internal lookup table. + * This function does nothing if DoLinkAutoSegment() is \false : + * in destruction mode. + * \see _Lookup(). + */ + + /*! \function void KatabaticEngine::_unlink ( AutoSegment* autoSegment ); + * removes \b autoSegment AutoSegment internal lookup table. + * This function does nothing if DoLinkAutoSegment() is \false : + * in destruction mode. + * \see _Lookup(). + */ + + /*! \function void KatabaticEngine::_destroyAutoSegments (); + * clear the internal AutoSegment lookup table. Should be called + * only from inside the Katabatic destructor. + */ + + /*! \function void KatabaticEngine::_saveNet ( Net* net ); + * \param net The \Net to process. + * + * Revert (partially destruct) the AutoSegment/AutoContact + * structure of the \Net to the \Hurricane data-base. + * To be used only in the Katabatic destructor... + * + * \see destroy(). + */ + + + /*! \function KatabaticEngine* KatabaticEngine::get ( const Cell* cell ) + * \brief Returns the Katabatic ToolEngine attached to the Cell, if any. + */ + + /*! \function void KatabaticEngine::refresh ( bool openSession=true ); + * Force the update of all AutoContact. By default opens a new + * update Session. If one is already open, set openSession to + * \False. + */ + + /*! \function void KatabaticEngine::startMeasures (); + * Start memory consumption and timer measurment (reset any + * previous one). + * + * \see stopMeasures(), printMeasures(). + */ + + /*! \function void KatabaticEngine::stopMeasures (); + * compute memory consumption \& time elapsed since the last + * call to startMeasures(). + * + * \see startMeasures(), printMeasures(). + */ + + /*! \function void KatabaticEngine::printMeasures () const; + * Display memory consumption \& time elapsed. + * + * \see startMeasures(), stopMeasures(). + */ + + /*! \function void KatabaticEngine::_check ( const char* message=NULL ) const; + * \param message The message to print. + * + * Perform a coherency complete coherency check of the + * data-base. Currently : + *
    + *
  • No AutoSegment remains invalidated (\ref katabaticSession). + *
  • AutoSegment extentions are coherent. + *
+ */ + + + //! \addtogroup collapseCanonical + //! \{ + + /*! \function void KatabaticEngine::_canonize ( Net* net ); + * \param net The \Net to canonize. + * + * Find canonical AutoSegments and non-canonicals ones, + * sets up the flags accordingly. + * + * \see AutoSegment::isCanonical(). + */ + + //! \} + + } diff --git a/katabatic/doc/LayerAssign.dox b/katabatic/doc/LayerAssign.dox new file mode 100644 index 00000000..ce8526d8 --- /dev/null +++ b/katabatic/doc/LayerAssign.dox @@ -0,0 +1,143 @@ + + // -*- C++ -*- + + + namespace Katabatic { + + /*! \defgroup layerAssign 4. Layer Assignment (internal) + * + * This modules documents how layer assignment is performed. It is intented + * for developpers only. + * + * Layer Assignment functions works in two steps : + *
    + *
  1. For a given net, go through the \c AutoSegment and migrate them + * to upper (global) layers if needed. + *
  2. For each \c AutoContact of which at least one \c AutoSegment has been + * migrated, split the \c AutoContact (with SplitAutoContact()). + *
+ * + * SplitAutoContact() relies on the hypothesis that the split occurs + * between two sets of \b HV layers. For example between \b M2/M3 and + * \b M4/M5 but not between \b M2/M3 and \b M6/M7. + * + * The following figures shows all possible configurations, except for + * the most obvious : when all \c AutoSegment are migrated from \b M2/M3 to + * \b M4/M5 we just change the layer of the \c AutoContact from \b C23 to \b C34. + * SplitAutoContact() compute the layer span of the AutoContact, + * that is, the distance between the lowest layer and the higher one (it + * cannot exceed 3 as from \b M2 to \b M5). Then it detach the higher + * \c AutoSegment and re-attach them to a newly created \c AutoContact. + * In turn this new \c AutoContact is connected to the previous one. + *
    + *
  • The span is 3 (\b M2 to \b M5) : creates 2 \c AutoContact and + * 2 \c AutoSegment. + *
  • The span is 2 (\b M2 to \b M4 or \b M3 to \b M5) : creates one + * \c AutoContact and one \c AutoSegment. + *
  • The span is 1 (\b M3 to \b M4) : just change the layer of the + * \c AutoContact to \b C34. + *
+ * Simpler rules could be formulated : if \b M2 is present creates the + * \b M3 additionnal \c AutoSegment. If \b M5 is present, created the + * \b M4 additionnal \c AutoSegment. + * + * In M2+M3+M4+M5, M3+M4+M5 and M2+M3+M4 configurations + * two separates \b M4 \c AutoSegment (resp. \b M3 \c AutoSegment) are needed + * to avoid the incomplete AutoContact wiring problem + * (see \ref ssecFaultyTopologies). + * + * \image html SplitAutoContact-1.png "Full Configuration" + * \image latex SplitAutoContact-1.pdf "Full Configuration" width=0.4\textwidth + * \image html SplitAutoContact-2.png "No M3 Configuration" + * \image latex SplitAutoContact-2.pdf "No M3 Configuration" width=0.4\textwidth + * \image html SplitAutoContact-3.png "No M3,M4 Configuration" + * \image latex SplitAutoContact-3.pdf "No M3,M4 Configuration" width=0.4\textwidth + * \image html SplitAutoContact-4.png "No M2 Configuration (degenerate)" + * \image latex SplitAutoContact-4.pdf "No M2 Configuration (degenerate)" width=0.4\textwidth + * \image html SplitAutoContact-5.png "No M5 Configuration (degenerate)" + * \image latex SplitAutoContact-5.pdf "No M5 Configuration (degenerate)" width=0.4\textwidth + * \image html SplitAutoContact-6.png "No M2,M5 Configuration (degenerate)" + * \image latex SplitAutoContact-6.pdf "No M2,M5 Configuration (degenerate)" width=0.4\textwidth + */ + + + /*! \enum LayerAssignMethod + * List all avalaible global layer assignment algorithm avalaible for + * layerAssign(). + */ + + /*! \var LayerAssign LayerAssignByLength + * See layerAssign(). + */ + + /*! \var LayerAssign LayerAssignByTrunk + * See layerAssign(). + */ + + + /*! \function void KatabaticEngine::layerAssign ( unsigned int method ) + * \param method specify the algorithm used to perform the layer assignement. + * + * The loadGlobalRouting() method build a topology for each net using only the + * two first routing layers avalaibles (usually \e metal2 and \e metal3). + * To use upper routing layer we needs to go through a layer assignment + * step. The layerAssign() method provides two simples approaches to do so : + *
    + *
  • layerAssignByLength : every global AutoSegment which + * length is superior to the global threshold is moved to the upper layer. + *
  • layerAssignByTrunk : if any AutoSegment of a net + * exceed the global threshold, then all the global wiring of this + * net is put into the upper layers. + *
+ * + * This method is a switch to _layerAssignByLength() or _layerAssignByTrunk(). + * + * The global threshold is to be sets using the setGlobalThreshold() + * method. + */ + + + //! \addtogroup layerAssign + //! \{ + + + /*! \function void KatabaticEngine::_layerAssignByLength ( unsigned long& total, unsigned long& global, set& globalNets ); + * + * Perform the layer assignment on all nets, using the + * layerAssignByLength algorithm. See layerAssign(). + */ + + /*! \function void KatabaticEngine::_layerAssignByLength ( Net* net, unsigned long& total, unsigned long& global, set& globalNets ); + * \param net The net to process. + * \param total The total number of AutoSegment. + * \param global The number of AutoSegment that have been sets global. + * \param globalNets Set of global Nets. + * + * Perform the layer assignment on one net, using the + * layerAssignByLength algorithm. See layerAssign(). + */ + + /*! \function void KatabaticEngine::_layerAssignByTrunk ( unsigned long& total, unsigned long& global, set& globalNets ); + * + * Perform the layer assignment on all nets, using the + * layerAssignByTrunk algorithm. See layerAssign(). + */ + + /*! \function void KatabaticEngine::_layerAssignByTrunk ( Net* net, unsigned long& total, unsigned long& global, set& globalNets ); + * \param net The net to process. + * \param total The total number of AutoSegment. + * \param global The number of AutoSegment that have been sets global. + * \param globalNets Set of global Nets. + * + * Perform the layer assignment on one net, using the + * layerAssignByTrunk algorithm. See layerAssign(). + */ + + //! \} + +} + + + namespace { + + } diff --git a/katabatic/doc/LoadGrByNet.dox b/katabatic/doc/LoadGrByNet.dox new file mode 100644 index 00000000..786d9c62 --- /dev/null +++ b/katabatic/doc/LoadGrByNet.dox @@ -0,0 +1,27 @@ + + // -*- C++ -*- + + + namespace Katabatic { + + /*! \function void KatabaticEngine::_loadGrByNet () + * Load the global routing from the Nimbus structure (built by the Tornado + * global router) into the Katabatic ToolEngine. + */ + + /*! \function void KatabaticEngine::_loadNetGlobalRouting ( Net* net ) + * \param net The net for which to build the final routing. + * + * Load the global routing from the Nimbus structure. Do a recursive + * walk through the GCells. Recursivity is handled with the + * ForkStack stack. + */ + + } + + + + + namespace { + + } diff --git a/katabatic/doc/NetConstraints.dox b/katabatic/doc/NetConstraints.dox new file mode 100644 index 00000000..534f7555 --- /dev/null +++ b/katabatic/doc/NetConstraints.dox @@ -0,0 +1,128 @@ + + // -*- C++ -*- + + + namespace Katabatic { + + /*! \defgroup NetConstraints 5. Constraints Computations (internal) + * + * This module documents how constraints computation are performed. + * It is intented for developpers only. + * + * Constraints gives the absolute minimal and maximal position an + * \c AutoSegment axis can be set. They materialize the bounds over + * which we may have an electrical disconnection. + * + * Practically, due to the magic of \c AutoContact, disconnections + * can only occurs on \c AutoContact anchored on \c RoutingPad : + * if they go outside the \c RoutingPad area, we are in trouble. + * Those \c AutoContact can be spotted either by the fact they have + * an anchor or the AutoContact::isTerminal() flag is set. + * + * + * \section secConstraintsOrgan Organisation + * + * Due to algorithmic consideration, instead of storing constraint + * interval (one axis) in \c AutoSegment, we store constraint \c Box + * (both axis) in \c AutoContact. They are easier to propagate during the + * computation stage and should takes less memory as \c AutoContact + * are often shared by more than two \c AutoSegment. + * + * To spare memory, each coordinate of the constraint \c Box is expressed + * as a strictly positive offset in \e lambdas from the lower left corner + * of the \c FCell owning the \c AutoContact. Offsets are 8 bits unsigned int, + * thus a \c Box takes one word (32 bits). This leads to two restrictions : + *
    + *
  • A \c FCell side cannot be greater than 256 \e lambdas. + *
  • The constraint \c Box minimal precision is the \e lambda. + *
+ * In all cases I can foresee, none of them should be a problem. + * + * Constraint interval on \c AutoSegment can be deduced from any of + * the source or target \c AutoContact. For an horizontal \c AutoSegment + * we take the constraint \c Box vertical interval and for a vertical, + * the horizontal interval. + * + * + * \section secNativeConstraints Native Constraints + * + * Before the contraints computation starts, we needs to initialize + * each \c AutoContact \c Box to a reasonable default : the + * Native Constraint Box. Wich is : + *
    + *
  • For an anchored/passive \c AutoContact : the bounding box + * of the underlying terminal. + *
  • For any other \c AutoContact : the bounding box of the + * \c FCell owner. + *
+ * + * + * \section secConstraintsPropagation Constraints Propagation + * + * The only source of constraints being the anchored \c AutoContact + * we do a full propagation from each of them. Propagation is done + * through \c AutoSegment as follow : + *
    + *
  • Horizontal \c AutoSegment propagate the vertical (\b DY) + * constraint part. + *
  • Vertical \c AutoSegment propagate the horizontal (\b DX) + * constraint part. + *
+ * Obviously, any constraint diseapear after we have gone through + * exactly one horizontal and one vertical, thus the propagation is + * somewhat limited. + * + * Case of collapsed \c AutoSegment : those are to be kept at + * zero-length, thus they act as a bypass between two \c AutoContact. + * Their source and target can be considered as stacked + * and propagate both vertical and horizontal constraint (that is : + * the whole constraint \c Box). + * + * + * \section secCollapseUncollapse Collapsing & Uncollapsing + * + * Only local \c AutoSegment can be collapsed, as a global + * \c AutoSegment crosses the boundary of at least one \c FCell + * it can't have a null length. + * + * When collapsing a new \c AutoSegment, we can do an incremental + * constraint computation as it will result in a further increase + * of constraint (if any). + * + * When uncollapsing an \c AutoSegment we may have to slacken the + * constraint, but we do not know to which extend. So to make it + * simple we fully recompute constraints from scratch. + * + * Note that collapsing/uncollapsing are exceptionnal operations, + * so we can afford losing a little time there. + * + * + * \section secCollapseExample progressive Collapsing Example + * + * In this set of example we show how constraints propagate along the + * \c AutoSegment, depending on the collapsed ones. We starts we no + * collapse and ends with all \e local \c AutoSegment collapseds. + * + * \image html NetConstraints-1.png "Fully expanded" + * \image latex NetConstraints-1.pdf "Fully expanded" width=0.4\textwidth + * \image html NetConstraints-2.png "After One Vertical collapse" + * \image latex NetConstraints-2.pdf "After One Vertical collapse" width=0.4\textwidth + * \image html NetConstraints-3.png "After Horizontal collapse" + * \image latex NetConstraints-3.pdf "After Horizontal collapse" width=0.4\textwidth + * \image html NetConstraints-4.png "Fully collapsed" + * \image latex NetConstraints-4.pdf "Fully collapsed" width=0.4\textwidth + */ + + + //! \addtogroup NetConstraints + //! \{ + + /*! \function void KatabaticEngine::_computeNetConstraints ( Net* net ); + * \param net The net for which to compute constraints. + * + * compute constraints on a net. + */ + + //! \} + + } diff --git a/katabatic/doc/NetOptimals.dox b/katabatic/doc/NetOptimals.dox new file mode 100644 index 00000000..25109761 --- /dev/null +++ b/katabatic/doc/NetOptimals.dox @@ -0,0 +1,59 @@ + + // -*- C++ -*- + + + namespace Katabatic { + + /*! \defgroup NetOptimals 6. AutoSegment Optimal Placement (internal) + * + * This modules documents how \c AutoSegment optimal placement are computed. + * It is intented for developpers only. + * + * The principle is quite simple : for any given \c AutoSegment, for example + * a vertical one (\b A), we want to find the optimal position so the wire + * length of \c AutoSegment perpandicular to \b A would be minimal. This + * optimal position is an interval of X positions, possibly reduced to a + * point. + * + * Given an \c AutoSegment, we will take into account : + *
    + *
  • Perpandicular global \c AutoSegment. + *
  • Terminals linked to the \c AutoSegment through any number of + * local \c AutoSegment (collapsed or not). + *
+ * + * How to find the optimal interval : + * + * First we build an histogram in the direction perpandicular to the + * \c AutoSegment. For \b A : in horizontal direction. We populate the + * histogram with the axis coordinate of global \c AutoSegment and + * terminals linked to \b A. Note that for global \c AutoSegment the + * "axis" coordinate is the position of the side of the \c FCell. + * For terminal depending on their orientation relative to \b A we + * add either their axis or their two extremities. + * + * The optimal interval is then the median interval of the histogram. + * + * The set of examples below shows some representative cases. + * + * \image html NetOptimals-1.png "Multiple Verticals Terminals" + * \image latex NetOptimals-1.pdf "Multiple Verticals Terminals" width=0.6\textwidth + * \image html NetOptimals-2.png "Globals Only" + * \image latex NetOptimals-2.pdf "Globals Only" width=0.6\textwidth + * \image html NetOptimals-3.png "One Horizontal Terminal" + * \image latex NetOptimals-3.pdf "One Horizontal Terminal" width=0.6\textwidth + */ + + + //! \addtogroup NetOptimals + //! \{ + + /*! \function void KatabaticEngine::_computeNetOptimals ( Net* net ); + * \param net The net for which to compute optimal placement. + * + * compute optimal placement of all net's AutoSegment. + */ + + //! \} + + } diff --git a/katabatic/doc/Session.dox b/katabatic/doc/Session.dox new file mode 100644 index 00000000..8fd7e15f --- /dev/null +++ b/katabatic/doc/Session.dox @@ -0,0 +1,153 @@ + + // -*- C++ -*- + + + namespace Katabatic { + + /*! \defgroup katabaticSession 7. Katabatic update Session Mechanism (internal) + * + * This module documents the Katabatic update Session Mechanism. + * It is intented for developpers only. + * + * + * \section secSessionGoal Goal of The Katabatic::Session + * + * Due to obvious performance issue, we do not recompute the + * geometry of source and target of a Katabatic::AutoSegment + * each time it's moved by the router. Instead we uses a simple + * queuing mechanism : the Katabatic::Session. + * + * Note that, most of the time, the router only moves segments, + * that is, never modifies directly Katabatic::AutoContact. + * The only exceptions being during the initial building stage + * or when the router decide to change the topology of a net. + * + * The router knows which Katabatic::AutoSegment it has moved, + * but during the update of a Katabatic::AutoContact geometry + * more segments will be modified. The modification being a + * change in their soure and/or target extention. And of thoses + * the router will not know about. To solve this problem, + * the router has to set a callback Katabatic::SegmentRevalidateCB + * which will be called for each modificated Katabatic::AutoSegment. + * + * Note that, in order to uniformize the procedure, this callback + * will also be run on Katabatic::AutoSegment modificated by + * the router. + * + * + * \section secSectionLookup The lookup function. + * + * To find a Katabatic::AutoSegment from it's associated \Hurricane + * segment, we build a simple \STL map in the Katabatic \c ToolEngine. + * This lookup table, can be accessed through the Session lookup() + * function, once the session is open. + * + * + * \section secSessionRevalidate The Revalidate procedure + * + * The sequence of calls is as follow : + *
    + *
  1. The Router modifies some Katabatic::AutoSegment by moving + * their axis. For example, horizontal segments in an horizontal + * routing channel. + *
  2. The Katabatic::AutoSegment is then invalidated : put in the + * invalidated segment set. It's Katabatic::AutoContact anchors + * are also invalidated and put in the set of invalidated contacts. + *
  3. At some point, a global revalidation is performed : + * Katabatic::Session::revalidate(). Says, when the channel + * is successfully routed. + *
  4. Katabatic::updateGeometry() is called and update the + * geometry of all invalided Katabatic::AutoContact. Doing so + * almost surely leads to the invalidation of more Katabatic::AutoSegment + * which are added to the invalidated set. In this example, as + * we moved horizontal segments, the new invalidated segments + * will be vertical ones incident to the formers. + *
  5. Finally we call Katabatic::AutoSegment::onRevalidate() + * fonction for each Katabatic::AutoSegment. + * This function encapsulate the callback from the router, so it + * can take into account the segment extension change. + *
+ * + * \image html AutoInvalidate-1.png "Revalidate Procedure" + * \image latex AutoInvalidate-1.pdf "Revalidate Procedure" width=0.9\textwidth + * + * + * \section secStaticAccess The Static Member choice + * + * Almost all Session function members are \c static, this is + * because they refers to the currently opened Session which is + * kept entirely internal to the \c KatabaticSession module. + * This avoid carrying a global variable for the Session object. + */ + + + /*! \class Session + * \brief Katabatic update Session (\b API). + * + * The Katabatic Session is mandatory before any AutoSegment / + * AutoContact to be modified (supposedly by a router). + * + * Unlike \Hurricane \c update \c Session only one session + * can be opened at a time (no stacking mechanism). Opening a + * Katabatic update Session also opens an \Hurricane \c update + * \c Session. + * + * For details on how Katabatic Sessions works, have a look to + * \ref katabaticSession. + */ + + /*! \function static Session* Session::get (); + * \return The currently opened session, \c NULL if no session has + * been opened. + */ + + /*! \function static Katabatic* Session::getKatabatic (); + * \return The Katabatic ToolEngine associated to the current update + * session. + */ + + /*! \function static AutoSegment* Session::lookup ( Segment* segment ); + * \param segment An \Hurricane segment. + * \return The associated Katabatic AutoSegment. + * + * For this function to work, a Katabatic Session must be opened + * as it's a simple bypass to the Katabatic::_Lookup() member. + */ + + /*! \function static Session* Session::open ( KatabaticEngine* ktbt ); + * \param ktbt A Katabatic ToolEngine on which to work. + * + * Open a new Katabatic update Session on the \c ktbt \c ToolEngine. + * At this point only one session can be opened at a time. Attempt + * to open a second one will result in an exception. + */ + + /*! \function static size_t Session::close (); + * \return The number of AutoContact / AutoSegment that have been revalidateds. + * + * Ends an update Session. This functions made a call to Revalidate to + * ensure that no AutoContact / AutoSegment remains invalidated. + */ + + /*! \function static size_t Session::revalidate (); + * \return The number of AutoContact / AutoSegment that have been revalidateds. + * + * Revalidate all AutoContact / AutoSegment currently in the queue : + * that is, update the AutoContact geometry and AutoSegment extentions. + */ + + /*! \function void Session::invalidate ( AutoSegment* segment ); + * \param segment An AutoSegment that has been moved. + * + * The invalidated AutoSegment are stored into a \STL set, + * so it can be added multiples times without problems. + */ + + /*! \function void Session::invalidate ( AutoContact* contact ); + * \param contact An AutoContact of which a AutoSegment has been moved. + * + * The invalidated AutoContact are stored into a \STL set, + * so it can be added multiples times without problems. + */ + + } diff --git a/katabatic/doc/asimbook.cls b/katabatic/doc/asimbook.cls new file mode 100644 index 00000000..54270780 --- /dev/null +++ b/katabatic/doc/asimbook.cls @@ -0,0 +1,798 @@ +%% +%% This is file `book.cls', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% classes.dtx (with options: `book') +%% +%% This is a generated file. +%% +%% Copyright 1993 1994 1995 1996 1997 1998 1999 2000 2001 +%% The LaTeX3 Project and any individual authors listed elsewhere +%% in this file. +%% +%% This file was generated from file(s) of the LaTeX base system. +%% -------------------------------------------------------------- +%% +%% It may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either version 1.2 +%% of this license or (at your option) any later version. +%% The latest version of this license is in +%% http://www.latex-project.org/lppl.txt +%% and version 1.2 or later is part of all distributions of LaTeX +%% version 1999/12/01 or later. +%% +%% This file may only be distributed together with a copy of the LaTeX +%% base system. You may however distribute the LaTeX base system without +%% such generated files. +%% +%% The list of all files belonging to the LaTeX base distribution is +%% given in the file `manifest.txt'. See also `legal.txt' for additional +%% information. +%% +%% \CharacterTable +%% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z +%% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z +%% Digits \0\1\2\3\4\5\6\7\8\9 +%% Exclamation \! Double quote \" Hash (number) \# +%% Dollar \$ Percent \% Ampersand \& +%% Acute accent \' Left paren \( Right paren \) +%% Asterisk \* Plus \+ Comma \, +%% Minus \- Point \. Solidus \/ +%% Colon \: Semicolon \; Less than \< +%% Equals \= Greater than \> Question mark \? +%% Commercial at \@ Left bracket \[ Backslash \\ +%% Right bracket \] Circumflex \^ Underscore \_ +%% Grave accent \` Left brace \{ Vertical bar \| +%% Right brace \} Tilde \~} +\NeedsTeXFormat{LaTeX2e}[1995/12/01] +\ProvidesClass{asimbook} + [2005/11/21 v1.0 + ASIM LaTeX document class] +\newcommand\@ptsize{} +\newif\if@restonecol +\newif\if@titlepage +\@titlepagetrue +\newif\if@openright +\newif\if@mainmatter \@mainmattertrue +\if@compatibility\else +\DeclareOption{a4paper} + {\setlength\paperheight {297mm}% + \setlength\paperwidth {210mm}} +\DeclareOption{a5paper} + {\setlength\paperheight {210mm}% + \setlength\paperwidth {148mm}} +\DeclareOption{b5paper} + {\setlength\paperheight {250mm}% + \setlength\paperwidth {176mm}} +\DeclareOption{letterpaper} + {\setlength\paperheight {11in}% + \setlength\paperwidth {8.5in}} +\DeclareOption{legalpaper} + {\setlength\paperheight {14in}% + \setlength\paperwidth {8.5in}} +\DeclareOption{executivepaper} + {\setlength\paperheight {10.5in}% + \setlength\paperwidth {7.25in}} +\DeclareOption{landscape} + {\setlength\@tempdima {\paperheight}% + \setlength\paperheight {\paperwidth}% + \setlength\paperwidth {\@tempdima}} +\fi +\if@compatibility + \renewcommand\@ptsize{0} +\else +\DeclareOption{10pt}{\renewcommand\@ptsize{0}} +\fi +\DeclareOption{11pt}{\renewcommand\@ptsize{1}} +\DeclareOption{12pt}{\renewcommand\@ptsize{2}} +\if@compatibility\else +\DeclareOption{oneside}{\@twosidefalse \@mparswitchfalse} +\fi +\DeclareOption{twoside}{\@twosidetrue \@mparswitchtrue} +\DeclareOption{draft}{\setlength\overfullrule{5pt}} +\if@compatibility\else +\DeclareOption{final}{\setlength\overfullrule{0pt}} +\fi +\DeclareOption{titlepage}{\@titlepagetrue} +\if@compatibility\else +\DeclareOption{notitlepage}{\@titlepagefalse} +\fi +\if@compatibility +\@openrighttrue +\else +\DeclareOption{openright}{\@openrighttrue} +\DeclareOption{openany}{\@openrightfalse} +\fi +\if@compatibility\else +\DeclareOption{onecolumn}{\@twocolumnfalse} +\fi +\DeclareOption{twocolumn}{\@twocolumntrue} +\DeclareOption{leqno}{\input{leqno.clo}} +\DeclareOption{fleqn}{\input{fleqn.clo}} +\DeclareOption{openbib}{% + \AtEndOfPackage{% + \renewcommand\@openbib@code{% + \advance\leftmargin\bibindent + \itemindent -\bibindent + \listparindent \itemindent + \parsep \z@ + }% + \renewcommand\newblock{\par}}% +} +\ExecuteOptions{letterpaper,10pt,twoside,onecolumn,final,openright} +\ProcessOptions +\input{bk1\@ptsize.clo} +\setlength\lineskip{1\p@} +\setlength\normallineskip{1\p@} +\renewcommand\baselinestretch{} +\setlength\parskip{0\p@ \@plus \p@} +\@lowpenalty 51 +\@medpenalty 151 +\@highpenalty 301 +\setcounter{topnumber}{2} +\renewcommand\topfraction{.7} +\setcounter{bottomnumber}{1} +\renewcommand\bottomfraction{.3} +\setcounter{totalnumber}{3} +\renewcommand\textfraction{.2} +\renewcommand\floatpagefraction{.5} +\setcounter{dbltopnumber}{2} +\renewcommand\dbltopfraction{.7} +\renewcommand\dblfloatpagefraction{.5} +%%%% Select Chapter font. +\newcommand \textchapter [1] {\textsf{\textbf{#1}}} +\newcommand \fontchapter {\sffamily \bfseries} +\if@twoside + \def\ps@headings{% + \let\@oddfoot\@empty\let\@evenfoot\@empty + \def\@evenhead{\thepage\hfil\slshape\leftmark}% + \def\@oddhead{{\slshape\rightmark}\hfil\thepage}% + \let\@mkboth\markboth + \def\chaptermark##1{% + \markboth {\MakeUppercase{% + \ifnum \c@secnumdepth >\m@ne + \if@mainmatter + \@chapapp\ \thechapter. \ % + \fi + \fi + ##1}}{}}% + \def\sectionmark##1{% + \markright {\MakeUppercase{% + \ifnum \c@secnumdepth >\z@ + \thesection. \ % + \fi + ##1}}}} +\else + \def\ps@headings{% + \let\@oddfoot\@empty + \def\@oddhead{{\slshape\rightmark}\hfil\thepage}% + \let\@mkboth\markboth + \def\chaptermark##1{% + \markright {\MakeUppercase{% + \ifnum \c@secnumdepth >\m@ne + \if@mainmatter + \@chapapp\ \thechapter. \ % + \fi + \fi + ##1}}}} +\fi +\def\ps@myheadings{% + \let\@oddfoot\@empty\let\@evenfoot\@empty + \def\@evenhead{\thepage\hfil\slshape\leftmark}% + \def\@oddhead{{\slshape\rightmark}\hfil\thepage}% + \let\@mkboth\@gobbletwo + \let\chaptermark\@gobble + \let\sectionmark\@gobble + } + \if@titlepage + \newcommand\maketitle{\begin{titlepage}% + \let\footnotesize\small + \let\footnoterule\relax + \let \footnote \thanks + \null\vfil + \vskip 60\p@ + \begin{center}% + {\LARGE \@title \par}% + \vskip 3em% + {\large + \lineskip .75em% + \begin{tabular}[t]{c}% + \@author + \end{tabular}\par}% + \vskip 1.5em% + {\large \@date \par}% % Set date in \large size. + \end{center}\par + \@thanks + \vfil\null + \end{titlepage}% + \setcounter{footnote}{0}% + \global\let\thanks\relax + \global\let\maketitle\relax + \global\let\@thanks\@empty + \global\let\@author\@empty + \global\let\@date\@empty + \global\let\@title\@empty + \global\let\title\relax + \global\let\author\relax + \global\let\date\relax + \global\let\and\relax +} +\else +\newcommand\maketitle{\par + \begingroup + \renewcommand\thefootnote{\@fnsymbol\c@footnote}% + \def\@makefnmark{\rlap{\@textsuperscript{\normalfont\@thefnmark}}}% + \long\def\@makefntext##1{\parindent 1em\noindent + \hb@xt@1.8em{% + \hss\@textsuperscript{\normalfont\@thefnmark}}##1}% + \if@twocolumn + \ifnum \col@number=\@ne + \@maketitle + \else + \twocolumn[\@maketitle]% + \fi + \else + \newpage + \global\@topnum\z@ % Prevents figures from going at top of page. + \@maketitle + \fi + \thispagestyle{plain}\@thanks + \endgroup + \setcounter{footnote}{0}% + \global\let\thanks\relax + \global\let\maketitle\relax + \global\let\@maketitle\relax + \global\let\@thanks\@empty + \global\let\@author\@empty + \global\let\@date\@empty + \global\let\@title\@empty + \global\let\title\relax + \global\let\author\relax + \global\let\date\relax + \global\let\and\relax +} +\def\@maketitle{% + \newpage + \null + \vskip 2em% + \begin{center}% + \let \footnote \thanks + {\LARGE \@title \par}% + \vskip 1.5em% + {\large + \lineskip .5em% + \begin{tabular}[t]{c}% + \@author + \end{tabular}\par}% + \vskip 1em% + {\large \@date}% + \end{center}% + \par + \vskip 1.5em} +\fi +\newcommand*\chaptermark[1]{} +\setcounter{secnumdepth}{2} +\newcounter {part} +\newcounter {chapter} +\newcounter {section}[chapter] +\newcounter {subsection}[section] +\newcounter {subsubsection}[subsection] +\newcounter {paragraph}[subsubsection] +\newcounter {subparagraph}[paragraph] +\renewcommand \thepart {\@Roman\c@part} +\renewcommand \thechapter {\@arabic\c@chapter} +\renewcommand \thesection {\thechapter.\@arabic\c@section} +\renewcommand\thesubsection {\thesection.\@arabic\c@subsection} +\renewcommand\thesubsubsection{\thesubsection .\@arabic\c@subsubsection} +\renewcommand\theparagraph {\thesubsubsection.\@arabic\c@paragraph} +\renewcommand\thesubparagraph {\theparagraph.\@arabic\c@subparagraph} +\newcommand\@chapapp{\chaptername} +\newcommand\frontmatter{% + \cleardoublepage + \@mainmatterfalse + \pagenumbering{roman}} +\newcommand\mainmatter{% + \cleardoublepage + \@mainmattertrue + \pagenumbering{arabic}} +\newcommand\backmatter{% + \if@openright + \cleardoublepage + \else + \clearpage + \fi + \@mainmatterfalse} +\newcommand\part{% + \if@openright + \cleardoublepage + \else + \clearpage + \fi + \thispagestyle{plain}% + \if@twocolumn + \onecolumn + \@tempswatrue + \else + \@tempswafalse + \fi + \null\vfil + \secdef\@part\@spart} + +\def\@part[#1]#2{% + \ifnum \c@secnumdepth >-2\relax + \refstepcounter{part}% + \addcontentsline{toc}{part}{\thepart\hspace{1em}#1}% + \else + \addcontentsline{toc}{part}{#1}% + \fi + \markboth{}{}% + {\centering + \interlinepenalty \@M + \normalfont + \ifnum \c@secnumdepth >-2\relax + \huge\bfseries \partname\nobreakspace\thepart + \par + \vskip 20\p@ + \fi + \Huge \bfseries #2\par}% + \@endpart} +\def\@spart#1{% + {\centering + \interlinepenalty \@M + \normalfont + \Huge \bfseries #1\par}% + \@endpart} +\def\@endpart{\vfil\newpage + \if@twoside + \if@openright + \null + \thispagestyle{empty}% + \newpage + \fi + \fi + \if@tempswa + \twocolumn + \fi} +\newcommand\chapter{\if@openright\cleardoublepage\else\clearpage\fi + \thispagestyle{plain}% + \global\@topnum\z@ + \@afterindentfalse + \secdef\@chapter\@schapter} +\def\@chapter[#1]#2{\ifnum \c@secnumdepth >\m@ne + \if@mainmatter + \refstepcounter{chapter}% + \typeout{\@chapapp\space\thechapter.}% + \addcontentsline{toc}{chapter}% + {\protect\numberline{\thechapter}#1}% + \else + \addcontentsline{toc}{chapter}{#1}% + \fi + \else + \addcontentsline{toc}{chapter}{#1}% + \fi + \chaptermark{#1}% + \addtocontents{lof}{\protect\addvspace{10\p@}}% + \addtocontents{lot}{\protect\addvspace{10\p@}}% + \if@twocolumn + \@topnewpage[\@makechapterhead{#2}]% + \else + \@makechapterhead{#2}% + \@afterheading + \fi} +%%%%\def\@makechapterhead#1{% +%%%% \vspace*{50\p@}% +%%%% {\parindent \z@ \raggedright \normalfont +%%%% \ifnum \c@secnumdepth >\m@ne +%%%% \if@mainmatter +%%%% \huge\bfseries \@chapapp\space \thechapter +%%%% \par\nobreak +%%%% \vskip 20\p@ +%%%% \fi +%%%% \fi +%%%% \interlinepenalty\@M +%%%% \Huge \bfseries #1\par\nobreak +%%%% \vskip 40\p@ +%%%% }} + \newlength \titlewidth + \setlength \titlewidth {\textwidth} + \addtolength \titlewidth {\marginparwidth} + \addtolength \titlewidth {\marginparsep} + \def\@makechapterhead#1{% + \vspace*{50\p@}% + {\parindent \z@ \raggedleft \fontchapter + \ifnum \c@secnumdepth >\m@ne + \if@mainmatter + \huge \@chapapp\space \thechapter + \par\nobreak + \vskip 20\p@ + \fi + \fi + \interlinepenalty\@M + \hsize=\titlewidth + \Huge #1 \par\nobreak + \hsize=\textwidth + \vskip 40\p@ + }} +\def\@schapter#1{\if@twocolumn + \@topnewpage[\@makeschapterhead{#1}]% + \else + \@makeschapterhead{#1}% + \@afterheading + \fi} +%%%%\def\@makeschapterhead#1{% +%%%% \vspace*{50\p@}% +%%%% {\parindent \z@ \raggedright +%%%% \normalfont +%%%% \interlinepenalty\@M +%%%% \Huge \bfseries #1\par\nobreak +%%%% \vskip 40\p@ +%%%% }} + \def\@makeschapterhead#1{% + \vspace*{50\p@}% + {\parindent \z@ \raggedright + \normalfont + \interlinepenalty\@M + \hsize=\titlewidth + \flushright + \Huge \bfseries #1\par\nobreak + \hsize=\textwidth + \vskip 40\p@ + }} +\newcommand\section{\@startsection {section}{1}{\z@}% + {-3.5ex \@plus -1ex \@minus -.2ex}% + {2.3ex \@plus.2ex}% + {\normalfont\Large\bfseries}} +\newcommand\subsection{\@startsection{subsection}{2}{\z@}% + {-3.25ex\@plus -1ex \@minus -.2ex}% + {1.5ex \@plus .2ex}% + {\normalfont\large\bfseries}} +\newcommand\subsubsection{\@startsection{subsubsection}{3}{\z@}% + {-3.25ex\@plus -1ex \@minus -.2ex}% + {1.5ex \@plus .2ex}% + {\normalfont\normalsize\bfseries}} +\newcommand\paragraph{\@startsection{paragraph}{4}{\z@}% + {3.25ex \@plus1ex \@minus.2ex}% + {-1em}% + {\normalfont\normalsize\bfseries}} +\newcommand\subparagraph{\@startsection{subparagraph}{5}{\parindent}% + {3.25ex \@plus1ex \@minus .2ex}% + {-1em}% + {\normalfont\normalsize\bfseries}} +\if@twocolumn + \setlength\leftmargini {2em} +\else + \setlength\leftmargini {2.5em} +\fi +\leftmargin \leftmargini +\setlength\leftmarginii {2.2em} +\setlength\leftmarginiii {1.87em} +\setlength\leftmarginiv {1.7em} +\if@twocolumn + \setlength\leftmarginv {.5em} + \setlength\leftmarginvi {.5em} +\else + \setlength\leftmarginv {1em} + \setlength\leftmarginvi {1em} +\fi +\setlength \labelsep {.5em} +\setlength \labelwidth{\leftmargini} +\addtolength\labelwidth{-\labelsep} +\@beginparpenalty -\@lowpenalty +\@endparpenalty -\@lowpenalty +\@itempenalty -\@lowpenalty +\renewcommand\theenumi{\@arabic\c@enumi} +\renewcommand\theenumii{\@alph\c@enumii} +\renewcommand\theenumiii{\@roman\c@enumiii} +\renewcommand\theenumiv{\@Alph\c@enumiv} +\newcommand\labelenumi{\theenumi.} +\newcommand\labelenumii{(\theenumii)} +\newcommand\labelenumiii{\theenumiii.} +\newcommand\labelenumiv{\theenumiv.} +\renewcommand\p@enumii{\theenumi} +\renewcommand\p@enumiii{\theenumi(\theenumii)} +\renewcommand\p@enumiv{\p@enumiii\theenumiii} +\newcommand\labelitemi{\textbullet} +\newcommand\labelitemii{\normalfont\bfseries \textendash} +\newcommand\labelitemiii{\textasteriskcentered} +\newcommand\labelitemiv{\textperiodcentered} +\newenvironment{description} + {\list{}{\labelwidth\z@ \itemindent-\leftmargin + \let\makelabel\descriptionlabel}} + {\endlist} +\newcommand*\descriptionlabel[1]{\hspace\labelsep + \normalfont\bfseries #1} +\newenvironment{verse} + {\let\\\@centercr + \list{}{\itemsep \z@ + \itemindent -1.5em% + \listparindent\itemindent + \rightmargin \leftmargin + \advance\leftmargin 1.5em}% + \item\relax} + {\endlist} +\newenvironment{quotation} + {\list{}{\listparindent 1.5em% + \itemindent \listparindent + \rightmargin \leftmargin + \parsep \z@ \@plus\p@}% + \item\relax} + {\endlist} +\newenvironment{quote} + {\list{}{\rightmargin\leftmargin}% + \item\relax} + {\endlist} +\if@compatibility +\newenvironment{titlepage} + {% + \cleardoublepage + \if@twocolumn + \@restonecoltrue\onecolumn + \else + \@restonecolfalse\newpage + \fi + \thispagestyle{empty}% + \setcounter{page}\z@ + }% + {\if@restonecol\twocolumn \else \newpage \fi + } +\else +\newenvironment{titlepage} + {% + \cleardoublepage + \if@twocolumn + \@restonecoltrue\onecolumn + \else + \@restonecolfalse\newpage + \fi + \thispagestyle{empty}% + \setcounter{page}\@ne + }% + {\if@restonecol\twocolumn \else \newpage \fi + \if@twoside\else + \setcounter{page}\@ne + \fi + } +\fi +\newcommand\appendix{\par + \setcounter{chapter}{0}% + \setcounter{section}{0}% + \gdef\@chapapp{\appendixname}% + \gdef\thechapter{\@Alph\c@chapter}} +\setlength\arraycolsep{5\p@} +\setlength\tabcolsep{6\p@} +\setlength\arrayrulewidth{.4\p@} +\setlength\doublerulesep{2\p@} +\setlength\tabbingsep{\labelsep} +\skip\@mpfootins = \skip\footins +\setlength\fboxsep{3\p@} +\setlength\fboxrule{.4\p@} +\@addtoreset {equation}{chapter} +\renewcommand\theequation + {\ifnum \c@chapter>\z@ \thechapter.\fi \@arabic\c@equation} +\newcounter{figure}[chapter] +\renewcommand \thefigure + {\ifnum \c@chapter>\z@ \thechapter.\fi \@arabic\c@figure} +\def\fps@figure{tbp} +\def\ftype@figure{1} +\def\ext@figure{lof} +\def\fnum@figure{\figurename\nobreakspace\thefigure} +\newenvironment{figure} + {\@float{figure}} + {\end@float} +\newenvironment{figure*} + {\@dblfloat{figure}} + {\end@dblfloat} +\newcounter{table}[chapter] +\renewcommand \thetable + {\ifnum \c@chapter>\z@ \thechapter.\fi \@arabic\c@table} +\def\fps@table{tbp} +\def\ftype@table{2} +\def\ext@table{lot} +\def\fnum@table{\tablename\nobreakspace\thetable} +\newenvironment{table} + {\@float{table}} + {\end@float} +\newenvironment{table*} + {\@dblfloat{table}} + {\end@dblfloat} +\newlength\abovecaptionskip +\newlength\belowcaptionskip +\setlength\abovecaptionskip{10\p@} +\setlength\belowcaptionskip{0\p@} +\long\def\@makecaption#1#2{% + \vskip\abovecaptionskip + \sbox\@tempboxa{#1: #2}% + \ifdim \wd\@tempboxa >\hsize + #1: #2\par + \else + \global \@minipagefalse + \hb@xt@\hsize{\hfil\box\@tempboxa\hfil}% + \fi + \vskip\belowcaptionskip} +\DeclareOldFontCommand{\rm}{\normalfont\rmfamily}{\mathrm} +\DeclareOldFontCommand{\sf}{\normalfont\sffamily}{\mathsf} +\DeclareOldFontCommand{\tt}{\normalfont\ttfamily}{\mathtt} +\DeclareOldFontCommand{\bf}{\normalfont\bfseries}{\mathbf} +\DeclareOldFontCommand{\it}{\normalfont\itshape}{\mathit} +\DeclareOldFontCommand{\sl}{\normalfont\slshape}{\@nomath\sl} +\DeclareOldFontCommand{\sc}{\normalfont\scshape}{\@nomath\sc} +\DeclareRobustCommand*\cal{\@fontswitch\relax\mathcal} +\DeclareRobustCommand*\mit{\@fontswitch\relax\mathnormal} +\newcommand\@pnumwidth{1.55em} +\newcommand\@tocrmarg{2.55em} +\newcommand\@dotsep{4.5} +\setcounter{tocdepth}{2} +\newcommand\tableofcontents{% + \if@twocolumn + \@restonecoltrue\onecolumn + \else + \@restonecolfalse + \fi + \chapter*{\contentsname + \@mkboth{% + \MakeUppercase\contentsname}{\MakeUppercase\contentsname}}% + \@starttoc{toc}% + \if@restonecol\twocolumn\fi + } +\newcommand*\l@part[2]{% + \ifnum \c@tocdepth >-2\relax + \addpenalty{-\@highpenalty}% + \addvspace{2.25em \@plus\p@}% + \setlength\@tempdima{3em}% + \begingroup + \parindent \z@ \rightskip \@pnumwidth + \parfillskip -\@pnumwidth + {\leavevmode + \large \bfseries #1\hfil \hb@xt@\@pnumwidth{\hss #2}}\par + \nobreak + \global\@nobreaktrue + \everypar{\global\@nobreakfalse\everypar{}}% + \endgroup + \fi} +%%%%\newcommand*\l@chapter[2]{% +%%%% \ifnum \c@tocdepth >\m@ne +%%%% \addpenalty{-\@highpenalty}% +%%%% \vskip 1.0em \@plus\p@ +%%%% \setlength\@tempdima{1.5em}% +%%%% \begingroup +%%%% \parindent \z@ \rightskip \@pnumwidth +%%%% \parfillskip -\@pnumwidth +%%%% \leavevmode \bfseries +%%%% \advance\leftskip\@tempdima +%%%% \hskip -\leftskip +%%%% #1\nobreak\hfil \nobreak\hb@xt@\@pnumwidth{\hss #2}\par +%%%% \penalty\@highpenalty +%%%% \endgroup +%%%% \fi} +\newcommand\l@chapter[2]{% + \ifnum \c@tocdepth >\m@ne + \addpenalty{-\@highpenalty}% + \vskip 1.0em \@plus\p@ + \setlength\@tempdima{1.5em}% + \begingroup + \parindent \z@ \rightskip \@pnumwidth + \parfillskip -\@pnumwidth + \leavevmode \fontchapter + \advance\leftskip\@tempdima + \hskip -\leftskip + #1\nobreak\hfil \nobreak\hb@xt@\@pnumwidth{\hss #2}\par + \penalty\@highpenalty + \endgroup + \fi} +\newcommand*\l@section{\@dottedtocline{1}{1.5em}{2.3em}} +\newcommand*\l@subsection{\@dottedtocline{2}{3.8em}{3.2em}} +\newcommand*\l@subsubsection{\@dottedtocline{3}{7.0em}{4.1em}} +\newcommand*\l@paragraph{\@dottedtocline{4}{10em}{5em}} +\newcommand*\l@subparagraph{\@dottedtocline{5}{12em}{6em}} +\newcommand\listoffigures{% + \if@twocolumn + \@restonecoltrue\onecolumn + \else + \@restonecolfalse + \fi + \chapter*{\listfigurename}% + \@mkboth{\MakeUppercase\listfigurename}% + {\MakeUppercase\listfigurename}% + \@starttoc{lof}% + \if@restonecol\twocolumn\fi + } +\newcommand*\l@figure{\@dottedtocline{1}{1.5em}{2.3em}} +\newcommand\listoftables{% + \if@twocolumn + \@restonecoltrue\onecolumn + \else + \@restonecolfalse + \fi + \chapter*{\listtablename}% + \@mkboth{% + \MakeUppercase\listtablename}% + {\MakeUppercase\listtablename}% + \@starttoc{lot}% + \if@restonecol\twocolumn\fi + } +\let\l@table\l@figure +\newdimen\bibindent +\setlength\bibindent{1.5em} +\newenvironment{thebibliography}[1] + {\chapter*{\bibname}% + \@mkboth{\MakeUppercase\bibname}{\MakeUppercase\bibname}% + \list{\@biblabel{\@arabic\c@enumiv}}% + {\settowidth\labelwidth{\@biblabel{#1}}% + \leftmargin\labelwidth + \advance\leftmargin\labelsep + \@openbib@code + \usecounter{enumiv}% + \let\p@enumiv\@empty + \renewcommand\theenumiv{\@arabic\c@enumiv}}% + \sloppy + \clubpenalty4000 + \@clubpenalty \clubpenalty + \widowpenalty4000% + \sfcode`\.\@m} + {\def\@noitemerr + {\@latex@warning{Empty `thebibliography' environment}}% + \endlist} +\newcommand\newblock{\hskip .11em\@plus.33em\@minus.07em} +\let\@openbib@code\@empty +\newenvironment{theindex} + {\if@twocolumn + \@restonecolfalse + \else + \@restonecoltrue + \fi + \columnseprule \z@ + \columnsep 35\p@ + \twocolumn[\@makeschapterhead{\indexname}]% + \@mkboth{\MakeUppercase\indexname}% + {\MakeUppercase\indexname}% + \thispagestyle{plain}\parindent\z@ + \parskip\z@ \@plus .3\p@\relax + \let\item\@idxitem} + {\if@restonecol\onecolumn\else\clearpage\fi} +\newcommand\@idxitem{\par\hangindent 40\p@} +\newcommand\subitem{\@idxitem \hspace*{20\p@}} +\newcommand\subsubitem{\@idxitem \hspace*{30\p@}} +\newcommand\indexspace{\par \vskip 10\p@ \@plus5\p@ \@minus3\p@\relax} +\renewcommand\footnoterule{% + \kern-3\p@ + \hrule\@width.4\columnwidth + \kern2.6\p@} +\@addtoreset{footnote}{chapter} +\newcommand\@makefntext[1]{% + \parindent 1em% + \noindent + \hb@xt@1.8em{\hss\@makefnmark}#1} +\newcommand\contentsname{Contents} +\newcommand\listfigurename{List of Figures} +\newcommand\listtablename{List of Tables} +\newcommand\bibname{Bibliography} +\newcommand\indexname{Index} +\newcommand\figurename{Figure} +\newcommand\tablename{Table} +\newcommand\partname{Part} +\newcommand\chaptername{Chapter} +\newcommand\appendixname{Appendix} +\def\today{\ifcase\month\or + January\or February\or March\or April\or May\or June\or + July\or August\or September\or October\or November\or December\fi + \space\number\day, \number\year} +\setlength\columnsep{10\p@} +\setlength\columnseprule{0\p@} +\pagestyle{headings} +\pagenumbering{arabic} +\if@twoside +\else + \raggedbottom +\fi +\if@twocolumn + \twocolumn + \sloppy + \flushbottom +\else + \onecolumn +\fi +\endinput +%% +%% End of file `book.cls'. diff --git a/katabatic/doc/customHierarchy.html b/katabatic/doc/customHierarchy.html new file mode 100644 index 00000000..2b27d725 --- /dev/null +++ b/katabatic/doc/customHierarchy.html @@ -0,0 +1,110 @@ + + + + + + Katabatic Documentation + + +

Katabatic Documentation

+
+ + + + + + + + + +
SummaryNamespacesClass HierarchyClassesMember Index
+
+
+
+ +

Katabatic Synthetic Class Hierarchy

+
+ +

The complete class hierarchy could be accessed here.

+

All the classes below are in the Katabatic namespace.

+

The inheritance tree has been splitted/simplificated.

+ Legend :
+
+      
+        
+        
+      
ClassA  ClassA is abstract
ClassB  ClassB is instanciable
+
+
+ +

Katabatic Engine

+ + + + +
Katabatic
Session
DataAlgorithm
+ +

Contacts

+ + +
AutoContact
+ +

Segments

+ + +
AutoSegment
+ + + +
AutoSegmentDecorator
AutoSegmentConcrete
+ + + +
AutoHorizontal
AutoVertical
+ +

FCells

+ + +
FCell
+ + + +
FCellDecorator
FCellConcrete
+ + +
FCellGrid
+ + + +
FCellGridConcrete
+ + + +
FCellConfiguration
FCellConfiguration::UState
+ +

Miscellaneous Utilities

+ + + + + +
DebugSession
RPSortX
RPSortY
SplitterForkList
+ + +
+ + + + + +
Customized Class HierarchyReturn to top of page
+ + + + + +
Katabatic DocumentationCopyright © 2000-2007 Bull S.A. All rights reserved
+ + diff --git a/katabatic/doc/customSummary.html b/katabatic/doc/customSummary.html new file mode 100644 index 00000000..377b97ad --- /dev/null +++ b/katabatic/doc/customSummary.html @@ -0,0 +1,77 @@ + + + + + + Katabatic Documentation + + +

Katabatic Documentation

+
+ + + + + + + + + +
SummaryNamespacesClass HierarchyClassesMember Index
+
+
+
+ + + +

Katabatic Documentation Summary

+
+

The classical Doxygen module documentation could be accessed here.

+

Katabatic Concepts (internal)

+
    +
  1. Rules for building wires. +
    Rules for building AutoContacts. Global/Locals AutoSegments. +
  2. Global Routing Loading. +
    How the Knik global routing is loaded into Katabatic data-base. + Details the wiring topologies used to complete the routing to the + terminals. +
  3. AutoSegment Collapse & Canonical. +
    How to force alignment of AutoSegments. +
  4. Layer Assignment. +
    Simple strategy to put long wires on higher routing metals. +
  5. Constraints Computations. +
    Compute the legal range of variation of each wire (note that the + constraints are stored on AutoContacts). +
  6. AutoSegment Optimal Placement. +
    Compute the optimal range of variation of each wire. +
  7. Katabatic Update Session Mechanism. +
    The Session mechanism for modifying the Katabatic data-base. +
+

API documentations

+ +
+ + +
+ + + + + +
Customized Concepts (a.k.a. modules)Return to top of page
+ + + + + +
Katabatic DocumentationCopyright © 2005-2007 LIP6. All rights reserved
+ + diff --git a/katabatic/doc/doxyfile b/katabatic/doc/doxyfile new file mode 100644 index 00000000..bf987084 --- /dev/null +++ b/katabatic/doc/doxyfile @@ -0,0 +1,275 @@ +# Doxyfile 1.3.4 + +# -------------------------------------------------------------------- +# Project related configuration options + +PROJECT_NAME = "Katabatic - Routing Toolbox" +PROJECT_NUMBER = 1.0 +OUTPUT_DIRECTORY = . +OUTPUT_LANGUAGE = English +#USE_WINDOWS_ENCODING = NO +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = NO +STRIP_FROM_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +#DETAILS_AT_TOP = YES +INHERIT_DOCS = YES +DISTRIBUTE_GROUP_DOC = NO +TAB_SIZE = 2 +ALIASES = "function=\fn"\ + "important=\par Important:\n"\ + "remark=\par Remark:\n"\ + "True=\b True"\ + "true=\b true"\ + "False=\b False"\ + "false=\b false"\ + "VERTICAL=\b VERTICAL"\ + "HORIZONTAL=\b HORIZONTAL"\ + "NULL=\c NULL"\ + "vector=\c vector"\ + "Collection=\c Collection"\ + "Collections=\c Collections"\ + "Box=\c Box"\ + "box=\c box"\ + "Layer=\c Layer"\ + "Layers=\c Layers"\ + "Net=\c Net"\ + "Nets=\c Nets"\ + "Pin=\c Pin"\ + "Pins=\c Pins"\ + "Plug=\c Plug"\ + "Plugs=\c Plugs"\ + "RoutingPad=\c RoutingPad"\ + "RoutingPads=\c RoutingPads"\ + "Cell=\c Cell"\ + "Cells=\c Cells"\ + "ToolEngine=\c ToolEngine"\ + "ToolEngines=\c ToolEngines"\ + "GCell=\c GCell"\ + "GCells=\c GCells"\ + "Splitter=\c Splitter"\ + "Splitters=\c Splitters"\ + "SplitterContact=\c SplitterContact"\ + "SplitterContacts=\c SplitterContacts"\ + "Hurricane=Hurricane"\ + "STL=STL" +OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_JAVA = YES +SUBGROUPING = YES + +# -------------------------------------------------------------------- +# Build related configuration options + +EXTRACT_ALL = NO +EXTRACT_PRIVATE = YES +EXTRACT_STATIC = YES +EXTRACT_LOCAL_CLASSES = YES +HIDE_UNDOC_MEMBERS = YES +HIDE_UNDOC_CLASSES = YES +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 1 +SHOW_USED_FILES = YES + +# -------------------------------------------------------------------- +# Configuration options related to warning and progress messages + +QUIET = YES +WARNINGS = YES +WARN_IF_UNDOCUMENTED = NO +WARN_IF_DOC_ERROR = YES +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = + +# -------------------------------------------------------------------- +# Configuration options related to the input files + +INPUT = \ + ../src/katabatic/KatabaticEngine.h ../src/KatabaticEngine.cpp KatabaticEngine.dox \ + ../src/LoadGrByNet.cpp LoadGrByNet.dox \ + ../src/LayerAssign.cpp LayerAssign.dox \ + ../src/NetConstraints.cpp NetConstraints.dox \ + ../src/NetOptimals.cpp NetOptimals.dox \ + ../src/katabatic/AutoContact.h ../src/AutoContact.cpp AutoContact.dox \ + ../src/katabatic/AutoSegment.h ../src/AutoSegment.cpp AutoSegment.dox \ + ../src/katabatic/AutoHorizontal.h ../src/AutoHorizontal.cpp \ + ../src/katabatic/AutoVertical.h ../src/AutoVertical.cpp \ + ../src/katabatic/Grid.h ../src/Grid.cpp Grid.dox \ + ../src/katabatic/GCell.h ../src/GCell.cpp GCell.dox \ + ../src/katabatic/GCellGrid.h ../src/GCellGrid.cpp GCellGrid.dox \ + ../src/katabatic/Session.h ../src/Session.cpp Session.dox + +FILE_PATTERNS = *.h \ + *.cpp \ + *.dox + +RECURSIVE = YES + +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = images +INPUT_FILTER = +FILTER_SOURCE_FILES = YES + +# -------------------------------------------------------------------- +# Configuration options related to source browsing + +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES +VERBATIM_HEADERS = YES + +# -------------------------------------------------------------------- +# Configuration options related to the alphabetical class index + +ALPHABETICAL_INDEX = YES +COLS_IN_ALPHA_INDEX = 2 +IGNORE_PREFIX = + +# -------------------------------------------------------------------- +# Configuration options related to the HTML output + +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = header.html +HTML_FOOTER = footer.html +HTML_STYLESHEET = ASIM.css +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = YES +ENUM_VALUES_PER_LINE = 1 +GENERATE_TREEVIEW = NO +TREEVIEW_WIDTH = 250 + +# -------------------------------------------------------------------- +# Configuration options related to the LaTeX output + +GENERATE_LATEX = YES +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = header.tex +PDF_HYPERLINKS = YES +USE_PDFLATEX = YES +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO + +# -------------------------------------------------------------------- +# Configuration options related to the RTF output + +GENERATE_RTF = YES +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = + +# -------------------------------------------------------------------- +# Configuration options related to the man page output + +GENERATE_MAN = YES +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO + +# -------------------------------------------------------------------- +# Configuration options related to the XML output + +GENERATE_XML = NO +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = + +# -------------------------------------------------------------------- +# Configuration options for the AutoGen Definitions output + +GENERATE_AUTOGEN_DEF = NO + +# -------------------------------------------------------------------- +# Configuration options related to the Perl module output + +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = + +# -------------------------------------------------------------------- +# Configuration options related to the preprocessor + +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = __DOXYGEN__ +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES + +# -------------------------------------------------------------------- +# Configuration::addtions related to external references + +TAGFILES = ../../../../hurricane/doc/hurricane/html/hurricane.tag=../hurricane +GENERATE_TAGFILE = html/katabatic.tag +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl + +# -------------------------------------------------------------------- +# Configuration options related to the dot tool + +CLASS_DIAGRAMS = NO +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = YES +CLASS_GRAPH = YES +COLLABORATION_GRAPH = NO +UML_LOOK = NO +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +GRAPHICAL_HIERARCHY = NO +DOT_IMAGE_FORMAT = png +DOT_PATH = +DOTFILE_DIRS = +#MAX_DOT_GRAPH_WIDTH = 512 +#MAX_DOT_GRAPH_HEIGHT = 1024 +#MAX_DOT_GRAPH_DEPTH = 0 +GENERATE_LEGEND = YES +DOT_CLEANUP = YES + +# -------------------------------------------------------------------- +# Configuration::addtions related to the search engine + +SEARCHENGINE = NO diff --git a/katabatic/doc/footer.html b/katabatic/doc/footer.html new file mode 100644 index 00000000..3bbb05ce --- /dev/null +++ b/katabatic/doc/footer.html @@ -0,0 +1,16 @@ +
+
+ + + + + +
Generated by doxygen $doxygenversion on $dateReturn to top of page
+ + + + + +
Katabatic - Routing ToolboxCopyright © 2008-2009 LIP6. All rights reserved
+ + diff --git a/katabatic/doc/header.html b/katabatic/doc/header.html new file mode 100644 index 00000000..3d287482 --- /dev/null +++ b/katabatic/doc/header.html @@ -0,0 +1,22 @@ + + + + Katabatic - Routing Toolbox: Routing Toolbox Documentation + + +

Katabatic - Routing Toolbox

+
+ + + + + + + + + +
SummaryNamespacesClass HierarchyClassesMember Index
+
+
+
+ diff --git a/katabatic/doc/header.tex b/katabatic/doc/header.tex new file mode 100644 index 00000000..ec779312 --- /dev/null +++ b/katabatic/doc/header.tex @@ -0,0 +1,47 @@ + + + \documentclass[a4paper]{asimbook} + + \usepackage{a4wide} + \usepackage{makeidx} + \usepackage{fancyhdr} + \usepackage{graphicx} + \usepackage{multicol} + \usepackage{float} + \usepackage{textcomp} + \usepackage{alltt} + \usepackage{times} + \ifx\pdfoutput\undefined + \usepackage[ps2pdf,pagebackref=true,colorlinks=true,linkcolor=blue]{hyperref} + \usepackage{pspicture} + \else + \usepackage[pdftex,pagebackref=true,colorlinks=true,linkcolor=blue]{hyperref} + \fi + \usepackage{doxygen} + + \makeindex + \setcounter{tocdepth}{1} + \renewcommand{\footrulewidth}{0.4pt} + \raggedbottom + + + \begin{document} + + \begin{titlepage} + \vspace*{7cm} + \begin{center} + {\Large $projectname Reference Manual\\[1ex]\large $projectnumber }\\ + \vspace*{1cm} + {\large Generated by Doxygen $doxygenversion}\\ + \vspace*{0.5cm} + {\small $datetime}\\ + \end{center} + \end{titlepage} + + \clearemptydoublepage + \pagenumbering{roman} + + \tableofcontents + \clearemptydoublepage + + \pagenumbering{arabic} diff --git a/katabatic/doc/html.entry b/katabatic/doc/html.entry new file mode 100644 index 00000000..08e4fdf5 --- /dev/null +++ b/katabatic/doc/html.entry @@ -0,0 +1 @@ +
  • Katabatic
    Routing Database

    diff --git a/katabatic/doc/images/AutoContact-1.fig b/katabatic/doc/images/AutoContact-1.fig new file mode 100644 index 00000000..47adcccb --- /dev/null +++ b/katabatic/doc/images/AutoContact-1.fig @@ -0,0 +1,107 @@ +#FIG 3.2 +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +6 11025 2325 13275 2925 +2 2 0 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5 + 11100 2400 13200 2400 13200 2850 11100 2850 11100 2400 +4 1 0 50 -1 18 16 0.0000 4 240 1635 12150 2700 AutoSegment\001 +-6 +6 11025 5925 13275 6525 +2 2 0 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5 + 11100 6000 13200 6000 13200 6450 11100 6450 11100 6000 +4 1 0 50 -1 18 16 0.0000 4 180 1500 12150 6300 AutoContact\001 +-6 +6 11025 7425 13275 8025 +2 2 0 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5 + 11100 7500 13200 7500 13200 7950 11100 7950 11100 7500 +4 1 0 50 -1 18 16 0.0000 4 240 1635 12150 7800 AutoSegment\001 +-6 +2 1 0 2 0 7 50 -1 15 0.000 0 0 -1 0 0 4 + 5700 0 5700 3300 6000 3300 6000 0 +2 1 0 2 0 7 50 -1 15 0.000 0 0 -1 0 0 4 + 12300 3900 9000 3900 9000 4200 12300 4200 +2 2 3 2 0 7 60 -1 -1 15.000 0 0 -1 0 0 5 + 2100 2100 10200 2100 10200 9600 2100 9600 2100 2100 +2 2 0 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5 + 8100 7200 8400 7200 8400 9000 8100 9000 8100 7200 +2 2 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 7950 7950 8550 7950 8550 8550 7950 8550 7950 7950 +2 2 0 2 0 7 45 -1 15 6.000 0 0 -1 0 0 5 + 6900 8100 8400 8100 8400 8400 6900 8400 6900 8100 +2 2 0 4 4 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 7350 6150 7950 6150 7950 6750 7350 6750 7350 6150 +2 1 0 4 20 7 50 -1 -1 10.000 0 0 -1 0 0 3 + 5850 3450 5850 8250 6750 8250 +2 1 0 4 20 7 50 -1 -1 10.000 0 0 -1 0 0 2 + 3450 6450 5850 6450 +2 1 0 4 20 7 50 -1 -1 10.000 0 0 -1 0 0 2 + 8850 4050 5850 4050 +2 2 0 4 20 7 50 -1 -1 10.000 0 0 -1 0 0 5 + 5700 6300 6000 6300 6000 6600 5700 6600 5700 6300 +2 2 0 4 20 7 50 -1 -1 10.000 0 0 -1 0 0 5 + 5700 3900 6000 3900 6000 4200 5700 4200 5700 3900 +2 1 0 4 4 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 7500 6450 7800 6450 +2 1 0 4 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 5850 2850 5850 3150 +2 1 0 4 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 9150 4050 9450 4050 +2 1 0 4 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 7050 8250 7350 8250 +2 1 0 4 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2850 6450 3150 6450 +2 1 0 2 0 7 50 -1 15 0.000 0 0 -1 0 0 4 + 0 6300 3300 6300 3300 6600 0 6600 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 1 0 4 + 1 1 2.00 120.00 240.00 + 11400 2850 11400 3300 9450 3300 9450 3975 +2 1 0 2 0 7 50 -1 -1 6.000 0 0 -1 1 0 2 + 1 1 2.00 120.00 240.00 + 12600 2850 12600 6000 +2 1 0 2 0 7 50 -1 -1 6.000 0 0 -1 1 0 3 + 1 1 2.00 120.00 240.00 + 12900 2850 12900 3300 13725 3300 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 1 0 3 + 1 1 2.00 120.00 240.00 + 11100 7725 7350 7725 7350 8250 +2 1 0 2 0 7 50 -1 -1 6.000 0 0 -1 1 0 2 + 1 1 2.00 120.00 240.00 + 12600 7500 12600 6450 +2 1 0 2 0 7 50 -1 -1 6.000 0 0 -1 1 0 3 + 1 1 2.00 120.00 240.00 + 12900 7950 12900 8400 13800 8400 +2 1 0 2 0 7 50 -1 -1 6.000 0 0 -1 1 0 2 + 1 1 2.00 120.00 240.00 + 11100 6300 7950 6300 +3 0 0 2 4 7 40 -1 -1 6.000 0 1 0 4 + 3 0 2.00 120.00 240.00 + 7650 6450 7650 6900 7200 7500 7200 8250 + 0.000 1.000 1.000 0.000 +3 0 0 2 4 7 40 -1 -1 6.000 0 1 0 6 + 3 0 2.00 120.00 240.00 + 7200 8325 7200 8700 6900 9000 4800 9000 3000 7200 3000 6450 + 0.000 1.000 1.000 1.000 1.000 0.000 +3 0 0 2 4 7 40 -1 -1 6.000 0 1 0 4 + 3 0 2.00 120.00 240.00 + 3000 6450 3000 5100 5100 3000 5850 3000 + 0.000 1.000 1.000 0.000 +3 0 0 2 4 7 40 -1 -1 6.000 0 1 0 4 + 3 0 2.00 120.00 240.00 + 5850 3000 8700 3000 9300 3600 9300 4050 + 0.000 1.000 1.000 0.000 +3 0 0 2 4 7 40 -1 -1 0.000 0 1 0 4 + 3 1 2.00 120.00 240.00 + 9300 4050 9300 4800 7650 5700 7650 6450 + 0.000 1.000 1.000 0.000 +4 1 0 50 -1 18 16 1.5708 4 180 360 12525 5100 AC\001 +4 1 0 50 -1 18 16 1.5708 4 180 360 12525 7050 AC\001 +4 1 0 50 -1 18 16 0.0000 4 180 165 11550 3300 S\001 +4 1 0 50 -1 18 16 0.0000 4 180 150 13050 3150 T\001 +4 1 0 50 -1 18 16 0.0000 4 180 165 10950 8025 S\001 +4 1 0 50 -1 18 16 0.0000 4 180 150 13050 8250 T\001 diff --git a/katabatic/doc/images/AutoContact-1.pdf b/katabatic/doc/images/AutoContact-1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..f6942d4a4df0030a79111d485e2f60e43ad8dba5 GIT binary patch literal 5370 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 JKK<9}{BOgJ4?F+> literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/AutoContact-10.fig b/katabatic/doc/images/AutoContact-10.fig new file mode 100644 index 00000000..5c4f4236 --- /dev/null +++ b/katabatic/doc/images/AutoContact-10.fig @@ -0,0 +1,72 @@ +#FIG 3.2 +Landscape +Center +Inches +Letter +70.00 +Single +-2 +1200 2 +6 825 1125 6000 6300 +6 825 1125 3075 1575 +2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 900 1200 3000 1200 3000 1500 900 1500 900 1200 +4 0 0 50 -1 14 12 0.0000 4 135 1890 975 1425 HExtended - case 1\001 +-6 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 1800 1875 2550 1875 2550 2100 1800 2100 1800 1875 +2 2 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 2625 3450 4725 3450 4725 3750 2625 3750 2625 3450 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 1800 2100 5400 2100 5400 5400 1800 5400 1800 2100 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 900 1200 6000 1200 6000 6300 900 6300 900 1200 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 2625 3600 1575 3600 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 2700 2700 2700 3450 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 3300 3750 3300 5700 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 4500 3750 4500 4500 +4 1 0 50 -1 14 12 0.0000 4 135 525 2175 2025 GCell\001 +4 1 0 50 -1 14 18 0.0000 4 165 165 2850 2925 L\001 +4 1 0 50 -1 14 18 0.0000 4 165 165 1650 3900 G\001 +4 1 0 50 -1 14 18 0.0000 4 165 165 4650 4500 L\001 +4 1 0 50 -1 14 18 0.0000 4 165 165 3450 5625 G\001 +-6 +1 2 0 2 4 7 50 -1 -1 0.000 1 0.0000 9450 3600 150 300 9300 3300 9600 3900 +1 4 0 2 4 7 50 -1 -1 0.000 1 0.0000 8550 3600 150 150 8400 3600 8700 3600 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 8100 1875 8850 1875 8850 2100 8100 2100 8100 1875 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 8100 2100 11700 2100 11700 5400 8100 5400 8100 2100 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 7200 1200 12300 1200 12300 6300 7200 6300 7200 1200 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 8850 3600 7800 3600 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 9000 2700 9000 3450 +2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 7200 1200 9300 1200 9300 1500 7200 1500 7200 1200 +2 2 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 8850 3450 9150 3450 9150 3750 8850 3750 8850 3450 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 9150 3525 9900 3525 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 9150 3675 12000 3675 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 8925 3600 9075 3600 +2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 3 0 2.00 120.00 240.00 + 8550 3750 8700 4500 +2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 3 0 2.00 120.00 240.00 + 9450 3900 9300 4500 +4 1 0 50 -1 14 12 0.0000 4 135 525 8475 2025 GCell\001 +4 1 0 50 -1 14 18 0.0000 4 165 165 9150 2925 L\001 +4 1 0 50 -1 14 18 0.0000 4 165 165 7950 3900 G\001 +4 0 0 50 -1 14 12 0.0000 4 135 1890 7275 1425 HExtended - case 2\001 +4 1 0 50 -1 14 18 0.0000 4 165 165 11925 3975 G\001 +4 1 0 50 -1 14 18 0.0000 4 165 165 9750 3450 L\001 +4 1 4 50 -1 18 12 0.0000 4 180 1170 9000 4650 kept aligneds\001 diff --git a/katabatic/doc/images/AutoContact-10.pdf b/katabatic/doc/images/AutoContact-10.pdf new file mode 100644 index 0000000000000000000000000000000000000000..c61281fe2d26ffb74e7cef375fc4d0b0b2b54914 GIT binary patch literal 3592 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 literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/AutoContact-10.png b/katabatic/doc/images/AutoContact-10.png new file mode 100644 index 0000000000000000000000000000000000000000..a5ddfa35474c09ea231a6eaf41ff834aa297267d GIT binary patch literal 4398 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 literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/AutoContact-11.fig b/katabatic/doc/images/AutoContact-11.fig new file mode 100644 index 00000000..7baf87c6 --- /dev/null +++ b/katabatic/doc/images/AutoContact-11.fig @@ -0,0 +1,68 @@ +#FIG 3.2 +Landscape +Center +Inches +Letter +70.00 +Single +-2 +1200 2 +1 2 0 2 4 7 50 -1 -1 0.000 1 0.0000 10200 3150 300 150 9900 3000 10500 3300 +1 4 0 2 4 7 50 -1 -1 0.000 1 0.0000 10200 4050 150 150 10050 4050 10350 4050 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 8100 1875 8850 1875 8850 2100 8100 2100 8100 1875 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 8100 2100 11700 2100 11700 5400 8100 5400 8100 2100 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 7200 1200 12300 1200 12300 6300 7200 6300 7200 1200 +2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 7200 1200 9300 1200 9300 1500 7200 1500 7200 1200 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 1800 1875 2550 1875 2550 2100 1800 2100 1800 1875 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 1800 2100 5400 2100 5400 5400 1800 5400 1800 2100 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 900 1200 6000 1200 6000 6300 900 6300 900 1200 +2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 900 1200 3000 1200 3000 1500 900 1500 900 1200 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 3750 3600 1500 3600 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 3900 4650 3900 5700 +2 2 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 3750 2850 4050 2850 4050 4650 3750 4650 3750 2850 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 3750 3000 3000 3000 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 4800 4500 4050 4500 +2 2 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 10050 3450 10350 3450 10350 3750 10050 3750 10050 3450 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 10200 5700 10200 3750 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 10275 1800 10275 3450 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 10125 3450 10125 2700 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 10350 3600 11100 3600 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 10200 3675 10200 3525 +2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 3 0 2.00 120.00 240.00 + 9900 3150 8850 3375 +2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 3 0 2.00 120.00 240.00 + 10050 4050 8850 3750 +4 1 0 50 -1 14 12 0.0000 4 135 525 8475 2025 GCell\001 +4 0 0 50 -1 14 12 0.0000 4 135 1890 7275 1425 VExtended - case 2\001 +4 1 0 50 -1 14 12 0.0000 4 135 525 2175 2025 GCell\001 +4 0 0 50 -1 14 12 0.0000 4 135 1890 975 1425 VExtended - case 1\001 +4 1 0 50 -1 14 18 0.0000 4 165 165 4050 5625 G\001 +4 1 0 50 -1 14 18 0.0000 4 165 165 4725 4425 L\001 +4 1 0 50 -1 14 18 0.0000 4 165 165 3075 2925 L\001 +4 1 0 50 -1 14 18 0.0000 4 165 165 1650 3900 G\001 +4 1 0 50 -1 14 18 0.0000 4 165 165 11025 3900 L\001 +4 1 0 50 -1 14 18 0.0000 4 165 165 9975 2925 L\001 +4 1 0 50 -1 14 18 0.0000 4 165 165 10425 2025 G\001 +4 1 4 50 -1 18 12 0.0000 4 180 1170 8775 3600 kept aligneds\001 +4 1 0 50 -1 14 18 0.0000 4 165 165 10350 5700 G\001 diff --git a/katabatic/doc/images/AutoContact-11.pdf b/katabatic/doc/images/AutoContact-11.pdf new file mode 100644 index 0000000000000000000000000000000000000000..f09c9dc6f480da5965390a2973ba56bade45aae7 GIT binary patch literal 3584 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 literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/AutoContact-12.fig b/katabatic/doc/images/AutoContact-12.fig new file mode 100644 index 00000000..dffaf863 --- /dev/null +++ b/katabatic/doc/images/AutoContact-12.fig @@ -0,0 +1,91 @@ +#FIG 3.2 +Landscape +Center +Inches +Letter +70.00 +Single +-2 +1200 2 +6 6600 1875 10200 5400 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 6600 1875 7350 1875 7350 2100 6600 2100 6600 1875 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 6600 2100 10200 2100 10200 5400 6600 5400 6600 2100 +4 1 0 50 -1 14 12 0.0000 4 135 525 6975 2025 GCell\001 +-6 +1 4 0 2 4 7 45 -1 -1 0.000 1 0.0000 3300 4200 150 150 3150 4200 3450 4200 +1 4 0 2 4 7 45 -1 -1 0.000 1 0.0000 4500 4050 150 150 4350 4050 4650 4050 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 1800 1875 2550 1875 2550 2100 1800 2100 1800 1875 +2 2 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 2625 3450 4725 3450 4725 3750 2625 3750 2625 3450 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 1800 2100 5400 2100 5400 5400 1800 5400 1800 2100 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 2625 3600 1500 3600 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 2700 2700 2700 3450 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 4500 3750 4500 4500 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 900 1200 11100 1200 11100 6225 900 6225 900 1200 +2 1 0 2 4 7 45 -1 -1 0.000 0 0 -1 1 0 2 + 3 0 2.00 120.00 240.00 + 3375 4350 3900 4800 +2 1 0 2 4 7 45 -1 -1 0.000 0 0 -1 1 0 2 + 3 0 2.00 120.00 240.00 + 4425 4125 3975 4800 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 7350 3600 6300 3600 +2 2 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 7350 3450 8250 3450 8250 3750 7350 3750 7350 3450 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 3300 3750 3300 5700 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 7500 2700 7500 3450 +2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 900 1200 3900 1200 3900 1500 900 1500 900 1200 +2 2 0 4 4 7 45 -1 -1 0.000 0 0 7 0 0 5 + 7950 4050 8250 4050 8250 4350 7950 4350 7950 4050 +2 1 0 4 4 7 55 -1 -1 0.000 0 0 -1 0 0 2 + 8100 3750 8100 4050 +2 1 0 4 4 7 55 -1 -1 0.000 0 0 -1 0 0 2 + 8250 4200 8550 4200 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 8700 4350 8700 5700 +2 2 0 4 4 7 45 -1 -1 0.000 0 0 7 0 0 5 + 8550 4050 8850 4050 8850 4350 8550 4350 8550 4050 +2 2 0 4 4 7 45 -1 -1 0.000 0 0 7 0 0 5 + 9750 4050 10050 4050 10050 4350 9750 4350 9750 4050 +2 1 0 4 4 7 55 -1 -1 0.000 0 0 -1 0 0 2 + 8850 4200 9750 4200 +2 4 0 1 4 7 45 -1 -1 0.000 0 0 7 0 0 5 + 10125 4425 10125 3975 8475 3975 8475 4425 10125 4425 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 9900 3300 9900 4050 +2 1 0 4 4 7 55 -1 -1 0.000 0 0 -1 0 0 2 + 8625 4200 8775 4200 +3 0 0 1 4 7 45 -1 -1 0.000 0 1 1 6 + 3 0 1.00 60.00 120.00 + 3 0 1.00 60.00 120.00 + 6900 3600 6900 3450 7200 3150 8100 3150 8400 3450 8400 4200 + 0.000 1.000 1.000 1.000 1.000 0.000 +3 0 0 1 4 7 45 -1 -1 0.000 0 1 1 6 + 3 0 1.00 60.00 120.00 + 3 0 1.00 60.00 120.00 + 8100 3900 7800 3900 7500 4200 7500 4500 7800 4800 8700 4800 + 0.000 1.000 1.000 1.000 1.000 0.000 +4 1 0 50 -1 14 12 0.0000 4 135 525 2175 2025 GCell\001 +4 0 0 50 -1 14 12 0.0000 4 180 2520 975 1425 Split HExtended - case 1\001 +4 1 4 45 -1 18 12 0.0000 4 135 840 3900 4950 M3 -> M5\001 +4 0 0 50 -1 14 14 0.0000 4 150 540 1500 3825 G.M2\001 +4 0 0 50 -1 14 14 0.0000 4 150 540 2775 2850 L.M3\001 +4 0 0 45 -1 14 14 0.0000 4 150 540 4575 4500 L.M3\001 +4 0 0 45 -1 14 14 0.0000 4 150 540 3375 5700 G.M3\001 +4 0 0 45 -1 14 14 0.0000 4 150 540 6300 3825 G.M2\001 +4 0 0 45 -1 14 14 0.0000 4 150 540 6975 2850 L.M3\001 +4 0 0 45 -1 14 14 0.0000 4 150 540 8775 5700 G.M5\001 +4 0 0 45 -1 14 14 0.0000 4 150 540 9975 3450 L.M5\001 +4 1 4 45 -1 18 12 0.0000 4 135 120 7425 4425 Y\001 +4 1 4 45 -1 18 12 0.0000 4 135 120 7800 3150 X\001 diff --git a/katabatic/doc/images/AutoContact-12.pdf b/katabatic/doc/images/AutoContact-12.pdf new file mode 100644 index 0000000000000000000000000000000000000000..c17a6e86f9dd83cc05539b29360d79aa9d64ab46 GIT binary patch literal 5463 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 literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/AutoContact-12.png b/katabatic/doc/images/AutoContact-12.png new file mode 100644 index 0000000000000000000000000000000000000000..48ee39e021c92ded735adeecee33547348f470d0 GIT binary patch literal 5260 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 literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/AutoContact-13.fig b/katabatic/doc/images/AutoContact-13.fig new file mode 100644 index 00000000..1696be33 --- /dev/null +++ b/katabatic/doc/images/AutoContact-13.fig @@ -0,0 +1,104 @@ +#FIG 3.2 +Landscape +Center +Inches +Letter +70.00 +Single +-2 +1200 2 +6 6600 1875 10200 5400 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 6600 1875 7350 1875 7350 2100 6600 2100 6600 1875 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 6600 2100 10200 2100 10200 5400 6600 5400 6600 2100 +4 1 0 50 -1 14 12 0.0000 4 135 525 6975 2025 GCell\001 +-6 +1 4 0 2 4 7 45 -1 -1 0.000 1 0.0000 2250 3600 150 150 2100 3600 2400 3600 +1 4 0 2 4 7 45 -1 -1 0.000 1 0.0000 3600 3150 150 150 3750 3150 3450 3150 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 1800 1875 2550 1875 2550 2100 1800 2100 1800 1875 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 1800 2100 5400 2100 5400 5400 1800 5400 1800 2100 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 2625 3600 1575 3600 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 900 1200 11100 1200 11100 6225 900 6225 900 1200 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 7350 3600 6300 3600 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 3300 3750 3300 5700 +2 1 0 2 4 7 45 -1 -1 0.000 0 0 -1 1 0 2 + 3 0 2.00 120.00 240.00 + 2250 3750 2250 4200 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 2700 3750 2700 4500 +2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 900 1200 3900 1200 3900 1500 900 1500 900 1200 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 3600 2700 3600 3450 +2 1 0 2 4 7 45 -1 -1 0.000 0 0 -1 1 0 2 + 3 0 2.00 120.00 240.00 + 3450 3075 2925 2475 +2 2 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 2625 3450 3750 3450 3750 3750 2625 3750 2625 3450 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 8400 2700 8400 3450 +2 2 0 4 4 7 45 -1 -1 0.000 0 0 7 0 0 5 + 7350 3450 8550 3450 8550 3750 7350 3750 7350 3450 +2 2 0 4 4 7 45 -1 -1 0.000 0 0 7 0 0 5 + 8850 3450 9150 3450 9150 3750 8850 3750 8850 3450 +2 1 0 4 4 7 55 -1 -1 0.000 0 0 -1 0 0 2 + 9000 3750 9000 4050 +2 1 0 4 4 7 55 -1 -1 0.000 0 0 -1 0 0 2 + 8550 3600 8850 3600 +2 1 0 4 4 7 55 -1 -1 0.000 0 0 -1 0 0 2 + 8550 4200 8850 4200 +2 2 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 8850 4050 9150 4050 9150 4350 8850 4350 8850 4050 +2 2 0 4 4 7 45 -1 -1 0.000 0 0 7 0 0 5 + 8250 4050 8550 4050 8550 4350 8250 4350 8250 4050 +2 1 0 4 4 7 55 -1 -1 0.000 0 0 -1 0 0 2 + 7425 3600 8475 3600 +2 2 0 4 4 7 45 -1 -1 0.000 0 0 7 0 0 5 + 7650 4050 7950 4050 7950 4350 7650 4350 7650 4050 +2 1 0 4 4 7 55 -1 -1 0.000 0 0 -1 0 0 2 + 7950 4200 8250 4200 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 7800 4350 7800 5100 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 8400 4350 8400 5700 +2 1 0 4 4 7 55 -1 -1 0.000 0 0 -1 0 0 2 + 8325 4200 8475 4200 +2 4 0 1 4 7 45 -1 -1 0.000 0 0 7 0 0 5 + 9225 4425 9225 3975 7575 3975 7575 4425 9225 4425 +3 0 0 1 4 7 45 -1 -1 0.000 0 1 1 6 + 3 0 1.00 60.00 120.00 + 3 0 1.00 60.00 120.00 + 6900 3600 6900 3300 7200 3000 8550 3000 8700 3300 8700 3600 + 0.000 1.000 1.000 1.000 1.000 0.000 +3 0 0 1 4 7 45 -1 -1 0.000 0 1 1 6 + 3 0 1.00 60.00 120.00 + 3 0 1.00 60.00 120.00 + 8400 4800 9300 4800 9600 4500 9600 4050 9300 3900 9000 3900 + 0.000 1.000 1.000 1.000 1.000 0.000 +3 0 0 1 4 7 45 -1 -1 0.000 0 1 1 6 + 3 0 1.00 60.00 120.00 + 3 0 1.00 60.00 120.00 + 6900 3600 6900 4500 7200 4800 7950 4800 8100 4500 8100 4200 + 0.000 1.000 1.000 1.000 1.000 0.000 +4 1 0 50 -1 14 12 0.0000 4 135 525 2175 2025 GCell\001 +4 1 4 45 -1 18 12 0.0000 4 135 840 2250 4350 M2 -> M4\001 +4 0 0 50 -1 14 12 0.0000 4 180 2520 975 1425 Split HExtended - case 2\001 +4 0 0 45 -1 14 14 0.0000 4 150 540 1575 3825 G.M2\001 +4 0 0 45 -1 14 14 0.0000 4 150 540 2775 4500 L.M3\001 +4 0 0 45 -1 14 14 0.0000 4 150 540 3375 5700 G.M3\001 +4 1 4 45 -1 18 12 0.0000 4 135 840 2925 2475 M3 -> M5\001 +4 0 0 45 -1 14 14 0.0000 4 150 540 3675 2850 L.M3\001 +4 0 0 45 -1 14 14 0.0000 4 150 540 6300 3825 G.M4\001 +4 0 0 45 -1 14 14 0.0000 4 150 540 8475 2850 L.M5\001 +4 1 4 45 -1 18 12 0.0000 4 135 120 7800 2925 Y\001 +4 1 4 45 -1 18 12 0.0000 4 135 120 9675 4350 X\001 +4 0 0 45 -1 14 14 0.0000 4 150 540 8475 5700 G.M3\001 +4 2 0 45 -1 14 14 0.0000 4 150 540 7725 5100 L.M3\001 +4 1 4 45 -1 18 12 0.0000 4 135 120 7125 4500 Y\001 diff --git a/katabatic/doc/images/AutoContact-13.pdf b/katabatic/doc/images/AutoContact-13.pdf new file mode 100644 index 0000000000000000000000000000000000000000..97d787a870f1a6448c77efe584ffdb6ce62e7d53 GIT binary patch literal 6277 zcmb_Bdpwls_f#r_k}gQ)&80!jymK>#Wn6QKDIw%mV`eannQ3M)ZYvThaw`doB&khE zNGO|2w4_x@C{r#ix#SvZ>-UaQyS2OD-yi#ad_JD{Jm-GSbDneFQMEQPMWB&5nCji( z_#BuffC5yFn&g< z6DeM$T&ntQVg7l_L5-aJR?Ai5lCK1M9d5vVv}56j+(Xm%qAL3OV~KWt)6L8zDUV_~ z#xd2s>vrl9i(kJ&j9gRwaN=W+3wZnEWmeC}pv2ZN3|H)!jZ$q--_|DE{3m-L47wHt}{y*ql86Dfj)`ft!DfYr0_Z&D~{B zdd~gKSUq*Jy_%DBvo>R7dU~SiRanrw+1bh``fkMF&^b)3Ahy+4(6e@JO3z@@)u74v z*V+g!lby6u_P~T%YxFB*uiQ_;t6NuJg(+3ZbLS_=^R&{fJxk5*bzMa($j02}Y3;ME zO30DJ`;42dqSVUPkS{z8Qn)Mn=1#2W%7wJj8(t>Mckg=p>hAP5+*6xX z`xL7}#ry|S#>&SGU%BbzR*dqeNBWZsKaS77?J3g_nh7Z&!CCE?JzB#qSwnH1T{8^<*&Ci>?Qbl%+uNf|tg2{E9MN><^$amv z^N#MZoEsV`i9)lG`ZZ?C4}W9NO=Fz=Z96vE79FeRGQ*G=PZS?^lrYS~I(>p>-wZ6- zpSmUS`tsS5!ErN(u&MIEGkVPDtsOZz$D|EBiEh_^AN<8lF9%+feP^&VFH~g(eC>6W zN~@?NjSn^_a+3OvceD%?cD=h0;q-B0aOPou$614oV;?ljR zi4PUG-%Tm2{UIIQekFK_qEMYW^ZG)2*(6&sR#@^x|=R?p(Bj z%!ELGK&H|gW`d6mKIy&O-^!=8USyI3uBy9Raqjj+O_ZbE^HN2YZ)$pAbHX7^SCUi| z+0z-3ErogIX0LF5y;=wBS?S>Zr{0||n|yr{r0l-&_ARG(rC$*bo z&F$8ElPs^gN52fRI(4iOv%42)dgleNuNVkSli#(Y`J{1DxuUXfiL&3tYw?Vh>IV_> zPBVtDS`7>PFE<^T$a54s7AJFqnI`hU*HvVdRPic{r^)K-O*x7(OVpNGJ20#!x%wp! ztX2+WS^?gTY$xnYp{OPhE-oFbZRBGpSeIP1uR@Okko{*G_TzrIo8T%Tc6#(^_Ib-| zYigJH@?I!$>yJy0@_!6fm2xXW@*m5zcyq_L89utXzGH3a-o~r$q4T`zqIkAQKH`@1 z(i7LV5GLK1tT0$PPmB_8BVH;aKW!Rb5h*!C&uKUD-!hz#{ElsoRm6|}R4Q*aY3AS7w^r$9LELpupP%=49=utR+q-q^Tjj{d`0{we z_@#wI%-kwU3qiT|J|%j!dF4&hDnA+V7yP=oifW365_!4tMD^>?dG{YOx=Ev<@-(iam&JcQ&LwxKIIq7C99vc5?{HLR381^L3+!@eO`C2mUEmg zZL?{uU7O~8V0mRB?iY>CS}gB7_RWVTwA#$2dg?Osa|f);W=P@ZPOdL5^*?qTX`nN% zF1;?+Q+lvZA)@GoPl;;5wd4;ctIA}y z#XK`>vq~DrO&-XyJ#w*|dEqQ{oIuE{0k z7+>-xbqlTo;rlaX5_BZ=s{Fjd+tX4ngew|Y4_&$37x?@~-A;K2S%nDM$n*`HsB!ww zv&0hvreELEpWGz%BuUO+# zALdUN4@9Z_G@FZx#N1z!(%)D1Qq-6&!Con&9Jj;227v&Nv8_(frGD5Kn9+?U%pKJd zr=H!EG~9Jm>t#fp^>0hEhbf=)_HEc;;U=`H3f z#67nC5bt9~+99>u*(Y4q1{K^Jld#S?4N+WCM_6WmK$o&h)L1Zm*yT~BNI(oXH*rJo z1%_|1D=Z?yjdBJ$2FT{(M`~0w9~~t8(N^Q9yJJ|e*C>g}w3gdT zYIA=KGcK|4xN*;YS;Wh+Vta+X5y1j?d`PCum3^mvv-&0WSh4elM{y4BX9Oat>Y7Of zYK1cG7dZu|fN8dS%8IHJG2j}Nh637eHlxd|wEJ}%lV0pc@WIwjx_91Cpr;$&XZ5={ zkyDd0CG!Pi1IypU)LN*>*OlfSxsS6LmQ{YBN*{UBnJL-sM3TWZFbhm-8ggHxuDsJk zufK}kd!qQ@{@;{;y7K(a_RVMfGuw1Lx{o%^cBG(O)5b2jxdKNV?iTws)vhBAQqktTB8lL~d_>s`|BI4u_6#H)PiNNL4v&<{2-=@SeKKE`a$+;E zEU-H*JCUHVhyS~nRnn0eYAK)P4)8nb<)zu2P(I%eomlm z7hf`=QtFa*F*6`9FSb4R zBx{WHOIZGGwXyMXay{pM!6r)m{BNTwH#DX~G}_EJ?yV3RoXXyvJp58cfbf0nTj%;b zCd~>ejx#m$QjhJjNG_wQbf(%(S7>7yqrtw)2fiZ4{Akfg+qx6k%#;ml-}#v zn}wmbBR1kv&m6kxo#4oUZ&$q3Lya_PxooJ(JbWU&KkE7#2~NuLCdWK})E%*M&_DKk zMwjCiy!?{}zj9NZ{KiAECHMOY1v^Ei@-Z!9{O%K(y$1I0MAxchgR1U+dhZSq#GLIx zWl@mhEVJFg&(+{wM%^ykYWSnG)5k*K^80&Z8UTAK8{+HDjXra_nqfJqBaAJ-CImUv z96YC*b%x;4*U}$(mZ~mpMpFCL^T4$Y>+>Ew!NyPSwvxJdnr_BQsb6ugNI81#4eRjW zlX6F>6~&U{+9Fm+16%D8rPgz1ylXFwnx=HZ#fr}2&tDB%HW%6Z z`jB*^f{oMl4YD%$E~Q_0J&HQGytkqHut95^7xAat&W2J+&DK#=S6^6lGeha_izNq2 z0=dW8eXX7M)(LJ05LCkjf*ZA|4)9Mljp@qDA0XB!8GA(XJ z#i^*#*IhmwTz?|)@S(T4?mH_g>h?rz`&m&{q_QVn+VJ_5f|!I(l}M(_OhM#Oj_%vR zk@*i(0l9aXQ}06u6LBvu_-*VDOzJ8e+x5ZIo6SAY{V*$WY1;gRQ%lFknZ(AB52wQ& zHMaT44IPlLy4O{!Smw|_%M;9c_lM1{tQQ&BtuMJg`$1p4*UXyQ5BF~E64Wz;4XECw zpxmvF1M2<$;-N+5>%z9Um-Nld-T7E-BRylIrIL8b=Yse40l+(2VeKTk@~N;q8!XDZ=;EEbP~ zeTLz_PF{9_Y#L}y_N0L%8kJ5qV(|fI6ts;&V*wl%1oyrBAVM4WSV6Fhf!B5EYPozTbpJ&NWl*VKp znZfd0Wbs*h5{*ZuLOTHZ6R)qbwf@TBs~IqGk2MKE6N#UdT(Ii1C>t%9kj~~Sn*}o$ zcL^|pa2K@EhH3v5O$h&tWklxEgdP$a#i7$U2qPAQx?ui-;~sLylZr>_nPGk7fcytQ+ zU({LfDfmz7d=2I&V;0T$pXw}x=Ff&K1`YN_mLth(@sj}>tBoNNKc~E|KA%md_|SNO zJI#~M)Ps*z-i8Bosvg`ylY}C%jcHzV^B@k*HfXmUCCG=OO@-?dVY>Qc=%mmPd@>v1 zvGDDI3(&X}JtbosD^n#Q0$+#k%l3tG2jKfMm|Pvc9(;jB2U-ikARJgg;rZyn9ZA*z zkHup6(0Kp`sf|P<(AXV-2Z!uS3t(}405lR0hgfo`9y&JAvH8Rhdeeh@@px<<5DW+i zKn7ruERH9L*4EYrQ5X<|K|mM?ZXlCK<|CL~Wk}wFB6P76Of?X(Le3gP>8h30O@nJeGnb zFG^znNyER0f;J#oSjYv?N(U+lR6h!hqX##$wgSw&SX|yG(EtI7N5R3*mj4F|LDBkq z+o6q5#sknwhXkD+k3bWs9_hg`C=_HN0s6DUpmeYV9Te6HvJb*ChQ2L9-Uhr zjm5Ep!b|j^dt#_Gf54u`;R^kVMPdMJGLPcLp!w4n08SVDmO>X4`uaX2~@QV6eyBAA=+TT?Ib*K#x`WT9;@YJc9=m-xdihv?uP*?(VE+GWy z=>FrLoiG8^z7OppUlvF0e;rT=6{7coF#kQM>R+yYK8NN3Ljh<_n6ONKdH}qpCRP*h z06xR8crB={5k3HO5vGYpLAT*wVOTsG>dd}@;qc$lqEP7XU|1aPdzcmuYPY`ON6`Ep zrmYS2O5fmV5x$2Jgssdsc-q+S?7*S4zOw^|#zO7YA}xmytZG$WVJ%U1A z5%&RIGouT-UV+FUq&vdSCcKqK0*Wl z{I%qPygLwVbidIM{9-p+ssZH+9<6r;J(}f1{Qxuw_y?j*(^g<*}7HGRfK3E#gjTCU-CPYx&(}X`s znFq&hmC~DbtbH4nP5snn(gF_0wlt!g&O?Z@$NmAuM>aj0lmSH>hZYUN0RP&fnq}+f zJG21*y)q{Z)JUNT0niuG$5RHsvNJtiAmw7xrsy=LiK|UWEUv$-Oh9w2Yc=|v-NCNh z805W?xUx>0sA?0}Nw>6pw^hSnr$6DqjjJ&=`GzUkA1s{50of9teq(9B9q($rso4VG zfPmNmXFFG4RZNM4crK^!Wj|zAP=q}top>LrKDYk^vtYIA5E`Sknm{Y{VNL%SLHVbD z?%1$k;V^gMI@S~Ei(jT=!})rC{J{z+Rfaet&)pXWYJTuxIJ!;(Ftx{@sZ{xsH-Wjn zM>xQRYn%gE=EnR-z_EjA`ldiVS58HMCP=e%#hn>>p=4CoJ3fsTNMn8hScYR}2a=ivC*bvW{011V$l6_Ri6><#B&a#Qx3}%F^4%!!Q7L zUre~?aCd%ka`L8nDwi58r#*c!x@pwi9vxM89y2;RT74|*f>KclTd!?P-$fZ!x0hLz}Xu$Q*y`sZmo#vt4rYDY3DvR zbt-Heu)1(1zscAB6rrzgo_Vtmh0V-Vx+1s?K3&#Rxlw0~<%fidGe0Pi)JE2Wqy`LK z-wwelCqG6E*|~MKN1OoERLqlg(yG!^3yBfQ&F}ynWFu0NY!Qq{XPJfi12?i5ir0;& zJ(6{*du$EAJ(F(@nPml9VMY+&Z#i?*r)=acSC;~YZuv80vES+W^=CBT&a(tIU{Dj{ zOhR{|hdzGHZWsk_@Q+7g$fFm@*x$K9pi?ePT2$zLuOfJ1CNC3bsX{sGgz>$o+j|_P zYUQZJ8K`tcBx|fn%JRdmz!KJbuSH{h7})+!f%FTeDJ@8bg~!BIWOODLcq@^wn|c?a zb~vt_rsoL+b7Qi8PS4Y{8b>5otsJc|I; zDwIW~@9`yZV?y(wMM&&Y58B)Shqo}0mZG5LN|0QRTIpXZn@yD!$L}j3OjDNWBTg`9 zE1z=|G)*n>TOoC!eKQscnXl^p5Vru)qAqO5XWKat%=p*PfzVBmJJwDP8CizV`ZQAW0}Nx+7<7jWXe&O zL#vRKH<=y@a_nPYHsc7D?-A9dQF3WqPxeN@b3%D3bqP@t`JT;x#&QCkT9DBvK?7SL zr7oBj^5iS|SUNW**b=nH@l7dZ*+=ed2$#g~T4imlV+no8X%5b+$*zFzA9%XcsW`Yz z==WM3s|^oSpLyU{F;e~=PNupmWbJjn_zs?sd%bkGNrUZl6Y=_!p z3!T_1J{r@cG-=xi#u)hM^;1JM?d=GmJ>2_N+=kwlJ>Dr@$n_tUO;Y)xm7iYh+WXnO z+14lT{~QB+enSs+-ZinKtQda11G(-Nc?Ds>F)?>mOs2iII~BYw@(c?dFKZ~RR^<=6 zzcvI%+C2}_5!0fY4-^vJIaUJJV7dHKNMlAvU9tLC=PHt`m_#nWpt{^wL}5N4mU*mhLm|WllP$n z)%7n*!bv`sx045aGTD;jVL?q#Rle1E@o34%!We$z#`GF-!K~xt1N(u5`bg-0=?6J^gWioD3DYH7TZLPS@tTVn8gd^v|Z^;?UB zIFW|T^XjB^|Me$x1;4DQd3`=;me2M<8KOFJFD4{1WWh6emqRB%91HL~tGCFQQxoL~ zse0n%v>IDV^F=hNR5NCabtO8(#kpW%T>O^x`HRisuem==-!~}~fp(3wv(Nh3c9Kq1 zgVaqP`q2;OiKLk00=0t%I|Po>RQqt~v>MKSdZftIb&@=~^~bwi9T#;4{=YV;@Z1$S zD5{=(M&S2sz zc=-QNCYPyoZuvenH;_hAEDXQ{Aa~f8cB=HU8IJUb@I9b$YEU&b{Ca);*1iGtqaOm> zd?ouSl@eQtTy=^Gzz`y$@Q!UU^IfAC?Jh+ef8S(_X79OWag@{QvEXe)ax1ttobq`X zh1bTm&ubC;mEND^@*m4Nn)*{`pk`hTO&i{Uu0C@KOioJis=!BT`{o>7n%+x82vC-K zj#X8cAMh&v=D(%ccyM$W;hh+MW45PGc5SOc!cYsjQu_I$cD2CgiiK4P(vF59VR&)T zSY-0rv+d`o(9p&jYGq*J>3o0lq~x#xP*3DuImIW^SC?v*ZQ8n@jR?i6D{hH6MX`Gh zYd01LN{{1zvnoVZc-pZG)#hKfg!JA+``+acsQK2 zvvc_CopbcFdPbDo_vC@LcBygH#u6criS^T|ec%ttJ0Ek1m4Tr~dRh>jCs z`X)f^ew>ncLEa*%rb1v}Hm}9?OC6_c6`6^^=(V7Oc}=e8(JkIS;?~t$pkIB?Rsn zGt9bUt*~=_6vRKX68^X?u2oCRO*HsAvup{C(Acx&)%^$GT*-ps)~53xz)IJWm)!A< z?VF2U%lYT)wp3)WjY`WQK@Kfny>gHxtZ1Pd@gZ%O4(ADhDuK819nJ!xgLUj=|MW4l zC8KX4gS>>^GI;Xr+$I0GhHj4{l-;om*=4$Cb$M;XSgNSAwzj$DJ!=$C-h!Ja zb5+roUHH*Xecyod_w6=^wd@G0wNaWxCnEczDF0cuk37@ak$O7gK*7(s;gle zq=SvFh7Ic`8MI>F&z3b5pS2j=JuUGHc~+lIqvV$^Z&B#exVNaBhfYg{21Gq*(J9pa zg_bj`qVi;X@*a6x(M$6kPP8#h(a?&DLtwG(?2UYtjG{={Gm6`N%JlK)rL#Y-hIoPr$6F$b9UGyw8q;C8cK6Uok*Ts=PTaCTM`Z8kry)uYht!N z@b9qAYy0BD+fbUwFIYMw|A~;y+we%?u#8!#F0pQCyxg(sRp}F5bp>#!Vrr(B-)q>F zUQNX+%a-rR8hCUyz7U3`dVt@xRxgi@<5eEcMu^u7wcTej2jzN^5i-!ULMejrLAFG^Q z|81`=q1bL+5Vzmj#xu@gxr`=tVf+5%LhQNpBQ%m(-?7!^51%M&URn6rS}?34k-cG` zo;$2L&2g|P}^aTLhN z4|l(E)O+7w^aY>d;lf#Q>6*|2`h)*#zcqZYTF#PhBI39jw0cO_6nLYm+F2BX^9m*UymH71oxrp{_ZSlW`z;G&EFTM1*U%hsn%E@WppC;o_g z0%i1&O+!$o#2~j`r*8lp#$~IUHm;nTOitC4uE<7U_b(LJA5LaC9$jlm_hL1Yfi~0N z*f@BxTRp>fGgZM4X~C2z+D;+z-px|9WPaQZr#3QeJc20lX&Xur5fkoJX{yqUxI)5f zJTpHdk!^Bs-AvAK0AzT~`iR=igXvWXZ=8;BMzr7ZlKUF*D}x$Gzmv@RZ+yf55D$L` zE>|iFcQB2HtTR^q`s^5*aj-BOoR4^Vnw4CRymj*&s3kq8tDKuzO!#k#V@Icd+GkY^ zeO^;f`uX6#W$yKQ7J;$MTrJ3K#S M5\001 +4 1 4 45 -1 18 12 0.0000 4 135 120 8250 2325 Y\001 +4 1 4 45 -1 18 12 0.0000 4 135 120 8700 3525 X\001 +4 0 0 45 -1 14 14 0.0000 4 150 540 2775 2850 L.M3\001 +4 0 0 45 -1 14 14 0.0000 4 150 540 1500 3825 G.M2\001 +4 0 0 45 -1 14 14 0.0000 4 150 540 4575 4500 L.M3\001 +4 0 0 45 -1 14 14 0.0000 4 150 540 3375 5700 G.M3\001 +4 2 0 45 -1 14 14 0.0000 4 150 540 7425 2850 L.M3\001 +4 0 0 45 -1 14 14 0.0000 4 150 540 6300 3825 G.M2\001 +4 0 0 45 -1 14 14 0.0000 4 150 540 9375 4200 L.M5\001 +4 0 0 45 -1 14 14 0.0000 4 150 540 8175 5700 G.M3\001 diff --git a/katabatic/doc/images/AutoContact-14.pdf b/katabatic/doc/images/AutoContact-14.pdf new file mode 100644 index 0000000000000000000000000000000000000000..f54327136bbada183f96f2659fc79956578f4719 GIT binary patch literal 4502 zcmb_gc~}$I7O#L*qP7%~J`~HyVsJ?&la)jgSwc`2iGeDs8j=Y_LMBco5YQrm50pw< zaj7E36|EZz;;ywtD=31fh)+>`C>2pFD&m3*?@riMZ2SIjKEKbKbIy=33SfY^=s2EjXN>n7G=m{K^ zCs2&}`(~WhI`FKIJ)805JOX9^$p;qi zZa!C)`ufob)zf_gcin3bh+5g6zDhOJ-*tpbqw=`N;a4q*2VOqtsCwL#k}Swsf9eP~ zFt#PE(w?ep{U(ALJ$hv4x%=1BvM-EjYv66m9zCrs%qqvceE2q-iD&CvjuvEfTn(2){XrOPcHj)i?C?2LcbT;ASH?VNw~ zo0m7A{+?3Y@aj=xVpUeyk?~otR@&NgR{Pcm3`uxi=kUeXoNUZ`$;f9?|J?)X%>$;D z1&2p9u3{GtPJ~%_`d!Q_6CNG=zOsdh3r{*qDxXWZlR`h39Xs`m>;9 zbA;m&pV!xZWm_Dun&Z6Bc6Gw8-=#H!ne2fhYHYMkQ`0k-O+LTyhe!T1j-+uf83*j7 zt@+Qw@uN;J@2HUP;Vm6uo}X^cG|MZ~+Q-0Qdem4i;JtOH;v64VmPWg82e&N zd(Hv#nOSDGKaF2Zv&}=87SBS=(l+mvv}|E|6F&~~cRarXlGpVQJ1b z>lxCTtnIFup?=#6y(fCjo;EvJRi6~R&2Dg&$ZS@5X8M{SN}hMIbhE?HTlPN)+gLcX zes4kXKA-=D+qjy|Z9BgGV0F}l_VKcY(A!^aEN-&B3uU^ulx~-Wu>1?hNiC|%bX(Xq zF@`kjPcnS`l4k4(D;k&HEQ?pH8&K#RNg3spx>kMlF58Z75bQ7n78O1CrS9w|w&kVm z+&wZ&f2WZH28@_5KY2f8*&z$-MUDI8$Br&>bIPwsEguY(vnyxmIfvGlZsR#NjLZ8y zzdZ5ag<4u6ZXr6arA9Ul(%&DoDb0Gc%Rtp?*`2#CwRba}n&!yXTsoD3ms+N^+za1Y zG0f6z#e)}f*AIGiDdmjogqy^;aHU=KmdGENNjry~oLRZV+&E1$;iBJJYH+Lh5N|4P zu{ewN#b*v~u{YakF9cXiD{3%bf4b?VzzAGQuq~}PAf1(8#bT)HNEZv^hY_Q$iBDQ~oC{Fz9 zzo~?MXHdlQ_BU5P^^E&Y=bL*lET0`e=9`-rGlQR=DwnC<3s7^;VIJh`e z&vHz5O3BK3{b%m5sRx}3qV=2i#@`N?_*vDzm_PlY5ZRq~NE@)0pIE(r(y*6f_eFkw zY`5LCjt+184f<9CU+pJkXAJcTU?oGbd`LL|{)7wj+$a&|UHX2r5 z{?@T>{2!NB%$5wEU{f0@d-=TM`W;R4m)RZct5_Di`vk8uc79oXMq{m=tt8@nbItd0 z6>#GjQ475$9GOmMJkF}u*%#%mS!Ox!%s|WNr^}r`PnZ~C87#!Mp0<8 z4uz%iSQHLIm1?;+W`rUc;F^hWAvTKT!HGr7?a|dA_OHO zVKC?*I21J!fZf+f_=ON)ltBoI14JYk5JwQx4=~waAMhI>>LGF>$|!);Z5FAbYeE7v zU>9UEOb@{UYNZ~Eq>yIIDA5o=Fp!XMiIV8u!?jD&M^4B!SZohOxAj3NAyrQbeZ($jq!he^Iq<3?9%k?N3 zA<`*ajp8(KOrtcpZwed;s1~dQYHcipFimJ7h8TiO8tEr6t0#D-+qXi{D+i0!DisQH z2$BY3$bl2oT7y2iPm;9lePbr0nnaXPE98G;jwz<_UzyXF%r0ko-1tXxOsRR>k)EVc zdUb^b1@`Pv2#e1YiMmVPW0FxPSHzgZItrSvcaDo^?Iv+GnJvjwO zLsF)ODpKMVd?j^~h~hCx4qggMGs<-|m1!B%L#SRMbn=k}N}NarqrjM;O8~V4851;G zy}&4>nnVQPOp;+LWMU!Wh19ShDMVnHCSFZIOgf*A&=A%HNQKK2&?F3xhY&iK3LtT% zN+1KzrV9}K5>n#`LMMRXq@*Nz5{r)Eu`t5t^I--PW-@7jgQic`5^^I=t9J(aOoph# zdd0MQy2&QG0!x6^VK72xz&(n@z#UwzBh;7{A{EPHFasf^a=A=*E`zJ2#VB}u8iJsF z8UuVZ6`#Xlx$}7nK7-SvN%xk8@2CP7Ko<*y0GtG%B`6IF6cWB-=x zA2k?3L4O~Pgaoom<+`9Cff!R55sVgVC2Y=D+n6Grh~k7B|@VXbsbCya33l-Dad-j@GjsGbZ(CZ(Hxz^Q-kW_ z40nb*lfiZe?-DS8r~8+8 zp=1HL^-paNE{41P(*p&pKt2v|{(Vx%_Ktodj;bgO2;or3Hre$-T+k~ykP7OiA$$f{ zd&m#c_Rv`FOfc}@r6KNYu(P~J8%% LimR({u!QnIk6ct) literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/AutoContact-14.png b/katabatic/doc/images/AutoContact-14.png new file mode 100644 index 0000000000000000000000000000000000000000..2380936c5cdc7aa5e04027c479076c3534ab07c3 GIT binary patch literal 4875 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 literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/AutoContact-15.fig b/katabatic/doc/images/AutoContact-15.fig new file mode 100644 index 00000000..ea1af2ec --- /dev/null +++ b/katabatic/doc/images/AutoContact-15.fig @@ -0,0 +1,73 @@ +#FIG 3.2 +Landscape +Center +Inches +Letter +70.00 +Single +-2 +1200 2 +6 6600 1875 10200 5400 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 6600 1875 7350 1875 7350 2100 6600 2100 6600 1875 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 6600 2100 10200 2100 10200 5400 6600 5400 6600 2100 +4 1 0 50 -1 14 12 0.0000 4 135 525 6975 2025 GCell\001 +-6 +1 4 0 2 4 7 45 -1 -1 0.000 1 0.0000 4050 3675 150 150 3900 3675 4200 3675 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 1800 1875 2550 1875 2550 2100 1800 2100 1800 1875 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 1800 2100 5400 2100 5400 5400 1800 5400 1800 2100 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 2550 3600 1500 3600 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 2700 2700 2700 3450 +2 1 0 2 4 7 45 -1 -1 0.000 0 0 -1 1 0 2 + 3 0 2.00 120.00 240.00 + 4050 3825 4050 4200 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 7350 3600 6300 3600 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 7500 2700 7500 3450 +2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 900 1200 3900 1200 3900 1500 900 1500 900 1200 +2 2 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 2550 3450 2850 3450 2850 3750 2550 3750 2550 3450 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 2850 3675 5700 3675 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 2850 3525 3600 3525 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 2625 3600 2775 3600 +2 2 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 7350 3450 7650 3450 7650 3750 7350 3750 7350 3450 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 7650 3525 8400 3525 +2 1 0 4 4 7 55 -1 -1 0.000 0 0 -1 0 0 2 + 7500 3750 7500 4050 +2 2 0 4 4 7 45 -1 -1 0.000 0 0 7 0 0 5 + 7350 4050 7650 4050 7650 4350 7350 4350 7350 4050 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 7650 4200 10500 4200 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 7425 3600 7575 3600 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 900 1200 11100 1200 11100 6300 900 6300 900 1200 +3 0 0 1 4 7 45 -1 -1 0.000 0 1 1 6 + 3 0 1.00 60.00 120.00 + 3 0 1.00 60.00 120.00 + 7500 3150 7200 3150 6900 3450 6900 3750 7200 3900 7500 3900 + 0.000 1.000 1.000 1.000 1.000 0.000 +4 1 0 50 -1 14 12 0.0000 4 135 525 2175 2025 GCell\001 +4 0 0 50 -1 14 12 0.0000 4 180 2520 975 1425 Split HExtended - case 4\001 +4 1 4 45 -1 18 12 0.0000 4 135 840 4050 4350 M2 -> M4\001 +4 1 4 45 -1 18 12 0.0000 4 135 120 6900 3450 X\001 +4 0 0 45 -1 14 14 0.0000 4 150 540 2775 2850 L.M3\001 +4 2 0 45 -1 14 14 0.0000 4 150 540 3600 3450 L.M2\001 +4 2 0 45 -1 14 14 0.0000 4 150 540 5700 3900 G.M2\001 +4 0 0 45 -1 14 14 0.0000 4 150 540 6300 3825 G.M2\001 +4 0 0 45 -1 14 14 0.0000 4 150 540 1500 3825 G.M2\001 +4 2 0 45 -1 14 14 0.0000 4 150 540 8400 3450 L.M2\001 +4 0 0 45 -1 14 14 0.0000 4 150 540 7575 2850 L.M3\001 +4 2 0 45 -1 14 14 0.0000 4 150 540 10500 4425 G.M4\001 diff --git a/katabatic/doc/images/AutoContact-15.pdf b/katabatic/doc/images/AutoContact-15.pdf new file mode 100644 index 0000000000000000000000000000000000000000..6a2c03dcda360f9ac2f3b49b72c139bc130b3318 GIT binary patch literal 4217 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 literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/AutoContact-15.png b/katabatic/doc/images/AutoContact-15.png new file mode 100644 index 0000000000000000000000000000000000000000..95e3a16015ca20f9d203f38cc271705bee4a12d2 GIT binary patch literal 4517 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 Cc1Gy{ literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/AutoContact-2.fig b/katabatic/doc/images/AutoContact-2.fig new file mode 100644 index 00000000..f345f9fd --- /dev/null +++ b/katabatic/doc/images/AutoContact-2.fig @@ -0,0 +1,43 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +6 0 0 5625 2475 +2 2 0 1 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 765 945 4635 945 4635 1260 765 1260 765 945 +2 1 0 4 0 7 45 -1 45 0.000 0 0 -1 0 0 2 + 900 990 900 1215 +2 1 0 4 0 7 45 -1 45 0.000 0 0 -1 0 0 2 + 4500 990 4500 1215 +2 1 3 1 0 7 45 -1 45 8.000 0 0 -1 0 0 2 + 900 1350 900 2070 +2 1 3 1 0 7 45 -1 45 8.000 0 0 -1 0 0 2 + 4500 1350 4500 2070 +2 1 3 1 0 7 45 -1 45 8.000 0 0 -1 0 0 2 + 4725 1125 5220 1125 +2 1 0 1 0 7 45 -1 45 4.000 0 0 -1 1 1 2 + 3 0 1.00 60.00 120.00 + 3 0 1.00 60.00 120.00 + 450 2025 1350 2025 +2 1 0 1 0 7 45 -1 45 4.000 0 0 -1 1 1 2 + 3 0 1.00 60.00 120.00 + 3 0 1.00 60.00 120.00 + 4050 2025 4950 2025 +2 1 0 1 0 7 45 -1 45 4.000 0 0 -1 1 1 2 + 3 0 1.00 60.00 120.00 + 3 0 1.00 60.00 120.00 + 5175 675 5175 1575 +2 2 0 1 0 7 55 -1 -1 0.000 0 0 -1 0 0 5 + 0 0 5625 0 5625 2475 0 2475 0 0 +2 1 0 1 0 7 55 -1 -1 0.000 0 0 -1 0 0 3 + 0 315 2025 315 2025 0 +4 1 0 45 -1 14 12 0.0000 4 120 1155 4500 2250 AutoContact\001 +4 1 0 45 -1 14 12 0.0000 4 120 1155 900 2250 AutoContact\001 +4 1 0 45 -1 14 12 1.5708 4 120 630 5400 1125 Router\001 +4 0 0 55 -1 18 12 0.0000 4 180 1740 90 225 Horizontal Segment\001 +-6 diff --git a/katabatic/doc/images/AutoContact-2.pdf b/katabatic/doc/images/AutoContact-2.pdf new file mode 100644 index 0000000000000000000000000000000000000000..3c212c75aab9bbadae0e165bb08479835be34831 GIT binary patch literal 6625 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 SNJ25P1qlU=jO=GP0RID({{tZa literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/AutoContact-2.png b/katabatic/doc/images/AutoContact-2.png new file mode 100644 index 0000000000000000000000000000000000000000..834443dc1eeb2dd627f5f2d51f8bbb4458613315 GIT binary patch literal 1851 zcmeHHYdF+t6#w(D#&yRQu_>2LMw4PtM2y_VY#Enmc{Ze3q$C-+jb@Zfk!V(KBMoT` zT~OH>#30Y23o}bk>yqnO{IKZ~NiA=e*}R=XajxJ@4f{9gavHKYK|x-2>iBtN$(&-Os~-UXRNOw9Tu=8SoGhsu?d%(U?0iUc zY*17%;C#$O4|DoFA)0`X3X6=^vqJ6PXKI!oQ@j-bHq2n14tvMlo*NpMvmodBbI znUHX6v)$@^-gI)QV;?^!n=K#@*fb>Ab)^O=z*?naP%`QfEwfY&pBN=MP(aTI1AdJp zT~jURL7@HW7OPzwD@gL7zWr}&s$7b$J%$AA5XnVPz`pVlI76xS&(TdRW00OENdRjB zIMoSf;}YUJ);+h&fRv?>Q3=Y9`0@$_8>x^Qd}|{BEwqxIWMeweEmw~?S_wc&{m0wx z0x)rLSh`rJemc#T-aG8XUqQ#4_&roddQ&xM&xQ(ltlBFASgg4Jr1zvtaC(QAn+(x4ggI|e69$Lj^mOF!!1En@6iUx+M`-ZK@M3-Qdi-;J`vL`%%pinYo&)MUxs zCme&2P!4s-l~3n3ne|&B(0S`OST}wM_T7~@z}P*5xnWZsEAPQsoaz-@NnL^;zkI+9 zY@ghi*f+}r(9iS}qm%#v7n0=8E3TEt2* zS28*pwpmnY$&=?w0diH=$cYtn(w-s_BCZp@h=52NJFRSamZR?5n7>PbtJI~61$}F0 z(&9xSk?O`O5S)((Snn*ZG13 zyk-T-MO>iJd^SDP3duDb`ySnLw-f$F_ZnbHf29gezvjXm2bm&3s%fT%#8=vGXfvEYN+Xup9wMwW`sc6b{sL8v_*SzM zw72iQgyN&}XSl23#JXOCO|`J~HAFyS&+4VH)VC&-!s&L_)zK2H5s#JVuGYY-BEbjW zcV$nW2yA1nOlplb3Awa-I<|2@r;emFC9`)9|3*r{Tml-GPxQOEHTBB`62Lm+oT?m7 zUP=G&B~~u*ABpWftP1F0YH<~MgSxfEtx>FLc am|U_9kN!XTH4ma$o)0e3@}pe7-0NSc!<9M! literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/AutoContact-3.fig b/katabatic/doc/images/AutoContact-3.fig new file mode 100644 index 00000000..7af9a7a1 --- /dev/null +++ b/katabatic/doc/images/AutoContact-3.fig @@ -0,0 +1,54 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +6 0 0 5400 3150 +6 765 1620 4635 1980 +2 2 0 1 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 765 1620 4635 1620 4635 1980 765 1980 765 1620 +2 1 0 4 0 7 45 -1 45 0.000 0 0 -1 0 0 2 + 900 1671 900 1929 +2 1 0 4 0 7 45 -1 45 0.000 0 0 -1 0 0 2 + 4500 1671 4500 1929 +-6 +6 4320 1665 4680 2835 +2 2 0 1 12 7 60 -1 45 0.000 0 0 -1 0 0 5 + 4320 2835 4680 2835 4680 1665 4320 1665 4320 2835 +2 1 0 4 12 7 45 -1 45 0.000 0 0 -1 0 0 2 + 4371 1800 4629 1800 +2 1 0 4 12 7 45 -1 45 0.000 0 0 -1 0 0 2 + 4371 2700 4629 2700 +-6 +6 3420 765 3780 1935 +2 2 0 1 12 7 60 -1 45 0.000 0 0 -1 0 0 5 + 3420 1935 3780 1935 3780 765 3420 765 3420 1935 +2 1 0 4 12 7 45 -1 45 0.000 0 0 -1 0 0 2 + 3471 900 3729 900 +2 1 0 4 12 7 45 -1 45 0.000 0 0 -1 0 0 2 + 3471 1800 3729 1800 +-6 +2 1 3 1 12 7 45 -1 -1 8.000 0 0 -1 0 0 2 + 3690 1800 5085 1800 +2 1 0 4 12 7 45 -1 -1 0.000 0 0 -1 1 0 2 + 3 0 4.00 120.00 240.00 + 3600 1845 3600 2475 +2 1 0 4 12 7 45 -1 -1 0.000 0 0 -1 1 0 2 + 3 0 4.00 120.00 240.00 + 4950 1800 4950 2475 +2 1 0 4 0 7 45 -1 -1 0.000 0 0 -1 1 0 2 + 3 0 4.00 120.00 240.00 + 450 1800 450 2475 +2 1 3 1 0 7 45 -1 -1 8.000 0 0 -1 0 0 2 + 225 1800 900 1800 +2 2 0 1 0 7 45 -1 -1 0.000 0 0 -1 0 0 5 + 0 0 5400 0 5400 3150 0 3150 0 0 +2 1 0 1 0 7 45 -1 -1 0.000 0 0 -1 0 0 3 + 0 540 2115 540 2115 0 +4 0 0 45 -1 18 12 0.0000 4 180 1545 90 225 Moved by Router\001 +4 0 12 45 -1 18 12 0.0000 4 180 2025 90 495 Moved by Autocontact\001 +-6 diff --git a/katabatic/doc/images/AutoContact-3.pdf b/katabatic/doc/images/AutoContact-3.pdf new file mode 100644 index 0000000000000000000000000000000000000000..03d0690039f612bbfbe9700be88ed6136fb65a63 GIT binary patch literal 7314 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 UH4cKH;M@6|db%{H|NcGx03~iE^#A|> literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/AutoContactG1-1.fig b/katabatic/doc/images/AutoContactG1-1.fig new file mode 100644 index 00000000..e8826d8f --- /dev/null +++ b/katabatic/doc/images/AutoContactG1-1.fig @@ -0,0 +1,33 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +6 585 -225 765 3375 +2 1 0 1 0 7 40 -1 15 0.000 0 0 -1 0 0 4 + 765 -225 765 450 585 450 585 -225 +2 1 3 1 0 7 45 -1 20 10.000 0 0 -1 0 0 2 + 675 450 675 3375 +-6 +6 540 2115 810 2385 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 675 2160 675 2340 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 585 2250 765 2250 +-6 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 0 0 3150 0 3150 3150 0 3150 0 0 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 1350 3600 1800 3600 1800 3825 1350 3825 1350 3600 +2 2 0 1 0 7 40 -1 15 0.000 0 0 -1 0 0 5 + 1125 2160 1575 2160 1575 2340 1125 2340 1125 2160 +2 1 3 1 0 7 45 -1 20 10.000 0 0 -1 0 0 2 + 450 2250 1125 2250 +2 4 0 2 4 7 55 -1 -1 0.000 0 0 7 0 0 5 + 810 2385 540 2385 540 2115 810 2115 810 2385 +4 0 0 50 -1 18 12 0.0000 4 135 465 0 -45 FCell\001 +4 1 0 50 -1 0 12 0.0000 4 135 360 1575 3780 G1.1\001 diff --git a/katabatic/doc/images/AutoContactG1-1.pdf b/katabatic/doc/images/AutoContactG1-1.pdf new file mode 100644 index 00000000..4afad3dd --- /dev/null +++ b/katabatic/doc/images/AutoContactG1-1.pdf @@ -0,0 +1,78 @@ +%PDF-1.3 +%Çì¢ +5 0 obj +<> +stream +xœR»nÜ0ìù[:²á>(.[‰ëøÔ©äW ]a§Èïgy¤(nDr4šYÎîD$ˆõéër_ï3<ÿ U-Á¿@ð'´÷wAI‘¦hŠy‚ód ’3æd5$­Œ”|s8“áÄ°„ )ÑX«Æ†¨¢D‚M³¸ÛdÍ•Æy šcÖ¬AÍå#$¹Sšã|q­²U¶V{ÓÜoÛ\÷».á%œŠ¦^Á‰ U^šP©æÖ€¢‚QÈ­NœóBK)˜Y*É +Z¦T–û°r÷„шŠÛWù¾¾?:Ñ’—1 d¿Š6AM¤„Y§Õ÷þÞµ}_–3ÜÎ> ®I(b óS£{ŠIæs¸ùñíq]?ͯÎ/G¾‡ÅÓú±ÈóC¸¹#¤Êý>‡Ÿ®X÷ïq0ùštχ a´:VOŸÃ/ ëTjÆK}H·ão¯îá +)ïïk{Ô™&œ$¢vÃkh¢&ì/¿ÍÖÉ­"A1/²·çr›^oo2'oXæCÛ·ßׂ¤ÿU Åõ¡ïöÍ÷ +ÖÉ[óÄ Ð2endstream +endobj +6 0 obj +437 +endobj +4 0 obj +<> +/Contents 5 0 R +>> +endobj +3 0 obj +<< /Type /Pages /Kids [ +4 0 R +] /Count 1 +>> +endobj +1 0 obj +<> +endobj +7 0 obj +<>endobj +10 0 obj +<> +endobj +11 0 obj +<> +endobj +8 0 obj +<> +endobj +9 0 obj +<> +endobj +2 0 obj +<>endobj +xref +0 12 +0000000000 65535 f +0000000751 00000 n +0000001044 00000 n +0000000692 00000 n +0000000541 00000 n +0000000015 00000 n +0000000522 00000 n +0000000799 00000 n +0000000909 00000 n +0000000978 00000 n +0000000840 00000 n +0000000870 00000 n +trailer +<< /Size 12 /Root 1 0 R /Info 2 0 R +/ID [(ŒG³vv²=æÓtIy-Ó)(ŒG³vv²=æÓtIy-Ó)] +>> +startxref +1155 +%%EOF diff --git a/katabatic/doc/images/AutoContactG1-1.png b/katabatic/doc/images/AutoContactG1-1.png new file mode 100644 index 0000000000000000000000000000000000000000..706767925e1851cff07273ab36a107ac1311db75 GIT binary patch literal 1637 zcmeAS@N?(olHy`uVBq!ia0vp^bAb2+2NRH-bX5K~km4-xh%9Dc;PC}v#!Khc`T+&y zOI#yLg7ec#$`gxH8C-({6x=iNi%W`=i!uvJ6f6u)^$d)rm(3MpU|^o?>EaktG3V{w zyFsrEL>wL-dw8^>sA6-4An(HZfERhElWN0H1(rl?o-OcnM$x(0hAEe>*q;A0Ijpd2 z_v_bRrOKbr`ndVK`GT*KqA%WmnjN&td@Aeudq%tdT`j%H`l%r=JL~o`-_U#W^4B=; zjIF!8|DOAmMbG|-Jf3W|YRT8C>YD!fmnt6qwRjxZ-kq`6X!f@s{}%BDf6bd&b^RE7 ziPXCuvkj-k{|Z??4;DAh{d{xIdxfWo-(5IQtZ;B+HPV_8*x19B5~8q}Nm3NA(4so~ z+xOM(xK;-GT+u$cJkEJJZ^cg(19AngJ~x&w4gwmu#Wf_}e4pX<5C#4HKx>M8S&Klz z$o71iA#lPIr2lw}gP+y}X;lSv(G#Yk5HVCo$q6%Au5^Hq>sEqP2R7c(U<8Vx`k>N> zqG57igxb# z>^t}T^K!etn=5=cwp@PqeQEcGc_Lc_v%(J=t^6v+Zhng^(7nv?`}QR(%irg(-*}t# zhVn7-H3D1hEBVd6F3X$kIec%*Ysq;UjBiCse+En0>X)v5AH#O=)X~rHR_pYzjgcX)^02B`eq;7-!k{_w|Sl0@}o5(p7>|F@qZCLe^(zCr}bahAb!7pfgKqB zupld1%z_alPYe}-fdz~oV35QFH}3fZ3PxgTe~DWR#8_GJO%187-rk&%-@ zLEwPH*81n$TNHYBvoyb*8M$T7ea1cMSrb+|E@PW1l`_g0dVwJRynv;5z0{X`$O#Jo Dq{pa; literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/AutoContactG2-1.fig b/katabatic/doc/images/AutoContactG2-1.fig new file mode 100644 index 00000000..cbf4162a --- /dev/null +++ b/katabatic/doc/images/AutoContactG2-1.fig @@ -0,0 +1,75 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +6 585 -225 765 3375 +2 1 0 1 0 7 40 -1 15 0.000 0 0 -1 0 0 4 + 765 -225 765 450 585 450 585 -225 +2 1 3 1 0 7 45 -1 20 10.000 0 0 -1 0 0 2 + 675 450 675 3375 +-6 +6 -225 810 3375 990 +6 -225 810 450 990 +2 1 0 1 0 7 40 -1 15 0.000 0 0 -1 0 0 4 + -225 810 450 810 450 990 -225 990 +-6 +2 1 3 1 0 7 45 -1 20 10.000 0 0 -1 0 0 2 + 450 900 3375 900 +-6 +6 5535 -180 5715 3420 +2 1 0 1 0 7 40 -1 15 0.000 0 0 -1 0 0 4 + 5715 -180 5715 495 5535 495 5535 -180 +2 1 3 1 0 7 45 -1 20 10.000 0 0 -1 0 0 2 + 5625 495 5625 3420 +-6 +6 4725 2385 8325 2565 +6 4725 2385 5400 2565 +2 1 0 1 0 7 40 -1 15 0.000 0 0 -1 0 0 4 + 4725 2385 5400 2385 5400 2565 4725 2565 +-6 +2 1 3 1 0 7 45 -1 20 10.000 0 0 -1 0 0 2 + 5400 2475 8325 2475 +-6 +6 5490 765 5760 1035 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 5625 810 5625 990 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 5535 900 5715 900 +-6 +6 540 2115 810 2385 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 675 2160 675 2340 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 585 2250 765 2250 +-6 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 4950 0 8100 0 8100 3150 4950 3150 4950 0 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 6300 3600 6750 3600 6750 3825 6300 3825 6300 3600 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 0 0 3150 0 3150 3150 0 3150 0 0 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 1350 3600 1800 3600 1800 3825 1350 3825 1350 3600 +2 4 0 2 4 7 55 -1 -1 0.000 0 0 7 0 0 5 + 5760 2610 5490 2610 5490 2340 5760 2340 5760 2610 +2 2 0 1 0 7 40 -1 15 0.000 0 0 -1 0 0 5 + 1125 2160 1575 2160 1575 2340 1125 2340 1125 2160 +2 1 3 1 0 7 45 -1 20 10.000 0 0 -1 0 0 2 + 450 2250 1125 2250 +2 2 0 1 0 7 40 -1 15 0.000 0 0 -1 0 0 5 + 6075 810 6525 810 6525 990 6075 990 6075 810 +2 1 3 1 0 7 45 -1 20 10.000 0 0 -1 0 0 2 + 5400 900 6075 900 +2 4 0 2 4 7 55 -1 -1 0.000 0 0 7 0 0 5 + 765 990 585 990 585 810 765 810 765 990 +2 4 0 2 4 7 55 -1 -1 0.000 0 0 7 0 0 5 + 810 2385 540 2385 540 765 810 765 810 2385 +4 0 0 50 -1 18 12 0.0000 4 135 465 4950 -45 FCell\001 +4 1 0 50 -1 0 12 0.0000 4 135 360 6525 3780 G2.2\001 +4 0 0 50 -1 18 12 0.0000 4 135 465 0 -45 FCell\001 +4 1 0 50 -1 0 12 0.0000 4 135 360 1575 3780 G2.1\001 diff --git a/katabatic/doc/images/AutoContactG2-1.pdf b/katabatic/doc/images/AutoContactG2-1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..eb1d8b2502ad3932d1a14adf200d6cd434fcd5ba GIT binary patch literal 1928 zcma)7do)ye951J%x?7v|*oq#P5}C}scgAHrn&WL`CK{r$$uM^q#$3(Z5o>GDZh7=D zB)e_9T2zXYQj|JHwUn$*4=E+7#fX^F16iHe-<1;e$KHSLy`S&*`?=rW_xt^PueqPQ zr!~f8L*`et=?5SjMqx563UYEn_=G%yiiB+eB1Al;GKx^Zh^I_M5$;4dDJHmFNJ%LO zQ4AEHofaq{4Y3&&9YLBk8BzLGCRU? zOMmZLladEnzHhnv@20#h$Qdf&-!Ly8wmSM_;oys*mENhY*{V2K&mwM*Uh!;L-!l0p z9=f}zz7ewjBYA&VZdL`i@F(7qJ@vJ9dR3Z(&$BRA`(36>{Rx+Ej+vL5=B6@*Cz|%n zS%l51m6!dNbigz^Brd<8rlx#Ve^=rydCnbQl^@rkgx4V1ddT2;WcspN$HRuL&gE&E z%z9gMpG=D;lS5OVEHB}w3K(7;yXHRaGR``mAao2}^;f(e<(OJ{)udVS#?Z>lA2Jcv zAKxWsLyT-nXcazo z&R&ECZn`0xpR`T8Zb5UkQOgqkyh)ITzo4s=_hR4uK^J>19+}t46Uf>-c|H}fx>W~H z8B>hYA^H~j9oHuP9y7o)5TBhM4Oir+ur_zPED$*Cb>U^T-YN4wSUr`OcsugmtFF6- zzbX&c=oB+|s11>n4QijmmGPP>tW){rny9kAx9xcY>--?yeL8#RwrwlN(jpB!3b_rx zsFTlZU!l|bTFqmoc3r7(DvThyd-_!l-RWM-9AaI|GS@6z*rcxVV>5%;#@Z`S+txP! z@Ne&lWj*SP8_jN72rC6Gu4Lof+JdeDx8{e~#=eTsi$;sHV~b0Bnl29+owUA?litP1 zv|gCi&{Q3`E%({6-PzaVP-I?t65-$MW6P)#6Um!B(bW^^7wz zizHJGE>Fn|P1fIT;jIj{VXZ#SD0gmm=`LT%JwE8tuY*j{^4iZ;#xN9nwj>z4FL~L-TBrnfpE;de!d0k?a+ke&RJZiI5U&B>$&0pQ*$kiCTk#`95>9%544H0v+VfQT0cJ~b*n=nY zk7~^x8HJ<>kiI9?aTT3^5AXl_J~}+f{Oqt1As3HI3p~+sq(w;IIX3ptC}cCH)PRIo z0`U_?5Qu;fOGU0^JRFPyGj4;yEZlBA1dIwoPQh$i%Mc_j-i^jby<9~~f-VTcBV=&|B@Gu@ zyOJ{T$azO91tI>bFpBO9eGrhyhw9Lr6G;N3F@(}uNXCfd|AT=w#sFF;R)rG^OAmiP z*ejA$Qp#|JG?s!n7|ujlOF@^wdZwhL+#R&i(%pfDq8!u?Wn&x`2giY3K#IR?`dGSn z1tEb@7-K=`#|yT_aW)Q1;86_2Y(Z=23zmPxY;Z8M6EF+~-5-yk_V{P9D2jopn&`*= zEEZ$YtsC!$u~}ch?7Nuw>uncSrksqnx;0?>}-&x!9K#IrJp0~>2X(5A_X;4SPZwdgUro6d_AH6 E0HKM|zW@LL literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/AutoContactG2-1.png b/katabatic/doc/images/AutoContactG2-1.png new file mode 100644 index 0000000000000000000000000000000000000000..adf19fa8e1079df54fd6fab57d3bd4f539e8c977 GIT binary patch literal 2823 zcmeH|do-JQ8pmI%LRwiJcPoUlRYld5(1=ShsB2M|sv)DaXcHCUGFqw}w-H(rtdde& zyDp(IWVTpDV>ni_ZbdU;rqyZ)+NwlE*f(uw&hE~cJ!j9J-M{9K_xe2N`#k4)KELNF z@bhs~f@(tn08sL9cku@RnFjEESV0!N8{=e!;6pLNJroZB2fd}2%mk~|2mGm*6^DlK)PekQlaAh+RBdjJyTr@^t9FMYd4yf%NX`|BLw`QVp3fm z8#3qL3>9n6w>#ER*!oBLw?xsiTvoJKlniNL$$u8oWyQyqynA+=Vog$rZB<_)GlHfm zuddCuvbdkEysdY&IqN2#sceF6wznfU`362EV#vIr)?<;iP+%D_-FxNe6?&13kpk+T z90pR3;Aef31NX~r-*-lt;Hb!e89UAXM@Gi+K0~n?YYG2tFystRov_hHifZ4pz? z%jfh9a=6%@>9Tw}LpUU$y|^sU8Db2WvXI`MChErj6!|EFWoWK!<~l3mqC!w+mKu>% zF)4fgURg7LP(Udmq?Q4FEn0&CA5p09X%fC(ESXvBoa8kbmn*!+N*L76b-%D3y9K$_ zyf(8*XqzwERJ>7?RPA878$AE!hoO#_%-j617|B-;+#)JQjkc}G6nDG*b32Z(!3A%K ze9Y%|&ewIf8icY;i;PCj)`n_Y5G_l{(;&z<^%LJ-_kT0nSavJp0n?O|G5K9+1S*%C zSi8AU|2S!DNiUKcgZgV`?DZwR&$^4?Lu07PUX-2ai=juOWxi{BxKn2IRKjLt^4|2I zr0B>}T@7Pxc~J|6?O5YHi^y|3K--Y$)slTzb+#9a;E(J?Nl>)7D`90Yf>1mg`VEGRN7UH5cQJkH>g!5V0o?FL-)h>N%<|gx#57vuU_l)Mq z5w`X8yH;w6ame1|CiXQxL}N&Fnm$-mh_sZkfUTi3InX}`?s)P&1&BgXRp8G-Xiz}S zd@egK_4`^Cvy^BE8+qTEk0LiOA7#K`BRgIu3|PG;t>KOV|74cb6Qb-r>!b=s__vZ^ z=(7hy{XGs5sJ(LaV4t%yxtCx%);6RTj1W(U zeXpS#!4+()B{chG0&@EGcQ}o9%K+AZnl2PB)HQbecwVzy#z#(zy zJ>xJDA$dVNyHIiE%mKfS~u9|w{|eBN2|HG;SwDs2eZt&N-1 z{{p6;4-K&C`xK;50pmGvmlGE~K*s)M5S}h<$FCYGuf~u1j30Y7Xc5wIDH9b~!(iR# zos&^(&>V`BNFjwuN&B??W$6ce0q}&>$d~@at;+jRT3<=|F#?F^rE%y7-b4uCo*ep@ z#xG`)UIgzC!;TQV4d#sbt4%pv-iyP_DyG987~Dm$#D0IggsehFM>X4^Epdk5LWz+%KT6Hhka)O3j#GybD2^lCoijS}Nd*20UDST&Slb zvkU(BOJ4R*AD8^pfKop~xxalvl49Ql6wInDlB_<}>tEUB$N)zw;iZuT$Lu*7#Tba; auOGkG;Q!A7L*DUka>ZNK8r}bRLjDd(4yvO7 literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/AutoContactG3-1.fig b/katabatic/doc/images/AutoContactG3-1.fig new file mode 100644 index 00000000..3e72139c --- /dev/null +++ b/katabatic/doc/images/AutoContactG3-1.fig @@ -0,0 +1,89 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +6 585 -225 765 3375 +2 1 0 1 0 7 40 -1 15 0.000 0 0 -1 0 0 4 + 765 -225 765 450 585 450 585 -225 +2 1 3 1 0 7 45 -1 20 10.000 0 0 -1 0 0 2 + 675 450 675 3375 +-6 +6 2385 -225 2565 3375 +2 1 3 1 0 7 45 -1 20 10.000 0 0 -1 0 0 2 + 2475 2700 2475 -225 +2 1 0 1 0 7 40 -1 15 0.000 0 0 -1 0 0 4 + 2385 3375 2385 2700 2565 2700 2565 3375 +-6 +6 450 2160 2700 2340 +2 2 0 1 0 7 40 -1 15 0.000 0 0 -1 0 0 5 + 1125 2160 1575 2160 1575 2340 1125 2340 1125 2160 +2 1 3 1 0 7 45 -1 20 10.000 0 0 -1 0 0 2 + 450 2250 2700 2250 +-6 +6 2340 2115 2610 2385 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 2475 2160 2475 2340 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 2385 2250 2565 2250 +-6 +6 -225 810 3375 990 +6 -225 810 450 990 +2 1 0 1 0 7 40 -1 15 0.000 0 0 -1 0 0 4 + -225 810 450 810 450 990 -225 990 +-6 +2 1 3 1 0 7 45 -1 20 10.000 0 0 -1 0 0 2 + 450 900 3375 900 +-6 +6 5535 -180 5715 3420 +2 1 0 1 0 7 40 -1 15 0.000 0 0 -1 0 0 4 + 5715 -180 5715 495 5535 495 5535 -180 +2 1 3 1 0 7 45 -1 20 10.000 0 0 -1 0 0 2 + 5625 495 5625 3420 +-6 +6 7335 -225 7515 3375 +2 1 3 1 0 7 45 -1 20 10.000 0 0 -1 0 0 2 + 7425 2700 7425 -225 +2 1 0 1 0 7 40 -1 15 0.000 0 0 -1 0 0 4 + 7335 3375 7335 2700 7515 2700 7515 3375 +-6 +6 4725 2385 8325 2565 +6 4725 2385 5400 2565 +2 1 0 1 0 7 40 -1 15 0.000 0 0 -1 0 0 4 + 4725 2385 5400 2385 5400 2565 4725 2565 +-6 +2 1 3 1 0 7 45 -1 20 10.000 0 0 -1 0 0 2 + 5400 2475 8325 2475 +-6 +6 5400 810 7650 990 +2 2 0 1 0 7 40 -1 15 0.000 0 0 -1 0 0 5 + 6075 810 6525 810 6525 990 6075 990 6075 810 +2 1 3 1 0 7 45 -1 20 10.000 0 0 -1 0 0 2 + 5400 900 7650 900 +-6 +6 5490 765 5760 1035 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 5625 810 5625 990 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 5535 900 5715 900 +-6 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 4950 0 8100 0 8100 3150 4950 3150 4950 0 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 6300 3600 6750 3600 6750 3825 6300 3825 6300 3600 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 0 0 3150 0 3150 3150 0 3150 0 0 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 1350 3600 1800 3600 1800 3825 1350 3825 1350 3600 +2 4 0 2 4 7 55 -1 -1 0.000 0 0 7 0 0 5 + 2610 1035 540 1035 540 765 2610 765 2610 1035 +2 4 0 2 4 7 55 -1 -1 0.000 0 0 7 0 0 5 + 7560 2610 5490 2610 5490 2340 7560 2340 7560 2610 +4 0 0 50 -1 18 12 0.0000 4 135 465 4950 -45 FCell\001 +4 1 0 50 -1 0 12 0.0000 4 135 360 6525 3780 G3.2\001 +4 0 0 50 -1 18 12 0.0000 4 135 465 0 -45 FCell\001 +4 1 0 50 -1 0 12 0.0000 4 135 360 1575 3780 G3.1\001 diff --git a/katabatic/doc/images/AutoContactG3-1.pdf b/katabatic/doc/images/AutoContactG3-1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..d4190b425f2054694b62f28e9528f565269d4975 GIT binary patch literal 1938 zcma)7do)ye98XztH!6=dR&|NY?BLEF#>})G6=skuhQn#aIb-HxG&8qmE)BcYCfVrW z-9sLm9;iu((n*gkRz>F6^@u#SLL!w-c2k`FT`6Jz*!$1D_w)UJKlk(dzOJRW3(p3% zwSz2co+sr&OqdSiAra7;HONLx7Dj}_4gldJJh6npQMM}YfhNjNRwmmE}nhN;-{#EI@&vPGoQX_OD(ak&S}f(4~WEr z-?*sq-;2BQxjU2xMthPrbZ05Y0!qeD_usD3?zv{QQpMTiB^l zN0D{BrLG~x^qAqH__7DuVYO1F^l92?q29gt@Vge-rnZ5+j1jj(^;%z3;&(rwb5E%Z zZfn%CJ?ix2@$*U&&ggfnTjlK7|DEy46Mprrg$ES2Wr}pIw5C^o z!7{2~+nI2;g_XV|-N)5CRYnY_=C{@t3O)8evB zJ*vexa?i?n{@gJq>M6hLW>?aRj8AOR^E6m%c3xtbom{nBMAPPn$@evDrr$D2Z6C5I ziYe&Ay;=`*Qn@|UqnnLZzS=vw{+6M%TyUgmd67ZSW|dc%OO&f0ZDb@b*r=szaG|t4MB6@7s zUzzfh4Hw&*`)gjhjn#OHe*UK7j>ZqCYt_o6a^cwv=hS8zWldMgn(`~&D^7Y9w})Ix zJr6Op%&a;ogmct=Nw&_ON9Grebqp4`SY`}p(W)$0shE`fpo2w@t`^IEI2WpG7*KfJ zUW2NKDJJ)HLusvTpAt=9Ac=@r|$YXL3oImR~2!ZUJfA}Z%xid9!Hhze>Hw%F%3wdne5 z@7?w#bx-8oOD0BXM@<@vjn75jxoq}2aTwddtL*6XEa-3_N=PZHA9Z3a-%(t;X=t$R z$NGyJZQ17kEGUo}<-CFaBqR4+r$2R$6eiJOndwT%Mj@4{rF$sq$z~VB>~*IO2XBb05cDxBo7GT;UFAECtkn`K%BulU{t{5>fl2F znv_L;;=?KdY(N)0Axr@y9%7LK4unYAd?*M843Q+|XQ3qfgYJBY2px*%zPF^#_^|UCQkLy%7)ma72$Ir&U7~tpY(DPC@?Z1 zh#Mw}!U(ZYVB>^KL=)$o$P|S5Mure%Rmg(?As@3ta?T|26H76L4Ih^ZWdDPKF~tB% zCyEqeathbi8+HxH6@)@47jGqCHp;Z6GpL|SU{ModT;>8wNpV@tpwroO7TpeIGuTWf zuzTX7|2BO}ol=g4LUb5qK=e-+?7(E&G2u{n5<^iIC=GeRvQL=31L)Zq7>a`GPsivS zhgq?7ItsdKrl0++Sd_s4Ei>H@wX>Uz*#l)W{TL1)lQUu&oX;>qE)YvFIrt~Sh_5&X zi~<8j_&5%FmTU|dahHYSFj)>T9_}u1AVp7<{LJTZUuM`?#}Z%KAdNa32_oBFK?vl; QL}F1Uiv?L)a=m!azcDk^L;wH) literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/AutoContactG3-1.png b/katabatic/doc/images/AutoContactG3-1.png new file mode 100644 index 0000000000000000000000000000000000000000..5f40b4360d135b88b62cf310f8eb0b96574376ef GIT binary patch literal 3093 zcmeHJdmxkj9v@4y%{|Pu;qZn;$h}+^p~B=X_oI=J%jULKWbqogBo$|`%I!toa+`=Z z6PlvjT5fIjj%sdc?39FNoK30DIe(w?*Zarw{GRXkd7kg(_x*gnzi$T8)lnRx1OWg5 z;?7R?#{dAKa{lvEQDOdF8!f!dU%(hA?^pmp%tdes4Gz?}@|Ey72d_8}^yxSpDkd1< z;DJW!XS(0G(I+p0d=T){=-)Vf zecTQ>BKLNE#Yx|gn#xhB;Wwl^y0+gWo^xmS9#^imDEzd;DpX7g|xSv=$kIjtD`7kc{`2#(jBiH zzrgUM-Tkb3;6=ktG;_79$aI4hC>7;i3n2%&_0h%gdPT($gh{Itu!vK2w@ru5O5OKL zG67rF)kE!^xy-(EoWM*6x*}(1hO`LG0(cse<=3@O9;s+^n}e|+FcD5DjySn{x#jG1 zRXP~{!9TR>dX4Ey5v8f3NM_J)BAq$+XJk0BHB?$XANOD}ygK6eb8fFoKyX5`{{gZ* zx%*Rk^Fh;NSiEoi*@8QBb&c!n1PEh3&`wj@AEFb10_CZ(FUq8D?LY*5~|TZ1A|Vj|G)B$g@M z%SJ$~G}wqS;aM+xngu|(#vxTT?pdx@Ch3`okz2aS>qV8PUc1*R~Rd2J`j&G z6T{=CS10oKjM+7GL?_J`oH%=74n;3+R^~*vhyT88vS4D6b4s#c$@s=j-siQo2%b_e zTC)j=M^$J~`JXdbC$Shr6m14TB!Gtg)&l%qE_B?4C#}?T)`UPj3KK_129JN}gz&sgTqg z?iOkCv>su2?zSnNbcK-d*3UY#xfd2+e;Uj2|Kn{Be#LOPaG3Gn!^oISq)h`e>Uq&+ ze`boK!?+@0?DQ1KC`3@?lt1#X=@a;&paZ$Ty~$ne?X79-d;z0}%{jljjd6dkIfVDts(W3o@Pfxq@lA@RT~4J%4lh@RRGDOU%k~R+_RU) z+8upQt;nUwZ=qMj@W~f%BH)6ti$MfgtUZm;C_=5jL;{Ao&;;67+G%=a{~1EzxV690 zsSKHK&c8`utI#I`3_*X$V-t&yWhKASC?&OzMd5ScJN|?k`N^p-5{W|+g@&gTHv`$! zNnGS_jbo>_1{>hB153?RKazKeG{gY;WQkf`9Q~511MOQLo197w@N7>GQZcfKITwt3CLQl@;^3!d8uPy;rvCTB?TG;$hH|AZZkc>SNPMGg~re znBxx>FW1l$%W|I;7*nEH>_@b1EMbq>#QSTB$!OSm{ej&9dV4oym3ujBzgD47`+lvARBz&UDUb1|?|C9IlHTZf~UAw&* zOs+XeS>59aSjm(i!E8@sL|QY4Cbh5;{jLLD*ajeO(JoUdXyA~aLRx#I(FWJAFjZBL zy`Ro|Q?(Y0IZwO1ROb07$8)NXzv12H)U0O71?iY9R9i4AAP?t??2xWiF08*!0@h+a zhpC`okAuDA!YWAp^hXJ+A!g&P6`VW1k~n?*{DsSIHHpzI78t%5y?TjcY-lqmfu3pO zW@he)x)D*2aocT{E#f*85fMGjo;~J-!o`ri;QN-62k4KQ40KO79*cKuK3>Xra`JUb z*-HHK_SS+P98&geIJMo7v%WI3edW!xYUFYkLQ*UO9^ClL4%x4jgj#q5N-BW2TawFWw-0@? zc2ocW!9lWpS9Zx&6bUc#q5*gqGbwbK%3psxR=&rD<+XT$BpzrnOft&dY24#{AouzX zn|b9rqd2D&pn1sOL(B@`JzZsQKK8AtSy+3Qr@MiQblJWS$Mj*?EK%ilVxYTX8JG9> z%Jk=ChBs{pRxevUpV>(}XLr=?v+2%pW)Y>YjE=O1EXp$4J!6{f(YtR;7oC zSb1!JIa%&jgR*2?R?_-Mw;^N8^Q}ZQG@&Tk#H}qKN@nCl?$<}w$ezV9*EC6Q*SNmGT$&`%${m3JH=j+Hb{7Ae*O{#-5 z$irDT0WxSiCi6{<;T`YR8A5T_*8x#O832 z=_PH6X$TLn02LCB%$tWUBD5+x4Dca>qaLK1CUgMxP|ImTLMSLD;p~j)X&oWgAcoyr z{I4Wf2|ha4I*X=piPT3aOYz{Id zZPV^-J8=y+rN^lfhs~5q)5o~yB(LkK39zVbGl}eW#b>qd7jBJfv9c0pq&l|L+h6ah zozYwxA-i#PP_Tc*mxvK>*3jKae-`uw4L>lw(|~lp|%U%9B$T z^KRaSqG0pjgP0-~b zmNVjR#c;*#-M5CEzn;4o9NT~IsMCYl%5w60g^XOeH)OB>+|V%pEq`vk);Rg(ooH$H zj?Ch{5r-~3Ei+HP7amjds4Vx<)P327;g6kar_B4w(%;y#XKB#`@zK(v zpZCQ7WvolDS>J|XLg|Tub)x;YWxwOvk~~i3h|`?aCz6I;>I`XprZ#G-UfzlDC(qxs zdt5c;a6_(iQ_uF@ar=7iG;9~8gw~JF6gw@qs+(}X^5&t;QKwR8cGx%VF0kC!Kn$p>C^He5b1_DFT>tD%LbyetT z+<^)Ai-{yqnOsGn-h`5ryHW-a$bx1b7XxgbAQ*v09igQGhuHxLiW7P&N~a+7a68C! zl){&w15vm?0P05=Xz1>4pryVv+z!@DNu?eHB8+St2?mfMilKZblwp4z+8^mAr{!u&^@ifL`hiag-uE9+ zji5d&N@$XHQagoxgEWAJ`2SGk^G5`uaX>Qw|y zD&&r?lv>%Rx-U}*>Khe8GgVah(2I^y}6k!33jj-NcfY0M`cpwz?V;CEQ=VC6PeT(rhsB{p9@nJU&!dR>iVp%KgR%vApewS^wJPf^V4U@F5b+w7Z^`>*&73Vth9IVNZAW H@j(6snZx+& literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/AutoContactG3-2.png b/katabatic/doc/images/AutoContactG3-2.png new file mode 100644 index 0000000000000000000000000000000000000000..a74698388b2da1ae000c0586cb2e9fa1e7dbefb6 GIT binary patch literal 3030 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 literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/AutoContactG3-3.png b/katabatic/doc/images/AutoContactG3-3.png new file mode 100644 index 0000000000000000000000000000000000000000..8aef666ce27c32414ed688fd123109d78eedf1d9 GIT binary patch literal 9777 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 literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/AutoContactG3-4.fig b/katabatic/doc/images/AutoContactG3-4.fig new file mode 100644 index 00000000..da66a163 --- /dev/null +++ b/katabatic/doc/images/AutoContactG3-4.fig @@ -0,0 +1,146 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 5625 3645 5625 4050 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 6750 2565 6750 4050 +2 2 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 5 + 1125 0 8325 0 8325 8550 1125 8550 1125 0 +2 1 0 2 -1 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 1350 6300 1935 6300 +2 2 3 1 0 7 30 -1 -1 8.000 0 0 -1 0 0 5 + 1575 4950 4275 4950 4275 7650 1575 7650 1575 4950 +2 2 3 1 0 7 30 -1 -1 8.000 0 0 -1 0 0 5 + 5175 4950 7875 4950 7875 7650 5175 7650 5175 4950 +2 2 0 2 -1 7 50 -1 45 0.000 0 0 -1 0 0 5 + 4950 6255 7425 6255 7425 6345 4950 6345 4950 6255 +2 2 0 2 18 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 5535 6210 5715 6210 5715 6390 5535 6390 5535 6210 +2 2 0 2 18 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 7335 6210 7515 6210 7515 6390 7335 6390 7335 6210 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 3 1 1.00 60.00 120.00 + 2925 4005 5625 4005 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 3 1 1.00 60.00 120.00 + 2925 4320 5625 4320 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 3 1 1.00 60.00 120.00 + 6975 4005 6750 4005 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 3 1 1.00 60.00 120.00 + 6975 4320 6750 4320 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 5625 4005 6750 4005 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 5580 4320 6750 4320 +2 2 3 1 0 7 30 -1 -1 8.000 0 0 -1 0 0 5 + 1575 675 4275 675 4275 3375 1575 3375 1575 675 +2 2 3 1 0 7 30 -1 -1 8.000 0 0 -1 0 0 5 + 5175 675 7875 675 7875 3375 5175 3375 5175 675 +2 1 0 2 -1 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 1350 2025 1935 2025 +2 2 0 2 -1 7 50 -1 45 0.000 0 0 -1 0 0 5 + 4950 1980 7425 1980 7425 2070 4950 2070 4950 1980 +2 2 0 2 18 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 5535 1935 5715 1935 5715 2115 5535 2115 5535 1935 +2 2 0 2 18 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 7335 1935 7515 1935 7515 2115 7335 2115 7335 1935 +2 1 0 2 -1 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2025 3015 2025 3600 +2 1 0 2 -1 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2115 2475 2700 2475 +2 2 0 2 0 7 40 -1 45 0.000 0 0 -1 0 0 5 + 2700 2430 3150 2430 3150 2520 2700 2520 2700 2430 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 3 0 1.00 60.00 120.00 + 2925 2385 2925 1620 +2 1 0 2 -1 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2025 7290 2025 7875 +2 2 0 2 0 7 40 -1 45 0.000 0 0 -1 0 0 5 + 2700 5805 3150 5805 3150 5895 2700 5895 2700 5805 +2 1 0 2 -1 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3825 4725 3825 6255 +2 1 0 2 -1 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3825 450 3825 1935 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 5580 2025 5670 2025 5670 3600 5580 3600 5580 2025 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 5625 2430 6750 2430 6750 2520 5625 2520 5625 2430 +2 2 0 2 18 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 5535 2385 5715 2385 5715 2565 5535 2565 5535 2385 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 7470 2025 7380 2025 7380 450 7470 450 7470 2025 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 7470 6300 7380 6300 7380 4725 7470 4725 7470 6300 +2 4 0 2 18 7 50 -1 -1 0.000 0 0 7 0 0 5 + 2115 3015 2115 1935 1935 1935 1935 3015 2115 3015 +2 4 0 2 18 7 50 -1 -1 0.000 0 0 7 0 0 5 + 3915 2115 3915 1935 3735 1935 3735 2115 3915 2115 +2 1 0 2 -1 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2115 2025 3735 2025 +2 1 0 1 18 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 3 0 1.00 60.00 120.00 + 5085 2475 5535 2115 +2 1 0 1 18 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 3 0 1.00 60.00 120.00 + 5085 2475 5535 2475 +2 4 0 2 18 7 50 -1 -1 0.000 0 0 7 0 0 5 + 2115 7290 2115 5760 1935 5760 1935 7290 2115 7290 +2 1 0 2 -1 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2115 5850 2700 5850 +2 4 0 2 18 7 50 -1 -1 0.000 0 0 7 0 0 5 + 3915 6390 3915 6210 3735 6210 3735 6390 3915 6390 +2 1 0 2 -1 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2115 6300 3735 6300 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 5625 5805 6750 5805 6750 5895 5625 5895 5625 5805 +2 2 0 2 18 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 5535 5760 5715 5760 5715 5940 5535 5940 5535 5760 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 5625 5760 5625 4275 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 6750 5760 6750 4275 +2 1 0 1 18 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 3 0 1.00 60.00 120.00 + 5130 5850 5535 5850 +2 1 0 1 18 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 3 0 1.00 60.00 120.00 + 5130 5850 5535 6210 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 5580 5850 5670 5850 5670 7875 5580 7875 5580 5850 +4 1 0 30 -1 14 12 0.0000 4 120 2205 2790 270 AutoContact Structure\001 +4 1 0 30 -1 14 12 0.0000 4 180 1680 6390 225 Physical Mapping\001 +4 1 0 40 -1 18 12 0.0000 4 135 255 1440 6255 G2\001 +4 1 0 40 -1 18 12 0.0000 4 135 255 5040 6210 G2\001 +4 0 0 50 -1 19 12 0.0000 4 180 2055 3105 3960 L1 before displacement\001 +4 0 0 50 -1 19 12 0.0000 4 180 1905 3105 4500 L1 after displacement\001 +4 1 0 40 -1 18 12 0.0000 4 135 255 1440 1980 G2\001 +4 1 0 40 -1 18 12 0.0000 4 135 255 5040 1935 G2\001 +4 1 -1 40 -1 18 12 0.0000 4 135 255 2205 3600 G1\001 +4 1 -1 40 -1 18 12 0.0000 4 135 210 2925 2700 L1\001 +4 1 -1 40 -1 18 12 0.0000 4 135 255 2205 7875 G1\001 +4 1 -1 40 -1 18 12 0.0000 4 135 210 2925 5760 L1\001 +4 1 -1 40 -1 18 12 0.0000 4 135 255 4005 4860 G3\001 +4 1 -1 40 -1 18 12 0.0000 4 135 255 4005 585 G3\001 +4 1 -1 40 -1 18 12 0.0000 4 135 255 5850 3600 G1\001 +4 1 -1 40 -1 18 12 0.0000 4 135 210 6525 2385 L1\001 +4 1 -1 40 -1 18 12 0.0000 4 135 255 7650 585 G3\001 +4 1 -1 40 -1 18 12 0.0000 4 135 255 5850 7875 G1\001 +4 1 -1 40 -1 18 12 0.0000 4 135 255 7650 4860 G3\001 +4 1 -1 40 -1 18 12 0.0000 4 135 210 6570 5760 L1\001 +4 1 18 40 -1 18 12 0.0000 4 135 600 2025 1845 AC-SW\001 +4 1 18 40 -1 18 12 0.0000 4 135 570 3825 2295 AC-NE\001 +4 1 18 40 -1 18 12 0.0000 4 135 570 7425 2340 AC-NE\001 +4 1 18 40 -1 18 12 0.0000 4 135 570 7425 6615 AC-NE\001 +4 2 18 40 -1 18 12 0.0000 4 135 600 5040 2565 AC-SW\001 +4 2 18 40 -1 18 12 0.0000 4 135 600 5085 5895 AC-SW\001 +4 1 18 40 -1 18 12 0.0000 4 135 600 2025 5670 AC-SW\001 +4 1 18 40 -1 18 12 0.0000 4 135 570 3825 6570 AC-NE\001 diff --git a/katabatic/doc/images/AutoContactG3-4.pdf b/katabatic/doc/images/AutoContactG3-4.pdf new file mode 100644 index 0000000000000000000000000000000000000000..3cc6dd7daea1f64a0e66bc6729227dca0d29c6fa GIT binary patch literal 10548 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 aL(&-X3r7zw4+~H<0+9k}YMNS`0sjXcF37h4 literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/AutoContactG3-4.png b/katabatic/doc/images/AutoContactG3-4.png new file mode 100644 index 0000000000000000000000000000000000000000..f5bce88f28c9590c023295814bd4917586b9b90b GIT binary patch literal 10669 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 Q)Z!i-4}`_?6$z350Fi~?umAu6 literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/AutoContactG4-1.png b/katabatic/doc/images/AutoContactG4-1.png new file mode 100644 index 0000000000000000000000000000000000000000..d7c954a9d3225034b025b70623030f699193e32e GIT binary patch literal 3151 zcmeH}dpy(oAICRj8@Z({IWD7%IvH`?TCR~Ul3M!FES4DM7P3qsQIy;HX`GW75m7Xk zNOQ>?QcF|F&@9Dv@HMe>3^RTsT~6os@9+25`8*!q@AvchKHiVd=l%Y?U(fgFlj!W^ zASbgy1_T1h?b~a21Ox&Xi2H3&3GrJuNJ1d~z=HR>g@Qn<4=z36*Dp(*#6LB|>|Mjq zK|WywT!=Tw9__5<;2RVg7U~t^7aXQ#w!;`{V3--6tpWl;tM=L196f()oOPJkSEsVd zIka*0ebtDaM!d_5M|#!=uc7z7avLkYvkg4r>jjHN_Kcky9So`6HTUY!f}g)PdFJkO zd0!3?H8zFDH%2e=W;!p0OW*~IL@Q8?5fqghS5IfsheL$?x}gSEMXf|*=?i)wCT*gj zr08ONX-V|$LqM;d1HqhGGuRj;J$P)mgaVmP^ah4gyT@x{o#ogCk_^G!k|G_M{+K
    qX1ZJ?4+?_-fUOxdY zw$U~buLd3}f)Qohu(XVzQajsqeHPC@;`e`Nc{9`HIwSdZk@(Pk=&SqjrstjwjrBha z%Z`fCvyj8QbQvFCYR+!2N$vCavMPOW_@7v_=K{3>MS~-DT!(aXr4RCc*K9QAtX>7A zSlqBW>X;bAFa9X6VjQzB{%A#Zd3no|E2ZXlMp!50_XU^~iQR8Gy{MX#mZLvZA&kl~Qsma;$QB0glCO<%`OV9#uI=&__Vu)+ zui|zB$<8+yjhxCaR&!6>lUeM2yEiMkOTR;1lLJ zaQ!Y(dDFsy4fVC6a_^d>oN=@((r$g}^=^$#ms+Z^6$-%wP7odPjmN)K@+rVo*VI&`5tT5LiU%Exe|;SmR07`0?wWon0kYmhDL@ z?2fb>Jymfed_Je5&29PoxdzLJyHA%VY2}!;)#?mH(Z?!wFR@Lz<7W0iFMo+ywMb_9 zrmd^KDAYWeyshri-q7shz|EJe<^o6CQJaRr_J@zY%WeqPu2_2CF)4giZ=^y+a*|3; zyjvYvezExp5B*1Z;Tm$sEbfe}ajv|mzQsM464(5}uV+>$&uxkl)3gvp=d}HeTaU$^ zHF^0Y?8V8n`?9TLk3|;@Hs?T_GU|&~_{Ex-Z0pJkYZ(fT>%0erlu(hRrv~L02d~M8 zSKGwh@J8uHwiPSy#yCA#-D;6Kc4aK**{H&ep_-zPS2kOv-&mm5xPWru&iNZ9w{-0i z#Po`h179t12xWSnZBVxVI(p-8v7`+S8(Z@$s}J8d%rH<%cS9fY9mKXlg|0}s*N@7# zqhlK%>vP(=9jkUQeC7IsTaKH2qtG(!!8CrAwveY#G=KH>Uve&fbAYMWn4x&iNu{mC zO!S3)?@RN$ubNCFez7qxq^Bm6Iy@1}Lw;E*ZEU!2NQY4>=ql(;jT(uUC1=}aVO;iP z1IND+O`mA>#D9crNCGBhL@CC z!1)ET#Gi4C0+8S(CV-13-6D>d;3?c1?iVO=OaMam9JT=T1_-yAfG>z!h`>!E(^QG0 zCMj-0(~>1*h42EWOiXzH<|yjS{cpSmASY)>5HU5K^hpxLq-7=*AoQ4T%t)e|T15~5 zk%SB}Q5Zl86qyhcp#q3R3u4j$+N6w(r(>oiWEx3N@bYw8p5kpX&D8WYKa<>G8B0sh z0qNK6mkZ~AZzgBtgSR3X+kmiLdi~+&a~7BJ%fc1-vNHa%%7+P%XI2I>RT_9I|M*D6 z5C`L3&s5jdu-K=m{dn2qrDh2SE%@tmv)AR;A3A1X=fcs=-CmcNC7WBXxL*i_eGd2E zj7l-=M|VHE8Py&Y87a?~4+$ANt1jGuUVUy<_Wiadv!=*Mp9AZG;M6%8K0p7`;ogNR zF+w+1o?>^GYF~5E*!N>YV{gNwpDI;b)LRr}7JI?#-V!8Hcas_V;~@W9T;J63|1qva zDZgi2jo#(Rzj?jBQ;Zb&onJ}Wt~?+3k#(gH$7hF+Om^rz?pxjwqE-FZT>j00m9*x` zASI+n&=O8pT>RR@;Rb@Jgd!lzAQqqCH35isMFd19hy%jOaEibnLeY^W;0+La0LV3Bi;y5;!YR@;YMItW zB>ql$3R$oO*y{%m4%eJ3;Jkje;sgX>IAP-q?G3;X3?aVLY)(rwVTFhUvc*CoF(JpF zWnjSzVN2YQgfbl)30ckX6eoo#+D2!O6K{8hOo2i<+z7!meAxx`)B32yZkGxs4hBPkh)LNw%=`$&dH(lR4d>I^a>9S50Ao)(*s&*Fq& zeEhdW5OU?j;I}*)2r+p){5nRoBoMOW2JpZMu7vEYKyPijm^yFt)Cfb_q#o=Yt7_Ac amiQ7kIf0PH7fK3~Y)D1`EiG#&I`AJab&!kz literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-41.png b/katabatic/doc/images/GCellConfiguration-41.png new file mode 100644 index 0000000000000000000000000000000000000000..b59500b4922c00c9839e78ab48b56c9ebea97170 GIT binary patch literal 5532 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 literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-42.fig b/katabatic/doc/images/GCellConfiguration-42.fig new file mode 100644 index 00000000..7b1ddad1 --- /dev/null +++ b/katabatic/doc/images/GCellConfiguration-42.fig @@ -0,0 +1,104 @@ +#FIG 3.2 +Portrait +Center +Metric +A4 +55.00 +Single +-2 +1200 2 +6 -270 13230 5490 17370 +6 4140 14355 4410 15345 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 4185 14760 4365 14760 4365 14940 4185 14940 4185 14760 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 4230 14400 4320 14400 4320 15300 4230 15300 4230 14400 +-6 +1 4 0 2 -1 7 40 -1 -1 0.000 1 0.0000 2025 14850 90 90 1935 14850 2115 14850 +1 4 0 2 -1 7 40 -1 -1 0.000 1 0.0000 2925 15525 90 90 2835 15525 3015 15525 +2 2 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 5 + 0 13500 5175 13500 5175 17100 0 17100 0 13500 +2 1 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 3 + 0 16650 3375 16650 3375 17100 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 2250 16155 3825 16155 3825 16245 2250 16245 2250 16155 +2 2 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 2835 16110 3015 16110 3015 16290 2835 16290 2835 16110 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2925 16110 2925 15615 +2 1 0 2 -1 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 2115 14850 3510 14850 +2 1 0 2 12 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 4185 14850 3690 14850 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 3600 15615 3600 17325 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 2025 13275 2025 14760 +2 1 0 2 -1 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 3015 15525 3510 15525 +2 4 0 2 0 7 38 -1 -1 0.000 0 0 6 0 0 5 + 3690 15615 3510 15615 3510 14760 3690 14760 3690 15615 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 3510 15300 -225 15300 +2 1 0 2 0 7 38 -1 -1 0.000 0 0 -1 0 0 2 + 3510 15255 3690 15255 +4 0 0 30 -1 18 12 0.0000 4 135 615 45 17055 Global:\001 +4 0 0 30 -1 18 12 0.0000 4 180 1230 45 16830 Configuration:\001 +4 0 0 30 -1 18 12 0.0000 4 135 645 1575 16830 3-1-1-0\001 +4 0 0 30 -1 18 12 0.0000 4 135 1665 1575 17055 North+South+West\001 +4 1 12 40 -1 18 12 0.0000 4 135 180 3915 14805 Lt\001 +4 1 0 40 -1 18 12 0.0000 4 135 180 3060 15930 Lt\001 +4 2 0 40 -1 18 12 0.0000 4 180 1665 1890 14715 _northEastContact\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 1890 13410 G\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 3510 17325 G\001 +4 0 0 40 -1 18 12 0.0000 4 180 1725 3735 15660 _southWestContact\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 -180 15255 G\001 +-6 +6 6075 13230 11565 17370 +6 10215 14355 10485 15345 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 10260 14760 10440 14760 10440 14940 10260 14940 10260 14760 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 10305 14400 10395 14400 10395 15300 10305 15300 10305 14400 +-6 +1 4 0 2 -1 7 40 -1 -1 0.000 1 0.0000 9000 15525 90 90 8910 15525 9090 15525 +2 2 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 5 + 6075 13500 11250 13500 11250 17100 6075 17100 6075 13500 +2 1 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 3 + 6075 16650 9450 16650 9450 17100 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 8325 16155 9900 16155 9900 16245 8325 16245 8325 16155 +2 2 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 8910 16110 9090 16110 9090 16290 8910 16290 8910 16110 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 9000 16110 9000 15615 +2 1 0 2 -1 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 8190 14850 9585 14850 +2 1 0 2 12 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 10260 14850 9765 14850 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 9675 15615 9675 17325 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 8100 13275 8100 14085 +2 1 0 2 -1 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 9090 15525 9585 15525 +2 4 0 2 0 7 38 -1 -1 0.000 0 0 6 0 0 5 + 9765 15615 9585 15615 9585 14760 9765 14760 9765 15615 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 11475 14175 8190 14175 +2 4 0 2 0 7 38 -1 -1 0.000 0 0 6 0 0 5 + 8190 14940 8010 14940 8010 14085 8190 14085 8190 14940 +2 1 0 2 0 7 38 -1 -1 0.000 0 0 -1 0 0 2 + 9585 15210 9765 15210 +4 0 0 30 -1 18 12 0.0000 4 135 615 6120 17055 Global:\001 +4 0 0 30 -1 18 12 0.0000 4 180 1230 6120 16830 Configuration:\001 +4 0 0 30 -1 18 12 0.0000 4 135 645 7650 16830 3-1-1-0\001 +4 0 0 30 -1 18 12 0.0000 4 135 1635 7650 17055 North+South+East\001 +4 1 12 40 -1 18 12 0.0000 4 135 180 9990 14805 Lt\001 +4 1 0 40 -1 18 12 0.0000 4 135 180 9135 15930 Lt\001 +4 2 0 40 -1 18 12 0.0000 4 180 1665 7965 14715 _northEastContact\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 7965 13410 G\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 9585 17325 G\001 +4 0 0 40 -1 18 12 0.0000 4 180 1725 9810 15660 _southWestContact\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 11430 14130 G\001 +-6 diff --git a/katabatic/doc/images/GCellConfiguration-42.pdf b/katabatic/doc/images/GCellConfiguration-42.pdf new file mode 100644 index 0000000000000000000000000000000000000000..5ce09f6bc68fe5a5aa039234092da1a8fbc27214 GIT binary patch literal 5290 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 literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-42.png b/katabatic/doc/images/GCellConfiguration-42.png new file mode 100644 index 0000000000000000000000000000000000000000..47fe02eaf5a6e1bb1954d12c7e969cd10e42226e GIT binary patch literal 5438 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 J@xN2WzX6WS1QGxM literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-44.fig b/katabatic/doc/images/GCellConfiguration-44.fig new file mode 100644 index 00000000..cf11f1af --- /dev/null +++ b/katabatic/doc/images/GCellConfiguration-44.fig @@ -0,0 +1,60 @@ +#FIG 3.2 +Portrait +Center +Metric +A4 +55.00 +Single +-2 +1200 2 +6 -270 22230 5490 26370 +6 4140 23355 4410 24345 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 4185 23760 4365 23760 4365 23940 4185 23940 4185 23760 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 4230 23400 4320 23400 4320 24300 4230 24300 4230 23400 +-6 +1 4 0 2 -1 7 40 -1 -1 0.000 1 0.0000 2925 24525 90 90 2835 24525 3015 24525 +2 2 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 5 + 0 22500 5175 22500 5175 26100 0 26100 0 22500 +2 1 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 3 + 0 25650 4050 25650 4050 26100 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 2250 25155 3825 25155 3825 25245 2250 25245 2250 25155 +2 2 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 2835 25110 3015 25110 3015 25290 2835 25290 2835 25110 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2925 25110 2925 24615 +2 1 0 2 -1 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 2115 23850 3510 23850 +2 1 0 2 12 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 4185 23850 3690 23850 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 3600 24615 3600 26325 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 2025 22275 2025 23085 +2 1 0 2 -1 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 3015 24525 3510 24525 +2 4 0 2 0 7 38 -1 -1 0.000 0 0 6 0 0 5 + 3690 24615 3510 24615 3510 23760 3690 23760 3690 24615 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 5400 23175 2115 23175 +2 4 0 2 0 7 38 -1 -1 0.000 0 0 6 0 0 5 + 2115 23940 1935 23940 1935 23085 2115 23085 2115 23940 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 3510 24300 -225 24300 +2 1 0 2 0 7 38 -1 -1 0.000 0 0 -1 0 0 2 + 3510 24210 3690 24210 +4 0 0 30 -1 18 12 0.0000 4 135 615 45 26055 Global:\001 +4 0 0 30 -1 18 12 0.0000 4 180 1230 45 25830 Configuration:\001 +4 0 0 30 -1 18 12 0.0000 4 135 645 1575 25830 4-1-1-0\001 +4 0 0 30 -1 18 12 0.0000 4 135 2175 1575 26055 North+South+East+West\001 +4 1 12 40 -1 18 12 0.0000 4 135 180 3915 23805 Lt\001 +4 1 0 40 -1 18 12 0.0000 4 135 180 3060 24930 Lt\001 +4 2 0 40 -1 18 12 0.0000 4 180 1665 1890 23715 _northEastContact\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 1890 22410 G\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 3510 26325 G\001 +4 0 0 40 -1 18 12 0.0000 4 180 1725 3735 24660 _southWestContact\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 5355 23130 G\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 -135 24525 G\001 +-6 diff --git a/katabatic/doc/images/GCellConfiguration-44.pdf b/katabatic/doc/images/GCellConfiguration-44.pdf new file mode 100644 index 0000000000000000000000000000000000000000..52a5c8c871728bd455fa4723632bb5073527a5c3 GIT binary patch literal 3443 zcmdT{c~leE8V40E~LK92J!QMb3L4wG5nxJ4LC|*GmLPDuk z5x%~Vj;07j0+hP5Wbw7-(h!GBt*j$ z>|oL44{(SK466Uise;gc{rjAKy!0D#gUd^<3YOh@zT$WXa_qY)D;+Ymen);Ct)JuW zz)N>WiYhso>nVaTbt-n4XbBPpxO|G85FMGR3M!|^SIh<+kt)jBzPl_ja zZ4h63B&zdZyI3DaB&DY@^N&cik z(*5Zja`ukJ>+y*TYCW6o<<3G3e$DIK{}wlPe8O^9{g?%#&b!W#)V9?{kG`ff-kt7p zQ69c0`jLN4$Y9&$TY~MTK3hirb$#;Voa0EjOZJ*6kF#5=sv{J6gTK%Q2O181|HrK- zovCkLG{?m1mpUmov~TAL_+j>wY{DKTh=t>vKP@b}pXDd03%RgDd-F)qfhBue{w|ho zINCm3n-{g}j1g{h^B*=MYVXFeH=qea&Q>1w-c$@KRt+|-o%?I8yrqvjZPaa7#7mfWC#>!+XV&wrVu-kL9Takfu* zGGe3Qbw$i?C(fQ+@OEzFYSqAiqNSUUrEHylyXnd9!Te<*p;wLU1Dn2;{`q|8%fMMW zU1zE6yq(anxq8jshk?T%Jh0K*lUtviUe${32rDF0$JVB=ds(H5bRr9yZ=HVrtor&M z+rz7l+MjKyVu?zBiPqG#MZ5es>GAHbwRv?y(Y*$ZgYVO~oiC6(!yXTO@Jh{F`C{{o zTW7|FRt%k(HG%!$PFZ#R`Iz)yKO5nAkuDE}Pjrgxvt|`#geP6#I?lQqTF_Y^7A)|Q zI2SF#8%BD22DJJ-{k-JhrI9)JWwj$;9}IXzXjJC522TtXFa*H-^0_R?EMoVtgmh&h zfru5c1QJT9NQFR~3d>NijH4)wvGFJfEK-DqhFJ`cK!}9UX_F}>p#uyfrnJfkf|enG zgJ48Tq|#vfyi|IA1PxdQ#uzdJDnVMHj+uA}0;Gckf_Gq12ftefA~P)Jh7LqC*EQ1)>5-17=7Lpm0j5V_=)~#yR3{=pHcx`N#iFfFG_H%ph??DYAVd792 z^Y!gAY{94!F2v|bdd!%-GV`qj!yt^oAweV<8^TOz5eX0C_0hq5&VEPBmaN=G+iae% zZ#O-&q^M0`AS}X+p2h)5RE7TlzC2UhWD~4T%=pllbSiIr300D0N7>paZHFFUV$!<= zu%5`8CqaKlV&1^*_dRo*r=uX>+2iiSyH5U}76~Y?f^F^vHKpZ(kZ{to;FA;Ua%~H0 zhHR&y#KowwDP@zl5zlIGN@-5f>jzQ;m2&9;PL8tXGLrd7=O|IfMnKM$;_sLf8A=z?iz(C8X)iy$?zFlK5B zBrr}vF^r&t0X1N-spdfU0~%opUILoc!~~%Vnj%wWOrwA$<~zzH7Xa!pF%M7$5|Yx< zj71nlL<;jGhAbgfbev8GF?%2+A~}X;=!*fxvS>=H<~Acm1PUF|1smAX1ZZ?*_q&i( zs|i4LfZJpcil7Jbj!J?q*RLM$$ z@|YJPhUdp=b+k@Nk%=_S!#G|jJ`;=_aL=Vltwspul84X-3^yLiMOhe+g<>dJ57nyr zU+SI%sT84xn6U_<-5=PS!(nk?HEfn)I1iK_^MN&8GMtA3=X=XA90&R9BSX1Xx+uzw z(7yXP*19Z!qR&2@!vW3JN0*0!sP&QYF)MpG#_MVTI;g7VEXso zhp|yB8P3A{vB$TTad8WOX-YxH6BPK%10xY+8Ub_-&E+%9yqf}%~S$N3=jZf^6!f}no`Aga)$ literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-44.png b/katabatic/doc/images/GCellConfiguration-44.png new file mode 100644 index 0000000000000000000000000000000000000000..54ebe9379d2e22b85f8769e4da889100448fb130 GIT binary patch literal 3750 zcmeHJc{tQ-8=fJGLdY0njUr8!Ny@IW@8=kqXe`ZyLWi+$W9uZ#I8t^aqKqZWSW_6I zF%m}7FtSDxhhyIv-#Dl1>s;sm@B8cg@q2&o^}O%77I!BiEM&!-3EfB=A_>?ZnGY=ZFfBSRtgNn-HV5 zcumMz^FzyxBI@125m!?fz&$#EGvbC z&DIlvOR+F12^c4(Q@mJ*ms%557Y{d7<)p|QcnCUG?%fLge&N6(=FR3x2Ff`*v5pK& zmbg*JVvTVBbuk$!sC<-H4Y(ssmBF-dRY?7a0%pzA6`kzPdUz035(OyNI6>CN18}H_ ziJgtTd$kPVO)eA@K9st8xyo5y(E;5C#=)qQeD#zb$eAxwiVxV1H} zmWeUm&m;9!zr$belY;imHyFC!r{9?TJ5!QTd zrKfT~rycX~(p$PJl|1Vvo29RA71y0v9Xno8Xwhf6=(lyfw@%cAB)xyy`Q_<-;igjJ zW4d#_dVlh|?;nISIa@=b!qitw>-qDByKR}enRunGX0na#?>0M{U0bS+QeJUDs}GtD zshp+hkm5S8{jwL@qm(9NC*<(!M44}!FK^IuAJJ*{P0z^m%{u$h^{Dy6U3tW#)cTE3 zm!92gcGzY7>|M}_-HTl7iE{O$a-IY3Vq(@l+*$hshVNSaYRdI&qR1|GnUXK4aB7>a zC@^)xh$Faz-Lec776ef^qS;5ds4J=EQFg2}AZK>1?u7jr%?E^AR}gJXq6GALI8#D* z?_5UwT(WyCNK2){;nCWR#Qu(^#`O!97x_>)Sacj+#OTxfTZhxDn_^ZTGpNvD3Yh&= zRhDIyM2WQ(C2V!rR>9#*j(WtdG#lEmAUfJ+> zwcHJhXw`PF{MrC7>zenq6LGV2dZ4rfE96!gYvV96#0n35*;G{g-kt|RTyCtGq>@h> z0UrC7E*1MPE&|qxjADMxP0?|tSo=f0;EZ3f=o8bj@(O8fKsl$SqkMSWomu6*S*)6u z)Jo8heun^f;{2Ywr}RidVUjk91kNS7xttBaZ3sdeQc(QEma4#*q-ZU5S}`>?J7&Wn ze*tU`4 z+~CWblnFAAgC}Rrq)#y>P;32nhPyzXgGu$;ZOqK;Mcj9#OJFJ6I<}q{MjoGa%xAjj zP6^=h1(jWd%tITPS^@t4A6)DgMfsYg3H)vx_(D7>3nY*rL*49I)2XhN;DMR#-cssy z>@f70O4lK=jg?j@ zrLBDw^V+=qN)8B}I(hKs2fedgPef>QryBxT><&&!o;AfYqZYM6b51j8tKYzS#jiuz z){%lI^58tNMygL7a#2B{**%43`yDq9VRyj1YTdNKWpZgk^u}gquEO3hg9iu|-u9~# zAB{qOuDNg60lQ*>jAAI1*L$!@!ay?9<(UeuD{{@v?{gQN0?#xqpkmEp#>)%#1Dt{` zMo1qkAp$H3mo^Ejl%c^7V}Ubc^UT!yS@O)|!VTD8!9C@A8|O#j=HIvNy-z5AW32jz zndJVq4!GD*-TJJ!9`ZmPCo%W`kzu6Wq66|k1E}a{uLM|{_@@Z|C8I1o%iuVSkHqq$ zaqU2Y=?`^iJS;;mLvRG$AJ#jo-JD?dM?YC-{l%ppFg|YuOQuE3l^`^Avyf&v}FZ*R3 zZZ6&|(f&uC2lJM$H$?t+pWRlLXGU9_>!PszMZSjxUp~ZM2kZt%N4*F>jzoqq8CfS( za*~G%ebQ1%FtdR`rTlt&Wj2W+KBprq?_{ae!h|mh%4y%z<$GA6OfAq^i5~e%+m#M} zE$>rzjdnLYD(_LUd#JY=c0n$iOy7N&?KUVVC{sgTx=!XEoyJhfiL=cY z*wkO;;I>emvNyc zJnPMVe%h15AXt0z6FKiiAsja=a&zZOEsom=P2vMhy4bK~&XQGKH?gVF5l`%LpQ}}i z#A%3lD)*+uBgR*Hq2&5U;NKU1XL8#g3D6G&&EZLo=|1mrsv%@WOg>q^ebl_`j!04p zVzP_(X61u431Oj+)$vUpUhTX-S^oA3wURG_wnP^L7_D(gvPYb%OZc9=LokwsRqNPB z=Po@{Z9f9GZYrpxvZ)r4&?YNen4&N>lVTK+xVLQ*zWW(OhyYAz7g6V0@{)5AV-BLt zKM(Q&DFuJR{#S!@|5?ReyXl+G(16d{B92%tI=CsvKDS?pzo;E3x4NRvd)E7?UkNO- z_|3Czp@Yo~!s(j>LYn$*`s1flY2TV-EmcEgS}M@7M~^Q!4V-A_(4356jnM#riGihl z`BmrWxc~j^%|`q_d-q-80Z1KhQEnkk>mA~&dUma{XT9rO-rO!Pz;O_~?0GEsVvLrk n-jl?WJ=BM8=(p9dFaMhV#pM595RFH>%MP_;viBYT-YNe9h${%? literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-45.fig b/katabatic/doc/images/GCellConfiguration-45.fig new file mode 100644 index 00000000..1c0ba1d5 --- /dev/null +++ b/katabatic/doc/images/GCellConfiguration-45.fig @@ -0,0 +1,50 @@ +#FIG 3.2 +Portrait +Center +Metric +A4 +55.00 +Single +-2 +1200 2 +6 -270 26730 5490 30600 +6 4140 27855 4410 28845 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 4185 28260 4365 28260 4365 28440 4185 28440 4185 28260 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 4230 27900 4320 27900 4320 28800 4230 28800 4230 27900 +-6 +1 4 0 2 -1 7 40 -1 -1 0.000 1 0.0000 2925 29025 90 90 2835 29025 3015 29025 +2 2 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 5 + 0 27000 5175 27000 5175 30600 0 30600 0 27000 +2 1 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 3 + 0 30150 4050 30150 4050 30600 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 2250 29655 3825 29655 3825 29745 2250 29745 2250 29655 +2 2 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 2835 29610 3015 29610 3015 29790 2835 29790 2835 29610 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2925 29610 2925 29115 +2 1 0 2 12 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 4185 28350 3690 28350 +2 1 0 2 -1 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 3015 29025 3510 29025 +2 4 0 2 0 7 38 -1 -1 0.000 0 0 6 0 0 5 + 3690 29115 3510 29115 3510 28260 3690 28260 3690 29115 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 3510 28800 -225 28800 +2 1 0 2 0 7 38 -1 -1 0.000 0 0 -1 0 0 2 + 3510 28710 3690 28710 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 3600 26775 3600 28260 +4 0 0 30 -1 18 12 0.0000 4 135 615 45 30555 Global:\001 +4 0 0 30 -1 18 12 0.0000 4 180 1230 45 30330 Configuration:\001 +4 0 0 30 -1 18 12 0.0000 4 135 645 1575 30330 2-1-1-0\001 +4 0 0 30 -1 18 12 0.0000 4 135 1035 1575 30555 North+West\001 +4 1 12 40 -1 18 12 0.0000 4 135 180 3915 28305 Lt\001 +4 1 0 40 -1 18 12 0.0000 4 135 180 3060 29430 Lt\001 +4 0 0 40 -1 18 12 0.0000 4 180 1725 3735 29160 _southWestContact\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 5355 27630 G\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 -135 29025 G\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 3465 26910 G\001 +-6 diff --git a/katabatic/doc/images/GCellConfiguration-45.pdf b/katabatic/doc/images/GCellConfiguration-45.pdf new file mode 100644 index 0000000000000000000000000000000000000000..01422d35b29a76c16e6f17558bcaa55618e944f6 GIT binary patch literal 3266 zcmdT{dr(tn76;L3d+Cbp4h{utFADNdxcAG81ZW0%gMbiNT}kLRBsbwoNaDShM;VKc zEnuih5fEki5QHMs$Li`<1r=Rg5D*n`6|`(?gB8a|$NGX6-S5T#31MfP{bOe~f8=q_ zch2|w&N;u|cjK8D9_a`Cxrk@m-O^fwkK(8}prYiDO~3U$P4^sJ=k)N&s$e8%>v^x8aUQze zGJ8XH`rR_3H1D2I-6eP8%K96Izkd60>0i1oJ}n;|8Wt4aPVXE|-D@ls-HdwYeEY~2 zZ;||O^x2)sWl#Tkek69@Nm2ESx0||J@-O_{D_i?}Pkfv2pPmOa{`sEpSEuH>lW*V+ z-y0vepK9D&WLWsMi>f4{vmtX$$&KB)M*fGp+jmxEs=(i$&0qCoQ-WbL9Wu~l-`}k2 zO8&Uk>uOml(%n~Ed9lvb;ix+Px!>)jBXNE6Tbo8wW~$$vrTDbxvu~1xxh21J^k3>o z4^H*kC0r#t;I6qe*1Z38aM5q}pO@8MKDNZ!u6bn)hkIvr-H(^D=Pp+MaP&QFmtA0d z!{s+iPwd!Gvn6v=OYMTe@-s#GMSG$TzL(wyRvcb3u(?{f@Y>+n8UCVoMTZ?5>bDkc z#9U{l>^TwSml~&VccY|+;e@K7ltI@Q7o1k)_bk#JX)Nr2OYGsX<$WS*ZGX!@G|lao zW5oHSb9G|>TcUx!kj>q((LvJtZNH2XbZ*XA%gE7!Ycl^Lk6oX*FJ9;t+o4X1wEJm$ z#4WwtA@Q{o&I6yML%RVo@9_D`z0r-854?T1jh%@UbPO){G`8!nhp6!aa@^n=@v=WdW3{z6>%wR=CWT2}I1jbWpU#3%3PLgnj~ ziY$k`Ag7z^97DzZyJ|(p{;c*xQLYiU=6}@|^y?|D{)nP8X!d%^O|mfI+_AnL6~ zd+UChc3Vw^SD|u??Hw1${`KSI zfoBee=Ds#Ut2FZjeq*`CGK&2S5D5{pi8o2Rl#lcTmMB*fSUjO5<)OMfREk442ggys z<)tCeNfBBG<+8*?FbP5HvMB{YL&_#nIz=+UNHIui6iXrU7`QwlkBLfVAZ<~=vKxj( z>R>o95gUOl#=_uln2|mW}k7EkCMHwCu~3q#|8(bqU*4RtJJhDcVF z*kc#1(ibi^t~p&Xx1OqBGmEmfQ`kE;u{E(C0Weuvv$RgPB@n=4zv`aOzAmAaZr-Q85u${s%H`$IqHjo7SJjmMP(b>0`_Tq=iK z&wSrHbfn$R@82oIhawtfq-=xCt~~2at?izGrHZ-# z|GAg{=Y=&5wfT@HxnKzmiLQm$GO1Ogz(fixEJIGQia?`K8UPdzcI*)h$_P8~5=d5) z62!|Hip-O;M1d~$J+oTAN;TTA>$Y~*&Y!}<%-}OTIb_%xYNYqkm%Oy0EcU1;{cv*KG>wGu^c|%;=BwcCp82G z|3jcyGMP`n9-){-r-Kg&?6{*?j8>&XAt-kAW5Q9XcbepSZ|j0@+|Pk4Z8e@B4*1ww Z(%5GUnvqkCsqvfu9v|`aj94Ct{2Q*xhUowR literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-45.png b/katabatic/doc/images/GCellConfiguration-45.png new file mode 100644 index 0000000000000000000000000000000000000000..9985c9d97f014aab2f4d7d3711b63c1e59e4442f GIT binary patch literal 3064 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%0DKwejkK+S)0fNeg!=kCKuvuA9`$g=8JI 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 z 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 kY%~7p;(n5YcaxoR&P#JhA1)FGte<0+~J|+yDRo literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-7.fig b/katabatic/doc/images/GCellConfiguration-7.fig new file mode 100644 index 00000000..b2bb7a5b --- /dev/null +++ b/katabatic/doc/images/GCellConfiguration-7.fig @@ -0,0 +1,106 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +6 -270 -1575 3150 3825 +6 1665 -1395 2610 3195 +1 4 0 2 12 7 40 -1 -1 0.000 1 1.5708 2475 1890 90 90 2475 1980 2475 1800 +1 4 0 2 12 7 40 -1 -1 0.000 1 1.5708 1800 1890 90 90 1800 1980 1800 1800 +1 4 0 2 12 7 40 -1 -1 0.000 1 1.5708 1795 530 90 90 1795 620 1795 440 +1 4 0 2 12 7 40 -1 -1 0.000 1 1.5708 2250 540 90 90 2250 630 2250 450 +1 4 0 2 0 7 40 -1 -1 0.000 1 1.5708 2251 -768 183 183 2251 -585 2251 -951 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 2520 3150 2430 3150 2430 2250 2520 2250 2520 3150 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 1845 1575 1755 1575 1755 900 1845 900 1845 1575 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 2385 2340 2385 2160 2565 2160 2565 2340 2385 2340 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 1710 1665 1710 1485 1890 1485 1890 1665 1710 1665 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 1710 990 1710 810 1890 810 1890 990 1710 990 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 2295 -225 2205 -225 2205 -1350 2295 -1350 2295 -225 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 2160 -135 2160 -315 2340 -315 2340 -135 2160 -135 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 2475 2160 2475 1980 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 1890 1890 2385 1890 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 1800 1800 1800 1665 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 1800 810 1800 630 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 1890 540 2160 540 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 2250 450 2250 -135 +-6 +2 1 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 3 + 0 3375 2700 3375 2700 3825 +2 2 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 5 + 0 -1575 3150 -1575 3150 3825 0 3825 0 -1575 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + -225 -765 2070 -765 +4 0 0 30 -1 18 12 0.0000 4 135 615 45 3780 Global:\001 +4 0 0 30 -1 18 12 0.0000 4 180 1230 45 3555 Configuration:\001 +4 0 0 30 -1 18 12 0.0000 4 135 435 1575 3780 West\001 +4 0 0 30 -1 18 12 0.0000 4 135 645 1575 3555 1-0-0-3\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 -135 -585 G\001 +4 1 0 40 -1 18 12 0.0000 4 180 1335 1350 -585 _targetContact\001 +-6 +1 4 0 2 12 7 40 -1 -1 0.000 1 1.5708 7470 1890 90 90 7470 1980 7470 1800 +1 4 0 2 12 7 40 -1 -1 0.000 1 1.5708 6795 1890 90 90 6795 1980 6795 1800 +1 4 0 2 12 7 40 -1 -1 0.000 1 1.5708 6790 530 90 90 6790 620 6790 440 +1 4 0 2 12 7 40 -1 -1 0.000 1 1.5708 7245 540 90 90 7245 630 7245 450 +1 4 0 2 0 7 40 -1 -1 0.000 1 1.5708 7246 -768 183 183 7246 -585 7246 -951 +1 4 0 2 0 7 40 -1 -1 0.000 1 1.5708 6075 -768 93 93 6075 -675 6075 -861 +2 1 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 3 + 4995 3375 7695 3375 7695 3825 +2 2 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 5 + 4995 -1575 8145 -1575 8145 3825 4995 3825 4995 -1575 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 7515 3150 7425 3150 7425 2250 7515 2250 7515 3150 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 6840 1575 6750 1575 6750 900 6840 900 6840 1575 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 7380 2340 7380 2160 7560 2160 7560 2340 7380 2340 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 6705 1665 6705 1485 6885 1485 6885 1665 6705 1665 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 6705 990 6705 810 6885 810 6885 990 6705 990 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 7290 -225 7200 -225 7200 -1350 7290 -1350 7290 -225 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 7155 -135 7155 -315 7335 -315 7335 -135 7155 -135 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 7470 2160 7470 1980 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 6885 1890 7380 1890 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 6795 1800 6795 1665 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 6795 810 6795 630 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 6885 540 7155 540 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 7245 450 7245 -135 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 7065 -765 6165 -765 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 4725 -765 5985 -765 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 6075 -900 6075 -1800 +4 0 0 30 -1 18 12 0.0000 4 135 615 5040 3780 Global:\001 +4 0 0 30 -1 18 12 0.0000 4 180 1230 5040 3555 Configuration:\001 +4 0 0 30 -1 18 12 0.0000 4 135 1035 6570 3780 West+North\001 +4 0 0 30 -1 18 12 0.0000 4 135 645 6570 3555 2-0-0-3\001 +4 1 0 40 -1 18 12 0.0000 4 180 1335 6075 -495 _targetContact\001 +4 1 0 40 -1 18 12 1.5708 4 135 1005 7605 -810 subContact\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 4815 -585 G\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 6165 -1665 G\001 diff --git a/katabatic/doc/images/GCellConfiguration-7.pdf b/katabatic/doc/images/GCellConfiguration-7.pdf new file mode 100644 index 0000000000000000000000000000000000000000..47da82b405d92e40273267553a4dc63e9b9117d3 GIT binary patch literal 6966 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 QuvC~#1$1;4J6Hk#1w-X@(EtDd literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/LegalConstruct-1.png b/katabatic/doc/images/LegalConstruct-1.png new file mode 100644 index 0000000000000000000000000000000000000000..0415dba1eb5f892266853bd10f330c57695a6233 GIT binary patch literal 11193 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 W{5Xuk;bEzQhQv64!x@+x0{;Pr0~HAX literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/LegalConstruct-2.png b/katabatic/doc/images/LegalConstruct-2.png new file mode 100644 index 0000000000000000000000000000000000000000..c8ba3a62a6a2dbfef9c1065f23ac89e2e2cdaeca GIT binary patch literal 12317 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 R{Z{zlD`(}r|35(J{{l4A(Lw+K literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/LegalConstruct-3.fig b/katabatic/doc/images/LegalConstruct-3.fig new file mode 100644 index 00000000..d0747f65 --- /dev/null +++ b/katabatic/doc/images/LegalConstruct-3.fig @@ -0,0 +1,55 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +6 1260 630 7875 3600 +2 2 3 1 0 7 30 -1 -1 8.000 0 0 -1 0 0 5 + 1575 900 4275 900 4275 3600 1575 3600 1575 900 +2 2 3 1 0 7 30 -1 -1 8.000 0 0 -1 0 0 5 + 5175 900 7875 900 7875 3600 5175 3600 5175 900 +2 1 0 2 -1 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 1350 2250 1935 2250 +2 1 0 2 -1 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2700 2160 2700 675 +2 4 0 2 18 7 50 -1 -1 0.000 0 0 7 0 0 5 + 2790 2385 2790 2160 1935 2160 1935 2385 2790 2385 +2 1 0 2 -1 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2025 3060 2025 2385 +2 4 0 2 18 7 50 -1 -1 0.000 0 0 7 0 0 5 + 2115 3240 2115 3060 1935 3060 1935 3240 2115 3240 +2 2 0 2 18 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 5535 2160 5715 2160 5715 2340 5535 2340 5535 2160 +2 2 0 2 -1 7 50 -1 45 0.000 0 0 -1 0 0 5 + 5580 3150 5670 3150 5670 2250 5580 2250 5580 3150 +2 2 0 2 -1 7 50 -1 45 0.000 0 0 -1 0 0 5 + 4950 2205 6300 2205 6300 2295 4950 2295 4950 2205 +2 2 0 2 18 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 6210 2160 6390 2160 6390 2340 6210 2340 6210 2160 +2 2 0 2 18 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 5535 3060 5715 3060 5715 3240 5535 3240 5535 3060 +2 1 0 1 18 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 3 0 1.00 60.00 120.00 + 5625 1620 5625 2160 +2 1 0 1 18 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 3 0 1.00 60.00 120.00 + 5625 1620 6210 2160 +2 2 0 2 -1 7 50 -1 45 0.000 0 0 -1 0 0 5 + 6255 2250 6345 2250 6345 675 6255 675 6255 2250 +4 1 0 40 -1 18 12 0.0000 4 135 255 1395 2205 G1\001 +4 1 0 40 -1 18 12 0.0000 4 135 210 2160 2790 L2\001 +4 1 18 40 -1 18 12 0.0000 4 135 555 2340 2115 AC-BL\001 +4 1 0 40 -1 18 12 0.0000 4 135 255 5040 2160 G1\001 +4 1 0 40 -1 18 12 0.0000 4 135 210 5805 2790 L2\001 +4 1 18 40 -1 18 12 0.0000 4 135 555 5580 1575 AC-BL\001 +4 1 0 40 -1 18 12 0.0000 4 135 255 2880 810 G3\001 +4 1 0 40 -1 18 12 0.0000 4 135 255 6525 810 G3\001 +-6 +2 2 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 5 + 1125 0 8325 0 8325 4050 1125 4050 1125 0 +4 1 0 30 -1 14 12 0.0000 4 120 2205 2790 270 AutoContact Structure\001 +4 1 0 30 -1 14 12 0.0000 4 180 1680 6390 270 Physical Mapping\001 diff --git a/katabatic/doc/images/LegalConstruct-3.pdf b/katabatic/doc/images/LegalConstruct-3.pdf new file mode 100644 index 0000000000000000000000000000000000000000..560b1b2582ef897acac425e030bb4b3e11516f95 GIT binary patch literal 4307 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 a5(p9)_}(cZ74+uhu)&47xw*5a3-n(kuT{JN literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/LegalConstruct-4.png b/katabatic/doc/images/LegalConstruct-4.png new file mode 100644 index 0000000000000000000000000000000000000000..902e745d6047f9165a7cdb8e9af365a2b42f4984 GIT binary patch literal 9533 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 S_*k%*&4_PPMBqPV!hZojBX1u7 literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/LegalConstruct-5.fig b/katabatic/doc/images/LegalConstruct-5.fig new file mode 100644 index 00000000..4899adff --- /dev/null +++ b/katabatic/doc/images/LegalConstruct-5.fig @@ -0,0 +1,94 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +2 2 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 5 + 1125 0 8325 0 8325 7875 1125 7875 1125 0 +2 2 3 1 0 7 30 -1 -1 8.000 0 0 -1 0 0 5 + 1575 4500 4275 4500 4275 7200 1575 7200 1575 4500 +2 2 3 1 0 7 30 -1 -1 8.000 0 0 -1 0 0 5 + 5175 4500 7875 4500 7875 7200 5175 7200 5175 4500 +2 1 0 2 -1 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 1350 5850 3735 5850 +2 1 0 2 -1 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 4500 4950 3960 4950 +2 2 3 1 0 7 30 -1 -1 8.000 0 0 -1 0 0 5 + 1575 900 4275 900 4275 3600 1575 3600 1575 900 +2 2 3 1 0 7 30 -1 -1 8.000 0 0 -1 0 0 5 + 5175 900 7875 900 7875 3600 5175 3600 5175 900 +2 1 0 2 -1 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2025 3825 2025 2385 +2 2 0 2 18 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 5535 2160 5715 2160 5715 2340 5535 2340 5535 2160 +2 4 0 2 18 7 50 -1 -1 0.000 0 0 7 0 0 5 + 2160 2385 2160 2160 1935 2160 1935 2385 2160 2385 +2 1 0 2 -1 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3825 2160 3825 675 +2 4 0 2 18 7 50 -1 -1 0.000 0 0 7 0 0 5 + 3960 2385 3960 2160 3735 2160 3735 2385 3960 2385 +2 1 0 2 -1 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3735 2250 2160 2250 +2 2 0 2 -1 7 50 -1 45 0.000 0 0 -1 0 0 5 + 7380 2250 7470 2250 7470 675 7380 675 7380 2250 +2 2 0 2 18 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 7335 2160 7515 2160 7515 2340 7335 2340 7335 2160 +2 2 0 2 -1 7 50 -1 45 0.000 0 0 -1 0 0 5 + 5580 3825 5670 3825 5670 2250 5580 2250 5580 3825 +2 1 0 2 -1 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3960 2250 4545 2250 +2 2 0 2 -1 7 50 -1 45 0.000 0 0 -1 0 0 5 + 5625 2205 7425 2205 7425 2295 5625 2295 5625 2205 +2 2 0 2 -1 7 50 -1 45 0.000 0 0 -1 0 0 5 + 7425 2205 8100 2205 8100 2295 7425 2295 7425 2205 +2 4 0 2 18 7 50 -1 -1 0.000 0 0 7 0 0 5 + 3960 5085 3960 4860 3735 4860 3735 5085 3960 5085 +2 1 0 2 -1 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3825 5760 3825 5085 +2 1 0 2 -1 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3825 4860 3825 4275 +2 4 0 2 18 7 50 -1 -1 0.000 0 0 7 0 0 5 + 3960 5985 3960 5760 3735 5760 3735 5985 3960 5985 +2 2 0 2 18 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 7335 4860 7515 4860 7515 5040 7335 5040 7335 4860 +2 2 0 2 18 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 7335 5760 7515 5760 7515 5940 7335 5940 7335 5760 +2 2 0 2 -1 7 50 -1 45 0.000 0 0 -1 0 0 5 + 7425 4905 8100 4905 8100 4995 7425 4995 7425 4905 +2 2 0 2 -1 7 50 -1 45 0.000 0 0 -1 0 0 5 + 7380 5850 7470 5850 7470 4950 7380 4950 7380 5850 +2 2 0 2 -1 7 50 -1 45 0.000 0 0 -1 0 0 5 + 7380 4950 7470 4950 7470 4275 7380 4275 7380 4950 +2 2 0 2 -1 7 50 -1 45 0.000 0 0 -1 0 0 5 + 4950 5805 7425 5805 7425 5895 4950 5895 4950 5805 +4 1 0 30 -1 14 12 0.0000 4 120 2205 2790 270 AutoContact Structure\001 +4 1 0 30 -1 14 12 0.0000 4 180 1680 6390 270 Physical Mapping\001 +4 1 0 40 -1 18 12 0.0000 4 135 255 5040 5760 G1\001 +4 1 0 40 -1 18 12 0.0000 4 135 255 5040 2160 G1\001 +4 1 0 40 -1 18 12 0.0000 4 135 255 4005 810 G3\001 +4 1 0 40 -1 18 12 0.0000 4 135 255 2205 3825 G2\001 +4 1 0 40 -1 18 12 0.0000 4 135 255 7650 810 G3\001 +4 1 0 40 -1 18 12 0.0000 4 135 255 5850 3825 G2\001 +4 1 18 40 -1 18 12 0.0000 4 135 600 2070 2070 AC-SW\001 +4 1 18 40 -1 18 12 0.0000 4 135 570 3825 2610 AC-NE\001 +4 1 18 40 -1 18 12 0.0000 4 135 600 5625 2070 AC-SW\001 +4 1 18 40 -1 18 12 0.0000 4 135 570 7425 2610 AC-NE\001 +4 1 0 40 -1 18 12 0.0000 4 135 255 4455 2205 G4\001 +4 1 0 40 -1 18 12 0.0000 4 135 255 8055 2160 G4\001 +4 1 0 40 -1 18 12 0.0000 4 135 255 4005 4410 G3\001 +4 1 0 40 -1 18 12 0.0000 4 135 255 4455 4905 G4\001 +4 1 18 40 -1 18 12 0.0000 4 135 600 3825 6210 AC-SW\001 +4 1 18 40 -1 18 12 0.0000 4 135 570 3330 5040 AC-NE\001 +4 1 18 40 -1 18 12 0.0000 4 135 600 7425 6210 AC-SW\001 +4 1 0 40 -1 18 12 0.0000 4 135 255 7650 4410 G3\001 +4 1 0 40 -1 18 12 0.0000 4 135 255 8055 4860 G4\001 +4 1 0 40 -1 18 12 0.0000 4 135 210 2925 2475 L1\001 +4 1 0 40 -1 18 12 0.0000 4 135 210 6525 2475 L1\001 +4 1 0 40 -1 18 12 0.0000 4 135 210 7200 5445 L1\001 +4 1 0 40 -1 18 12 0.0000 4 135 210 3645 5490 L1\001 +4 1 18 40 -1 18 12 0.0000 4 135 570 6975 5040 AC-NE\001 +4 1 0 40 -1 18 12 0.0000 4 135 255 1440 5805 G1\001 diff --git a/katabatic/doc/images/LegalConstruct-5.pdf b/katabatic/doc/images/LegalConstruct-5.pdf new file mode 100644 index 0000000000000000000000000000000000000000..1aa5a5bd1822612917db938ebd26305914d4b1eb GIT binary patch literal 8269 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 literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/LegalConstruct-5.png b/katabatic/doc/images/LegalConstruct-5.png new file mode 100644 index 0000000000000000000000000000000000000000..f7c7ec17d1d0974766b212d92dcea52af7f87371 GIT binary patch literal 9308 zcmeHsX*iqPyM9#n&hDVPi``u{b<`T$qH2h=rD)AmO+{4|F{B!#NKh@R-K7(1rj!~Y zEfPZ{>7*2)2>O#mS}GB#7$SlQ=cV0e_;Aku!@2&~`LaLcjccuV*R!6rp69vm`$@64 zwUF8@zZnDqNu9Mca|D4TmO!8lhkx4ujI`*5tbJ{|X6c3ifwtPLeI$CjFt)&;a`+k7 za3}cHaHP+5KhPN`dlicSI3gV3dp+=4xXOv6dRj-0Wk%-x0RruAK5KUB{Egg6Mo>oa z3H-124VAwt=soJ(C0Z$bbTF#z*l!w~??hOHh2iUiU#8tGU6peD_JX3G>;9h zJwJpgBz;{a5qE)%PthfBtMDXFZx@30+=+?b{vLAjw-F_kjbYN;6B@w3{XM+o!id*1}n z6t-<_s8avCNQRlnSMX(C!)jHIP=q>f%jpZjP4_fqRa#7sH56!=#^q3H%x&P1+kQte z?MGjIyZ(yv=6wey!#H|qPNxLf0&D5lQOI+#m_iur&T!?9J74H|%r6T|_EW4*9h$uc zXCAo#4VFC0wr;HXSEWUy-RrUA!I^aNV;MWbavzJm)tM+KV8Ded$7by+ zkuQ_DEzBC2nX)tdGNZp+8S>78mSuwJWzVK$5^AFRNdJn#(LOea*)Ipvo9Qe@tB$hq z#JIIK%I_V1$2}q=i2>O*`qO2UWR@#I*c9GcL` zzYj5H^fiIU>C~px6?;vP^#9}5{qLq1*tFdzAAbl#5xtnhn;RG>Qfc7bnz3PaM=ND~ zqt0o>^^cdIcCEb2KuZQZTZmxUe>mTVg(eYYE(yZ|Jk?vYd514)2^Sywg>@jCUTLzD z?t1%gLuT25i28Fr@-^*erw#9U)18JL{QaCY6&Eb83I;AN8zK(DdF95@%}KqJicf3Ljo^+A!p_%CKuzX?B?{X?UZG6_*iihyV?9zpN;%4^P=Cx1Q(b%j+?cp1IU# zj7jQYr<7El3(Buw1$KTIeMPLoD|b@%eEy(2*8ucn5ATO@9|m(kb6CMq55Oy4;L)?| zi<>waJ>7fXP>=D*k)IcJkju!DoJOOY6Ys^uKQXC^J#t1~wv1K&cmT+I^>z;jC=uJQ zIP!@wagz;K=?ifiuSHe}g4YdK7yMa~_?C*oW`_<*lZI~_;$ppe9{ZQJA3Y=gIy0hg z;m2Ktm56czIy8r@B9|~#8R3-X6?Yh%H@hco^@AtgDxCb zpP?ujPE z?gb7(mrn-E{w3tGdzJC|De+!a90=9{vTEuGF-A)of0ovFy8Q4 zP?+8QY?JcwUIqqkiUTnR-&nxFVbTu z@8b$ty8{^A{RU$F;0j~Jq8Zvq;>8<_=lQO#<;)^Zq`0K1!CQ`pH$?1Mos?l=yIkfN zbp=l}1(R>j5eva4j-rzk7itziFu~u1MxQrux3)@7meUY)8Y(|o`bE*Y;7ECOL>vRJ z6E6Jjo~P8cap;j7`abh<6D1w&fK&=ct*9_Pu5YE@O&JH}(^D*mqHbCa{w#rfZ#4`T5r6 zi^07YUx~neo-X^8$w;N?GEF|hrvNs&2{MLyqfW|f)JY>$)QoY&=4DMRFTl?%)bMI!=UkUCu)nndY4Cu00EFBdc=OHt@wR;A+5i$O$O=WkC zszbU%-tC|1g^{34BJz^Q4fb8~yWK}Q-S|zl6IM~IU?8hLGp>Ovik-jaRnIpi!S*mG z=mhvNnS{z(WT@L@mdA?-yOCZ0F2iD~#x^=>`+enm{rOZ*gl zGT}-p{jHqp<|)jDsm`;gOYbpP>zCT|?dX|!E+KRHmmt!2Gskb-;BIKRzin7bT1vMQ z=y(_?o8JO~3OdL{$)=q0stj9H`|Z84^SqmG{jMG{q<)g9xVz7*0G{m0`RJ_?dFR}eDIfxkq1iA31;`TM4Zb@zP1;XTt-a9BXqn8i4?MU%WFZL#)rx!6|OW&|n2k$r9=q-t; z=#Kl4xa7fM3%FOSID;^S^1c4DM=iw}2CPM02)S^rdd4xuA7+AHjFVNq&`4^x(I&dH z-d8sFyE2JAgYZ{u?yF{X-<7C{cjhDJsm0!Iexf#>Eh(@YUZ6&7PiYUV(g7#Lh_m46 zi@Gzh`mxX(iN}zEZy?a&xb2iI)2KH_JUAvwRklp;xW6q+>I$E#$S|%`RP;l*_8WBQT0^vJ$LM4GGx2( zzEuB;hM{^rSqw?NpL%E@E^(Nf54W=W>KaE8mc1GfS2b>WkmhdK@eDq4(zuq56J5X? zm8^JDZ79&<WaKbJbkpB&}mOK;E#%0~w663oGE$;=@_npUA3YgJHvH;io@| z!@0!~(waTsw}B%{*+rh+a)t<{vHaWCf;7`u2agzYihpz=t3_L*lqD5#Tuk>+bGFItCXQ=pg&7}^L!v}&X_hKT0xhMF$ZFk)3U!2i@YW5<^6jw#t zM=OV;`i=5Z-1sDlT3uSHxFfhi*1$BI^vl@IY&ZaXT)t%wW|^LaVh0^K+RE6;z4e;> z!5mbK>7PlZKq=MP8h38K532&bemVE9wIk_Cyk1-kT^}iQRj5qu$W27BQ9jCqfc)r6!qELH@_Kf8Tl*dNF=RIl+cwReq;NZL zW;8&P``$xzO$qtx?;(1Rf;MH(dmi)OHm!{Gy8dtgQg>`cMMk_c(a1Hna~ z7k_Lfl(X{AtqrVmi#PU~vXMwi+UR)Q$VN;ItfXM+jtCL$*QM|!PIsd5G~Lu!chbOu z?zE5c853Bc;Ko!(ut2N7&t2TlD}NZUPaddTKtWpG9L-f{NU7T{qWbSDD7_wz-9Z@Y3v%{7row~R|mMFt6d6fRhDXLl@YMD ze}hqYWLQE&@`pcb#}p7O`{Gg$EC3c{fSJ`%z$<{YQZ@Pa*4#aSNIcwI_%a9P1^9Oj zeegPOzNH#R96KYgYYsll9{+hXKza8O_BYq2sMi6z9tcXv>w6B~R!NEpxK)0=!IG;q zq{3~q1e}ydHS_&ZUa6L?XR<2`Rse8uiSksFeJ3U$B@$AWrIReLrw9XHmPU>2wAY+g zcI!R^9M>LhSe|7eL&X$b+%UMBrH!#IJqpxF(B3n{$__&r7#T%iRPQ}l;qR5q= z*ccK^y?huE)c;blFNjex*nJ1wHM1WBEG$Btu%Vmk z)N%j)K$(!bH<%L_sXlb9)(si`Cc~%zOWQ`Z*d5W_&Ma`v!FSKvWylHJ4#oC1-4#vR zY*EWmk%ht|K4;Y)D*#n{am=sYQIE}tP8E$EekBGijpj)DS^MHS@)wqa1qwpK&f1hd z(1g%|;5AcAMbP0PW$@cc7Z)utBW0CELm~IB)*mjR2RayX<)CoEKvThzuFFnLAJj$v zIfabAvE}RCIqJmSf{lHe65(AaA?W7+z>5EO{N%s+@2>@LILJo6bw&`4j#2*tP=`?E z;JSqtNK2LNU%-}^or}vh`(V@}g;IqnBS5a%RGe zT90JykL+7EX++ad!I(J*;4$ev^V;1d@=}*t%3%A&N{5~bA>IAV+M_IJr9G(Mo?q{s z|MX9y)wZ=zc+5cFVWm#hQ2_qnn7u`~55U}l9_P)AN-v_;C5$q2#zm99EYZ*xX=-x= z08mF%CLc9`Z(wiDl+Z>=9DP&LbB>c0MaaIHMwPGlWuazUsohiH%=Hc1mcHHuh)sop ztvx@FvyThL#Kfztg(EEAa1nsU8W?0Br&9uWl?bsuOoE~nobn8)FF40#iA^|-dOK2d z+F6YUjXr>)GN$e{7EIpCUAj6>09!6b4|GGdX(H97Odza#LQM~%LqwcJ>a+qi7Lr zkSlN)zZWxftre%K>yyPn=&YKposl^~Q}`YiqO5OgPsXB%AGrc|wEj|K=5}EnEMi*# z2T@<4b*O9$eUY8(9M1Zb-;WD%R^3C4p51)CV#3b{E<$9a`45l>Ad_x*Zp7$xJR9n0 zgmme`EO4>I%dH7fpQlD|h!4A1R{kmqZB$M0I*V|4*5z_8U5wdT-uIZ>xn~fyA($Jp z)ISxb@pQo|C5YCy6aQeown6cd^Hn~S&y<4|>LhEVR23-YDv_~EQw{h;1;+X8!@Ub9 zn`Tx{j%Z8e@UKN+yXs#o@-%Z4efOy5PxMg+vYfERzY5gs`hGXoT;>aL{(Cc#1tEg{ zo1j=1kIZ^%dHx6!H_>UZv~eMHbadRMpxV)wKKN;9;v+r*5#1@%LGPi(daK6DP?v2; zUdxrY61lUF=g{HGuD1KeM%-o`jK&8`3&c+ElDn^s*%cqh$*tl)e+aXd9p+(&t836l zi0zwz8~m5ajO$Ia%%$0xHpr1*$`>n)-IgtqO&BhS&~zColqn9Ea~Ed`Ur7I2o=g~R zIbf>SLe@?GKKBkw+$OH)mKN}folW-gg6bx)oo+Yk0en4Pg}JAUhiR=exos1owf9O!n}N3wY$&;c%4lof!SgkNjf7h`OGBJ5dH< zXPuP}wSm1(bMw26btJC$QBihyi`tgaN}XiB!oWtOGF3>67!VsMlRIIb<~+B<@@0TX z)4#moN??=Rv8Os|vxXu{!IIQ>y!ViJ* z(s~(I3|jgEV>lIuMq6<{Vtn!I@p=ObFgr6kzMbB}@KkpuZ9i;BwI(R!e5PahHhHC=$LN|n>vNS%A#IT^;JWHt!Z(BTRM zK=;6w?xTf{tcCE%qak|UEWqm*NZSB$0!TG=fDQpbh;jzc0RUwKIeVqPbQlH<+5vEE zg0=CMHK3*(de>S7s;M(6`9`aH;n2rU&z|aK2-(K=e0SmWhY4dk8^s4_Cs=b96--JeT`< z<$<+BI}N75pPqFFKI=D*SSr+E(-Sqri__Gj-!?`2r*833NiF41F56Ew*k8Ly0$=WzhAJr%YLNgXUESFAjcae1YM@(>2W z?*MECRmie=_#tMIsOvPsB%iUPiwif7A{@GbMY;*flrW-8E)Xv)H(mV z&W5gIQPRQh`VA1F?ukRoOY^@{M^pb?nwxl|hQ!VW!P5tdt4=b}?#_8HbDc_zNYb3> zVezG?E;UuJ7Pb278o~vx18eP+@+dFDMQAO-WUKvf_4N_ws@Z8ZWK1DTs{he}8`v|9+9PGgwsjt)c9E8=Pi@8szchd5w8nb<>>>Esj;}&ijEv!N;&y* z^;o`>T4uhPPowq2QsVBWJFJ21f_!>wRok)Th0w?TFcFk+=CywvZ?RKHMkRlW6o(TcZP4d=J@~!#U9K=gvS$jC3Gg3-(BijsN@s0 zGT)`(GS=U&-MXA|ggtM2`D5;{wtdRhA;=EG&SroxG+v=eM2DMWx;8@$bSoIZTTqdl zCc;uh6{6|b*L#--mVrcL43e;#bxa5QXO!|%zkrkLAEsF?tXub2=e2-W*Ou8-I#tS zLB2<2lHyY@?m@05s8DD01j$Pq&`STOhSh%quK(_5{U1z&;iiQ#QXcqv!kC3Dw__Nbgo?!S?O95R8n*{aLC35HnnErDY+8t`j)b~^^u<6ABb^znYwVT z-GMurNOjfzAhXO9@kCf;X7tch*P510-^aToPG3b8<5#jy`MMm7%|AVv$!(6Y*W31A~Nv-qG9(){jsA|D-8}wQ5wRPs^-f=jzu4DD(M#mqsV%!c| z|BxO1pfK%5=Fyuq%Z6*;_(r^W8f!Y{N=C?t4Yl)De4lpmkn6~bqGXG*cCS-=Gn=HI zZq}iXs!j`X9^6c|Nh^Od_hG{qPYN#B)xFF~o>09uV^7hgj>)%!HW#n&G?CcaYxr{` z>?ewuBs2rY?0xE;g6dPeMtjV6DX~;Sj>Y5X5}R}dc`E<#39E0Hlby-7=@u?85KFA- zp8eHZ>n4lc(l>qOn^KE8_*h=&S0!%yXrF&2S}?h_pkl&~3yzh6W*xUm{VN}DRW%M5 zCp?;``6cYRkE2b6w#@|}ZjVmH_V( zC(2%k{*Zg`v01#wKjx(*d|#!H(rHhaFK*Lc77=BFLA#;mFT^jZ?)n?7zA zT0Y5VcSlr0y~AdRo?9$ASL|Q@M7*R~JuK9`B>VonVYc5&4#TbA9Nj+4-FvpB$+0xk z=VptV{N@Z%n71swu=V)#w)Q)Bn_o8WA}GX%k}G8rbs`*sf?<-!hj9TG3V}hIQZX>Wk`9DODUCXg4yQDLj(ll#xIe{& zAb_x7B!Eg}z;w4n#>1Zhlmz1}bAcu9YOoyVNDBfCg}8ucpiu*Nj{}j;EOv`-rUTl5 zT`*^u21Y(p$~ABZ#F{OILSdjG4yeRfZMvmc?^4}L7a1dqR!8)x=(fIZzQAyPpVbgD z-`5Am#A2Od&Iuj;N(B(RPTHr2^QvbQMjFAw=E$Y)R0wX&0-E^FmLx z#c95m26-xCQ>U~nsn}$dN9QdWN}CJ{H~BE1h0icuFxG?L+!Eshgx+;eODAiIcD%#= zarej0{&I(ecFx&opHsf4NaE$Ebjn%r-KuPpobq9RW1!eTwB=Gl2EPSQzk4a+azcE( zDQy}Z{jAKAS&5&2A<8RVdV2Qh`1r-!ouR0;LpCga+IeNcb=+)jOz^&A^2S{bb>7z6 zwv(rBoxIz=Z`4`KvqJ}2EkfVeUJWlS@Fe!u2W`i~)&~)-bF_ z7)88gy1y8*P$_33H6ai?2SWVg!Wg#UVT~gCj#b;nKf__&mmoF^dhR~&iQx#n4r0J66GT}D z0bp@?TsTELxcU3S9+7GdqY0;#u?#H4c+M#92rhl#wG^XNt6ag&(7|;&j-o>)mPk_y2!#m(LVG_jpT{G3umaY}FoJcI{lKao87U9|*bQYEE&#OB zPlmAvkf97k*+3b}Fbp-ChY>BIRVBR@zUn`VYxFJ`e&U-w2V&cn^^=E(A&#`9a`(qkVClF!qBW0Rb4=M+kXF z^9UY$yEdGMk!)+wU&b?%5hQ68BSIiB!hjHwMluo;7}-LSZ^;C(G%*@K3J(*`e@1DJ%{YD!b>M)++IRgTL z81-~DZ-YQIzkoyH^a;R%xFr`2T<9O@S|LH8vj)EpnvuaOL%=A2(y~OEB3w}ZcYU2f zTBgQ=I`q775RnTxVg}U!_F#B1U=Bs4hkSkZ@ajV@~P_7`6 z7InRuZuv0^JbY?}|0Tl+Or5g`^H5Tk3bIQg(=`9((4OdTq*lFfb=t0ZX=|@YiXx-t z+xJc?mpso>U)`}SZ7a?tY{|H|(IrmZxT$i>S--q(Yd|_JO!;M50!E1#);6nkC69Tr zFHmS844-M9NcbLZ!>`=F3WYNuiCvG2&s&|sytOn~yuNuDTH2hFtI#li;fun^k!1_l z#G74**O|{7+C}Y&9K49NtVRsj-jG@tI0BYI?|!~p7=IO9qNS)^pN)_wa48WTKU8&e zCo;FO$MSLNOjW>bC`i#$u|II=G_6&=z0t-F6(&x9uTXr4LR^=zfl_--2|ocB8_HR$;v7R0cM2V;*^oQ?E?e^FOmHcUOexQ`mq&Eux8{;(=~JJ+43 z=9gI0czI)9n8TBFdafxF7n4bi4wo=Z>ZFxESX23ch_G4^6vdX>$Vyp&@mF>Zdd9_q zm$8;GYmt~`Jobu1XKavi(Be7i?}9o;DB)LdYSnU@+@-_Ip~vJUtCoQ8MG8d!xu0=V z8|p@yQ_OlViZojZ5ckpDBZSnl5(P6!FVq=Cr*(C_BiAw@tYixs3KZT@=4Yc49+YKo zxSzv*5Ha+3rdG6m!r-QRxsDWHp@oM&wEPO1kG0{;*@(xoi?e_7Y&csPHr@0%LT5@D z-qL@Mv(4e|vLWyJ))fs|Ukim9l8h+R{(Tz`gI&_7+r`m<%u+OXxbZdm_{dlS1pfE5`d{Gwm| zr#$He+&<6;DT+NKLCyf6R7z@cGi54~=c;9&e?5nvv({hdtq{(-n$Ynw>asb@fi>_g z4mZ>3-qz(ja07nq+fxGD44dhuOfdLR6vowXLE3LO>yZ@4(-O78`+ zJru(EkFNC7OijK$IIn?A%1B2T@lwr5xvb{I$O7|*$nUgJEQMdNWT)8oG7ve`YvI@R z=F(eUsMH(E9*dx)D3nojW?*m$lrVGhWe6_u(@lUL9xkJ2WEwx&_2lVytZvWCSJR%S zBl=~UX8O-Rq~bO>B#E@0b;%?;{i5rB01h{x2F~pWk7NciJ=Sz2nB&wM022_MWXbOs zcKi_*GjC1)eVTXWaGl0MYL42xost04hcGQ8?B+) zT&g+nGi~IVO^+wz_zCv>Rlh@BV8uSZ)p4g=;TNoqw^iGfhxD0kKdDVe4AD}@0BkSh zwvHr#{{lb*OqAYA)1}qDz0cc}Z~gvOze4$=J*8hjSYtEQ0(w-CUWNBGIMV&XHRx=* zPkHt<^6(|vD1)cWTJ~GU{W?t^P~bmGxM(sN(T8%lXDvhblD#3cwU-uHUo&)Zfu4T@ z0f5$meUv!H1eASS-lotR7bfS5pfZd8hMvhRP#rddiukK3h$sJ%5xr*-qMBEMsGfkm zCH%3tl%7Eg*mlf_WqJ3Bv_j>F@n7I6w4GxFv%$_kDdQd0t`nM_lrr4!4qLDrIGf&PTl3t~a}9VRwF!TME`n4zD1} zqJaBx{JXkqv``0Q*TIixa|7zi*J^PYX-wb`T&vMOs;9RZcq~=#n%R<$nrmcGI6sMs zs7!S`)^EYgt4gv-q$ughex+%<+MsZ)r=&Np^v4g2R-j?fv4(lT!3vf_5_r0ITN%j# zOBdxmJ_zlIFXilc;810_A#nGu2^bCu`&AcXo39$v8Mqr`jQ!yK)qq#1+g@}fv@RVY ze?b2;u)!&PpyP?S-=k5E!}@PAOR>}F0=qQfv97?5+b1aN(5Nf{bJkcc?KPEf%_ zg_YkbLTQz()E?1~ci=0`YEv}&xs}N+8a!j1h>#k?X3Y*1R;|Q}#GIU|VZm%X5iq3c z2zWA-H!N)5Y)rju()L4e9hbkXnCl{tttGqw(RzRO4Svr{0&IC{pjY#Mm@Rcd1fp9+=N2v&~+0?qk(N zyS;I`o(4w>ayZ&fl3(l_H@CqH)Gj{x^{+mg1Z`gf2Eo#>Gq&ABq~%n^kivtX+qQUi z^Ylo6`Y@a6)LHsZa&pBOcb~)f9a~wo#oCWq>~0U7zZ93Xqj35r#jv^cmVGuOW)Z(n zo0R1EWA4Z>*>#!n?|o|Psy;fxYN)#B1Ad9Y1y^$@&o<|`ieU>6n$@gxRINmc`Bovj z4MajjRMTckfJ)eLoQMF?nIyikRJ7}|aVhW0ttEUv!h;@u6wcZ89jAVF(}P0b(_c=5~9BZ4^?Gx^hoHOAi@2tJZsIQMm^v5vM_$hnP(g}kQr(URSn}%&a>Y$-wR$pA#6Vq2R}j{8?>~d z!^n0|D{#|3dCL>&@O(vy&+K^vZ1+Mw+{^}%G1G4_yM1cIBTYu#?F#k2`dYbdn+@Fu zOJ81a5+Fw=M|<+cTF0)4P0u-c@*KorcRXNbtjqzm(gH6C!Sx(;@as}j8OM*Z(H4%V8<_2rHl<8tpvQ3> z%1HiQUT@_9`whC!#GaWMGnA`_KRclqmACnsX{A5k^bM#rP;hYoAJwht zY?wmM=b7HN&6im+Srify3p>B5g|_2{<}Lqjivp}|$rUvC3Je4LR&g>J)3ELHsq5fZ z;RliaFx#980kxO5%)SP`EAl{7wFvjg-enX?9_TyR<&6t^8mNI2|9oj~M1ioH)BTfs zi!e~(5tVkR?^$uL{DQgB^}rwdzDoH^>5~~6hH7oIRl|90_R|{Pb|qMaK)m2t4Rfdz zQRZyejh$t95<&@TsCCgw^#zmD5zw58KVFB5D@&Tn+k3qicT^skTImddQZC^*(fnK1 z)K&)0H((ps)}vP=JmQB*BqRWj#3Y!=1P@PqogCc(9=h)5%Gqv9Va*x#>WA-rk6^e+ zFem@G5lzr_fat@Ji ztJ^c{r+U8!QNy4j^wNUe2+XWQ$Gxc?=#HNZpi+~_38P$hNSOq1#Q=hQW2I#@q&&!DQg&E}r*o#dN9>sdC7N zvqJv@bawm%pe?}L(E4}uz2JXKB0nq;D1kg4v3SBJ#vft|Qstlbp8?Z#IZpPevMcIWibncF!Or^gu z0-$lx0BF(V36JpD(IPtUN&*m4v2UX;iGNiPU>T5DsN18w`b9K<$}N;_XW%clL`3b0 zw75^c2`I4K$Lb|nk458xij?U;bBj^NjN#z&?^q&Pt;w+IcEgQ`W10{ln%{cA}-`h(F|&qc-Z+@i+P&Aiuyr$)sT zg;#zRDZmY8y9s*8_7|vZLhe8ODpFmJ5-_x8{)D=*UR(KYFgv3BL_kn6ceI}Ey3C|+ za~?c;opw2qlWvo%$MYLhe3u@VO@<4&Tp9=U`Ip&A?Pho=5u@6_^X6ZKtKNp}y1AFh zdwzT+9}#{{E@mm{-B9&}HPtC^aXue?-~$!)`nA>}91fY+uVe_lDBf^#Sdjz>Jx##1p?h~r|uuBS*Z7lI`Ko%z}5puPs>oV`o^8d(f|LO7bjKzxp^`6j`6J^ z^V^z{Lx0tJQ1lerLaLmM00_H}paVU44Cu)znEKzBzbW`T3;zBP{;CC@jqRu4xLL=Q Ie=l191;X)0C;$Ke literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/Makefile.am b/katabatic/doc/images/Makefile.am new file mode 100644 index 00000000..68eb5a0e --- /dev/null +++ b/katabatic/doc/images/Makefile.am @@ -0,0 +1,65 @@ + + +EXTRA_DIST = AutoInvalidate-1.fig \ + AutoContact-1.fig \ + AutoContact-2.fig \ + AutoContact-3.fig \ + AutoContactG1-1.fig \ + AutoContactG2-1.fig \ + AutoContactG3-1.fig \ + AutoContactG3-2.fig \ + AutoContactG3-3.fig \ + AutoContactG3-4.fig \ + AutoContactG4-1.fig \ + AutoContactG4-2.fig \ + AutoContactG4-3.fig \ + AutoContactG4-4.fig \ + AutoContactG4-5.fig \ + LegalConstruct-1.fig \ + LegalConstruct-2.fig \ + LegalConstruct-3.fig \ + LegalConstruct-4.fig \ + LegalConstruct-5.fig \ + LegalConstruct-6.fig \ + AutoSegmentCollapse-1.fig \ + AutoSegmentCollapse-2.fig \ + AutoSegmentCollapse-3.fig \ + AutoSegmentCollapse-4.fig \ + AutoSegmentCollapse-5.fig \ + AutoSegmentCollapse-6.fig \ + PerpandicularState-1.fig \ + PerpandicularState-2.fig \ + PerpandicularState-3.fig \ + PerpandicularState-4.fig \ + NetConstraints-1.fig \ + NetConstraints-2.fig \ + NetConstraints-3.fig \ + NetConstraints-4.fig \ + NetOptimals-1.fig \ + NetOptimals-2.fig \ + NetOptimals-3.fig \ + NetOptimals-4.fig \ + SplitAutoContact-1.fig \ + SplitAutoContact-2.fig \ + SplitAutoContact-3.fig \ + SplitAutoContact-4.fig \ + SplitAutoContact-5.fig \ + SplitAutoContact-6.fig \ + FCellConfiguration-1.fig \ + FCellConfiguration-2.fig \ + FCellConfiguration-3.fig \ + FCellConfiguration-4.fig \ + FCellConfiguration-5.fig \ + FCellConfiguration-6.fig \ + FCellConfiguration-7.fig \ + FCellConfiguration-10.fig \ + FCellConfiguration-11.fig \ + FCellConfiguration-12.fig \ + FCellConfiguration-13.fig \ + FCellConfiguration-14.fig \ + FCellConfiguration-15.fig \ + FCellConfiguration-16.fig \ + FCellConfiguration-17.fig \ + FCellConfiguration-18.fig \ + FCellConfiguration-19.fig \ + FCellConfiguration-20.fig diff --git a/katabatic/doc/images/Makefile.in b/katabatic/doc/images/Makefile.in new file mode 100644 index 00000000..19113af0 --- /dev/null +++ b/katabatic/doc/images/Makefile.in @@ -0,0 +1,403 @@ +# Makefile.in generated by automake 1.9.6 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../.. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = doc/images +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +SOURCES = +DIST_SOURCES = +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CORIOLIS_CFLAGS = @CORIOLIS_CFLAGS@ +CORIOLIS_CONFIG = @CORIOLIS_CONFIG@ +CORIOLIS_LIBS = @CORIOLIS_LIBS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DEVEL_LIBS = @DEVEL_LIBS@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +GTK_CFLAGS = @GTK_CFLAGS@ +GTK_CONFIG = @GTK_CONFIG@ +GTK_LIBS = @GTK_LIBS@ +HURRICANE_CFLAGS = @HURRICANE_CFLAGS@ +HURRICANE_LIBS = @HURRICANE_LIBS@ +HUR_CONFIG = @HUR_CONFIG@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +KATABATIC_DLL_VERSION = @KATABATIC_DLL_VERSION@ +LDFLAGS = @LDFLAGS@ +LEFDEF_CFLAGS = @LEFDEF_CFLAGS@ +LEFDEF_CONFIG = @LEFDEF_CONFIG@ +LEFDEF_LIBS = @LEFDEF_LIBS@ +LEFDEF_LIBXXS = @LEFDEF_LIBXXS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_LIBS = @PYTHON_LIBS@ +PYTHON_LIB_PATH = @PYTHON_LIB_PATH@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SUNLD_FALSE = @SUNLD_FALSE@ +SUNLD_TRUE = @SUNLD_TRUE@ +VERSION = @VERSION@ +XML2_CONFIG = @XML2_CONFIG@ +XML_CPPFLAGS = @XML_CPPFLAGS@ +XML_LIBS = @XML_LIBS@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +EXTRA_DIST = AutoInvalidate-1.fig \ + AutoContact-1.fig \ + AutoContact-2.fig \ + AutoContact-3.fig \ + AutoContactG1-1.fig \ + AutoContactG2-1.fig \ + AutoContactG3-1.fig \ + AutoContactG3-2.fig \ + AutoContactG3-3.fig \ + AutoContactG3-4.fig \ + AutoContactG4-1.fig \ + AutoContactG4-2.fig \ + AutoContactG4-3.fig \ + AutoContactG4-4.fig \ + AutoContactG4-5.fig \ + LegalConstruct-1.fig \ + LegalConstruct-2.fig \ + LegalConstruct-3.fig \ + LegalConstruct-4.fig \ + LegalConstruct-5.fig \ + LegalConstruct-6.fig \ + AutoSegmentCollapse-1.fig \ + AutoSegmentCollapse-2.fig \ + AutoSegmentCollapse-3.fig \ + AutoSegmentCollapse-4.fig \ + AutoSegmentCollapse-5.fig \ + AutoSegmentCollapse-6.fig \ + PerpandicularState-1.fig \ + PerpandicularState-2.fig \ + PerpandicularState-3.fig \ + PerpandicularState-4.fig \ + NetConstraints-1.fig \ + NetConstraints-2.fig \ + NetConstraints-3.fig \ + NetConstraints-4.fig \ + NetOptimals-1.fig \ + NetOptimals-2.fig \ + NetOptimals-3.fig \ + NetOptimals-4.fig \ + SplitAutoContact-1.fig \ + SplitAutoContact-2.fig \ + SplitAutoContact-3.fig \ + SplitAutoContact-4.fig \ + SplitAutoContact-5.fig \ + SplitAutoContact-6.fig \ + FCellConfiguration-1.fig \ + FCellConfiguration-2.fig \ + FCellConfiguration-3.fig \ + FCellConfiguration-4.fig \ + FCellConfiguration-5.fig \ + FCellConfiguration-6.fig \ + FCellConfiguration-7.fig \ + FCellConfiguration-10.fig \ + FCellConfiguration-11.fig \ + FCellConfiguration-12.fig \ + FCellConfiguration-13.fig \ + FCellConfiguration-14.fig \ + FCellConfiguration-15.fig \ + FCellConfiguration-16.fig \ + FCellConfiguration-17.fig \ + FCellConfiguration-18.fig \ + FCellConfiguration-19.fig \ + FCellConfiguration-20.fig + +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign doc/images/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign doc/images/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-libtool + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-exec install-exec-am \ + install-info install-info-am install-man install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am \ + uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/katabatic/doc/images/NetConstraints-1.fig b/katabatic/doc/images/NetConstraints-1.fig new file mode 100644 index 00000000..55487b6a --- /dev/null +++ b/katabatic/doc/images/NetConstraints-1.fig @@ -0,0 +1,78 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +6 0 4185 4275 4950 +1 4 0 2 0 0 40 -1 20 0.000 1 0.0000 270 4770 90 90 180 4770 360 4770 +2 1 0 1 12 7 40 -1 -1 0.000 0 0 -1 1 0 2 + 3 1 1.00 60.00 120.00 + 45 4590 495 4590 +2 1 0 1 12 7 40 -1 -1 0.000 0 0 -1 1 1 2 + 3 1 1.00 60.00 120.00 + 3 1 1.00 60.00 120.00 + 45 4365 495 4365 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2925 4185 2925 4950 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 3 + 0 4185 4275 4185 4275 4950 +4 0 0 40 -1 18 12 0.0000 4 180 1230 720 4860 Starting Point\001 +4 0 0 40 -1 18 12 0.0000 4 180 2025 720 4635 Constraint Propagation\001 +4 0 0 40 -1 18 12 0.0000 4 180 735 720 4410 Collapse\001 +4 0 0 40 -1 18 12 0.0000 4 135 165 3195 4500 L:\001 +4 0 0 40 -1 18 12 0.0000 4 135 210 3195 4770 G:\001 +4 0 0 40 -1 18 12 0.0000 4 135 465 3510 4500 Local\001 +4 0 0 40 -1 18 12 0.0000 4 135 555 3510 4770 Global\001 +-6 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 450 2700 90 90 360 2700 540 2700 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 2700 2700 90 90 2610 2700 2790 2700 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 1575 3825 90 90 1485 3825 1665 3825 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 2700 1575 90 90 2610 1575 2790 1575 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 3825 1575 90 90 3735 1575 3915 1575 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 3825 450 90 90 3735 450 3915 450 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 4950 450 90 90 4860 450 5040 450 +1 4 0 2 0 0 40 -1 20 0.000 1 0.0000 1575 2700 90 90 1485 2700 1665 2700 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 0 0 5400 0 5400 4950 0 4950 0 0 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 540 2700 1485 2700 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 1665 2700 2610 2700 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 1575 2790 1575 3735 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2700 1665 2700 2610 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2790 1575 3735 1575 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3825 540 3825 1485 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3915 450 4860 450 +2 1 0 1 12 7 40 -1 -1 0.000 0 0 7 1 0 2 + 3 1 1.00 60.00 120.00 + 1350 2790 675 2790 +2 1 0 1 12 7 40 -1 -1 0.000 0 0 7 1 0 2 + 3 1 1.00 60.00 120.00 + 1485 2925 1485 3600 +2 1 0 1 12 7 40 -1 -1 0.000 0 0 7 1 0 2 + 3 1 1.00 60.00 120.00 + 1800 2790 2475 2790 +3 2 0 1 12 7 40 -1 -1 0.000 0 1 1 4 + 3 1 1.00 60.00 120.00 + 3 1 1.00 60.00 120.00 + 3735 495 3600 765 3600 1215 3780 1530 + 0.000 -1.000 -1.000 0.000 +4 1 0 40 -1 18 12 0.0000 4 135 150 990 2655 G\001 +4 1 0 40 -1 18 12 0.0000 4 135 150 1710 3330 G\001 +4 1 0 40 -1 18 12 0.0000 4 135 150 3240 1530 G\001 +4 1 0 40 -1 18 12 0.0000 4 135 150 4365 405 G\001 +4 1 0 40 -1 18 12 0.0000 4 135 105 2115 2655 L\001 +4 1 0 40 -1 18 12 0.0000 4 135 105 2835 2205 L\001 +4 1 0 40 -1 18 12 0.0000 4 135 105 3960 1080 L\001 +4 1 12 40 -1 19 12 0.0000 4 135 240 1035 2970 dX\001 +4 1 12 40 -1 19 12 0.0000 4 135 210 1305 3330 dY\001 +4 1 12 40 -1 19 12 0.0000 4 135 240 2115 2970 dX\001 diff --git a/katabatic/doc/images/NetConstraints-1.pdf b/katabatic/doc/images/NetConstraints-1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..9d030919ccea90b5122ea76699bcc254e70e2ec8 GIT binary patch literal 3062 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 E0~+J@1^@s6 literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/NetConstraints-1.png b/katabatic/doc/images/NetConstraints-1.png new file mode 100644 index 0000000000000000000000000000000000000000..1595213f4c92bb65ca7bc8313840b72eb24e2ae4 GIT binary patch literal 5012 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 literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/NetConstraints-3.fig b/katabatic/doc/images/NetConstraints-3.fig new file mode 100644 index 00000000..fcce99ce --- /dev/null +++ b/katabatic/doc/images/NetConstraints-3.fig @@ -0,0 +1,72 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +6 0 3060 4275 3825 +1 4 0 2 0 0 40 -1 20 0.000 1 0.0000 270 3645 90 90 180 3645 360 3645 +2 1 0 1 12 7 40 -1 -1 0.000 0 0 -1 1 0 2 + 3 1 1.00 60.00 120.00 + 45 3465 495 3465 +2 1 0 1 12 7 40 -1 -1 0.000 0 0 -1 1 1 2 + 3 1 1.00 60.00 120.00 + 3 1 1.00 60.00 120.00 + 45 3240 495 3240 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2925 3060 2925 3825 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 3 + 0 3060 4275 3060 4275 3825 +4 0 0 40 -1 18 12 0.0000 4 180 1230 720 3735 Starting Point\001 +4 0 0 40 -1 18 12 0.0000 4 180 2025 720 3510 Constraint Propagation\001 +4 0 0 40 -1 18 12 0.0000 4 180 735 720 3285 Collapse\001 +4 0 0 40 -1 18 12 0.0000 4 135 165 3195 3375 L:\001 +4 0 0 40 -1 18 12 0.0000 4 135 210 3195 3645 G:\001 +4 0 0 40 -1 18 12 0.0000 4 135 465 3510 3375 Local\001 +4 0 0 40 -1 18 12 0.0000 4 135 555 3510 3645 Global\001 +-6 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 450 1575 90 90 360 1575 540 1575 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 1575 2700 90 90 1485 2700 1665 2700 +1 4 0 2 0 0 40 -1 20 0.000 1 0.0000 1575 1575 90 90 1485 1575 1665 1575 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 1575 1575 135 135 1440 1575 1710 1575 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 1575 450 90 90 1485 450 1665 450 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 2700 450 90 90 2610 450 2790 450 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 2700 450 135 135 2565 450 2835 450 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 3825 450 90 90 3735 450 3915 450 +2 1 0 1 12 7 40 -1 -1 0.000 0 0 7 1 0 2 + 3 1 1.00 60.00 120.00 + 1350 1665 675 1665 +2 1 0 1 12 7 40 -1 -1 0.000 0 0 7 1 0 2 + 3 1 1.00 60.00 120.00 + 1485 1800 1485 2475 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 0 0 5400 0 5400 3825 0 3825 0 0 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 1665 450 2565 450 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2835 450 3735 450 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 1575 540 1575 1440 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 540 1575 1440 1575 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 1575 1710 1575 2610 +2 1 0 1 12 7 40 -1 -1 0.000 0 0 7 1 0 2 + 3 1 1.00 60.00 120.00 + 1485 1350 1485 675 +3 2 0 1 12 7 40 -1 -1 0.000 0 1 1 4 + 3 1 1.00 60.00 120.00 + 3 1 1.00 60.00 120.00 + 1665 495 2025 765 2025 1260 1665 1485 + 0.000 -1.000 -1.000 0.000 +4 1 0 40 -1 18 12 0.0000 4 135 150 990 1530 G\001 +4 1 0 40 -1 18 12 0.0000 4 135 150 1710 2205 G\001 +4 1 12 40 -1 19 12 0.0000 4 135 240 1035 1845 dX\001 +4 1 12 40 -1 19 12 0.0000 4 135 210 1305 2205 dY\001 +4 1 0 40 -1 18 12 0.0000 4 135 150 2115 405 G\001 +4 1 0 40 -1 18 12 0.0000 4 135 150 3240 405 G\001 +4 1 0 40 -1 18 12 0.0000 4 135 105 1710 1080 L\001 +4 1 12 40 -1 19 12 0.0000 4 135 210 1305 1125 dY\001 diff --git a/katabatic/doc/images/NetConstraints-3.pdf b/katabatic/doc/images/NetConstraints-3.pdf new file mode 100644 index 0000000000000000000000000000000000000000..e19d367869156b445673e6d05640bedebf59e9e4 GIT binary patch literal 3119 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 literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/NetConstraints-4.fig b/katabatic/doc/images/NetConstraints-4.fig new file mode 100644 index 00000000..63a05d53 --- /dev/null +++ b/katabatic/doc/images/NetConstraints-4.fig @@ -0,0 +1,68 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +6 0 2160 4275 2925 +1 4 0 2 0 0 40 -1 20 0.000 1 0.0000 270 2745 90 90 180 2745 360 2745 +2 1 0 1 12 7 40 -1 -1 0.000 0 0 -1 1 0 2 + 3 1 1.00 60.00 120.00 + 45 2565 495 2565 +2 1 0 1 12 7 40 -1 -1 0.000 0 0 -1 1 1 2 + 3 1 1.00 60.00 120.00 + 3 1 1.00 60.00 120.00 + 45 2340 495 2340 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2925 2160 2925 2925 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 3 + 0 2160 4275 2160 4275 2925 +4 0 0 40 -1 18 12 0.0000 4 180 1230 720 2835 Starting Point\001 +4 0 0 40 -1 18 12 0.0000 4 180 2025 720 2610 Constraint Propagation\001 +4 0 0 40 -1 18 12 0.0000 4 180 735 720 2385 Collapse\001 +4 0 0 40 -1 18 12 0.0000 4 135 165 3195 2475 L:\001 +4 0 0 40 -1 18 12 0.0000 4 135 210 3195 2745 G:\001 +4 0 0 40 -1 18 12 0.0000 4 135 465 3510 2475 Local\001 +4 0 0 40 -1 18 12 0.0000 4 135 555 3510 2745 Global\001 +-6 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 450 675 90 90 360 675 540 675 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 1575 1800 90 90 1485 1800 1665 1800 +1 4 0 2 0 0 40 -1 20 0.000 1 0.0000 1575 675 90 90 1485 675 1665 675 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 1575 675 135 135 1440 675 1710 675 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 1575 675 180 180 1395 675 1755 675 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 2700 675 90 90 2610 675 2790 675 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 2700 675 135 135 2565 675 2835 675 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 3825 675 90 90 3735 675 3915 675 +2 1 0 1 12 7 40 -1 -1 0.000 0 0 7 1 0 2 + 3 1 1.00 60.00 120.00 + 1350 765 675 765 +2 1 0 1 12 7 40 -1 -1 0.000 0 0 7 1 0 2 + 3 1 1.00 60.00 120.00 + 1485 900 1485 1575 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 540 675 1395 675 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 1575 855 1575 1710 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2835 675 3735 675 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 1755 675 2565 675 +2 1 0 1 12 7 40 -1 -1 0.000 0 0 7 0 1 2 + 3 1 1.00 60.00 120.00 + 2475 765 1800 765 +2 1 0 1 12 7 40 -1 -1 0.000 0 0 7 0 1 2 + 3 1 1.00 60.00 120.00 + 3600 765 2925 765 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 0 0 5400 0 5400 2925 0 2925 0 0 +4 1 0 40 -1 18 12 0.0000 4 135 150 990 630 G\001 +4 1 0 40 -1 18 12 0.0000 4 135 150 1710 1305 G\001 +4 1 12 40 -1 19 12 0.0000 4 135 240 1035 945 dX\001 +4 1 12 40 -1 19 12 0.0000 4 135 210 1305 1305 dY\001 +4 1 0 40 -1 18 12 0.0000 4 135 150 2115 630 G\001 +4 1 0 40 -1 18 12 0.0000 4 135 150 3240 630 G\001 +4 1 12 40 -1 19 12 0.0000 4 135 240 2070 945 dX\001 +4 1 12 40 -1 19 12 0.0000 4 135 240 3195 945 dX\001 diff --git a/katabatic/doc/images/NetConstraints-4.pdf b/katabatic/doc/images/NetConstraints-4.pdf new file mode 100644 index 0000000000000000000000000000000000000000..457a87796f8c0204dc4d9133b9910b841ce66abf GIT binary patch literal 2614 zcma)8XH-+!79OP-F5p;jjUvL8j)gQ6!ibcJ2%#hd5HSMAEmWix%U=NTK%|vFT>x1^3=R`AH3j$r9z;I? zh%>r(+i><8Dcz~`oL~zV?|ypcWoI^u@-hKBd<}7ss~0n}|IBHE{Or^mYyG*PGS87; z_zJI3TCq(#6E*8*Ol-5fQq5imSK9SfD!hA|V$W%EzOZs!pDEi6+W>jOjrY2oI6`rO245Rgco_%)|8^wlj6*Hpuovnu?__$g*Mj zO1JJ8g?5rPGRZc(*LMFk<@{G>@7|D{%b$!ZPMg-+tg48#?dqsyUQ|CMxgW#=G8JJF){@;2JxM2+}}Z6{ibVk7|;1v!*d<_=6C>XCu$ z6Io<#fEKweS?Gt{UwnMvqyybhCqVb!QWZbTq{gbt=|P=`nq*?}S3mfO`qf^Sg+oo& zN9En|!}ehG_^@P=Sp58W!iRbF|g zV$HN2W2>5>S?ElHkxH}n!$AjereyPTq^INv>P^`=+-*!z#&fTwna2j-~rd@RZi%742(0a^%FNelM(E zHR5`M+p9*r7-quQT7zsvqWszu+-^(vF}-?aY>!Z0ZRcp9hz$OPOjV) zTbZpTqW3`mpVna{>yeL=K5}%dfr8Ov(nG+fdz1NL1Rk;WKXw4|k>+fbuFtVR8d?w) zb<<$?%oWaWf5wIm2QWxm-{+-<6Z3*Q5o(SI6N5fnrf>cezPB=NlYe-P)iR%S&~>;> zac+-XrA4JL-pVy_NrP%#->^!+8trhycR0-X#u9I#a>h^(Nkk&%pKQJ=?;&bAwZb_O zR9@P0jc}vAz3X~ZxG_TX^vZ{vpnR3%sJNcxb>h;+(fu2HjU%XO8rh?J-DNIV++R{F zSsf5dN?hzw-0cvPV3}bPhIJgOE-QX;28TG1x!!f6O!48>z9v5(Zk)a(zPhG4A;Cg3 zxPG?4q=peJ=Q4EAC7X2?M;nuzq~>NpYN>sZ+DfJ5v+2|K6?n?8BFuP~9QCzi(&EQw z+TC;FoO`r35(nQrbB@UiYme}=WX)Kr>i0HUwOA9Y)go`RcF#CgwBb9G8b;SS6>QFu z12lr47Y}9V#vOYI*5zubuAP;PpNsC;&d?(H`R8Wg@ED6Q#=?3r`SxUS$`haU)#vX0 zO496ZXW6ak zTqC{wm0cmEgcX`2T%p#A>e;^n9d7pYvq%ydCzQG30CtgbQ!b$)q$pIq$6C3h6tz76 zaceZDv3QeumrdEei+59wZZeVAbaOfQKn8rGtEQsQ4LIj}K(OyBMA$G|wqvs5}b^RyzV8`!7tE;Xswti5x-lwYiBEGz+9y{>Pp(Gfp0X0w zilW|p>Im>K+o|v_X!_ymp3nI3eIuUzTRq;-AiGzILsDc!M5d_nm7k>AtZ(F z4I%9zCW}twh(Q_(c4N0-Kr{jG4!}+x#1?>9sonrcD#Ygqc?^gTD-ngqVK_ko8WPqj z5a|qw1u%SvSg_Mc0ILy*mh!+MRvb7Sjh=sj#R<6`euo+Ppj6bT0Bl-FOS;4tk%QUb zyukUy_#o1j#pHuDK$-a>W`0*+y~cpC)QhAN0K)e$seJ)Or1K$ZL6Fvve;_1a zG3c9#9DgQxzdtKL2+ePMzF+{-Nw{AiZH{z5a6Vs)B&Gh}T>l3N<{JszM5d4d@$`2% zQNW!(9KL|h;IX&@kbuS+qA&(U$g-kNGJU zg+jyg^&<}T6An!vz)k%ghd~*^1M|HNZEXA#4sDEq+wmg~_Ya$ZM`!s%Jow%QBAr+V z;X{D|kyH)`o?hvQfJhs*7YCHK13oA=mLN@EwJ1jxs}-@qU+b+xb6RnV!Os?V>EQDP Ube>?ouow&uz9#DIAX@?d1t5SU{Qv*} literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/NetConstraints-4.png b/katabatic/doc/images/NetConstraints-4.png new file mode 100644 index 0000000000000000000000000000000000000000..4244f8a34dea24f4b37e7d21b143219b3e1e768b GIT binary patch literal 3861 zcmeH}c{mj69>)jS8HpjGl!O>DmYB&l2w`Lyv>-)fEyljh(TvHiBH3mPjXg`rzLY`? zgY0QIC1%8!G?rtD>zsT4xPRQ|{BiGdp8L=FEz)^-6m0Bli>kV*Bw88#*(iWu_n z(BPMJMvV?d?LVtI`k6OBy4evg%uNzM0neGdH^0-)+^KhdZiqA?a@`gSS@SLhbI$o5 zg;p1VQ(Q!7TSJ1!b_moImC9bPGR0@*4QD$0Zp0M9<*)W=3}UECO_7i^pvE(Yw*&br zV}Y05lEl_BDB9RDSDdikh4{^JeN>_R#e8*Qs%o_Ds28~81q48{!wVx6(wvc;8^h6MefeDmdp$M$3l^yG?* zcO&_km2&H&pm9R)DQxg7sqP2OD13?CJ-oGa!K_wDvfYzWiF3Q4N3baYD}17#lBm{h zIMp8XV&WGKw_!1oC=|S~=%V}8G6CUx`%<21mjn3hqWx_c2H0Rgw^Yc4+03|C1kn0B z*%dJe5#wWv#WM1v3;G!$jrkY+$rSxIBDTk6K}G z_vvSaL{trMd%pH^-2n8M`m%8{%Rb#|#seR|ac%X+fa1r*c|N~Zk)Fw=Ll{!#Oa7m`I?-A(6SEh98 zibUWr%e~G^GDE3u6@l>~R5GUme zV!I>^?F!rA9EuxaD@Yu=1Fzs#Frkmi_@KT22!zo62s7Y3UN9vRFwAktnv+Q4FaQz% zjFACWc_08X<1y1mKFBAZas-Tpp;m>$tf=?ar_c(`j_dflP0VS2@f}`i6&YiCGJFMK zgF(nm_isg*pu7J08XUtwb~uJ&AV3G4{3Bx!Pm#mj|cT|GL))`GUpily#3 zhxk|T-Fzs|{%IlYf=7%~Sc-Br!-x(5pE7!`1-ZVpI{e#u2g_WD!_?@c)CB~|$h)u5 zfcO}RAsF&drnL7{QjRukbpI&K`m$iFjKT~{=%6qK2`WmK1S4RQA*IX_bg=8;(AG`^ zVbLx_96Y=3ndvp$cnezn{5Z^Gt$O$g0+nz*K493X`s4YX0_h2ldJJVSVeh)8Zc%wa zmuF_XwS0t*;>!`yn5VJGrS!R?b8u69?@4Z?1Kl@SE2&tRXjjM0id-ribZyxfL-6N! zsbq6JX-gm?zI7*!`iYbY*(46V8D35iKNGz!Lwls~V<6J>hZj!6YxqIsV(JrMdPS`f zj+=PDC|p05SHC1>gxW+^QkLJ2%qT22T^k1n=!H;LXd4q+E0tdBquD=S+*@R!;>+9h zp!+`uiUMQ`68R2}Xl-8Nzlho7-lXc1G#SB{!sF-oYXhC`qL&*DXe39$U;OH~V^FT@R9Uu3zWXF@v&`9KCZf+S}Ll%&6n@R=4*> z+o)v5+ZI>Lfzz)bKLphIJz^G25JZfoz%8{{KP3kag%2I_vrF6rxTD;1NH!t!-A+T) zw^Rp{(6~_ntlUM%$@Oh&zsa*4t>H{_kUX+(cPvcPC^YaY%{TA;Q_2IeL<&dSk8qGR zzPNg&$VT=I*To%SD5FVrE#X3O{hqOD2&6+ZC9{>#m@MyjY^E z#-TIXo|A>0I+8T#Za9>`%;%ov7(%DS1*z>hXUz4ewz({>xO$@n^EI*&5=qatmJdZr+xKB9e;J0WZ_+#y^>e8dZJfc*ElBi^$oXckU(kRk=4sWM}RkPSuDs>~1HkMbeFP<=w;@xedcS z>?y#lmN6eCA)^TX=VlEfJhJW4G#RPWV<$Q_nbR_za_JS3<}Y0c`_UyFEr6z%^cH+OR|EL-pKt|xT>gx{L=R&E|d=bHe{p_WA6KtcySMpbXhHvaM>4&n_nddM6yE6U(9HqHA literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/NetOptimals-1.fig b/katabatic/doc/images/NetOptimals-1.fig new file mode 100644 index 00000000..3b00a325 --- /dev/null +++ b/katabatic/doc/images/NetOptimals-1.fig @@ -0,0 +1,146 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +6 405 225 3195 6795 +6 2340 1305 2610 2070 +2 2 0 2 0 7 50 -1 44 0.000 0 0 -1 0 0 5 + 2430 1350 2520 1350 2520 2025 2430 2025 2430 1350 +2 2 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 2385 1710 2565 1710 2565 1890 2385 1890 2385 1710 +-6 +6 990 3105 1260 3870 +2 2 0 2 0 7 50 -1 44 0.000 0 0 -1 0 0 5 + 1080 3150 1170 3150 1170 3825 1080 3825 1080 3150 +2 2 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 1035 3285 1215 3285 1215 3465 1035 3465 1035 3285 +-6 +6 2340 2880 2610 3645 +2 2 0 2 0 7 50 -1 44 0.000 0 0 -1 0 0 5 + 2430 2925 2520 2925 2520 3600 2430 3600 2430 2925 +2 2 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 2385 3060 2565 3060 2565 3240 2385 3240 2385 3060 +-6 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 1575 675 90 90 1485 675 1665 675 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 1575 4275 90 90 1485 4275 1665 4275 +2 1 0 1 12 7 40 -1 -1 4.000 0 0 7 0 0 2 + 450 5625 3150 5625 +2 1 0 1 12 7 40 -1 -1 4.000 0 0 7 0 0 2 + 675 4770 675 5850 +2 1 0 1 12 7 40 -1 -1 4.000 0 0 7 0 0 2 + 1125 3870 1125 5850 +2 1 0 1 12 7 40 -1 -1 4.000 0 0 7 0 0 2 + 2475 3645 2475 5850 +2 1 0 1 12 7 40 -1 -1 4.000 0 0 7 0 0 2 + 2925 4770 2925 5850 +2 1 0 1 12 7 40 -1 -1 4.000 0 0 7 0 0 2 + 2475 2070 2475 2880 +2 1 0 4 12 7 40 -1 -1 10.000 0 0 -1 0 0 2 + 675 5400 675 5625 +2 1 0 4 12 7 40 -1 -1 10.000 0 0 -1 0 0 2 + 1125 5400 1125 5625 +2 1 0 4 12 7 40 -1 -1 10.000 0 0 -1 0 0 2 + 2475 5400 2475 5625 +2 1 0 4 12 7 40 -1 -1 10.000 0 0 -1 0 0 2 + 2925 5400 2925 5625 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 1 0 2 + 3 1 2.00 120.00 240.00 + 2475 6525 2475 5940 +2 1 3 1 0 7 40 -1 -1 4.000 0 0 -1 0 0 2 + 675 2475 2880 2475 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 1485 675 450 675 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 1665 4275 3150 4275 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 1215 3375 1575 3375 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 2385 3150 1575 3150 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 2385 1800 1575 1800 +2 2 3 1 0 7 40 -1 -1 4.000 0 0 -1 0 0 5 + 675 225 2925 225 2925 4725 675 4725 675 225 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 1575 765 1575 4185 +4 0 12 40 -1 18 12 0.0000 4 135 105 765 5580 1\001 +4 0 12 40 -1 18 12 0.0000 4 135 105 1215 5580 1\001 +4 0 12 40 -1 18 12 0.0000 4 135 105 2565 5580 2\001 +4 0 12 40 -1 18 12 0.0000 4 135 105 3015 5580 1\001 +4 1 12 40 -1 19 12 0.0000 4 180 660 2475 6750 Optimal\001 +-6 +6 4005 225 6750 6345 +6 5940 1305 6210 2070 +2 2 0 2 0 7 50 -1 44 0.000 0 0 -1 0 0 5 + 6030 1350 6120 1350 6120 2025 6030 2025 6030 1350 +2 2 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 5985 1710 6165 1710 6165 1890 5985 1890 5985 1710 +-6 +6 4590 3105 4860 3870 +2 2 0 2 0 7 50 -1 44 0.000 0 0 -1 0 0 5 + 4680 3150 4770 3150 4770 3825 4680 3825 4680 3150 +2 2 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 4635 3285 4815 3285 4815 3465 4635 3465 4635 3285 +-6 +6 5940 2880 6210 3645 +2 2 0 2 0 7 50 -1 44 0.000 0 0 -1 0 0 5 + 6030 2925 6120 2925 6120 3600 6030 3600 6030 2925 +2 2 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 5985 3060 6165 3060 6165 3240 5985 3240 5985 3060 +-6 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 5175 675 90 90 5085 675 5265 675 +2 1 0 1 12 7 40 -1 -1 4.000 0 0 7 0 0 2 + 4050 5625 6750 5625 +2 1 0 1 12 7 40 -1 -1 4.000 0 0 7 0 0 2 + 4275 4770 4275 5850 +2 1 0 1 12 7 40 -1 -1 4.000 0 0 7 0 0 2 + 4725 3870 4725 5850 +2 1 0 1 12 7 40 -1 -1 4.000 0 0 7 0 0 2 + 6075 3645 6075 5850 +2 1 0 1 12 7 40 -1 -1 4.000 0 0 7 0 0 2 + 6075 2070 6075 2880 +2 1 0 4 12 7 40 -1 -1 10.000 0 0 -1 0 0 2 + 4275 5400 4275 5625 +2 1 0 4 12 7 40 -1 -1 10.000 0 0 -1 0 0 2 + 4725 5400 4725 5625 +2 1 0 4 12 7 40 -1 -1 10.000 0 0 -1 0 0 2 + 6075 5400 6075 5625 +2 1 3 1 0 7 40 -1 -1 4.000 0 0 -1 0 0 2 + 4275 2475 6480 2475 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 5085 675 4050 675 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 4815 3375 5175 3375 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 5985 3150 5175 3150 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 5985 1800 5175 1800 +2 2 3 1 0 7 40 -1 -1 4.000 0 0 -1 0 0 5 + 4275 225 6525 225 6525 4725 4275 4725 4275 225 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 5175 765 5175 3375 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 1 1 2 + 3 1 2.00 120.00 240.00 + 3 1 2.00 120.00 240.00 + 4725 6075 6075 6075 +4 0 12 40 -1 18 12 0.0000 4 135 105 4365 5580 1\001 +4 0 12 40 -1 18 12 0.0000 4 135 105 4815 5580 1\001 +4 0 12 40 -1 18 12 0.0000 4 135 105 6165 5580 2\001 +4 1 12 40 -1 19 12 0.0000 4 180 660 5400 6300 Optimal\001 +-6 +6 1305 1980 1575 2295 +2 2 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 5 + 1350 2025 1530 2025 1530 2250 1350 2250 1350 2025 +4 1 0 40 -1 18 12 0.0000 4 135 120 1440 2205 A\001 +-6 +6 4905 1980 5175 2295 +2 2 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 5 + 4950 2025 5130 2025 5130 2250 4950 2250 4950 2025 +4 1 0 40 -1 18 12 0.0000 4 135 120 5040 2205 A\001 +-6 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 0 0 7200 0 7200 6975 0 6975 0 0 diff --git a/katabatic/doc/images/NetOptimals-1.pdf b/katabatic/doc/images/NetOptimals-1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..edd270f9c92c97f25305a9e4e19f7d6d0ff972da GIT binary patch literal 6987 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 literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/NetOptimals-1.png b/katabatic/doc/images/NetOptimals-1.png new file mode 100644 index 0000000000000000000000000000000000000000..e1111950e84443e2ca476c044d27be0dd5be353e GIT binary patch literal 7610 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 literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/NetOptimals-3.fig b/katabatic/doc/images/NetOptimals-3.fig new file mode 100644 index 00000000..3a96cb69 --- /dev/null +++ b/katabatic/doc/images/NetOptimals-3.fig @@ -0,0 +1,109 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +6 405 225 3150 5850 +6 1980 3240 2745 3510 +2 2 0 2 0 7 50 -1 44 0.000 0 0 -1 0 0 5 + 2025 3420 2025 3330 2700 3330 2700 3420 2025 3420 +2 2 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 2160 3465 2160 3285 2340 3285 2340 3465 2160 3465 +-6 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 1575 675 90 90 1485 675 1665 675 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 1575 3375 90 90 1485 3375 1665 3375 +2 1 0 1 12 7 40 -1 -1 4.000 0 0 7 0 0 2 + 450 5625 3150 5625 +2 1 0 1 12 7 40 -1 -1 4.000 0 0 7 0 0 2 + 675 4770 675 5850 +2 1 0 4 12 7 40 -1 -1 10.000 0 0 -1 0 0 2 + 675 5400 675 5625 +2 1 3 1 0 7 40 -1 -1 4.000 0 0 -1 0 0 2 + 675 2475 2880 2475 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 1485 675 450 675 +2 2 3 1 0 7 40 -1 -1 4.000 0 0 -1 0 0 5 + 675 225 2925 225 2925 4725 675 4725 675 225 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 1575 765 1575 3285 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 1665 3375 2160 3375 +2 1 0 1 12 7 40 -1 -1 4.000 0 0 7 0 0 2 + 2025 3465 2025 5850 +2 1 0 1 12 7 40 -1 -1 4.000 0 0 7 0 0 2 + 2700 3465 2700 5850 +2 1 0 4 12 7 40 -1 -1 10.000 0 0 -1 0 0 2 + 2025 5400 2025 5625 +2 1 0 4 12 7 40 -1 -1 10.000 0 0 -1 0 0 2 + 2700 5400 2700 5625 +4 0 12 40 -1 18 12 0.0000 4 135 105 765 5580 1\001 +4 0 12 40 -1 18 12 0.0000 4 135 105 2115 5580 1\001 +4 0 12 40 -1 18 12 0.0000 4 135 105 2790 5580 1\001 +-6 +6 5580 3240 6345 3510 +2 2 0 2 0 7 50 -1 44 0.000 0 0 -1 0 0 5 + 5625 3420 5625 3330 6300 3330 6300 3420 5625 3420 +2 2 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 5760 3465 5760 3285 5940 3285 5940 3465 5760 3465 +-6 +6 5175 1305 5445 1620 +2 2 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 5 + 5220 1350 5400 1350 5400 1575 5220 1575 5220 1350 +4 1 0 40 -1 18 12 0.0000 4 135 120 5310 1530 A\001 +-6 +6 1575 1350 1845 1665 +2 2 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 5 + 1620 1395 1800 1395 1800 1620 1620 1620 1620 1395 +4 1 0 40 -1 18 12 0.0000 4 135 120 1710 1575 A\001 +-6 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 5175 675 90 90 5085 675 5265 675 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 5180 4285 90 90 5090 4285 5270 4285 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 0 0 7200 0 7200 6975 0 6975 0 0 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 1 0 2 + 3 1 2.00 120.00 240.00 + 2025 6525 2025 5940 +2 1 0 1 12 7 40 -1 -1 4.000 0 0 7 0 0 2 + 4050 5625 6750 5625 +2 1 0 1 12 7 40 -1 -1 4.000 0 0 7 0 0 2 + 4275 4770 4275 5850 +2 1 0 4 12 7 40 -1 -1 10.000 0 0 -1 0 0 2 + 4275 5400 4275 5625 +2 1 3 1 0 7 40 -1 -1 4.000 0 0 -1 0 0 2 + 4275 2475 6480 2475 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 5085 675 4050 675 +2 2 3 1 0 7 40 -1 -1 4.000 0 0 -1 0 0 5 + 4275 225 6525 225 6525 4725 4275 4725 4275 225 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 5175 765 5175 4185 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 5175 3375 5760 3375 +2 1 0 1 12 7 40 -1 -1 4.000 0 0 7 0 0 2 + 5625 3465 5625 5850 +2 1 0 1 12 7 40 -1 -1 4.000 0 0 7 0 0 2 + 6300 3465 6300 5850 +2 1 0 4 12 7 40 -1 -1 10.000 0 0 -1 0 0 2 + 5625 5400 5625 5625 +2 1 0 4 12 7 40 -1 -1 10.000 0 0 -1 0 0 2 + 6300 5400 6300 5625 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 6750 4275 5265 4275 +2 1 0 1 12 7 40 -1 -1 4.000 0 0 7 0 0 2 + 6525 4770 6525 5850 +2 1 0 4 12 7 40 -1 -1 10.000 0 0 -1 0 0 2 + 6525 5400 6525 5625 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 1 1 2 + 3 1 2.00 120.00 240.00 + 3 1 2.00 120.00 240.00 + 5625 6075 6300 6075 +4 1 12 40 -1 19 12 0.0000 4 180 660 2025 6750 Optimal\001 +4 0 12 40 -1 18 12 0.0000 4 135 105 4365 5580 1\001 +4 0 12 40 -1 18 12 0.0000 4 135 105 5715 5580 1\001 +4 0 12 40 -1 18 12 0.0000 4 135 105 6390 5580 1\001 +4 0 12 40 -1 18 12 0.0000 4 135 105 6615 5580 1\001 +4 1 12 40 -1 19 12 0.0000 4 180 660 5940 6300 Optimal\001 diff --git a/katabatic/doc/images/NetOptimals-3.pdf b/katabatic/doc/images/NetOptimals-3.pdf new file mode 100644 index 0000000000000000000000000000000000000000..88eb9b89d63a0dc3c002b791cbff625800ad7ccf GIT binary patch literal 3836 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 literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/PerpandicularState-2.fig b/katabatic/doc/images/PerpandicularState-2.fig new file mode 100644 index 00000000..397bbe6e --- /dev/null +++ b/katabatic/doc/images/PerpandicularState-2.fig @@ -0,0 +1,113 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +6 2025 3555 3870 4860 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2565 3825 3645 3825 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2655 3825 2655 4050 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2970 3825 2970 4275 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3555 3825 3555 4680 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3240 3825 3240 4455 +4 1 0 40 -1 14 14 0.0000 4 195 945 3105 3735 C c g t\001 +4 2 0 40 -1 18 12 0.0000 4 135 840 2880 4185 Canonical\001 +4 2 0 40 -1 18 12 0.0000 4 180 840 3150 4410 Collapsed\001 +4 2 0 40 -1 18 12 0.0000 4 135 555 3465 4635 Global\001 +4 2 0 40 -1 18 12 0.0000 4 135 765 3870 4860 Terminal\001 +-6 +6 5670 3150 6210 3420 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 5670 3150 6210 3150 6210 3420 5670 3420 5670 3150 +4 1 0 40 -1 14 12 0.0000 4 90 420 5940 3330 -c--\001 +-6 +6 4770 3465 5310 3735 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 4770 3465 5310 3465 5310 3735 4770 3735 4770 3465 +4 1 0 40 -1 14 12 0.0000 4 165 420 5040 3645 Cg--\001 +-6 +6 6840 900 7380 1170 +2 2 0 1 1 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 6840 900 7380 900 7380 1170 6840 1170 6840 900 +4 1 1 40 -1 14 12 0.0000 4 15 420 7110 1080 ----\001 +-6 +6 495 1215 1035 1485 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 495 1215 1035 1215 1035 1485 495 1485 495 1215 +4 1 0 40 -1 14 12 0.0000 4 165 420 765 1395 Cg--\001 +-6 +6 2565 855 3105 1125 +2 2 0 1 1 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 2565 855 3105 855 3105 1125 2565 1125 2565 855 +4 1 1 40 -1 14 12 0.0000 4 15 420 2835 1035 ----\001 +-6 +6 5895 2385 6435 2655 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 5895 2385 6435 2385 6435 2655 5895 2655 5895 2385 +4 1 0 40 -1 14 12 0.0000 4 135 420 6165 2565 -g--\001 +-6 +6 1620 1260 2160 1530 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 1620 1260 2160 1260 2160 1530 1620 1530 1620 1260 +4 1 0 40 -1 14 12 0.0000 4 135 420 1890 1440 -g--\001 +-6 +6 6120 1980 6660 2250 +2 2 0 1 18 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 6120 1980 6660 1980 6660 2250 6120 2250 6120 1980 +4 1 18 40 -1 14 12 0.0000 4 90 420 6390 2160 -c--\001 +-6 +6 2700 1755 3240 2025 +2 2 0 1 18 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 2700 1755 3240 1755 3240 2025 2700 2025 2700 1755 +4 1 18 40 -1 14 12 0.0000 4 90 420 2970 1935 -c--\001 +-6 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 5625 3825 90 90 5535 3825 5715 3825 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 5625 2700 90 90 5535 2700 5715 2700 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 4500 3825 90 90 4410 3825 4590 3825 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 6750 450 90 90 6660 450 6840 450 +1 4 0 4 18 7 40 -1 -1 0.000 1 0.0000 6750 1575 90 90 6660 1575 6840 1575 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 6750 2700 90 90 6660 2700 6840 2700 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 225 1575 90 90 135 1575 315 1575 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 1350 1575 90 90 1260 1575 1440 1575 +1 4 0 1 0 7 40 -1 -1 0.000 1 0.0000 1350 1575 135 135 1215 1575 1485 1575 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 2475 450 90 90 2385 450 2565 450 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 2475 1575 90 90 2385 1575 2565 1575 +1 4 0 4 18 7 40 -1 -1 0.000 1 0.0000 2475 1575 180 180 2295 1575 2655 1575 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 1845 3375 1845 4950 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 3 + 0 3375 4050 3375 4050 4950 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 0 0 9675 0 9675 4950 0 4950 0 0 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 5625 2790 5625 3735 +2 1 0 4 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 4590 3825 5535 3825 +2 1 0 4 1 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 6750 540 6750 1485 +2 1 0 1 1 7 40 -1 -1 0.000 0 0 -1 1 0 2 + 3 1 1.00 60.00 120.00 + 7065 1845 7065 1170 +2 1 0 4 18 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 6750 1665 6750 2610 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 5715 2700 6660 2700 +2 1 0 4 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 315 1575 1215 1575 +2 1 0 4 1 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2475 540 2475 1395 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 1485 1575 2295 1575 +4 0 1 40 -1 18 12 0.0000 4 135 645 90 3780 current\001 +4 0 0 40 -1 18 12 0.0000 4 135 630 90 4230 master\001 +4 0 18 40 -1 18 12 0.0000 4 135 1530 90 4680 source & contact\001 +4 0 1 40 -1 14 12 0.0000 4 150 1785 7020 2025 PERPANDICULAR_ANY\001 +4 0 1 40 -1 14 12 0.0000 4 150 2310 7020 2250 PERPANDICULAR_INDIRECT\001 diff --git a/katabatic/doc/images/PerpandicularState-2.pdf b/katabatic/doc/images/PerpandicularState-2.pdf new file mode 100644 index 0000000000000000000000000000000000000000..f9924b4d2d79dcccf5a4f4e6ae27e4a5b40bfadd GIT binary patch literal 2827 zcmZ`*dpuO>8()>!(-M(Fn`6tZ(wVy%wc|455(#5Sp^R}b(hM`lU6d^q>Eco@ZHvMd z*=V|0sVKJ*N?F~6s4x>M%~qm4N7{bX{?0$=obU5I-{*Os=Y2ol*T98oYl>e<1PmHv z2MPc(hyw+F!NBU(&{~)uhy;NY6k$QOybuHyf{<+p2Z5O|SKtrR>3|3k!kn!@)X{UE zUIMn6TD--TTIa1+8$17QUQ(#6uRn`Za?05~MtMiDnMrQmbgITJ6A{%D8 zd2`nC_2Iptv^X7PqHA(r?2Fr4e53r+B*TF6Z5DSzgYp@NYpCkS#aam$#(Q@c`)M9| zEWagpwpZ9&U+kZJr=B+`8ujC*iCewOw<%4&Dv_2P=zCjcKVY1hye>qXZl2>wD~qgp zb%nq3(R|fhe`NHEkUhUGvNM4cy}a5f!sJRdRc5itJt^=(Z;S7?8$BAdU}Ivfx$MlV zJvnK0?|NsbR~o5x82~#~HX6=Vku>(pH21VzyoaPa=T&%E@&?1qF{|hW_a-kDGE6eJN?(le(x%8+Lu)<^cY*JyiDk9 z+d7;*FU>B&l4Z1{TAAJ~bJ)*y41fB1k5*F5viH|}E0)i2x>RQW^Ictq!R)ZsgJXA6 zZ?3YpIGr;2{dYt)U)C9+?;<)F!t9{xxT+E_h+C+$XTB}mYTs^j-cdTdK*a7@(S5k( zyH!amRNXlmk!#k+wpej;W2o<9G8&Q9?_1YKxv}(w zs*Z(-X|J`nD9<$3GP~V+9T4Q$$m}N0xJAEz3l03^52!K2p*BUAJ|FkD*Uav9EP0G|0i{SRGWI@N? ztj*j!Nz8C0t&S1t#kqtpVgyUGAKbWg^e07esaC)y>2_Irm$ZFV+_2&On5X10TzwJe ziOuVG7yHyULrz8F_MaTt(K`z}4fCHb>c}n2KV2DNUg)u4OHfAx<>G2>#W3738esPT zUc}&Q4NmMMY~8i)iT&6mxBDEO9Z}tmr^85oWlI5X7DYrDGpMU{8(McJ@w{6|;@@dj zB!>o1a%pu??8$0&%IfDC-*2pCFYs%t?LYLYrZvuSHuv1fBcnonbx#GTiC@h2FU`{r z)R5`^5|pvOJlHe#R?OVZ$150Z65gcPExwj#!z8%E*84s) z|IlU>_e{DYX|vUC7FMO6uP@U`wjI1!l5|e5B&J_IBX?`@9gmaSl3L>FL3)o%ZwDWU zzHsJM;Az7MtzvR`&AOA@(#T@^MwQT9czi7T1^Gp$QioO1OL@41sU^!%k-Fh|hh5$q z(M+dy@rmCf97^ac%MP=_kwUwtgT&)o9xs1C_s7Ku=eO|(#=sE=;s)bLZfWYW$d;#} zKAM&ice%XMN6GW(UtQdy{y|EE&Va;1J18a07fq#ZhNhAx$^<$vp`MhVS-aCaK(D~} zRHH)1%lLx<-Klo#8=wMNRz*hM{K-{3N$jlq&qxWP>Qbfa6K58>yY8u~qj!{spKaLx z*7)J0&F|`>$c?hybqe0y9Quy#;NsD9%EL){uVoEmyxl#t-FHm8be}+7NUeFU!akEK z?Lu#l<%*_7V;U*fYIg0lj@k3<+NhKpMt-0>uhyf$u=vpFlI*fKif?k`kN8L*{w9t! zqmZgKo&91zMD37%AiTP2d?Dw?J9_)V@>Mj=AG_BNUG>YZkdzH>Kem42o&AOrodw|| zyKQzHn~lT)W#dbuEiFt)o&(4|4>|TLS95q zeBLJDL#mNE4L*rU}Z=mhDx2&E#uy-kZnDk@11?RLY81kJ z1SDc=2S6-XBnTIBVG*i>Emrh+X5E#%V@G0v|^ z&_)P(u<#oS8$Nmu;qe1OJYlM&|3f)to#w={L7(CvCNCfWM(2(W8tpq7+REdHi+ny8 zgV9b0qPxI9oC^z$ZQNWyyC8uG5pjjQPz0pn$t!UL6LjF{T?pX`_)K(H7&FZYI2;vc zh9lys1R8;g+MNXc|84qr3QmBi} l8fN!|Sw>qz*(U!1`C#Wsgm8q&RJ#cz5(zLcuyM8p{sDyUhm-&S literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/PerpandicularState-2.png b/katabatic/doc/images/PerpandicularState-2.png new file mode 100644 index 0000000000000000000000000000000000000000..ed5b253857e62b84215845a46e0299a0fbdbf643 GIT binary patch literal 6862 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 Bn_>U} literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/PerpandicularState-3.fig b/katabatic/doc/images/PerpandicularState-3.fig new file mode 100644 index 00000000..30ee9aa4 --- /dev/null +++ b/katabatic/doc/images/PerpandicularState-3.fig @@ -0,0 +1,108 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +6 2025 3555 3870 4860 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2565 3825 3645 3825 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2655 3825 2655 4050 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2970 3825 2970 4275 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3555 3825 3555 4680 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3240 3825 3240 4455 +4 1 0 40 -1 14 14 0.0000 4 195 945 3105 3735 C c g t\001 +4 2 0 40 -1 18 12 0.0000 4 135 840 2880 4185 Canonical\001 +4 2 0 40 -1 18 12 0.0000 4 180 840 3150 4410 Collapsed\001 +4 2 0 40 -1 18 12 0.0000 4 135 555 3465 4635 Global\001 +4 2 0 40 -1 18 12 0.0000 4 135 765 3870 4860 Terminal\001 +-6 +6 4770 2025 5310 2295 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 4770 2025 5310 2025 5310 2295 4770 2295 4770 2025 +4 1 0 40 -1 14 12 0.0000 4 90 420 5040 2205 -c--\001 +-6 +6 3870 2340 4410 2610 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 3870 2340 4410 2340 4410 2610 3870 2610 3870 2340 +4 1 0 40 -1 14 12 0.0000 4 165 420 4140 2520 Cg--\001 +-6 +6 4995 1215 5535 1485 +2 2 0 1 18 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 4995 1215 5535 1215 5535 1485 4995 1485 4995 1215 +4 1 18 40 -1 14 12 0.0000 4 135 420 5265 1395 --g-\001 +-6 +6 495 1215 1035 1485 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 495 1215 1035 1215 1035 1485 495 1485 495 1215 +4 1 0 40 -1 14 12 0.0000 4 165 420 765 1395 Cg--\001 +-6 +6 1620 1215 2160 1485 +2 2 0 1 18 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 1620 1215 2160 1215 2160 1485 1620 1485 1620 1215 +4 1 18 40 -1 14 12 0.0000 4 135 420 1890 1395 --g-\001 +-6 +6 2565 855 3105 1125 +2 2 0 1 1 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 2565 855 3105 855 3105 1125 2565 1125 2565 855 +4 1 1 40 -1 14 12 0.0000 4 15 420 2835 1035 ----\001 +-6 +6 5940 900 6480 1170 +2 2 0 1 1 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 5940 900 6480 900 6480 1170 5940 1170 5940 900 +4 1 1 40 -1 14 12 0.0000 4 90 420 6210 1080 -c--\001 +-6 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 4725 2700 90 90 4635 2700 4815 2700 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 4725 1575 90 90 4635 1575 4815 1575 +1 4 0 4 18 7 40 -1 -1 0.000 1 0.0000 5850 1575 90 90 5760 1575 5940 1575 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 5850 450 90 90 5760 450 5940 450 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 3600 2700 90 90 3510 2700 3690 2700 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 225 1575 90 90 135 1575 315 1575 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 1350 1575 90 90 1260 1575 1440 1575 +1 4 0 1 0 7 40 -1 -1 0.000 1 0.0000 1350 1575 135 135 1215 1575 1485 1575 +1 4 0 4 18 7 40 -1 -1 0.000 1 0.0000 2475 1575 90 90 2385 1575 2565 1575 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 2475 450 90 90 2385 450 2565 450 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 6975 1575 90 90 6885 1575 7065 1575 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 0 0 8325 0 8325 4950 0 4950 0 0 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 1845 3375 1845 4950 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 3 + 0 3375 4050 3375 4050 4950 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 4725 1665 4725 2610 +2 1 0 4 18 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 4815 1575 5760 1575 +2 1 0 4 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3690 2700 4635 2700 +2 1 0 4 1 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 5850 540 5850 1485 +2 1 0 4 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 315 1575 1215 1575 +2 1 0 4 18 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 1485 1575 2385 1575 +2 1 0 4 1 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2475 540 2475 1485 +2 1 0 1 1 7 40 -1 -1 0.000 0 0 -1 1 0 2 + 3 1 1.00 60.00 120.00 + 6165 495 6165 900 +2 1 0 4 1 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 5940 1575 6885 1575 +2 1 0 1 1 7 40 -1 -1 0.000 0 0 -1 1 0 2 + 3 1 1.00 60.00 120.00 + 6345 2340 6345 1935 +2 2 0 1 1 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 6120 1665 6660 1665 6660 1935 6120 1935 6120 1665 +4 0 1 40 -1 18 12 0.0000 4 135 645 90 3780 current\001 +4 0 0 40 -1 18 12 0.0000 4 135 630 90 4230 master\001 +4 0 18 40 -1 18 12 0.0000 4 135 1530 90 4680 source & contact\001 +4 0 1 40 -1 14 12 0.0000 4 90 420 6075 405 zero\001 +4 0 1 40 -1 14 12 0.0000 4 150 2100 5265 2520 PARALLEL_OR_EXPANDED\001 +4 1 1 40 -1 14 12 0.0000 4 165 420 6390 1845 Cg--\001 diff --git a/katabatic/doc/images/PerpandicularState-3.pdf b/katabatic/doc/images/PerpandicularState-3.pdf new file mode 100644 index 0000000000000000000000000000000000000000..f0119afcab05cb75eb30f97e6d8b8e86e7b0611c GIT binary patch literal 2802 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 literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/PerpandicularState-4.fig b/katabatic/doc/images/PerpandicularState-4.fig new file mode 100644 index 00000000..c83e4aec --- /dev/null +++ b/katabatic/doc/images/PerpandicularState-4.fig @@ -0,0 +1,108 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +6 2025 3555 3870 4860 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2565 3825 3645 3825 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2655 3825 2655 4050 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2970 3825 2970 4275 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3555 3825 3555 4680 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3240 3825 3240 4455 +4 1 0 40 -1 14 14 0.0000 4 195 945 3105 3735 C c g t\001 +4 2 0 40 -1 18 12 0.0000 4 135 840 2880 4185 Canonical\001 +4 2 0 40 -1 18 12 0.0000 4 180 840 3150 4410 Collapsed\001 +4 2 0 40 -1 18 12 0.0000 4 135 555 3465 4635 Global\001 +4 2 0 40 -1 18 12 0.0000 4 135 765 3870 4860 Terminal\001 +-6 +6 4770 2025 5310 2295 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 4770 2025 5310 2025 5310 2295 4770 2295 4770 2025 +4 1 0 40 -1 14 12 0.0000 4 90 420 5040 2205 -c--\001 +-6 +6 3870 2340 4410 2610 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 3870 2340 4410 2340 4410 2610 3870 2610 3870 2340 +4 1 0 40 -1 14 12 0.0000 4 165 420 4140 2520 Cg--\001 +-6 +6 4995 1215 5535 1485 +2 2 0 1 18 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 4995 1215 5535 1215 5535 1485 4995 1485 4995 1215 +4 1 18 40 -1 14 12 0.0000 4 135 420 5265 1395 --g-\001 +-6 +6 495 1215 1035 1485 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 495 1215 1035 1215 1035 1485 495 1485 495 1215 +4 1 0 40 -1 14 12 0.0000 4 165 420 765 1395 Cg--\001 +-6 +6 1620 1215 2160 1485 +2 2 0 1 18 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 1620 1215 2160 1215 2160 1485 1620 1485 1620 1215 +4 1 18 40 -1 14 12 0.0000 4 135 420 1890 1395 --g-\001 +-6 +6 2565 855 3105 1125 +2 2 0 1 1 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 2565 855 3105 855 3105 1125 2565 1125 2565 855 +4 1 1 40 -1 14 12 0.0000 4 15 420 2835 1035 ----\001 +-6 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 4725 2700 90 90 4635 2700 4815 2700 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 4725 1575 90 90 4635 1575 4815 1575 +1 4 0 4 18 7 40 -1 -1 0.000 1 0.0000 5850 1575 90 90 5760 1575 5940 1575 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 5850 450 90 90 5760 450 5940 450 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 3600 2700 90 90 3510 2700 3690 2700 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 225 1575 90 90 135 1575 315 1575 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 1350 1575 90 90 1260 1575 1440 1575 +1 4 0 1 0 7 40 -1 -1 0.000 1 0.0000 1350 1575 135 135 1215 1575 1485 1575 +1 4 0 4 18 7 40 -1 -1 0.000 1 0.0000 2475 1575 90 90 2385 1575 2565 1575 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 2475 450 90 90 2385 450 2565 450 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 6975 1575 90 90 6885 1575 7065 1575 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 0 0 8325 0 8325 4950 0 4950 0 0 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 1845 3375 1845 4950 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 3 + 0 3375 4050 3375 4050 4950 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 4725 1665 4725 2610 +2 1 0 4 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3690 2700 4635 2700 +2 1 0 4 1 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 5850 540 5850 1485 +2 1 0 4 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 315 1575 1215 1575 +2 1 0 4 18 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 1485 1575 2385 1575 +2 1 0 4 1 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2475 540 2475 1485 +2 1 0 1 1 7 40 -1 -1 0.000 0 0 -1 1 0 2 + 3 1 1.00 60.00 120.00 + 6165 495 6165 900 +2 1 0 4 1 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 5940 1575 6885 1575 +2 1 0 1 1 7 40 -1 -1 0.000 0 0 -1 1 0 2 + 3 1 1.00 60.00 120.00 + 6345 2340 6345 1935 +2 2 0 1 1 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 6120 1665 6660 1665 6660 1935 6120 1935 6120 1665 +2 2 0 1 1 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 5940 900 6480 900 6480 1170 5940 1170 5940 900 +2 1 0 4 18 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 4815 1575 5895 1575 +4 0 1 40 -1 18 12 0.0000 4 135 645 90 3780 current\001 +4 0 0 40 -1 18 12 0.0000 4 135 630 90 4230 master\001 +4 0 18 40 -1 18 12 0.0000 4 135 1530 90 4680 source & contact\001 +4 1 1 40 -1 14 12 0.0000 4 135 420 6390 1845 -g--\001 +4 1 1 40 -1 14 12 0.0000 4 90 420 6210 1080 -c--\001 +# zero +4 0 1 40 -1 14 12 0.0000 4 90 420 6030 450 zero\001 +# zero +4 0 1 40 -1 14 12 0.0000 4 90 420 6120 2520 zero\001 diff --git a/katabatic/doc/images/PerpandicularState-4.pdf b/katabatic/doc/images/PerpandicularState-4.pdf new file mode 100644 index 0000000000000000000000000000000000000000..13ce5ffe627f797a44d5bcb786d78a8a3b23c18d GIT binary patch literal 2773 zcmZ`*c|25m8}D|z=!6QDrCXiRNk% zEw(5sElPwKvbCYqO=42QMDJuvTHZ6#?N;x5{yFD-pXd4hp5OC4zt8uFakaBI#+eWR zOvB669DoR7K_nm;u(X7>z`P(K3p7I!8f4Gr2w^@5*>mVZ*bZhOOqfCe1VTPc=K|qb zrCys6J@W-sug>+HV$F-kkR$zkw8(1~-Mv_3;GB4%t5F>oeK650UdsRVLfag*$Taf0 zRD?8NebUX~R7`W!*hI*Y-8(hw-nTPhYzIj`kyjtbmM%p6oF3_kDG4VkN9~@P>d;oZ zGn*~nE1fM|UH`8lx8F+ehW=#%@%(xZm4gn0WhL5-y{1Nj135LPZRoVc0l7K$D~>W9 zVv5Q_s*Y2f%isA&sjrcbEaPp=cGT4rKdjDd4rOKU5ZIa-~n-1Kv2$VnZwKO=#Rrvxl|(M-PW*h$d6vMj+?KpueGlsqH0Pu z@WxEwnqE`;vDVGw+L7fS3tzAPnd;s0D)mKsTwLvcWV?4-?Qc^mqjrW~h%XU6BpwJG zimZ!${4j3Vty7ui9E@b|VeW~&Horo`Ygn98>a4^$oZ_uteV$can`fTn2Bc3E}$$MA=n;#t~Ny@j$G&%VNArfSzr^p*Tq?VEL-u7=BB>BhY`*0ZCR1r|k@ zY7)yyFeW40B%|$g;$6O2<{1?I=OlAblyFhSDxl}?c?SMAD)*+{4|QmD-bUMEo7ue4>(+)8f0FBdw=J}_TW~o8Ij-ZosJkcX)J6RAD;>^;NB0}w zzrAfw2m{V~clB+}Q*PHIzk>9tM&01fUzEyBYKcew-rBunigF zUmZz|CF(X6M!EU7_nx%hkY0N|gU>X|Z+hkvu(V3=1?|H*x4@Ih8dIBivoKFP`BJ~1$^1Djq(8Uc7dAgOBv-Jr>(Y_gJvF1LGU?+n z?47BBiRJZ@H1HR#-*??!G3dRCNf>^xzU4+}FvKiTz!vMyB1(H_I~)IqtAL za;5$)Mp|2AyDiiC(F@KkX|v(>!}zdGJR6*QF)cJ=c_X)F(Wd(n%O%o)6{!{fZq}^Yus7u)!lf5@0;}G*_umz_uf{X@Jk`b$5+?=6*cxDvX?K6 zz^E#%5m);?g1V~POQ+1eQ&NA}n{;3?@0n~u+CCW>8D15sJNdGr!D(K{<{?+Lzv>2t z2PVUJ%b)jFQ+7PQRIoRBtW-82Z=Vd&>Q0dKN=CY*ldofXWy>Iy_xMBm4r#SaJv~e5 ze+ih+O-``LZF1Q))aumIGoq=v!f@r}^Un1RBa9ERa=LYOd%FL}w!z-$$+1z$P-ANh z%wx{z2>PYa9);p4-Z&ze1k7NjUv$YMA_Rt9=|M2$1T)!m8zda`!J=j&-V7w*Onm{= z$cK4Ckf2a50HVPHM8s#n0#wsn`3S=u7WzP_>Vc34942bDR<7X3#V1)xG6X#fh%q@`HmlU$-~XkOrSVgeA_%w`HeA3%{d4e$j~29bjD zAE65N8KwOcX-gN!%biq)XcagZH5Fc3!jjy4*tI}zft zc_M-Dmt+*QGlA$7FhvZQZ$Nc-1vjz~fl$EUvqOX+2}d-+;tkP;qxTvi8{yfZQ(<6d zfyZJ=SaU1^N5YfwWYq42F#osd?=FP%;XnWj;s^lt?*}v^5(z{w5S+nqWE|RM#RKv_ zV|Y9Xos6$B9Epey(l;2I&bJsAi$e$W8$UDBcYZjs*>`K;ai-|-e;td*nt$(y#iEt` z){pQ#hR6S7T_K;&=D>XPS_wk#?49UIBY+SMLC_0;vvWITYuP+jbS{{rEyaBBbn literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/PerpandicularState-4.png b/katabatic/doc/images/PerpandicularState-4.png new file mode 100644 index 0000000000000000000000000000000000000000..f495c881692327945b8bd5a708e4b02ff8b3ea54 GIT binary patch literal 5896 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 literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/SplitAutoContact-2.fig b/katabatic/doc/images/SplitAutoContact-2.fig new file mode 100644 index 00000000..a93b4700 --- /dev/null +++ b/katabatic/doc/images/SplitAutoContact-2.fig @@ -0,0 +1,53 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +6 1710 90 2610 225 +4 0 0 50 -1 18 12 0.0000 4 135 270 1710 225 M2\001 +4 0 0 50 -1 19 12 0.0000 4 135 180 2070 225 to\001 +4 0 0 50 -1 18 12 0.0000 4 135 270 2340 225 M5\001 +-6 +1 3 0 2 0 7 40 -1 -1 0.000 1 0.0000 1800 1800 90 90 1800 1800 1890 1800 +1 3 0 2 12 7 40 -1 -1 0.000 1 0.0000 1800 2700 90 90 1800 2700 1890 2700 +1 3 0 2 12 7 40 -1 -1 0.000 1 0.0000 2700 2700 90 90 2700 2700 2790 2700 +2 1 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 4 + 675 1845 1350 1845 1350 1755 675 1755 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 1350 1800 1710 1800 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3150 2700 2790 2700 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2700 2790 2700 3150 +2 1 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 1800 1890 1800 2610 +2 1 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 1890 2700 2610 2700 +2 1 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 4 + 2745 3825 2745 3150 2655 3150 2655 3825 +2 1 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 4 + 3825 2745 3150 2745 3150 2655 3825 2655 +2 2 3 1 0 7 60 -1 -1 8.000 0 0 -1 0 0 5 + 1080 1125 3375 1125 3375 3375 1080 3375 1080 1125 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 225 4140 675 4140 +2 1 0 4 12 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 225 4365 675 4365 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 3 + 0 3960 2025 3960 2025 4500 +2 2 0 1 0 7 60 -1 -1 0.000 0 0 -1 0 0 5 + 0 0 4275 0 4275 4500 0 4500 0 0 +4 1 0 40 -1 18 12 0.0000 4 135 270 3690 2610 M4\001 +4 1 0 40 -1 18 12 0.0000 4 135 270 2925 3825 M5\001 +4 1 0 40 -1 18 12 0.0000 4 135 270 810 1710 M2\001 +4 1 0 60 -1 18 12 0.0000 4 135 330 2115 1845 C23\001 +4 1 12 60 -1 18 12 0.0000 4 135 330 1485 2745 C34\001 +4 1 12 60 -1 18 12 0.0000 4 135 330 2655 2565 C45\001 +4 0 0 50 -1 18 12 0.0000 4 135 405 810 4410 New\001 +4 0 0 50 -1 18 12 0.0000 4 180 1065 810 4185 Pre-existing\001 +4 1 12 60 -1 18 12 0.0000 4 135 270 1980 2340 M3\001 +4 1 12 60 -1 18 12 0.0000 4 135 270 2250 2655 M4\001 diff --git a/katabatic/doc/images/SplitAutoContact-2.pdf b/katabatic/doc/images/SplitAutoContact-2.pdf new file mode 100644 index 0000000000000000000000000000000000000000..eb75d9714700fb8fdca4f2fc6c2132b2360a1105 GIT binary patch literal 4153 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 literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/SplitAutoContact-2.png b/katabatic/doc/images/SplitAutoContact-2.png new file mode 100644 index 0000000000000000000000000000000000000000..4bd10f8b0fbbf0037d165adc0eca422533caa746 GIT binary patch literal 4049 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 literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/SplitAutoContact-4.png b/katabatic/doc/images/SplitAutoContact-4.png new file mode 100644 index 0000000000000000000000000000000000000000..13a9e07787665fcc3c5d50e6e7ae86e4ac4d5877 GIT binary patch literal 3934 zcmeHJdpy(o8=stml1-;ha~mzip~xk-HB%%JM(QBf9qS^A*}}}F^J`fSp_2P8wRS4E zXzsU+p)f`vxoaCCJ8m1sZ|I!Y>A&9}=l9=vy`Ina`*}Uz&+~bn_w)U{pXU>0XKNv~ zLv9BE0Fbggeex^-Afh20#uD3vnoh^Z`-QLV{->R>0KiV0jUmEp&$AUOm2l=xI0wH= zxFA%(MS!`3-9C#eepnpVE5O?yx6e>pPg6@LDKKL%0I-8&dGf@$;PmMM=lhRO?Ky7G z?3BD-&_MO#i;6!@v8YyP=ldtTGbP($9&X>3fXG6M1MZ%2>yiBdYG*Z3z+nS$FkpK1>ZSop^ZZIKJgMUuWBlbfOJ|g zSd7MCV;2ckEh)fT8B&(P=b5M{2~4e`yn#n6#nsa*4nIL6`yhSv>b8Det@kHM+RMMq z#9Y(g<L1nsw0+g^Zx#bDs|mN)2i>JwUZZ4eE!-*v@bakO*2sW}uF@s(7 z2EX*z2V#`Zw7I|*Dr4a-)FG;In&89PxT>2yiK(lTIYXUQ2P0f+>8*~=5x0;17B1po zWfMaxR|_GJNR@y@@5D!`z~)~AQiM2L@oC3NuTP$)(45*upHgUAr%c6QF(aOGbezm_ zV%#A?V>c>>*(0AxrUCY&bE1HGOYaVaQ5<(eF6GbPxU+(jX~EYa)dYIiMnj`NzF%ko zT!BA{0v3;^o3T=plP(Ora9mConnAI`e{X|xT7GhSQm+$=wk1g;zme|jd9$Y*8Is_p zath}yB`d8=(9bswpNNr>_$}o-pB%Gh*WHjrgg44@!XZ-yMr@ss9@XnaO+489yyqk- z-Uwm}|3=QPu`o#a|Ii&wgPn9bSJGtF}ow& zk&L|XyZdg4DQhdZug}v`Rwn1n{zM=&J~I^T={P~M-U25?qlVlJ^HGQmPGTd|o1Vko zbZy00r2;z~#xz|>! z#DQxaX>s8h5?P*bbkl)i#uvsDI(MBlG+uc5M(??lp`ySsLJUcPs(nJRx|Zv!89?O5 zo4w!mHUdyJypnZlvQX?nShBdE(aP{#)?CzV{nX2$=$gcjbd%~6q}76KkY}h$PE+>yJh(mJODqNBt!l83#NA|`>9Z26xvseB6ZB{$JW!21ljVS%BLuS3 zCsc1lm@Lb$hu${$!)b*g4#pGQpVRWl6%VPXX?ElH2G>8X-Q^n=@t3AlMrT#~dHs2U zuAsemJF6D<-WP~02D;v8FkEKcA@WlW_u$dMkS{x zQ7?m&Bbs%~hieztW+L4xW3N;HS2`kv)3K zqVQ_M`t$KV&C}^u71*o%ss_oG1R*n|1S-y*E*JS7P)C{VS!6R?pYhMjHI}4w<$427 zeAh{yAtWGHVkp~8NYTn$!1Bh}E(=b4^jRyi(z}$njh*0{rPWW#ptm--=3*<43El1n zJaS-4Kp@zpew?l*)5ltFlUcWz{bzhl_ya==gObUN=1?2=Vo9A+LkRU@u!B`gRRZ?F zlGsKC3y2QWkL!T;M9r$f#`m*DOiq(rQ3pa3fkqmox4hM}&DwX3$m5#5_lKqfjVy?M z8~p-W+KXA1fCSu|yQ%cVEWfa4-WfK26x-P}5g)xX5_I)bXlUjyX|q!FEn{K1ZPr-q zgPW3ERqH9eNSZkfm}YsGw%&dul*bP(DX8r|3<+p#yJtt(%_64<&Uwo1YL^8Wv4e?% zh8u{0Siep*Be>byVpMkMa`^hlHiyOe`500<7W9xb#m8-g0jFcusSvb9!ek^Q5UFX z&FHp4_s*V~zV#|&>jBvY6y`h{&mfB0ATQtEK3g2O zXtp0DK}nw}yb~ngTKfelu||!X2+k}u&Ff0;vsB}1bp8jff6>dOW@FXpT;Iov&wO~~ zQ|DkkyV@J>xgo?D7s_M(4-C!M9Vek8ea|S3I!rI3cD=G-1aEdpVIz9;*}o{Q)7?Vd z&YfgDZU5lIVv=oaOdo>KF=M4;KN;MsAr(bwKd=YNH;h;tVZ3E4tsyW(HZQSJcRLs~ zc9e3^;3DG;nAE^!7%)gTzx-52YwYSZxRhpL`;sL6DK8-!>?5}pgfXy&5U!;A*}oWN zlsZ-E*p!ny55Ksk9Ydn3hr@|5j`XOIu$uy?nDI!WC`??va&O~$46rn}J(+Ln`Jbr& z{{>r=`1OL_r7Z&3x3f;Gu9j_c%IJsh!$K~z0M8u70SF?9Cmn(yW`Z8E%{csjr~l^R X-$U?^l3{RLZus{>(|x#%zmxyJEB~6S literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/SplitAutoContact-5.fig b/katabatic/doc/images/SplitAutoContact-5.fig new file mode 100644 index 00000000..17371c26 --- /dev/null +++ b/katabatic/doc/images/SplitAutoContact-5.fig @@ -0,0 +1,46 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +1 3 0 2 0 7 40 -1 -1 0.000 1 0.0000 1800 1800 90 90 1800 1800 1890 1800 +1 3 0 2 12 7 40 -1 -1 0.000 1 0.0000 1800 2700 90 90 1800 2700 1890 2700 +2 1 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 4 + 675 1845 1350 1845 1350 1755 675 1755 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 1350 1800 1710 1800 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 1800 1350 1800 1710 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3150 2700 1890 2700 +2 1 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 1800 1890 1800 2610 +2 1 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 4 + 1755 675 1755 1350 1845 1350 1845 675 +2 1 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 4 + 3825 2745 3150 2745 3150 2655 3825 2655 +2 2 3 1 0 7 60 -1 -1 8.000 0 0 -1 0 0 5 + 1080 1125 3375 1125 3375 3375 1080 3375 1080 1125 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 225 4140 675 4140 +2 1 0 4 12 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 225 4365 675 4365 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 3 + 0 3960 2025 3960 2025 4500 +2 2 0 1 0 7 60 -1 -1 0.000 0 0 -1 0 0 5 + 0 0 4275 0 4275 4500 0 4500 0 0 +4 1 0 40 -1 18 12 0.0000 4 135 270 3690 2610 M4\001 +4 1 0 40 -1 18 12 0.0000 4 135 270 2025 810 M3\001 +4 1 0 40 -1 18 12 0.0000 4 135 270 810 1710 M2\001 +4 1 0 60 -1 18 12 0.0000 4 135 330 2115 1845 C23\001 +4 1 12 60 -1 18 12 0.0000 4 135 330 1485 2745 C34\001 +4 0 0 50 -1 18 12 0.0000 4 135 405 810 4410 New\001 +4 0 0 50 -1 18 12 0.0000 4 180 1065 810 4185 Pre-existing\001 +4 1 12 60 -1 18 12 0.0000 4 135 270 1980 2340 M3\001 +4 0 0 50 -1 18 12 0.0000 4 135 270 1710 225 M2\001 +4 0 0 50 -1 19 12 0.0000 4 135 180 2070 225 to\001 +4 0 0 50 -1 18 12 0.0000 4 135 270 2340 225 M4\001 diff --git a/katabatic/doc/images/SplitAutoContact-5.pdf b/katabatic/doc/images/SplitAutoContact-5.pdf new file mode 100644 index 0000000000000000000000000000000000000000..93135be0d3de58e4fc438205ca7f7bbe892dbc67 GIT binary patch literal 4064 zcmdT{c~BH*7UvL^23-r~@=B`^Zu*!Taex^>t`QvY;Fzof(?DCp4D|FMCNW+`j6w<# zl#RgvCTc*C!~_inC`pJY$wDEJgJm~a!zD3g&~;-(*ZsN~V1@~)tt~56nLlQF-uJ!Z z`+e{I-fQ=`&~QJ@p98tK-zho`@n96zrtX9S1Cba)lR;;~d?1k{;iQ@-C>RM>D`_H> zNYknau^7_P6rs$5^2+PBMr)Ub*lX(V`wVYCdh0^_{iXv;&aLeaAG6Gfl6v*~jY++O zo_lHJ{Wm}Kwmm|9{q+yy8GBd%?WOwl!GFI|AGqycK=Z;!!<+Z?wC*q19KY{q?WP@B z^p;1Rm%i$dpkE4~)W&^V(_Pf^u=eG`9jP}hH_(x9H!N=Yr^kFWB&fE}{o^kG(~Ebk zs_MSxVO?BN>?&31^EA;i~Q>3V`GRRl7HMc0ZZRA8yLZ>BfdFs{5?gbIuV?&jj z#LHj2{P>L6udgxBW@LSaba9^aAI`oGZqbkDx4Ly~SJ@OSlx%!=(bB^)ZTFH+mCH5{ z_%3xeM|dA5SPKTwz|+t9mg+uaANHm(cmbbq>govl-MPGg4Gb}NUn z!l824cws=mvEcJR>U$EbR_L_xmsa$TkB>Vgbr)ui)TFeG*giyi6;T7P%}d#x_RAHD zJao3TbV<`k68nKQ|8bOUXxQsIYJ*YvnQafy7x3y&a~*Swf3EA+R5f{a`%_-uRYjaQ z;QGe8Wp3ft137nm#z&8S;v@^|dFb}Rxr$RYC->M5|M_C6gGS4Xq7Ui{vmUQ`e)Y+~t5-aG z7s*;Ltchy2(si8wQWvnbJUR0G4Igs-1-ng7iopVD$sup&h2m~*>BX*FYx3U2?81v} z-VW{djq2@d4R`Q)aKGUPd10GqX%Nv-uZ?sXo;a zIALeE$2pPEs0>vCo|wvF>WTRki1?5}#GNU+gx%Q$5~s`{5E-E&l@e_poQ#5HT!6v2 zkf(saB1LFun8TDMgvbelw za4k^B8KZIt)G#6i|A9pv%+x+BGK9srnB)Rr4a5brf$3l*npElFWQYk{4k=(@K@Ut~ zj5UKQHmz#VlqzYZTAMLtVlw)f{Q}edGf_iGY@7_n#NsK#%pnW}B^N-9o_xj(d#b5b z5yT!Ckz*VPV;v%LAtYopfDDB&76S0dhcK4pX6#@_@lP_JG4V|?BUdOEPctAV0kx1y z;TUYtd(bL}Y7Dj#rMwz<(;^~0JKtw8r?u4S40R^QhO)Fsv$U&Wa57B`44*mJ+%7Rb zfZ~7k>FDhuIljVkbor=j@V+Vue-c>YfV|J)&FXCr1#^UzlhE>?*1(Jv)tU2xBQ`<1@nqh?)|%W%Qv`f zR90g36;=N`o?S66$8TT#Rf^*)0BP^ty;y>8^SCAs?~t8h}2}j zI71(DBwn9NGjz^yCn(z~Ze&*t8OhT9lpYdFrl%8t-2t5gcI6>iq(-k(%xJPKW~@2e zFT){nM4G9jm|mcRK~unBY?9Xz6vieQTP$V+mMLk9%u8ls1xw7gf|W}^(_woKPz4f_ z($S1X7)4@~hDQw9Mylvc5GAt*GC3({CSKf#(@amwpgDc)ZKNhdqa&yPo4|k~D1sSb zU{ua?TuE%In#|Ep!fv>kIc|dO0KbLjWY?IDCyO$~;K|-IXnVgGo--YJGVi7#`~UG| zTilvV5ag64Zu-Uhzd{+Cd5TJ2G(U-)vqs2&oFrukq&{8jt8OBADGYM zad>b#Y>;6Xlbp;4)=bGb91e)oRED8Ekc6f(R0OnU%TR^}X6+LS&2%x02d>t1A1>g4 z`Dm651Y;%>GDD2%K8%B!``|K3XSxsP3e04fNC*gc);Ue>B%XYc0C@l-a;+8&&u+ZO literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/SplitAutoContact-5.png b/katabatic/doc/images/SplitAutoContact-5.png new file mode 100644 index 0000000000000000000000000000000000000000..472e2645bc17dfe75634834564bae5012aac910b GIT binary patch literal 3844 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 +#include +#include + +#include "hurricane/Bug.h" +#include "hurricane/Error.h" +#include "hurricane/Warning.h" +#include "hurricane/Layer.h" +#include "hurricane/ViaLayer.h" +#include "hurricane/BasicLayer.h" +#include "hurricane/Technology.h" +#include "hurricane/Net.h" +#include "hurricane/Contact.h" +#include "hurricane/Plug.h" +#include "hurricane/RoutingPad.h" +#include "hurricane/Vertical.h" +#include "hurricane/Horizontal.h" +#include "hurricane/UpdateSession.h" +#include "hurricane/DebugSession.h" + +#include "crlcore/RoutingGauge.h" + +#include "katabatic/GCell.h" +#include "katabatic/AutoContact.h" +#include "katabatic/AutoSegment.h" +#include "katabatic/AutoVertical.h" +#include "katabatic/AutoHorizontal.h" +#include "katabatic/Session.h" + + +namespace { + + /*! \class SegmentEnd + * \brief Segment manipulator (\b internal) + * + * SegmentPosition compute detailed informations about how an + * Segment is connected to the current AutoContact. This + * object act as a cache, avoiding to recalculate the position + * information many times. + * + * It also provide uniform way of resizing the Segment extention + * from the AutoContact. + */ + + /*! \var bool SegmentEnd::_isSourceHook; + * set to \b true if the Segment is attached to the AutoContact + * through it's source hook (\b false for target \c hook). + */ + + /*! \function SegmentEnd::SegmentEnd ( AutoSegment* segment, bool isSourceHook ); + * \param segment the supporting segment. + * \param isSourceHook initialize _isSourceHook. + */ + + /*! \function static SegmentEnd* SegmentEnd::create ( Hook* hook, bool checking ); + * \param contact The AutoContact we are currently processing. + * \return The appropriate SegmentPosition. + * + * This create function allocate the relevant HorizontalPosition or + * VerticalPosition derived object, providing an uniform allocator + * function. + */ + + /*! \function virtual bool SegmentEnd::isVertical () const; + * \return \b true if the associated Segment is vertical. + */ + + /*! \function virtual bool SegmentEnd::isHorizontal () const; + * \return \b true if the associated Segment is horizontal. + */ + + /*! \function bool SegmentEnd::isSourceHook () const; + * \return The _isSourceHook value (accessor). + */ + + /*! \function bool SegmentEnd::isGlobal () const; + * \return The _isGlobal value (accessor). + */ + + /*! \function virtual DbU::Unit SegmentEnd::getAxis () const; + * \return For horizontal segment, the Y coordinate and the X coordinate for + * vertical ones. + */ + + /*! \function Layer* SegmentEnd::getLayer () const; + * \return The layer of the segment. + */ + + /*! \function Point SegmentEnd::getEnd () const; + * \return The position of the segment's extremity attached to the AutoContact. + */ + + + /*! \function void SegmentEnd::setDelta ( DbU::Unit delta ); + * \param delta the new value of the extention. + * + * Adjust the segment's extention. Coordinate must be expressed + * as an offset to the absolute coordinate of the relevant hook. + */ + + /*! \function void SegmentEnd::orient (); + * restore correct orientation of the segment (source \e lower than + * target), usually needed after a setDelta(). + */ + + + + + /*! \class HorizontalEnd + * \brief Horizontal Segment manipulator (\b internal) + * + * This class must only be accessed through it's base class + * SegmentPosition, it's constructed through SegmentPosition::create(). + */ + + + /*! \class VerticalEnd + * \brief Vertical Segment manipulator (\b internal) + * + * This class must only be accessed through it's base class + * SegmentPosition, it's constructed through SegmentPosition::create(). + */ + + + using namespace std; + using namespace Hurricane; + using namespace Katabatic; + + +// ------------------------------------------------------------------- +// Local Variables. + +// const char* badAutoContactAnchor = +// "AutoContact::AutoContact() :\n\n" +// " Only are supported to anchor an AutoContact :\n" +// " %s\n"; + +// const char* nonAdjacentLayers = +// "%s :\n\n" +// " %s and %s are not adjacent, cannot build a VIA.\n"; + +// const char* missingAutoLayer = +// "AutoContact::create() :\n\n" +// " DataBase is lacking \"AutoLayer\" layer, please check technology file.\n"; + +// const char* emptyJunctionBox = +// " Empty JunctionBox in %s (internal error)."; + + const char* badHookType = + "Hook of %s is neither a SourceHook nor a TargetHook (internal error)."; + + const char* missingAutoSegment = + "No AutoSegment associated to %s (internal error)."; + + +// Forward Declarations. + class StackedContact; + + +// ------------------------------------------------------------------- +// Class : "::UPoint". + + + class UPoint { + // Constructors. + public: + inline UPoint ( bool isHorizontal, DbU::Unit ux, DbU::Unit uy ); + // Accessors. + inline DbU::Unit getUX () const; + inline DbU::Unit getUY () const; + inline DbU::Unit getX () const; + inline DbU::Unit getY () const; + // Modifiers. + inline void setUX ( DbU::Unit ux ); + inline void setUY ( DbU::Unit uy ); + // Attributes. + protected: + bool _isHorizontal; + DbU::Unit _ux; + DbU::Unit _uy; + }; + + +// Inline Functions. + inline UPoint::UPoint ( bool isHorizontal, DbU::Unit ux, DbU::Unit uy ) + : _isHorizontal(isHorizontal), _ux(ux), _uy(uy) {} + inline DbU::Unit UPoint::getUX () const { return _ux; } + inline DbU::Unit UPoint::getUY () const { return _uy; } + inline DbU::Unit UPoint::getX () const { return (_isHorizontal)?_ux:_uy; } + inline DbU::Unit UPoint::getY () const { return (_isHorizontal)?_uy:_ux; } + inline void UPoint::setUX ( DbU::Unit ux ) { _ux = ux; } + inline void UPoint::setUY ( DbU::Unit uy ) { _uy = uy; } + + +// ------------------------------------------------------------------- +// Class : "::SegmentEnd". + + + class SegmentEnd { + public: + struct Compare : public binary_function { + inline bool operator() ( const SegmentEnd* lhs, const SegmentEnd* rhs ) const; + }; + public: + // AutoSegment & Segment wrapped functions. + inline bool isGlobal () const; + inline bool isLocal () const; + inline bool isHorizontal () const; + inline bool isVertical () const; + inline bool isSlackened () const; + inline Net* getNet () const; + inline const Layer* getLayer () const; + inline Hook* getSourceHook (); + inline Hook* getTargetHook (); + inline DbU::Unit getSourceX () const; + inline DbU::Unit getSourceY () const; + inline DbU::Unit getTargetX () const; + inline DbU::Unit getTargetY () const; + inline DbU::Unit getSourceU () const; + inline DbU::Unit getTargetU () const; + inline DbU::Unit getDuSource () const; + inline DbU::Unit getDuTarget () const; + inline DbU::Unit getAxis () const; + inline DbU::Unit getWidth () const; + inline void setDuSource ( DbU::Unit ); + inline void setDuTarget ( DbU::Unit ); + inline void invert (); + inline void invalidate (); + // Constructors & Destructors. + inline SegmentEnd ( AutoSegment* , bool isSourceHook ); + virtual ~SegmentEnd (); + static SegmentEnd* create ( Hook*, bool checking ); + // Accessors. + static size_t getAllocateds (); + inline bool isSourceHook () const; + inline AutoSegment* getSegment () const; + virtual Hook* getHook () const; + inline Point getEnd () const; + inline DbU::Unit getEndX () const; + inline DbU::Unit getEndY () const; + virtual vector* getForks (); + virtual vector* getAligneds (); + // Modifiers. + void setDelta ( DbU::Unit ); + virtual void orient (); + virtual void addFork ( SegmentEnd* ); + virtual void addAligned ( SegmentEnd* ); + virtual void split ( vector& ); + // Inspector Managment. + inline Record* _getRecord () const; + inline string _getString () const; + inline string _getTypeName () const; + protected: + // Attributes. + static size_t _allocateds; + AutoSegment* _autoSegment; + bool _isSourceHook; + }; + + +} + +INSPECTOR_P_SUPPORT(SegmentEnd); + +namespace { + + size_t SegmentEnd::_allocateds = 0; + + SegmentEnd::~SegmentEnd () { _allocateds--; } + size_t SegmentEnd::getAllocateds () { return _allocateds; } + inline bool SegmentEnd::isGlobal () const { return _autoSegment->isGlobal(); } + inline bool SegmentEnd::isLocal () const { return _autoSegment->isLocal(); } + inline bool SegmentEnd::isHorizontal () const { return _autoSegment->isHorizontal(); } + inline bool SegmentEnd::isVertical () const { return _autoSegment->isVertical(); } + inline bool SegmentEnd::isSlackened () const { return _autoSegment->isSlackened(); } + inline AutoSegment* SegmentEnd::getSegment () const { return _autoSegment; } + inline Net* SegmentEnd::getNet () const { return _autoSegment->getNet(); } + inline const Layer* SegmentEnd::getLayer () const { return _autoSegment->getLayer(); } + inline Hook* SegmentEnd::getSourceHook () { return _autoSegment->getSourceHook(); } + inline Hook* SegmentEnd::getTargetHook () { return _autoSegment->getTargetHook(); } + inline DbU::Unit SegmentEnd::getSourceX () const { return _autoSegment->getSourceX(); } + inline DbU::Unit SegmentEnd::getSourceY () const { return _autoSegment->getSourceY(); } + inline DbU::Unit SegmentEnd::getTargetX () const { return _autoSegment->getTargetX(); } + inline DbU::Unit SegmentEnd::getTargetY () const { return _autoSegment->getTargetY(); } + inline DbU::Unit SegmentEnd::getSourceU () const { return _autoSegment->getSourceU(); } + inline DbU::Unit SegmentEnd::getTargetU () const { return _autoSegment->getTargetU(); } + inline DbU::Unit SegmentEnd::getDuSource () const { return _autoSegment->getDuSource(); } + inline DbU::Unit SegmentEnd::getDuTarget () const { return _autoSegment->getDuTarget(); } + inline DbU::Unit SegmentEnd::getAxis () const { return _autoSegment->getAxis(); } + inline DbU::Unit SegmentEnd::getWidth () const { return _autoSegment->getWidth(); } + inline void SegmentEnd::setDuSource ( DbU::Unit du ) { _autoSegment->setDuSource(du); } + inline void SegmentEnd::setDuTarget ( DbU::Unit du ) { _autoSegment->setDuTarget(du); } + inline void SegmentEnd::invert () { _autoSegment->invert(); } + inline void SegmentEnd::invalidate () { _autoSegment->invalidate(); } + inline bool SegmentEnd::isSourceHook () const { return _isSourceHook; } + inline Point SegmentEnd::getEnd () const { return isSourceHook() ? Point(getSourceX(),getSourceY()) : Point(getTargetX(),getTargetY()); } + inline DbU::Unit SegmentEnd::getEndX () const { return isSourceHook() ? getSourceX() : getTargetX(); } + inline DbU::Unit SegmentEnd::getEndY () const { return isSourceHook() ? getSourceY() : getTargetY(); } + vector* SegmentEnd::getForks () { return NULL; } + vector* SegmentEnd::getAligneds () { return NULL; } + void SegmentEnd::addFork ( SegmentEnd* ) {} + void SegmentEnd::addAligned ( SegmentEnd* ) {} + void SegmentEnd::split ( vector& ) {} + inline Record* SegmentEnd::_getRecord () const { return _autoSegment->_getRecord(); } + inline string SegmentEnd::_getString () const { return _autoSegment->_getString(); } + inline string SegmentEnd::_getTypeName () const { return "Katabatic::SegmentEnd"; } + + inline bool SegmentEnd::Compare::operator() ( const SegmentEnd* lhs, const SegmentEnd* rhs ) const + { return AutoSegment::CompareCanonical() ( lhs->getSegment(), rhs->getSegment() ); } + + inline SegmentEnd::SegmentEnd ( AutoSegment* segment, bool isSourceHook ) + : _autoSegment(segment) + , _isSourceHook(isSourceHook) + { + _allocateds++; + } + + + Hook* SegmentEnd::getHook () const + { + if ( isSourceHook() ) return _autoSegment->getSourceHook(); + return _autoSegment->getTargetHook(); + } + + + void SegmentEnd::orient () + { + if ( ( !isGlobal() ) && ( getSourceU() > getTargetU() ) ) { + ltrace(99) << "Orient() before - " << this << endl; + + invert (); + DbU::Unit duSource = getDuSource(); + DbU::Unit duTarget = getDuTarget(); + setDuSource ( duTarget ); + setDuTarget ( duSource ); + _isSourceHook = !_isSourceHook; + + ltrace(99) << "Orient() after - " << this << endl; + } + } + + + void SegmentEnd::setDelta ( DbU::Unit delta ) + { + ltrace(99) << "setDelta(" << DbU::getLambda(delta) << ") - " << this << endl; + + if ( isSourceHook() ) { + if ( getDuSource() != delta ) { + setDuSource ( delta ); + ltrace(99) << "DuSource actualized: " << this << endl; + } + } else { + if ( getDuTarget() != delta ) { + setDuTarget ( delta ); + ltrace(99) << "DuTarget actualized: " << this << endl; + } + } + + orient (); + } + + +} + + +namespace { + + +// ------------------------------------------------------------------- +// Class : "::ForkCompare". + + + class ForkCompare { + public: + inline ForkCompare ( bool increasing ) : _increasing(increasing) {}; + inline bool operator() ( SegmentEnd* lhs, SegmentEnd* rhs ) const; + protected: + bool _increasing; + }; + + + bool ForkCompare::operator() ( SegmentEnd* lhs, SegmentEnd* rhs ) const + { + bool superior = rhs->isGlobal(); + + if ( lhs->getAxis() == rhs->getAxis() ) { + if ( lhs->isLocal() && rhs->isLocal() ) + return false; + } else + superior = lhs->getAxis() > rhs->getAxis(); + + return (_increasing) ? !superior : superior; + } + + +// ------------------------------------------------------------------- +// Class : "::StackedContact". + + + class StackedContact : public Contact { + + public: + static StackedContact* create ( Net* , const Layer* , DbU::Unit x, DbU::Unit y ); + StackedContact ( Net* , const Layer* , DbU::Unit x, DbU::Unit y ); + virtual ~StackedContact (); + public: + void setAnchor ( Component* ); + void addLayer ( const Layer* ); + void attachSlave ( SegmentEnd* ); + void breakUp (); + + protected: + vector _useds; + Component* _anchor; + private: + StackedContact ( const StackedContact& ); + StackedContact& operator= ( const StackedContact& ); + }; + + +// ------------------------------------------------------------------- +// Class : "::GlobalEnd". + + + class GlobalEnd : public SegmentEnd { + public: + GlobalEnd ( AutoSegment* , bool isSourceHook ); + virtual ~GlobalEnd (); + virtual vector* getForks (); + virtual vector* getAligneds (); + virtual void split ( vector& ); + virtual void addFork ( SegmentEnd* ); + virtual void addAligned ( SegmentEnd* ); + virtual Segment* _create ( Contact* source, Contact* target ) = 0; + protected: + vector _forks; + vector _aligneds; + }; + + + GlobalEnd::GlobalEnd ( AutoSegment* segment, bool isSourceHook ) + : SegmentEnd(segment,isSourceHook) + , _forks() + , _aligneds() + {} + + + GlobalEnd::~GlobalEnd () + {} + + + vector* GlobalEnd::getForks () + { + return &_forks; + } + + + vector* GlobalEnd::getAligneds () + { + return &_aligneds; + } + + + void GlobalEnd::addFork ( SegmentEnd* segmentEnd ) + { + for ( size_t i = 0 ; i < _forks.size() ; i++ ) { + if ( _forks[i] == segmentEnd ) return; + } + _forks.push_back ( segmentEnd ); + } + + + void GlobalEnd::addAligned ( SegmentEnd* segmentEnd ) + { + for ( size_t i = 0 ; i < _aligneds.size() ; i++ ) { + if ( _aligneds[i] == segmentEnd ) return; + } + _aligneds.push_back ( segmentEnd ); + } + + + void GlobalEnd::split ( vector& stackedContacts ) + { + ltrace(99) << "GlobalEnd::split() - " << this << endl; + ltracein(99); + + sort ( _forks.begin(), _forks.end(), ForkCompare(!isSourceHook()) ); + + StackedContact* contact1 = NULL; + StackedContact* contact2 = NULL; + const Layer* contactLayer = NULL; + Hook* hook = getHook(); + vector::iterator it = _forks.begin(); + + if ( it == _forks.end() ) { + ltrace(99) << "No forks!" << endl; + stackedContacts.push_back ( StackedContact::create ( getNet() + , getLayer() + , getEndX() + , getEndY() + ) ); + stackedContacts.back()->attachSlave ( this ); + + ltraceout(99); + return; + } + + ltrace(99) << "splitted Axis " << DbU::getLambda(getAxis()) << endl; + ltrace(99) << "iterator Axis " << DbU::getLambda((*it)->getAxis()) << " " << (*it) << endl; + + UPoint center ( isHorizontal(), (*it)->getAxis(), getAxis() ); + contactLayer = Session::getTechnology()->getViaBetween ( getLayer(), (*it)->getLayer() ); + stackedContacts.push_back + ( StackedContact::create ( getNet(), contactLayer, center.getX(), center.getY() ) ); + contact1 = stackedContacts.back (); + contact1->attachSlave ( *it ); + + hook->detach (); + hook->attach ( contact1->getBodyHook() ); + setDelta ( 0 ); + + for ( it++ ; it != _forks.end() ; it++ ) { + ltrace(99) << "splitted Axis " << DbU::getLambda(getAxis()) << endl; + ltrace(99) << "iterator Axis " << DbU::getLambda((*it)->getAxis()) << " " << (*it) << endl; + + if ( (*(it-1))->getAxis() != (*it)->getAxis() ) { + UPoint center ( isHorizontal(), (*it)->getAxis(), getAxis() ); + contactLayer = Session::getTechnology()->getViaBetween ( getLayer(), (*it)->getLayer() ); + stackedContacts.push_back + ( StackedContact::create ( getNet(), contactLayer, center.getX(), center.getY() ) ); + contact2 = stackedContacts.back (); + } else { + contact2 = contact1; + } + + if ( contact1 != contact2 ) { + if ( !isSourceHook() ) _create ( contact1, contact2 ); + else _create ( contact2, contact1 ); + } + + contact2->attachSlave ( *it ); + contact1 = contact2; + } + + for ( it = _aligneds.begin() ; it != _aligneds.end() ; it++ ) { + if ( isSourceHook() == (*it)->isSourceHook() ) { + stackedContacts.front()->attachSlave ( *it ); + } else { + stackedContacts.back()->attachSlave ( *it ); + } + } + + ltraceout(99); + } + + +// ------------------------------------------------------------------- +// Class : "::HorizontalEnd". + + + class HorizontalEnd : public GlobalEnd { + public: + HorizontalEnd ( AutoSegment* , bool isSourceHook ); + virtual ~HorizontalEnd (); + virtual Segment* _create ( Contact* source , Contact* target ); + }; + + + HorizontalEnd::HorizontalEnd ( AutoSegment* horizontal, bool isSourceHook ) + : GlobalEnd(horizontal,isSourceHook) + { } + + + HorizontalEnd::~HorizontalEnd () + { } + + + Segment* HorizontalEnd::_create ( Contact* source , Contact* target ) + { + return Horizontal::create ( source, target, getLayer(), getAxis(), getWidth() ); + } + + +// ------------------------------------------------------------------- +// Class : "::VerticalEnd". + + + class VerticalEnd : public GlobalEnd { + public: + VerticalEnd ( AutoSegment* , bool isSourceHook ); + virtual ~VerticalEnd (); + virtual Segment* _create ( Contact* source , Contact* target ); + }; + + + VerticalEnd::VerticalEnd ( AutoSegment* vertical, bool isSourceHook ) + : GlobalEnd(vertical,isSourceHook) + { } + + + VerticalEnd::~VerticalEnd () + { } + + + Segment* VerticalEnd::_create ( Contact* source , Contact* target ) + { + return Vertical::create ( source, target, getLayer(), getAxis(), getWidth() ); + } + + +// ------------------------------------------------------------------- +// Static Generic Constructor for all SegmentEnd. + + + SegmentEnd* SegmentEnd::create ( Hook* hook, bool checking ) + { + bool isSourceHook = (dynamic_cast(hook)); + if ( !isSourceHook && ( dynamic_cast(hook) == NULL ) ) { + cerr << Error ( badHookType, getString(hook->getComponent()).c_str() ) << endl; + return NULL; + } + + AutoSegment* autoSegment = Session::lookup ( dynamic_cast(hook->getComponent()) ); + + if ( !autoSegment ) + throw Error ( missingAutoSegment, getString(hook->getComponent()).c_str() ); + + if ( !checking ) + autoSegment->invalidate (); + + if ( autoSegment->isGlobal() ) { + if ( autoSegment->isHorizontal() ) + return new HorizontalEnd ( autoSegment, isSourceHook ); + else + return new VerticalEnd ( autoSegment, isSourceHook ); + } else { + if ( autoSegment->isHorizontal() ) + return new SegmentEnd ( autoSegment, isSourceHook ); + } + return new SegmentEnd ( autoSegment, isSourceHook ); + } + + +// ------------------------------------------------------------------- +// Class : "::JunctionBox". + + + class JunctionBox { + + public: + // Constructor & Destructor. + JunctionBox ( AutoContact*, bool checking ); + ~JunctionBox (); + // Predicates. + inline bool isVFlat (); + inline bool isHFlat (); + inline bool isFlat (); + inline bool isPunctual (); + inline bool isVEmpty (); + inline bool isHEmpty (); + inline bool isEmpty (); + bool isHExtended (); + bool isVExtended (); + bool canGoOutside ( const AutoSegment* ) const; + bool canHDesalignate () const; + bool canVDesalignate () const; + void getZSpan ( size_t& zMin, size_t& zMax ) const; + // Modifiers. + void checkTopology (); + void revalidateTopology (); + void computeGlobalStem (); + void computeAlignate (); + void mergeX ( DbU::Unit ); + void mergeY ( DbU::Unit ); + void mergeAnchor (); + void merge ( Hook* ); + void postMerge ( SegmentEnd* ); + void resizePunctual (); + void resize (); + void breakUpPunctual (); + void breakUp (); + void split (); + void splitTerminal (); + void updateContacts ( VirtualContacts& ); + void restoreHConnexity ( DbU::Unit x, bool split ); + void restoreVConnexity ( DbU::Unit y, bool split ); + + protected: + // Attributes. + RoutingGauge* _routingGauge; + AutoContact* _contact; + Component* _anchor; + DbU::Unit _xMin; + DbU::Unit _yMin; + DbU::Unit _xMax; + DbU::Unit _yMax; + SegmentEnd* _globalStem; + vector _globalEnds; + vector _localEnds; + vector _layerStack; + size_t _wireCount; + bool _failsafe; + bool _checking; + }; + + + inline bool JunctionBox::isVFlat () { return _yMin == _yMax; } + inline bool JunctionBox::isHFlat () { return _xMin == _xMax; } + inline bool JunctionBox::isFlat () { return isHFlat() || isVFlat(); } + inline bool JunctionBox::isPunctual () { return isHFlat() && isVFlat(); } + inline bool JunctionBox::isVEmpty () { return _yMin > _yMax; } + inline bool JunctionBox::isHEmpty () { return _xMin > _xMax; } + inline bool JunctionBox::isEmpty () { return isHEmpty() || isVEmpty(); } + + + JunctionBox::JunctionBox ( AutoContact* contact, bool checking ) + : _routingGauge(Session::getRoutingGauge()) + , _contact (contact) + , _anchor (NULL) + , _xMin (+1) + , _yMin (+1) + , _xMax (-1) + , _yMax (-1) + , _globalStem (NULL) + , _globalEnds () + , _localEnds () + , _layerStack (Session::getRoutingGauge()->getDepth()) + , _wireCount (0) + , _failsafe (false) + , _checking (checking) + { + ltrace(110) << "JunctionBox() " << contact << endl; + ltracein(109); + + forEach ( Hook*, hook, _contact->getBodyHook()->getSlaveHooks() ) merge ( *hook ); + mergeAnchor (); + + sort ( _globalEnds.begin(), _globalEnds.end(), SegmentEnd::Compare() ); + sort ( _localEnds.begin() , _localEnds.end() , SegmentEnd::Compare() ); + + if ( ( _wireCount < 1 ) && !_contact->getAnchor() ) + cerr << Warning("%s has less than 2 wires (%d)" + ,getString(_contact).c_str(),_wireCount) << endl; + + computeGlobalStem (); + if ( _globalStem ) { + ltrace(109) << "_globalStem: " << _globalStem << endl; + for ( size_t i=0 ; i < _localEnds.size() ; i++ ) + postMerge ( _localEnds[i] ); + for ( size_t i=0 ; i < _globalEnds.size() ; i++ ) + postMerge ( _globalEnds[i] ); + + ltraceout(109); + return; + } + + if ( isPunctual() || (isFlat() && !_contact->getAnchor()) ) { + ltraceout(109); + return; + } + + // JunctionBox is empty, non-flat or flat with anchor. + _failsafe = true; + ltraceout(109); + } + + + JunctionBox::~JunctionBox () + { + for ( size_t i = 0 ; i < _globalEnds.size() ; i++ ) delete _globalEnds[i]; + for ( size_t i = 0 ; i < _localEnds.size() ; i++ ) delete _localEnds[i]; + } + + + bool JunctionBox::isHExtended () + { + if ( _globalStem ) { + ltrace(109) << "JunctionBox::isHExtended(): " << _globalStem->isHorizontal() << endl; + return _globalStem->isHorizontal(); + } + return _contact->isHAlignate(); + } + + + bool JunctionBox::isVExtended () + { + if ( _globalStem ) { + ltrace(109) << "JunctionBox::isVExtended(): " << _globalStem->isVertical() << endl; + return _globalStem->isVertical(); + } + return _contact->isVAlignate(); + } + + + void JunctionBox::getZSpan ( size_t& zMin, size_t& zMax ) const + { + bool minFound = false; + + zMin = 0; + zMax = 0; + for ( size_t i=0 ; i<_layerStack.size() ; i++ ) { + if ( !minFound ) { + if ( _layerStack[i] > 0 ) { + zMin = zMax = i; + minFound = true; + } + } else { + if ( _layerStack[i] > 0 ) { + zMax = i; + } + } + } + } + + + void JunctionBox::revalidateTopology () + { + _contact->setInvalidatedTopology ( false ); + _contact->setCorner ( false ); + if ( !_contact->getAnchor() ) { + size_t horizontals = 0; + size_t verticals = 0; + + for ( size_t i=0 ; i < _globalEnds.size() ; i++ ) { + if ( _globalEnds[i]->isHorizontal() ) horizontals++; + else verticals++; + } + for ( size_t i=0 ; i < _localEnds.size() ; i++ ) { + if ( _localEnds[i]->isHorizontal() ) horizontals++; + else verticals++; + } + _contact->setCorner ( (horizontals == 1) + and (verticals == 1) + and (not _contact->isHAlignate()) + and (not _contact->isVAlignate()) ); + } + + checkTopology (); + } + + + void JunctionBox::checkTopology () + { + vector errors; + + bool anchored = (_contact->getAnchor()); + bool alignateHorizontal = _contact->isHAlignate() || anchored; + bool alignateVertical = _contact->isVAlignate() || anchored; + bool globalHorizontal = false; + bool globalVertical = false; + size_t localHorizontals = 0; + size_t localVerticals = 0; + + for ( size_t i=0 ; i < _globalEnds.size() ; i++ ) { + if ( _globalEnds[i]->isHorizontal() ) { + globalHorizontal = true; + localHorizontals++; + } else { + globalVertical = true; + localVerticals++; + } + } + + for ( size_t i=0 ; i < _localEnds.size() ; i++ ) { + if ( _localEnds[i]->isHorizontal() ) localHorizontals++; + else localVerticals++; + } + + if ( !(localHorizontals || globalHorizontal || anchored) ) + errors.push_back ( "No horizontal components" ); + + if ( !(localVerticals || globalVertical || anchored) ) + errors.push_back ( "No vertical components" ); + + if ( !alignateHorizontal && !globalVertical && (localHorizontals > 1) ) + errors.push_back ( "Disconnecteds horizontals components" ); + + if ( !alignateVertical && !globalHorizontal && (localVerticals > 1) ) + errors.push_back ( "Disconnecteds verticals components" ); + + if ( _globalEnds.size() > 3 ) + errors.push_back ( "More than three globals" ); + + if ( ( _globalEnds.size() == 3 ) && ( _localEnds.size() ) ) + errors.push_back ( "Three globals AND locals" ); + + if ( _globalEnds.size() + _localEnds.size() + ((anchored)?1:0) < 2 ) + errors.push_back ( "Less than two connections" ); + + if ( errors.size() ) { + cerr << Error("AutoContact topology of %s",getString(_contact).c_str()) << endl; + if ( anchored ) + cerr << " A: " << _contact->getAnchor() << endl; + + for ( size_t i=0 ; i < _globalEnds.size() ; i++ ) + cerr << " G: " << _globalEnds[i] << endl; + + for ( size_t i=0 ; i < _localEnds.size() ; i++ ) + cerr << " L: " << _localEnds[i] << endl; + + for ( size_t i=0 ; i < errors.size() ; i++ ) + cerr << " " << errors[i] << endl; + } + } + + + bool JunctionBox::canGoOutside ( const AutoSegment* segment ) const + { + if ( _contact->isCorner () ) return true; + if ( _contact->getAnchor() ) return false; + + for ( size_t i=0 ; i < _globalEnds.size() ; i++ ) { + if ( _globalEnds[i]->isHorizontal() xor segment->isHorizontal() ) { + ltrace(200) << "canGoOutside(): true (has global) " << _contact << endl; + return true; + } + } + + return false; + } + + + bool JunctionBox::canHDesalignate () const + { + if ( _contact->getAnchor () ) return false; + if ( !_contact->isHAlignate() ) return false; + + SegmentEnd* globalHorizontal = NULL; + SegmentEnd* globalVertical = NULL; + + size_t verticals = 0; + for ( size_t i=0 ; i < _globalEnds.size() ; i++ ) { + ltrace(109) << _globalEnds[i]->getSegment() << endl; + if ( _globalEnds[i]->isHorizontal() ) { + globalHorizontal = _globalEnds[i]; + } else { + globalVertical = _globalEnds[i]; + verticals++; + } + } + + for ( size_t i=0 ; i < _localEnds.size() ; i++ ) { + ltrace(109) << _localEnds[i]->getSegment() << endl; + if ( _localEnds[i]->isVertical() ) verticals++; + } + + ltrace(200) << "canHDesalignate(Contact*) - " << _contact << endl; + ltrace(200) << " Vertical stem: " << globalVertical + << " isVAlignate():" << _contact->isVAlignate() + << " verticals:" << verticals + << endl; + return (globalVertical != NULL) && (_contact->isVAlignate() || (verticals == 1)); + } + + + bool JunctionBox::canVDesalignate () const + { + if ( _contact->getAnchor () ) return false; + if ( !_contact->isVAlignate() ) return false; + + SegmentEnd* globalHorizontal = NULL; + SegmentEnd* globalVertical = NULL; + + size_t horizontals = 0; + for ( size_t i=0 ; i < _globalEnds.size() ; i++ ) { + if ( _globalEnds[i]->isHorizontal() ) { + globalHorizontal = _globalEnds[i]; + horizontals++; + } else { + globalVertical = _globalEnds[i]; + } + } + + for ( size_t i=0 ; i < _localEnds.size() ; i++ ) { + ltrace(109) << _localEnds[i]->getSegment() << endl; + if ( _localEnds[i]->isHorizontal() ) horizontals++; + } + + ltrace(200) << "canVDesalignate(Contact*) - " << _contact << endl; + ltrace(200) << " Vertical stem: " << globalHorizontal + << " isHAlignate():" << _contact->isHAlignate() + << " horizontals:" << horizontals + << endl; + return (globalHorizontal != NULL) && (_contact->isHAlignate() || (horizontals == 1)); + } + + + void JunctionBox::restoreHConnexity ( DbU::Unit x, bool split ) + { + ltrace(200) << "restoreHConnexity() - @" << DbU::getValueString(x) << " " << _contact << endl; + + _contact->invalidate (); + + if ( _contact->isHAlignate() ) return; + if ( _contact->getAnchor () ) { + _contact->setHAlignate ( true ); + return; + } + + bool slackened = false; + SegmentEnd* verticalStem = NULL; + vector horizontals; + for ( size_t i=0 ; i < _globalEnds.size() ; i++ ) { + if ( _globalEnds[i]->isHorizontal() ) { + horizontals.push_back ( _globalEnds[i] ) ; + } else { + verticalStem = _globalEnds[i]; + } + } + + if ( verticalStem ) { + ltrace(200) << "Done nothing has vertical stem: " << verticalStem << endl; + return; + } + + for ( size_t i=0 ; i<_localEnds.size() ; i++ ) { + if ( _localEnds[i]->isHorizontal() ) + horizontals.push_back ( _localEnds[i] ) ; + else + slackened = slackened or _localEnds[i]->isSlackened(); + } + + if ( (horizontals.size() == 1) and (horizontals[0]->isGlobal()) ) { + ltrace(200) << "Done nothing, has only a horizontal stem: " << horizontals[0] << endl; + return; + } + + if ( !split ) { + _contact->setHAlignate ( true ); + return; + } + + GCell* gcell = _contact->getGCell (); + Net* net = _contact->getNet (); + const Layer* layer = dynamic_cast(_contact->getLayer())->getTop(); + if ( _routingGauge->getLayerDirection(layer) != Constant::Vertical ) + layer = dynamic_cast(_contact->getLayer())->getBottom(); + + _contact->setVAlignate ( true ); + AutoContact* splitContact = NULL; + for ( size_t i=1 ; isetVAlignate ( true ); + + ltrace(200) << "| Separate " << horizontals[i]->getSegment()->base() + << ":" << horizontals[i]->getSegment() << endl; + + horizontals[i]->getHook()->detach(); + + splitContact = AutoContact::create ( gcell, net, _contact->getLayer() ); + AutoSegment* segment = AutoVertical::create ( _contact + , splitContact + , layer + , x //globalHorizontals[i]->getAxis() + , DbU::lambda(2.0) + , AutoSegment::Local + , false + , false + ); + horizontals[i]->getHook()->attach ( splitContact->getContact()->getBodyHook() ); + segment->setSlackened ( slackened ); + ltrace(200) << "restoreHConnexity() strap: " << segment << endl; + } + } + + + void JunctionBox::restoreVConnexity ( DbU::Unit y, bool split ) + { + ltrace(200) << "restoreVConnexity() - @" << DbU::getValueString(y) << " " << _contact << endl; + + _contact->invalidate (); + + if ( _contact->isVAlignate() ) return; + if ( _contact->getAnchor () ) { + _contact->setVAlignate ( true ); + return; + } + + bool slackened = false; + SegmentEnd* horizontalStem = NULL; + vector verticals; + for ( size_t i=0 ; i < _globalEnds.size() ; i++ ) { + if ( _globalEnds[i]->isVertical() ) { + verticals.push_back ( _globalEnds[i] ) ; + } else { + horizontalStem = _globalEnds[i]; + } + } + + if ( horizontalStem ) { + ltrace(200) << "Done nothing, has horizontal stem: " << horizontalStem << endl; + return; + } + + for ( size_t i=0 ; i<_localEnds.size() ; i++ ) { + if ( _localEnds[i]->isVertical() ) + verticals.push_back ( _localEnds[i] ) ; + else + slackened = slackened or _localEnds[i]->isSlackened(); + } + + if ( (verticals.size() == 1) and (verticals[0]->isGlobal()) ) { + ltrace(200) << "Done nothing, has only a vertical stem: " << verticals[0] << endl; + return; + } + + if ( !split ) { + _contact->setVAlignate ( true ); + return; + } + + GCell* gcell = _contact->getGCell (); + Net* net = _contact->getNet (); + const Layer* layer = dynamic_cast(_contact->getLayer())->getBottom(); + if ( _routingGauge->getLayerDirection(layer) != Constant::Horizontal ) + layer = dynamic_cast(_contact->getLayer())->getTop(); + + _contact->setHAlignate ( true ); + AutoContact* splitContact = NULL; + for ( size_t i=1 ; isetHAlignate ( true ); + + ltrace(200) << "| Separate " << verticals[i]->getSegment()->base() + << ":" << verticals[i]->getSegment() << endl; + + verticals[i]->getHook()->detach(); + + splitContact = AutoContact::create ( gcell, net, _contact->getLayer() ); + AutoSegment* segment = AutoHorizontal::create ( _contact + , splitContact + , layer + , y //globalVerticals[i]->getAxis() + , DbU::lambda(2.0) + , AutoSegment::Local + , false + , false + ); + verticals[i]->getHook()->attach ( splitContact->getContact()->getBodyHook() ); + segment->setSlackened ( slackened ); + ltrace(200) << "restoreVConnexity() strap: " << segment << endl; + } + } + + + void JunctionBox::computeAlignate () + { + + bool globalHorizontal = false; + bool globalVertical = false; + size_t horizontals = 0; + size_t verticals = 0; + + for ( size_t i=0 ; i < _globalEnds.size() ; i++ ) { + if ( _globalEnds[i]->isHorizontal() ) { + globalHorizontal = true; + horizontals++; + } else { + globalVertical = true; + verticals++; + } + } + + for ( size_t i=0 ; i < _localEnds.size() ; i++ ) { + if ( _localEnds[i]->isHorizontal() ) horizontals++; + else verticals++; + } + + if ( !globalVertical && (horizontals > 1) ) + _contact->setHAlignate ( true ); + + if ( !globalHorizontal && (verticals > 1) ) + _contact->setVAlignate ( true ); + + ltrace(109) << "computeAlignate(): [AFTER] " << _contact << endl; + } + + + void JunctionBox::computeGlobalStem () + { + SegmentEnd* globalHorizontal = NULL; + SegmentEnd* globalVertical = NULL; + size_t horizontals = 0; + size_t verticals = 0; + + for ( size_t i=0 ; i < _globalEnds.size() ; i++ ) { + if ( _globalEnds[i]->isHorizontal() ) { + globalHorizontal = _globalEnds[i]; + horizontals++; + } else { + globalVertical = _globalEnds[i]; + verticals++; + } + } + + for ( size_t i=0 ; i < _localEnds.size() ; i++ ) { + if ( _localEnds[i]->isHorizontal() ) horizontals++; + else verticals++; + } + + ltrace(109) << "computeGlobalStem(): " << _contact << endl; + ltrace(109) << "| h:" << horizontals << " v:" << verticals << endl; + + if ( globalVertical && (horizontals > 1) && !_contact->isHAlignate() ) { + ltrace(109) << "| Vertical GlobalStem h:" << horizontals << " v:" << verticals << endl; + _globalStem = globalVertical; + } + + if ( globalHorizontal && (verticals > 1) && !_contact->isVAlignate() ) { + ltrace(109) << "| Horizontal GlobalStem h:" << horizontals << " v:" << verticals << endl; + _globalStem = globalHorizontal; + } + + + if ( (horizontals > 1) && (verticals > 1) && !_contact->isVAlignate() && !_contact->isHAlignate() ) { + ltrace(109) << "* Bad AutoContact: " << _contact << endl; + + for ( size_t i=0 ; i < _globalEnds.size() ; i++ ) + ltrace(109) << "| G: " << _globalEnds[i] << endl; + + for ( size_t i=0 ; i < _localEnds.size() ; i++ ) + ltrace(109) << "| L: " << _localEnds[i] << endl; + } + } + + + void JunctionBox::mergeX ( DbU::Unit x ) + { + if ( _xMin > _xMax ) { _xMin = _xMax = x; return; } + if ( x < _xMin ) { _xMin = x; return; } + if ( x > _xMax ) { _xMax = x; return; } + } + + + void JunctionBox::mergeY ( DbU::Unit y ) + { + if ( _yMin > _yMax ) { _yMin = _yMax = y; return; } + if ( y < _yMin ) { _yMin = y; return; } + if ( y > _yMax ) { _yMax = y; return; } + } + + + void JunctionBox::mergeAnchor () + { + _anchor = _contact->getAnchor (); + if ( !_anchor ) return; + + RoutingPad* rp = dynamic_cast(_anchor); + if ( !rp ) { + _failsafe = true; + return; + } + + _layerStack [ _routingGauge->getLayerDepth(_anchor->getLayer()) ] ++; + _wireCount++; + + Point source = rp->getSourcePosition (); + Point target = rp->getTargetPosition (); + if ( ( source.getX() == target.getX() ) || isHEmpty() ) { + ltrace(109) << "merge() Axis " + << DbU::getLambda(source.getX()) << " [RoutingPad] " + << rp->getLayer() << endl; + mergeX ( source.getX() ); + } + if ( ( source.getY() == target.getY() ) || isVEmpty() ) { + ltrace(109) << "merge() Axis " + << DbU::getLambda(source.getY()) << " [RoutingPad] " + << rp->getLayer() << endl; + mergeY ( source.getY() ); + } + } + + + void JunctionBox::merge ( Hook* hook ) + { + SegmentEnd* segmentEnd = SegmentEnd::create ( hook, _checking ); + if ( !segmentEnd ) return; + + _layerStack [ _routingGauge->getLayerDepth(segmentEnd->getLayer()) ] ++; + _wireCount++; + + if ( segmentEnd->isGlobal() ) { + ltrace(109) << "merge() Axis " + << DbU::getLambda(segmentEnd->getAxis()) + << " [global] " << segmentEnd << endl; + _globalEnds.push_back ( segmentEnd ); + } else { + ltrace(109) << "merge() Axis " << DbU::getLambda(segmentEnd->getAxis()) + << " [local] " << segmentEnd << endl; + _localEnds.push_back ( segmentEnd ); + } + + if ( segmentEnd->isHorizontal() ) mergeY ( segmentEnd->getAxis() ); + else mergeX ( segmentEnd->getAxis() ); + } + + + void JunctionBox::postMerge ( SegmentEnd* segmentEnd ) + { + if ( segmentEnd == _globalStem ) return; + + if ( _globalStem->isHorizontal() xor segmentEnd->isHorizontal() ) + _globalStem->addFork ( segmentEnd ); + else + _globalStem->addAligned ( segmentEnd ); + } + + + void JunctionBox::resizePunctual () + { + Point center; + DbU::Unit delta; + + if ( isEmpty() ) center = _contact->getCenter(); + else if ( isPunctual() ) { + center.setX ( _xMin ); + center.setY ( _yMin ); + } else { + center.setX ( (_xMin+_xMax)/2 ); + center.setY ( (_yMin+_yMax)/2 ); + } + + for ( size_t i=0 ; i < _globalEnds.size() ; i++ ) { + if ( _globalEnds[i]->isHorizontal() ) + delta = center.getX() - _contact->getX(); + else + delta = center.getY() - _contact->getY(); + _globalEnds[i]->setDelta ( delta ); + } + + for ( size_t i=0 ; i < _localEnds.size() ; i++ ) { + if ( _localEnds[i]->isHorizontal() ) + delta = center.getX() - _contact->getX(); + else + delta = center.getY() - _contact->getY(); + + _localEnds[i]->setDelta ( delta ); + } + + Box constraint = _contact->getConstraintBox()/*.inflate(DbU::lambda(0.5))*/; + if ( !constraint.contains(center) ) + cerr << Bug("%s [%s %s] outside constraint %s." + ,getString(_contact).c_str() + ,DbU::getValueString(center.getX()).c_str() + ,DbU::getValueString(center.getY()).c_str() + ,getString(constraint).c_str()) << endl; + } + + + void JunctionBox::resize () + { + ltrace(99) << "JunctionBox::resize() - " << endl; + + if ( !_wireCount ) { + cerr << Warning("Standalone %s skipped.",getString(_contact).c_str()) << endl; + return; + } + + if ( _failsafe || isPunctual() || !_globalStem ) + resizePunctual (); + else { + // Flat geometry. + DbU::Unit deltaMin; + DbU::Unit deltaMax; + DbU::Unit deltaFork; + + if ( _globalStem->isHorizontal() ) { + deltaMin = _xMin - _contact->getX(); + deltaMax = _xMax - _contact->getX(); + deltaFork = _yMin - _contact->getY(); + } else { + deltaMin = _yMin - _contact->getY(); + deltaMax = _yMax - _contact->getY(); + deltaFork = _xMin - _contact->getX(); + } + + _globalStem->setDelta ( _globalStem->isSourceHook() ? deltaMin : deltaMax ); + + vector* forks = _globalStem->getForks(); + vector* aligneds = _globalStem->getAligneds(); + + for ( size_t i=0 ; i < aligneds->size() ; i++ ) + (*aligneds)[i]->setDelta ( (*aligneds)[i]->isSourceHook() ? deltaMax : deltaMin ); + + for ( size_t i=0 ; i < forks->size() ; i++ ) + (*forks)[i]->setDelta ( deltaFork ); + } + } + + + void JunctionBox::split () + { + ltrace(200) << "JunctionBox::split() - " << _contact << endl; + + size_t zMin, zMax; + size_t anchorDepth = 0; + getZSpan ( zMin, zMax ); + + if ( _anchor ) { + ltrace(200) << "Anchor: " << _anchor << endl; + + anchorDepth = _routingGauge->getLayerDepth(_anchor->getLayer()); + if ( anchorDepth == 0 ) { + if ( zMax-zMin < 2 ) return; + splitTerminal (); + _contact->split (); + return; + } + } + + ltracein(200); + ltrace(200) << "Z span: [" << zMin << ":" << zMax << "]" << endl; + ltrace(200) << "Global Stem: " << _globalStem << endl; + + if ( zMax-zMin > 3 ) { + cerr << Error("AutoContact::split(): Spans on more than 4 layers, ignoring." + "\n %s",getString(_contact).c_str()) << endl; + ltraceout(200); + return; + } + + _contact->invalidate (); + + if ( zMax-zMin < 2 ) { + const Layer* contactLayer = _routingGauge->getContactLayer(zMin); + _contact->setLayer ( contactLayer ); + ltrace(200) << "Needs only to change Layer." << endl; + ltraceout(200); + return; + } + + // The complete case. + bool hExtended = isHExtended(); + bool vExtended = isVExtended(); + bool xFound = false; + bool yFound = false; + vector hBottom; + vector vBottom; + vector hTop; + vector vTop; + Point position; + + for ( size_t i=0; i < _globalEnds.size() ; i++ ) { + ltrace(200) << "| G: " << _globalEnds[i] << endl; + if ( _globalEnds[i]->isHorizontal() ) { + if ( not yFound ) { + yFound = true; + position.setY ( _globalEnds[i]->getAxis() ); + } + if ( _routingGauge->getLayerDepth(_globalEnds[i]->getLayer()) < zMin+2 ) + hBottom.push_back ( _globalEnds[i] ); + else + hTop.push_back ( _globalEnds[i] ); + } else { + if ( not xFound ) { + xFound = true; + position.setX ( _globalEnds[i]->getAxis() ); + } + if ( _routingGauge->getLayerDepth(_globalEnds[i]->getLayer()) < zMin+2 ) + vBottom.push_back ( _globalEnds[i] ); + else + vTop.push_back ( _globalEnds[i] ); + } + } + + for ( size_t i=0; i < _localEnds.size() ; i++ ) { + ltrace(200) << "| L: " << _localEnds[i] << endl; + if ( _localEnds[i]->isHorizontal() ) { + if ( not yFound ) { + yFound = true; + position.setY ( _localEnds[i]->getAxis() ); + } + if ( _routingGauge->getLayerDepth(_localEnds[i]->getLayer()) < zMin+2 ) + hBottom.push_back ( _localEnds[i] ); + else + hTop.push_back ( _localEnds[i] ); + } else { + if ( not xFound ) { + xFound = true; + position.setX ( _localEnds[i]->getAxis() ); + } + if ( _routingGauge->getLayerDepth(_localEnds[i]->getLayer()) < zMin+2 ) + vBottom.push_back ( _localEnds[i] ); + else + vTop.push_back ( _localEnds[i] ); + } + } + + if ( not xFound ) position.setX ( _xMin ); + if ( not yFound ) position.setY ( _yMin ); + + for ( size_t i=0 ; igetHook()->detach (); + for ( size_t i=0 ; igetHook()->detach (); + + AutoContact* corner = AutoContact::create ( _contact->getGCell() + , _contact->getNet() + , _routingGauge->getContactLayer(zMin+1) + ); + ltrace(200) << "Corner " << corner << endl; + + AutoSegment* segment = AutoSegment::create ( _contact + , corner + , _routingGauge->getLayerDirection(zMin+1) + , AutoSegment::Local + ); + DbU::Unit axis = (segment->isHorizontal()) ? position.getY() : position.getX(); + segment->setLayer ( _routingGauge->getRoutingLayer(zMin+1) ); + segment->setAxis ( axis ); + segment->setSlackened ( true ); + segment->setLayerChange ( true ); + ltrace(200) << "Corner @" << DbU::getValueString(axis) << " " << segment << endl; + + if ( vExtended ) _contact->setVAlignate ( true ); + if ( hExtended ) _contact->setHAlignate ( true ); + + AutoContact* secondary = NULL; + if ( zMax-zMin == 3 ) { + secondary = AutoContact::create ( _contact->getGCell() + , _contact->getNet() + , _routingGauge->getContactLayer(zMin+2) + ); + ltrace(200) << "Secondary " << secondary << endl; + + segment = AutoSegment::create ( corner + , secondary + , _routingGauge->getLayerDirection(zMin+2) + , AutoSegment::Local + ); + axis = (segment->isHorizontal()) ? position.getY() : position.getX(); + segment->setLayer ( _routingGauge->getRoutingLayer(zMin+2) ); + segment->setAxis ( axis ); + segment->setCanonical ( true ); + segment->setSlackened ( true ); + segment->setLayerChange ( true ); + ltrace(200) << "Secondary @" << DbU::getValueString(axis) << " " << segment << endl; + } else + secondary = corner; + + for ( size_t i=0 ; igetHook()->attach ( secondary->getBodyHook() ); + for ( size_t i=0 ; igetHook()->attach ( secondary->getBodyHook() ); + + if ( _contact->isVAlignate() ) secondary->setVAlignate(true); + if ( _contact->isHAlignate() ) secondary->setHAlignate(true); + + if ( hExtended ) { + ltrace(200) << "Original was H extended: restore V connexity." << endl; + _contact ->restoreVConnexity ( position.getY(), true ); + secondary->restoreVConnexity ( position.getY(), true ); + } + + if ( vExtended ) { + ltrace(200) << "Original was V extended: restore H connexity." << endl; + _contact ->restoreHConnexity ( position.getX(), true ); + secondary->restoreHConnexity ( position.getX(), true ); + } + + ltraceout(200); + } + + + void JunctionBox::splitTerminal () + { + ltrace(200) << "JunctionBox::splitTerminal(): AutoSegment connected to RoutingPad." << endl; + ltracein(200); + Point position = _contact->getPosition (); + + _contact->getAnchorHook()->detach (); + + RoutingPad* routingPad = dynamic_cast ( _anchor ); + if ( !routingPad ) { + cerr << Bug("JunctionBox::splitTerminal(): %s is not anchored on a ." + ,getString(_contact).c_str()) << endl; + ltraceout(200); + return; + } + + AutoContact* rpContact = AutoContact::fromRp ( _contact->getGCell() + , routingPad + , _routingGauge->getContactLayer(0) + , position + , DbU::lambda(1.0), DbU::lambda(1.0) + ); + AutoContact* via23 = AutoContact::create ( _contact->getGCell() + , _contact->getNet() + , _routingGauge->getContactLayer(1) + ); + + AutoSegment* segment = AutoSegment::create ( rpContact + , via23 + , Constant::Horizontal + , AutoSegment::Local + , true // terminal. + , false // Temporary: *not* collapsed. + ); + segment->setLayer ( _routingGauge->getRoutingLayer(1) ); + segment->setAxis ( position.getY() ); + ltrace(200) << "@" << DbU::getValueString(position.getY()) << segment << endl; + + segment = AutoSegment::create ( via23 + , _contact + , Constant::Vertical + , AutoSegment::Local + , false // terminal. + , false //true // collapsed. + ); + segment->setAxis ( position.getX() ); + segment->setLayer ( _routingGauge->getRoutingLayer(2) ); + _contact->setLayer ( _routingGauge->getContactLayer(1) ); + ltrace(200) << "@" << DbU::getValueString(position.getX()) << segment << endl; + + ltraceout(200); + } + + + void JunctionBox::breakUpPunctual () + { + Component* anchor = _contact->getAnchor(); + Point center; + StackedContact* stackedContact; + + if ( isEmpty() ) center = _contact->getCenter(); + else if ( isPunctual() ) { + center.setX ( _xMin ); + center.setY ( _yMin ); + } else { + center.setX ( (_xMin+_xMax)/2 ); + center.setY ( (_yMin+_yMax)/2 ); + } + + const Layer* layer = NULL; + if ( !_localEnds.empty () ) layer = _localEnds [0]->getLayer(); + else if ( !_globalEnds.empty() ) layer = _globalEnds[0]->getLayer(); + else if ( anchor ) layer = anchor->getLayer (); + + stackedContact = StackedContact::create ( _contact->getNet() + , layer + , center.getX() + , center.getY() + ); + + if ( anchor ) stackedContact->setAnchor ( anchor ); + + for ( size_t i=0 ; i < _globalEnds.size() ; i++ ) + stackedContact->attachSlave ( _globalEnds[i] ); + + for ( size_t i=0 ; i < _localEnds.size() ; i++ ) + stackedContact->attachSlave ( _localEnds[i] ); + + stackedContact->breakUp (); + stackedContact->destroy (); + ltrace(99) << "JunctionBox::breakUpPunctual() succeded" << endl; + } + + + void JunctionBox::breakUp () + { + ltrace(99) << "JunctionBox::breakUp() - " << endl; + + if ( !_wireCount ) { + cerr << Warning("Standalone %s skipped.",getString(_contact).c_str()) << endl; + return; + } + + if ( _failsafe or isPunctual() ) + breakUpPunctual (); + else { + if ( not _globalStem ) { + cerr << Bug ( "JunctionBox::breakUp(): Flatten geometry whitout global stem,\n" + " on %p:%s." + , _contact->base() + , getString(_contact).c_str() + ) << endl; + breakUpPunctual (); + } else { + // Flat geometry. + vector stackedContacts; + + _globalStem->split ( stackedContacts ); + for ( size_t i=0 ; i < stackedContacts.size() ; i++ ) { + stackedContacts[i]->breakUp (); + stackedContacts[i]->destroy (); + } + } + } + ltrace(99) << "JunctionBox::breakUp() succeded" << endl; + } + + + void JunctionBox::updateContacts ( VirtualContacts& vcs ) + { + ltrace(109) << "JunctionBox::updateContacts()" << endl; + ltracein(109); + + vcs.clear (); + + Component* anchor = _contact->getAnchor (); + RoutingPad* rp = dynamic_cast(anchor); + if ( rp ) + vcs.merge ( Point(_xMin,_yMin), rp->getLayer() ); + + vector::iterator it = _localEnds.begin(); + for ( ; it != _localEnds.end() ; it++ ) + vcs.merge ( (*it)->getEnd(), (*it)->getLayer() ); + + for ( it = _globalEnds.begin() ; it != _globalEnds.end() ; it++ ) + vcs.merge ( (*it)->getEnd(), (*it)->getLayer() ); + + ltraceout(109); + } + + + StackedContact::~StackedContact () + { + ltrace(99) << "StackedContact::~StackedContact() - " << (void*)this << endl; + } + + + StackedContact::StackedContact ( Net* net, const Layer* layer, DbU::Unit x, DbU::Unit y ) + : Contact(net,layer,x,y) + , _useds(Session::getRoutingGauge()->getDepth()) + , _anchor(NULL) + { + for ( unsigned index = 0 ; index < Session::getRoutingGauge()->getDepth() ; index++ ) + _useds [ index ] = false; + + forEach ( BasicLayer*, basicLayer, getLayer()->getBasicLayers() ) + addLayer ( *basicLayer ); + } + + + StackedContact* StackedContact::create ( Net* net, const Layer* layer, DbU::Unit x, DbU::Unit y ) + { + StackedContact* contact = new StackedContact ( net, layer, x, y ); + contact->_postCreate (); + + ltrace(99) << "create: " << contact << endl; + + return contact; + } + + + void StackedContact::addLayer ( const Layer* layer ) + { + if ( !Session::getTechnology()->isMetal(layer) ) return; + + unsigned int index = Session::getRoutingGauge()->getLayerDepth ( layer ); + if ( index == UINT_MAX ) return; + + ltrace(99) << "StackedContact::addLayer() - " << layer << " [" << index << "]" << endl; + + _useds [ index ] = true; + } + + + void StackedContact::setAnchor ( Component* anchor ) + { + if ( (_anchor=anchor) ) { + forEach ( BasicLayer*, layer, _anchor->getLayer()->getBasicLayers() ) + addLayer ( *layer ); + } + } + + + void StackedContact::attachSlave ( SegmentEnd* segmentEnd ) + { + ltrace(88) << "add at " << getCenter() << " " << segmentEnd->getLayer() << endl; + + addLayer ( segmentEnd->getLayer() ); + + segmentEnd->setDelta ( 0 ); + + Hook* hook = segmentEnd->getHook(); + hook->detach (); + hook->attach ( getBodyHook() ); + } + + + void StackedContact::breakUp () + { + ltrace(99) << "StakedContact::breakUp() - " << this << endl; + + unsigned int zMin = 0; + unsigned int zMax = Session::getRoutingGauge()->getDepth() - 1; + Contact* contacts [ zMax+1 ]; + + for ( unsigned int i=0 ; i <= zMax ; i++ ) contacts[i] = NULL; + + for ( ; (zMin <= zMax) && !_useds[zMin] ; zMin++ ); + for ( ; (zMax > 0 ) && !_useds[zMax] ; zMax-- ); + + ltrace(99) << "Contact depth span [" << zMin << ":" << zMax << "]" << endl; + + if ( zMin > zMax ) return; + if ( zMin == zMax ) { + if ( _anchor ) + contacts[zMin] = Contact::create ( _anchor + , Session::getRoutingGauge()->getRoutingLayer(zMin) + , getX() - _anchor->getX() + , getY() - _anchor->getY() + , DbU::lambda(1.0), DbU::lambda(1.0) + ); + else + contacts[zMin] = Contact::create ( getNet() + , Session::getRoutingGauge()->getRoutingLayer(zMin) + , getX() + , getY() + , DbU::lambda(1.0), DbU::lambda(1.0) + ); + ltrace(88) << "Creating [" << zMin << "] " << contacts[zMin] << endl; + } else { + if ( _anchor ) + contacts[zMin] = contacts[zMin+1] + = Contact::create ( _anchor + , Session::getRoutingGauge()->getContactLayer(zMin) + , getX() - _anchor->getX() + , getY() - _anchor->getY() + , DbU::lambda(1.0), DbU::lambda(1.0) + ); + else + contacts[zMin] = contacts[zMin+1] + = Contact::create ( getNet() + , Session::getRoutingGauge()->getContactLayer(zMin) + , getX() + , getY() + , DbU::lambda(1.0), DbU::lambda(1.0) + ); + ltrace(88) << "Creating [" << zMin << "] " << contacts[zMin] << endl; + + for ( unsigned int j = zMin+1 ; j < zMax ; j++ ) { + contacts[j] = contacts[j+1] + = Contact::create ( contacts[j-1] + , Session::getRoutingGauge()->getContactLayer(j) + , 0 + , 0 + , DbU::lambda(1.0), DbU::lambda(1.0) + ); + ltrace(88) << "Creating [" << j << "] " << contacts[j] << endl; + } + } + + Hook* bodyHook = getBodyHook (); + Hook* currHook = bodyHook->getNextHook (); + + while ( currHook != bodyHook ) { + Hook* nextHook = currHook->getNextHook (); + + currHook->_setNextHook ( currHook ); + Segment* segment = dynamic_cast(currHook->getComponent()); + ltrace(88) << "Reattach [" << Session::getRoutingGauge()->getLayerDepth(segment->getLayer()) + << "] " << segment << endl; + currHook->attach ( contacts[Session::getRoutingGauge()->getLayerDepth(segment->getLayer())]->getBodyHook() ); + + currHook = nextHook; + } + + bodyHook->_setNextHook ( bodyHook ); + ltrace(99) << "StakedContact::breakUp() succeeded" << endl; + } + + +// ------------------------------------------------------------------- +// Class : "::FixedJunctionBox". + + + class FixedJunctionBox { + + public: + // Constructor & Destructor. + FixedJunctionBox ( AutoContact*, bool checking ); + ~FixedJunctionBox (); + // Modifiers. + void checkTopology (); + void merge ( Hook* ); + void resize (); + void breakUp (); + + protected: + // Attributes. + AutoContact* _contact; + vector _segmentEnds; + bool _checking; + }; + + + FixedJunctionBox::FixedJunctionBox ( AutoContact* contact, bool checking ) + : _contact(contact) + , _segmentEnds() + , _checking(checking) + { + ltrace(110) << "FixedJunctionBox() " << contact << endl; + ltracein(109); + + forEach ( Hook*, hook, _contact->getBodyHook()->getSlaveHooks() ) merge ( *hook ); + + ltraceout(109); + } + + + FixedJunctionBox::~FixedJunctionBox () + { + for ( size_t i=0 ; i<_segmentEnds.size() ; i++ ) delete _segmentEnds[i]; + } + + + void FixedJunctionBox::checkTopology () + { } + + + void FixedJunctionBox::merge ( Hook* hook ) + { + SegmentEnd* segmentEnd = SegmentEnd::create ( hook, _checking ); + if ( !segmentEnd ) return; + + ltrace(109) << "merge() Axis " + << DbU::getLambda(segmentEnd->getAxis()) + << " [global] " << segmentEnd << endl; + _segmentEnds.push_back ( segmentEnd ); + } + + + void FixedJunctionBox::resize () + { + for ( size_t i=0 ; i<_segmentEnds.size() ; i++ ) _segmentEnds[i]->setDelta(0); + } + + + void FixedJunctionBox::breakUp () + { + Component* anchor = _contact->getAnchor(); + StackedContact* stackedContact; + + const Layer* layer = NULL; + if ( !_segmentEnds.empty () ) layer = _segmentEnds[0]->getLayer(); + else if ( anchor ) layer = anchor->getLayer (); + + stackedContact = StackedContact::create ( _contact->getNet() + , layer + , _contact->getX() + , _contact->getY() + ); + + if ( anchor ) stackedContact->setAnchor ( anchor ); + + for ( size_t i=0 ; i < _segmentEnds.size() ; i++ ) + stackedContact->attachSlave ( _segmentEnds[i] ); + + stackedContact->breakUp (); + stackedContact->destroy (); + ltrace(99) << "FixedJunctionBox::breakUp() succeded" << endl; + } + + +} // End of local namespace. + + + + +namespace Katabatic { + + +// ------------------------------------------------------------------- +// Class : "Katabatic::VirtualContacts::VC". + + + bool operator== ( const VirtualContacts::VC& lhs + , const VirtualContacts::VC& rhs ) + { + return lhs._point == rhs._point; + } + + + void VirtualContacts::VC::merge ( const Layer* layer ) + { + if ( _layer->contains(layer) ) return; + Layer *newLayer = Session::getTechnology()->getLayer ( _layer->getMask() & layer->getMask() ); + + if ( !newLayer ) return; + _layer = newLayer; + } + + + void VirtualContacts::merge ( const Point& point, const Layer* layer ) + { + VC vc ( point, layer ); + + ltrace(109) << "VirtualContacts::merge() " << point << " " << layer << endl; + + vector::iterator it = _vcs.begin(); + vector::iterator end = _vcs.end(); + + for ( ; it != end ; it++ ) { + if ( *it == vc ) { (*it).merge ( layer ); return; } + } + + _vcs.push_back ( vc ); + _boundingBox.merge ( Box(point).inflate(DbU::lambda(1.0)) ); + } + + +// ------------------------------------------------------------------- +// Class : "Katabatic::AutoContact". + + + size_t AutoContact::_maxId = 0; + size_t AutoContact::_allocateds = 0; + const Name AutoContact::_goName = "Katabatic::AutoContact"; + + + AutoContact* AutoContact::fromRp ( GCell* gcell + , RoutingPad* routingPad + , const Layer* layer + , Point point + , DbU::Unit width + , DbU::Unit height + , bool fixed + ) + { + routingPad->getBodyHook()->detach (); + + DbU::Unit x = 0; + DbU::Unit y = 0; + Entity* entity = routingPad->getOccurrence().getEntity(); + + // Assumes there is no rotation in the Transformation. + if ( dynamic_cast(entity) ) { x = point.getX(); } + else if ( dynamic_cast(entity) ) { y = point.getY(); } + + return AutoContact::create ( gcell + , routingPad + , layer + , x, y + , width, height + , false, false + , fixed + ); + } + + + AutoContact::AutoContact ( GCell* gcell + , Contact* contact + , bool hAlignate + , bool vAlignate + ) + : ExtensionGo (contact->getCell()) + , _id (_maxId++) + , _contact (contact) + , _gcell (gcell) + , _invalid (false) + , _invalidTopology(true) + , _isTerminal (false) + , _fixed (false) + , _hAlignate (hAlignate) + , _vAlignate (vAlignate) + , _isCorner (false) + , _dxMin (0) + , _dxMax (_gcell->getXMax()-_gcell->getX()) + , _dyMin (0) + , _dyMax (_gcell->getYMax()-_gcell->getY()) + , _subContacts () + { + _allocateds++; + _gcell->addContact ( this ); + } + + + void AutoContact::_postCreate () + { + ExtensionGo::_postCreate (); + + restoreNativeConstraintBox (); + + ltrace(90) << "Native CBox: " << this + << " <" << DbU::getLambda(getCBXMin()) + << " " << DbU::getLambda(getCBYMin()) + << " " << DbU::getLambda(getCBXMax()) + << " " << DbU::getLambda(getCBYMax()) << ">" << endl; + + Session::link ( this ); + invalidate (); + + ltrace(90) << "AutoContact::_postCreate() - " << this << " in " << _gcell << endl; + } + + + void AutoContact::_preDestroy () + { + DebugSession::open ( _contact->getNet() ); + + ltrace(90) << "AutoContact::_preDestroy() - " << endl; + + if ( not _contact->getSlaveComponents().isEmpty() ) { + cerr << Error("Base contact still have slaves components, cancelled.\n" + " (%s)" + ,_getString().c_str()) << endl; + DebugSession::close (); + return; + } + + if ( not Session::doDestroyTool() ) { + _gcell->removeContact ( this ); + Session::unlink ( this ); + } + + ExtensionGo::_preDestroy (); + if ( Session::doDestroyBaseContact() ) + _contact->destroy (); + + DebugSession::close (); + } + + + AutoContact::~AutoContact () + { + _allocateds--; + } + + + AutoContact* AutoContact::create ( GCell* gcell + , Net* net + , const Layer* layer + , bool hAlignate + , bool vAlignate + ) + { + Contact* contact = Contact::create ( net + , layer + , gcell->getCenter().getX() + , gcell->getCenter().getY() + , DbU::lambda(2.0) + , DbU::lambda(2.0) + ); + AutoContact* autoContact = new AutoContact ( gcell, contact, hAlignate, vAlignate ); + + autoContact->_postCreate (); + + ltrace(90) << "create(net*) " << autoContact << endl; + return autoContact; + } + + + AutoContact* AutoContact::create ( GCell* gcell + , RoutingPad* rp + , const Layer* layer + , const DbU::Unit dx + , const DbU::Unit dy + , const DbU::Unit width + , const DbU::Unit height + , bool hAlignate + , bool vAlignate + , bool fixed + ) + { + Contact* contact = Contact::create ( rp + , layer + , dx /*- rp->getX()*/ + , dy /*- rp->getY()*/ + , width + , height + ); + AutoContact* autoContact = new AutoContact ( gcell, contact, hAlignate, vAlignate ); + + autoContact->setFixed ( fixed ); + autoContact->setTerminal ( true ); + autoContact->_postCreate (); + + ltrace(90) << "create(RoutingPad*) " << autoContact << endl; + return autoContact; + } + + + bool AutoContact::canDestroy ( bool error ) const + { + if ( not _contact->getSlaveComponents().isEmpty() ) { + if ( error ) { + cerr << Error("Base contact still have slaves components, cancelled.\n" + " (%s)" + ,_getString().c_str()) << endl; + } + return false; + } + return true; + } + + + size_t AutoContact::getSegmentEndAllocateds () + { + return SegmentEnd::getAllocateds(); + } + + + size_t AutoContact::getAllocateds () + { + return _allocateds; + } + + + const Name& AutoContact::getStaticName () + { + return _goName; + } + + + const Name& AutoContact::getName () const + { + return _goName; + } + + + unsigned int AutoContact::getMinDepth () const + { + unsigned int minDepth = (unsigned int)-1; + Component* anchor = getAnchor (); + if ( anchor ) { + minDepth = min ( minDepth, Session::getRoutingGauge()->getLayerDepth(anchor->getLayer()) ); + //ltrace(200) << "Anchor:" << anchor << endl; + } + + forEach ( Component*, icomponent, getSlaveComponents() ) { + minDepth = min ( minDepth, Session::getRoutingGauge()->getLayerDepth(icomponent->getLayer()) ); + //ltrace(200) << "Slave:" << *icomponent << endl; + } + + return minDepth; + } + + + void AutoContact::getLengths ( DbU::Unit* lengths, set& processeds ) + { + forEach ( Hook*, ihook, getBodyHook()->getSlaveHooks() ) { + bool isSourceHook = (dynamic_cast(*ihook)); + if ( !isSourceHook && ( dynamic_cast(*ihook) == NULL ) ) { + cerr << Error ( badHookType, getString(ihook->getComponent()).c_str() ) << endl; + return; + } + + bool isHorizontal = true; + Segment* segment = dynamic_cast((*ihook)->getComponent()); + if ( !segment ) { + isHorizontal = false; + segment = dynamic_cast((*ihook)->getComponent()); + if ( !segment ) + continue; + } + + AutoSegment* autoSegment = Session::lookup ( segment ); + if ( not autoSegment or processeds.find(autoSegment) != processeds.end() ) + continue; + processeds.insert ( autoSegment ); + + size_t depth = Session::getRoutingGauge()->getLayerDepth(segment->getLayer()); + DbU::Unit length; + if ( autoSegment->isLocal() ) { + length = segment->getLength(); + lengths[depth] += length; + if ( abs(length) >= DbU::lambda(50.0) ) + cerr << Error("Supicious length:%.2f of %s." + ,DbU::getLambda(length),getString(autoSegment).c_str()) << endl; + } else { + if ( isHorizontal ) { + if ( isSourceHook ) + lengths[depth] += _gcell->getBoundingBox().getXMax() - segment->getSourceX(); + else + lengths[depth] += segment->getTargetX() - _gcell->getBoundingBox().getXMin(); + } else { + if ( isSourceHook ) + lengths[depth] += _gcell->getBoundingBox().getYMax() - segment->getSourceY(); + else + lengths[depth] += segment->getTargetY() - _gcell->getBoundingBox().getYMin(); + } + } + } + } + + + Box AutoContact::getNativeConstraintBox () const + { + //if ( _fixed ) return Box(getCenter()); + + Component* component = getAnchor(); + if ( !component ) return _gcell->getBoundingBox (); + + DbU::Unit xMin; + DbU::Unit xMax; + DbU::Unit yMin; + DbU::Unit yMax; + Vertical* vertical; + Horizontal* horizontal; + RoutingPad* routingPad; + + if ( (horizontal = dynamic_cast(component))) { + xMin = horizontal->getSourcePosition().getX(); + xMax = horizontal->getTargetPosition().getX(); + yMin = yMax + = horizontal->getTargetPosition().getY(); + } else if ( (vertical = dynamic_cast(component)) ) { + yMin = vertical->getSourcePosition().getY(); + yMax = vertical->getTargetPosition().getY(); + xMin = xMax + = vertical->getTargetPosition().getX(); + } else if ( (routingPad = dynamic_cast(component)) ) { + Entity* entity = routingPad->getOccurrence().getEntity(); + + // Assumes there is no rotation in the Transformation. + if ( dynamic_cast(entity) ) { + xMin = routingPad->getSourcePosition().getX(); + xMax = routingPad->getTargetPosition().getX(); + yMin = yMax + = routingPad->getTargetPosition().getY(); + } else if ( dynamic_cast(entity) ) { + yMin = routingPad->getSourcePosition().getY(); + yMax = routingPad->getTargetPosition().getY(); + xMin = xMax + = routingPad->getTargetPosition().getX(); + } else { + xMin = xMax = routingPad->getPosition().getX(); + yMin = yMax = routingPad->getPosition().getY(); + } + } else { + xMin = xMax = component->getPosition().getX(); + yMin = yMax = component->getPosition().getY(); + } + + order ( xMin, xMax ); + order ( yMin, yMax ); + + return Box ( xMin, yMin, xMax, yMax ); + } + + + Interval AutoContact::getUConstraints ( unsigned int direction ) const + { + if ( direction == Constant::Horizontal ) { + return Interval ( getCBYMin(), getCBYMax() ); + } + return Interval ( getCBXMin(), getCBXMax() ); + } + + + AutoContacts AutoContact::getCollapseds ( unsigned int direction ) + { + return AutoContacts_Collapsed ( this, direction ); + } + + + void AutoContact::invalidate () + { + if ( !isInvalidated() ) { + ltrace(110) << "AutoContact::invalidate() - " << this << endl; + setInvalidated ( true ); + Session::invalidate ( this ); + getGCell()->invalidate (); + } + } + + + void AutoContact::revalidate () + { + updateGeometry (); + if ( _invalidTopology ) + revalidateTopology (); + } + + + void AutoContact::updateGeometry () + { + DebugSession::open ( getNet(), 80 ); + + ltrace(110) << "AutoContact::updateGeometry() " << this << endl; + ltracein(110); + + _contact->invalidate ( false ); + setInvalidated ( false ); + + if ( isFixed() ) { + FixedJunctionBox junctionBox ( this, false ); + junctionBox.resize (); + } else { + JunctionBox junctionBox ( this, false ); + junctionBox.resize (); + junctionBox.updateContacts ( _subContacts ); + } +#if defined(CHECK_DATABASE) + checkTopology(); +#endif + + ltraceout(110); + + DebugSession::close (); + } + + + void AutoContact::setGCell ( GCell* gcell ) + { + invalidate (); + if ( _gcell ) _gcell->removeContact ( this ); + + _gcell = gcell; + if ( _gcell ) { + _gcell->addContact ( this ); + _contact->setPosition ( _gcell->getCenter() ); + _dxMin = 0; + _dyMin = 0; + _dxMax = _gcell->getXMax()-_gcell->getX(); + _dyMax = _gcell->getYMax()-_gcell->getY(); + } else { + cerr << Bug("NULL GCell for %p:%s.",_contact,_getString().c_str()) << endl; + } + } + + + void AutoContact::breakUp () + { + if ( isFixed() ) { + FixedJunctionBox(this,false).breakUp(); + } else { + JunctionBox(this,false).breakUp(); + } + ltrace(110) << "AutoContact::breakUp() succeded" << endl; + } + + + void AutoContact::split () + { + DebugSession::open ( getNet() ); + JunctionBox(this,false).split(); + DebugSession::close (); + } + + + void AutoContact::checkTopology () + { + ltrace(110) << "checkTopology() " << this << endl; + + if ( isFixed() ) { + FixedJunctionBox(this,true).checkTopology(); + } else { + JunctionBox(this,true).checkTopology(); + } + } + + + void AutoContact::revalidateTopology () + { + ltrace(110) << "revalidateTopology() " << this << endl; + + JunctionBox(this,true).revalidateTopology(); + } + + + bool AutoContact::isAlignate ( unsigned int direction ) const + { + return (_hAlignate && (direction == Constant::Horizontal)) + || (_vAlignate && (direction == Constant::Vertical )); + } + + + bool AutoContact::isHExtended () + { return JunctionBox(this,true).isHExtended(); } + + + bool AutoContact::isVExtended () + { return JunctionBox(this,true).isVExtended(); } + + + void AutoContact::computeAlignate () + { + if ( !isFixed() ) + JunctionBox(this,true).computeAlignate(); + } + + + bool AutoContact::canGoOutsideGCell ( const AutoSegment* segment ) + { return JunctionBox(this,true).canGoOutside(segment); } + + + bool AutoContact::canHDesalignate () + { return JunctionBox(this,true).canHDesalignate(); } + + + bool AutoContact::canVDesalignate () + { return JunctionBox(this,true).canVDesalignate(); } + + + bool AutoContact::hDesalignate () + { + bool desalignate = JunctionBox(this,true).canHDesalignate(); + + if ( desalignate ) setHAlignate ( false ); + return desalignate; + } + + + bool AutoContact::vDesalignate () + { + bool desalignate = JunctionBox(this,true).canVDesalignate(); + + if ( desalignate ) setVAlignate ( false ); + return desalignate; + } + + + void AutoContact::restoreHConnexity ( DbU::Unit x, bool split ) + { JunctionBox(this,true).restoreHConnexity ( x, split ); } + + + void AutoContact::restoreVConnexity ( DbU::Unit y, bool split ) + { JunctionBox(this,true).restoreVConnexity ( y, split ); } + + + bool AutoContact::canMoveUp ( AutoSegment* moved ) const + { + ltrace(200) << "AutoContact::canMoveUp() " << this << endl; + size_t viaDepth = 100; + + RoutingGauge* rg = Session::getRoutingGauge(); + size_t movedDepth = rg->getLayerDepth(moved->getLayer()); + + Component* anchor = getAnchor (); + if ( anchor ) { + viaDepth = rg->getLayerDepth(anchor->getLayer()); + ltrace(200) << "| Anchor depth: " << viaDepth << endl; + } + + forEach ( Segment*, isegment, _contact->getSlaveComponents().getSubSet() ) { + if ( *isegment == moved->base() ) continue; + + size_t depth = rg->getLayerDepth(isegment->getLayer()); + if ( viaDepth == 100 ) viaDepth = depth; + else + if ( viaDepth != depth ) return false; + + ltrace(200) << "| Segment depth: " << depth << endl; + } + + return ( movedDepth+1 == viaDepth ); + } + + + void AutoContact::setConstraintBox ( const Box& box ) + { + setCBXMin ( box.getXMin() ); + setCBXMax ( box.getXMax() ); + setCBYMin ( box.getYMin() ); + setCBYMax ( box.getYMax() ); + ltrace(110) << "setConstraintBox() - " << this << " " << getConstraintBox() << endl; + ltrace(110) << "* " << _gcell << endl; + } + + + void AutoContact::restrictConstraintBox ( DbU::Unit constraintMin + , DbU::Unit constraintMax + , unsigned int direction ) + { + if ( direction & Constant::Horizontal ) { + if ( (constraintMin > getCBYMax()) || (constraintMax < getCBYMin()) ) { + if ( Session::getDemoMode() ) return; + + cerr << Error ( "Incompatible DY restriction on %s", _getString().c_str() ) << endl; + if ( constraintMin > getCBYMax() ) + cerr << Error ( "(constraintMin > CBYMax : %lf > %lf)" + , DbU::getLambda(constraintMin) + , DbU::getLambda(getCBYMax()) ) + << endl; + if ( constraintMax < getCBYMin() ) + cerr << Error ( "(constraintMax < CBYMin : %lf < %lf)" + , DbU::getLambda(constraintMax) + , DbU::getLambda(getCBYMin()) ) + << endl; + return; + } + setCBYMin ( max(getCBYMin(),constraintMin) ); + setCBYMax ( min(getCBYMax(),constraintMax) ); + } else if ( direction & Constant::Vertical ) { + if ( (constraintMin > getCBXMax()) || (constraintMax < getCBXMin()) ) { + if ( Session::getDemoMode() ) return; + + cerr << Error ( "Incompatible DX restriction on %s", _getString().c_str() ) << endl; + if ( constraintMin > getCBXMax() ) + cerr << Error ( "(constraintMin > CBXMax : %lf > %lf)" + , DbU::getLambda(constraintMin) + , DbU::getLambda(getCBXMax()) ) + << endl; + if ( constraintMax < getCBXMin() ) + cerr << Error ( "(constraintMax < CBXMin : %lf < %lf)" + , DbU::getLambda(constraintMax) + , DbU::getLambda(getCBXMin()) ) + << endl; + return; + } + setCBXMin ( max(getCBXMin(),constraintMin) ); + setCBXMax ( min(getCBXMax(),constraintMax) ); + } + ltrace(110) << "restrictConstraintBox() - " << this << " " << getConstraintBox() << endl; + } + + + void AutoContact::restoreNativeConstraintBox () + { + setConstraintBox ( getNativeConstraintBox() ); + } + + + Box& AutoContact::intersectConstraintBox ( Box& box ) const + { + return box = box.getIntersection ( getConstraintBox() ); + } + + + Box AutoContact::getBoundingBox () const + { + return _gcell->getBoundingBox (); + } + + + void AutoContact::translate ( const DbU::Unit& tx, const DbU::Unit& ty ) + { + cerr << Warning("Calling AutoContact::translate() is likely a bug.") << endl; + _contact->translate ( tx, ty ); + } + + + string AutoContact::_getString () const + { + string s = _contact->_getString(); + s.insert ( 1, "id: " ); + s.insert ( 4, getString(_id) ); + s.insert ( s.size()-1, (_fixed )?" F":" -" ); + s.insert ( s.size()-1, (_isTerminal)? "t": "-" ); + s.insert ( s.size()-1, (_hAlignate) ? "h": "-" ); + s.insert ( s.size()-1, (_vAlignate) ? "v": "-" ); + s.insert ( s.size()-1, (_invalid) ? "i": "-" ); + + // Point p = _contact->getCenter(); + // s.insert ( s.size()-1, " [" ); + // s.insert ( s.size()-1, DbU::getValueString(p.getX()) ); + // s.insert ( s.size()-1, ":" ); + // s.insert ( s.size()-1, DbU::getValueString(p.getY()) ); + // s.insert ( s.size()-1, "]" ); + return s; + } + + + Record* AutoContact::_getRecord () const + { + Record* record = _contact->_getRecord (); + record->add ( getSlot ( "_gcell" , _gcell ) ); + record->add ( getSlot ( "_constraintBox", getConstraintBox() ) ); + record->add ( getSlot ( "_fixed" , _fixed ) ); + record->add ( getSlot ( "_isTerminal" , _isTerminal ) ); + record->add ( getSlot ( "_hAlignate" , _hAlignate ) ); + record->add ( getSlot ( "_vAlignate" , _vAlignate ) ); + record->add ( getSlot ( "_invalid" , _invalid ) ); + return record; + } + + +} // End of Katabatic namespace. diff --git a/katabatic/src/AutoContacts.cpp b/katabatic/src/AutoContacts.cpp new file mode 100644 index 00000000..d2e2c974 --- /dev/null +++ b/katabatic/src/AutoContacts.cpp @@ -0,0 +1,140 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2008, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | K a t a b a t i c - Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Module : "./AutoContacts.cpp" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#include + +#include "hurricane/Segment.h" +#include "hurricane/Horizontal.h" +#include "hurricane/Vertical.h" + +#include "katabatic/Session.h" +#include "katabatic/AutoContact.h" +#include "katabatic/AutoSegment.h" + + +namespace Katabatic { + + + using namespace std; + using Hurricane::Hook; + using Hurricane::Error; + using Hurricane::Segment; + using Hurricane::ForEachIterator; + + +// ------------------------------------------------------------------- +// Class : "Katabatic::AutoContacts_Collapsed". + + + void AutoContactStack::push ( AutoContact* contact, Segment* segment ) + { + ltrace(80) << "Stacking " << (void*)contact->getContact() << ":" << contact + << " + " << (void*)segment << ":" << segment << endl; + + push_back(make_pair(contact,segment)); + } + + + AutoContact* AutoContacts_Collapsed::Locator::getElement () const + { + return _stack.getAutoContact (); + } + + + void AutoContacts_Collapsed::Locator::progress () + { + AutoContact* sourceContact = _stack.getAutoContact (); + Segment* sourceSegment = _stack.getSegment (); + + _stack.pop (); + + forEach ( Hook*, ihook, sourceContact->getBodyHook()->getHooks() ) { + Segment* segment = NULL; + + if ( _direction & Constant::Horizontal ) segment = dynamic_cast(ihook->getComponent()); + else segment = dynamic_cast(ihook->getComponent()); + + if ( segment && (segment != sourceSegment) ) { + AutoSegment* autoSegment = Session::lookup ( segment ); + + if ( !autoSegment ) { + cerr << Error("Can't lookup for %s.",getString(segment).c_str()) << endl; + continue; + } + if ( !autoSegment->isCollapsed() ) continue; + + Hook* opposite = segment->getOppositeHook ( *ihook ); + AutoContact* targetContact = dynamic_cast(opposite->getMasterHook()->getComponent()); + + if ( targetContact ) _stack.push ( targetContact, segment ); + } + } + } + + + Hurricane::Locator* AutoContacts_Collapsed::Locator::getClone () const + { + return new Locator(*this); + } + + + bool AutoContacts_Collapsed::Locator::isValid () const + { + return _stack.isEmpty(); + } + + + string AutoContacts_Collapsed::Locator::_getString () const + { + string s = "<" + _TName("AutoContacts_Collapsed::Locator") + + getString(_stack.getAutoContact()) + + ">"; + return s; + } + + + Collection* AutoContacts_Collapsed::getClone () const + { + return new AutoContacts_Collapsed(*this); + } + + + Hurricane::Locator* AutoContacts_Collapsed::getLocator () const + { + return new Locator(_contact,_direction); + } + + + string AutoContacts_Collapsed::_getString () const + { + string s = "<" + _TName("AutoContacts_Collapsed") + " " + + getString(_contact) + " " + + getString(_direction) + + ">"; + return s; + } + + +} // End of Katabatic namespace. diff --git a/katabatic/src/AutoHorizontal.cpp b/katabatic/src/AutoHorizontal.cpp new file mode 100644 index 00000000..7ae78a7f --- /dev/null +++ b/katabatic/src/AutoHorizontal.cpp @@ -0,0 +1,807 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2008, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | K a t a b a t i c - Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Module : "./AutoHorizontal.cpp" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#include +#include "hurricane/Bug.h" +#include "hurricane/Error.h" +#include "hurricane/DebugSession.h" +#include "crlcore/RoutingGauge.h" +#include "katabatic/Configuration.h" +#include "katabatic/AutoContact.h" +#include "katabatic/AutoHorizontal.h" +#include "katabatic/AutoVertical.h" + + +namespace { + + using namespace std; + using namespace Hurricane; + using namespace Katabatic; + + + bool slacken ( AutoContact* contact ) + { + if ( contact->getLayer() != Session::getConfiguration()->getContactLayer(0) ) + return false; + + ltrace(200) << "Session::slacken(): " << contact << endl; + + vector hooks; + forEach ( Hook*, ihook, contact->getBodyHook()->getSlaveHooks() ) hooks.push_back ( *ihook ); + + contact->getBodyHook()->_setNextHook ( contact->getBodyHook() ); + for ( size_t i=0 ; i_setNextHook ( hooks[i] ); + + const Layer* paralLayer = Session::getConfiguration()->getRoutingLayer(1); + const Layer* perpandLayer = Session::getConfiguration()->getRoutingLayer(2); + const Layer* contactLayer = Session::getConfiguration()->getContactLayer(1); + AutoContact* contact1 = AutoContact::create ( contact->getGCell(), contact->getNet(), contactLayer ); + AutoContact* contact2 = AutoContact::create ( contact->getGCell(), contact->getNet(), contactLayer ); + + AutoSegment* hsegment = AutoHorizontal::create ( contact + , contact1 + , paralLayer + , contact->getY() + , DbU::lambda(2.0) + , AutoSegment::Local + , true // terminal + , false // collapsed + ); + + AutoSegment* vsegment = AutoVertical::create ( contact1 + , contact2 + , perpandLayer + , contact->getX() + , DbU::lambda(2.0) + , AutoSegment::Local + , false + , false + ); + + for ( size_t i=0 ; iattach ( contact2->getBodyHook() ); + + contact2->setVAlignate ( true ); + contact2->restoreHConnexity ( contact->getX(), true ); + + hsegment->setSlackened ( true ); + vsegment->setSlackened ( true ); + vsegment->setSlackenStrap ( true ); + + ltrace(200) << "Session::slacken() new paral: " << hsegment << endl; + ltrace(200) << "Session::slacken() perpand: " << vsegment << endl; + + return true; + } + + + void slacken ( AutoHorizontal* segment, bool fromSource ) + { + AutoContact* contact = NULL; + Point slackPoint; + if (fromSource) { + contact = segment->getAutoSource(); + slackPoint = Point ( segment->getSourceX(), segment->getSourceY() ); + } else { + contact = segment->getAutoTarget(); + slackPoint = Point ( segment->getTargetX(), segment->getTargetY() ); + } + if ( !contact ) return; + + forEach ( Vertical*, ivertical, contact->getSlaveComponents().getSubSet() ) { + AutoSegment* autoVertical = Session::lookup ( *ivertical ); + if ( autoVertical ) { + autoVertical->invalidate (); + if ( autoVertical->isGlobal() and not contact->getAnchor() ) return; + } + } + + if ( slacken(contact) ) return; + + size_t depth = Session::getRoutingGauge()->getLayerDepth ( segment->getLayer() ); + Layer* contactLayer = Session::getRoutingGauge()->getContactLayer ( depth ); + const Layer* slackLayer = Session::getRoutingGauge()->getRoutingLayer ( depth + 1 ); + + if ( fromSource ) segment->getSourceHook()->detach (); + else segment->getTargetHook()->detach (); + + AutoContact* contact1 = AutoContact::create ( contact->getGCell(), segment->getNet(), contactLayer ); + AutoContact* contact2 = AutoContact::create ( contact->getGCell(), segment->getNet(), contactLayer ); + + AutoSegment* hsegment = AutoHorizontal::create ( contact + , contact1 + , segment->getLayer() + , slackPoint.getY() + , DbU::lambda(2.0) + , AutoSegment::Local + , false + , false + ); + + AutoSegment* vsegment = AutoVertical::create ( contact1 + , contact2 + , slackLayer + , slackPoint.getX() + , DbU::lambda(2.0) + , AutoSegment::Local + , false + , false + ); + + if ( fromSource ) + segment->getSourceHook()->attach ( contact2->getContact()->getBodyHook() ); + else + segment->getTargetHook()->attach ( contact2->getContact()->getBodyHook() ); + contact->restoreVConnexity ( slackPoint.getY(), true ); + + hsegment->setSlackened ( true ); + vsegment->setSlackened ( true ); + vsegment->setSlackenStrap ( true ); + + //contact->setVAlignate ( true ); + + ltrace(200) << "Session::slacken() new paral: " << hsegment << endl; + ltrace(200) << "Session::slacken() perpand: " << vsegment << endl; + ltrace(200) << "Session::slacken() original: " << segment << endl; + } + + +} // End of local namespace. + + +namespace Katabatic { + + + using std::min; + using std::max; + using Hurricane::ltracein; + using Hurricane::ltraceout; + using Hurricane::Error; + using Hurricane::Bug; + using Hurricane::DebugSession; + + +// ------------------------------------------------------------------- +// Class : "Katabatic::AutoHorizontal". + + + AutoHorizontal::AutoHorizontal ( Horizontal* horizontal + , int type + , bool terminal + , bool collapsed + ) + : AutoSegment(horizontal,true,type,terminal,collapsed) + , _horizontal(horizontal) + { + } + + + void AutoHorizontal::_postCreate () + { + AutoSegment::_postCreate (); + orient (); + setPositions (); + + AutoContact* source = getAutoSource(); + if ( source->isTerminal() ) source->setY ( _horizontal->getY() ); + + AutoContact* target = getAutoTarget(); + if ( target->isTerminal() ) target->setY ( _horizontal->getY() ); + + if ( source->getGCell() == target->getGCell() ) { + setGlobal ( false ); + } else { + GCell* gcell; + GCell* end; + + if ( source->getGCell()->getX() < target->getGCell()->getX() ) { + gcell = source->getGCell()->getRight(); + end = target->getGCell(); + } else { + gcell = target->getGCell()->getRight(); + end = source->getGCell(); + } + + for ( ; gcell != end ; gcell = gcell->getRight() ) { + if ( !gcell ) { + cerr << Error("AutoHorizontal::create() : NULL GCell.") << endl; + break; + } + gcell->addHSegment ( this ); + } + } + } + + + AutoHorizontal* AutoHorizontal::create ( Horizontal* horizontal + , int type + , bool terminal + , bool collapsed + ) + { + AutoSegment::_preCreate ( horizontal->getSource(), horizontal->getTarget() ); + AutoHorizontal* autoHorizontal = new AutoHorizontal ( horizontal + , type + , terminal + , collapsed + ); + autoHorizontal->_postCreate (); + return autoHorizontal; + } + + + AutoHorizontal* AutoHorizontal::create ( AutoContact* source + , AutoContact* target + , const Layer* layer + , DbU::Unit y + , DbU::Unit width + , int type + , bool terminal + , bool collapsed + ) + { + AutoSegment::_preCreate ( source, target ); + AutoHorizontal* autoHorizontal + = new AutoHorizontal ( Horizontal::create ( source->getContact() + , target->getContact() + , layer + , y + , width ), type, terminal, collapsed ); + + autoHorizontal->_postCreate (); + + return autoHorizontal; + } + + + void AutoHorizontal::_preDestroy () + { + ltrace(200) << "AutoHorizontal::_preDestroy() - " << (void*)this << endl; + ltrace(200) << " " << _getString() << endl; + ltracein(90); + + if ( not Session::doDestroyTool() ) { + AutoContact* source = getAutoSource(); + AutoContact* target = getAutoTarget(); + + if ( source and target and (source->getGCell() != target->getGCell()) ) { + GCell* gcell; + GCell* end; + + if ( source->getGCell()->getX() < target->getGCell()->getX() ) { + gcell = source->getGCell()->getRight(); + end = target->getGCell(); + } else { + gcell = target->getGCell()->getRight(); + end = source->getGCell(); + } + + for ( ; gcell != end ; gcell = gcell->getRight() ) { + if ( !gcell ) { + cerr << Error("AutoHorizontal::_preDestroy() : NULL GCell.") << endl; + break; + } + gcell->removeHSegment ( this ); + } + } + } + + AutoSegment::_preDestroy (); + ltraceout(90); + } + + + AutoHorizontal::~AutoHorizontal () + { + if ( Session::doDestroyBaseSegment() and not Session::doDestroyTool() ) { + ltrace(200) << "~AutoHorizontal() - " << (void*)_horizontal << endl; + _horizontal->destroy (); + } + } + + + Interval AutoHorizontal::getSourceConstraints ( bool native ) const + { + if ( native ) { + Box nativeBox ( getAutoSource()->getNativeConstraintBox() ); + return Interval ( nativeBox.getYMin(), nativeBox.getYMax() ); + } + return Interval ( getAutoSource()->getCBYMin(), getAutoSource()->getCBYMax() ); + } + + + Interval AutoHorizontal::getTargetConstraints ( bool native ) const + { + if ( native ) { + Box nativeBox ( getAutoTarget()->getNativeConstraintBox() ); + return Interval ( nativeBox.getYMin(), nativeBox.getYMax() ); + } + return Interval ( getAutoTarget()->getCBYMin(), getAutoTarget()->getCBYMax() ); + } + + + bool AutoHorizontal::getConstraints ( DbU::Unit& constraintMin, DbU::Unit& constraintMax ) const + { + AutoContact* contact = getAutoSource(); + constraintMin = contact->getCBYMin(); + constraintMax = contact->getCBYMax(); + + ltrace(148) << "Source constraints: " << contact << " [" + << DbU::getValueString(constraintMin) << ":" + << DbU::getValueString(constraintMax) << "]" + << endl; + + contact = getAutoTarget(); + constraintMin = max ( constraintMin, contact->getCBYMin() ); + constraintMax = min ( constraintMax, contact->getCBYMax() ); + + ltrace(148) << "Merge with target constraints: " << contact << " [" + << DbU::getValueString(constraintMin) << ":" + << DbU::getValueString(constraintMax) << "]" + << endl; + + constraintMin = max ( constraintMin, getUserConstraints().getVMin() ); + constraintMax = min ( constraintMax, getUserConstraints().getVMax() ); + + ltrace(148) << "Merge with user constraints: " << getUserConstraints() << " [" + << DbU::getValueString(constraintMin) << ":" + << DbU::getValueString(constraintMax) << "]" + << endl; + + return true; + } + + + unsigned int AutoHorizontal::getDirection () const + { return Constant::Horizontal; } + + + size_t AutoHorizontal::getGCells ( vector& gcells ) const + { + vector().swap ( gcells ); + gcells.push_back ( getAutoSource()->getGCell() ); + + GCell* gcell = gcells.front(); + GCell* end = getAutoTarget()->getGCell(); + + while ( gcell != end ) { + gcell = gcell->getRight (); + if ( !gcell ) break; + + gcells.push_back ( gcell ); + } + + return gcells.size(); + } + + + bool AutoHorizontal::_canSlacken () const + { + Interval sourceConstraints = Interval(getAutoSource()->getCBYMin(),getAutoSource()->getCBYMax()); + Interval targetConstraints = Interval(getAutoTarget()->getCBYMin(),getAutoTarget()->getCBYMax()); + + // Ugly: should uses topRightShrink from GCell. + sourceConstraints.inflate ( 0, /*Katabatic::GCell::getTopRightShrink()*/ DbU::lambda(1.0) ); + targetConstraints.inflate ( 0, /*Katabatic::GCell::getTopRightShrink()*/ DbU::lambda(1.0) ); + + ltrace(200) << "source " << (void*)getAutoSource() << ":" << getAutoSource() << endl; + ltrace(200) << "source constraints: " << sourceConstraints + << " " << DbU::getValueString(sourceConstraints.getSize()) << endl; + ltrace(200) << "target " << (void*)getAutoTarget() << ":" << getAutoTarget() << endl; + ltrace(200) << "target constraints: " << targetConstraints + << " " << DbU::getValueString(targetConstraints.getSize()) << endl; + + // Ugly: GCell's track number is hardwired. + if ( sourceConstraints.getSize() / DbU::lambda(5.0) < 10 ) return true; + if ( targetConstraints.getSize() / DbU::lambda(5.0) < 10 ) return true; + + return false; + } + + + void AutoHorizontal::_slacken () + { + ltrace(200) << "AutoHorizontal::_slacken() " << this << endl; + ltracein(200); + + AutoContact* contact = getAutoSource(); + Interval constraints = Interval(contact->getCBYMin(),contact->getCBYMax()); + + constraints.inflate ( 0, /*Katabatic::GCell::getTopRightShrink()*/ DbU::lambda(1.0) ); + + // Ugly: GCell's track number is hardwired. + if ( constraints.getSize() / DbU::lambda(5.0) < 10 ) ::slacken ( this, true ); + + contact = getAutoTarget (); + constraints = Interval(contact->getCBYMin(),contact->getCBYMax()); + constraints.inflate ( 0, /*Katabatic::GCell::getTopRightShrink()*/ DbU::lambda(1.0) ); + + if ( constraints.getSize() / DbU::lambda(5.0) < 10 ) ::slacken ( this, false ); + + setSlackened ( true ); + + ltraceout(200); + } + + + bool AutoHorizontal::canDesalignate ( AutoContact* contact ) const + { return contact->canHDesalignate(); } + + + void AutoHorizontal::desalignate ( AutoContact* contact ) + { contact->hDesalignate(); } + + + void AutoHorizontal::alignate ( DbU::Unit axis ) + { + if ( _horizontal->getY() == axis ) return; + + ltrace(80) << "alignate() " << (void*)this << " " << this << " @Y " << DbU::getLambda(axis) << endl; + + _horizontal->setY ( axis ); + invalidate (); + + AutoContact* anchor = getAutoSource(); + anchor->invalidate (); + if ( anchor->isTerminal() ) anchor->setY ( axis ); + + anchor = getAutoTarget(); + anchor->invalidate (); + if ( anchor->isTerminal() ) anchor->setY ( axis ); + } + + + void AutoHorizontal::orient () + { + if ( _horizontal->getTargetX() < _horizontal->getSourceX() ) + _horizontal->invert (); + } + + + void AutoHorizontal::setPositions () + { + _sourcePosition = _horizontal->getSourceX() - Session::getExtensionCap(); + _targetPosition = _horizontal->getTargetX() + Session::getExtensionCap(); + } + + + bool AutoHorizontal::checkPositions () const + { + bool coherency = true; + DbU::Unit sourcePosition = _horizontal->getSourceX() - Session::getExtensionCap(); + DbU::Unit targetPosition = _horizontal->getTargetX() + Session::getExtensionCap(); + + if ( _sourcePosition != sourcePosition ) { + cerr << Error ( "%s\n Source position incoherency: " + "shadow: %s, real: %s." + , _getString().c_str() + , DbU::getValueString(_sourcePosition).c_str() + , DbU::getValueString( sourcePosition).c_str() + ) << endl; + coherency = false; + } + + if ( _targetPosition != targetPosition ) { + cerr << Error ( "%s\n Target position incoherency: " + "shadow: %s, real: %s." + , _getString().c_str() + , DbU::getValueString(_targetPosition).c_str() + , DbU::getValueString( targetPosition).c_str() + ) << endl; + coherency = false; + } + + return coherency; + } + + + bool AutoHorizontal::checkConstraints () const + { + Interval sourceConstraints = Interval(getAutoSource()->getCBYMin(),getAutoSource()->getCBYMax()); + Interval targetConstraints = Interval(getAutoTarget()->getCBYMin(),getAutoTarget()->getCBYMax()); + + if ( !sourceConstraints.intersect(targetConstraints) ) { + cerr << Error ( "%p:%s\n Constraints incoherency: S:%p:%s, T:%p:%s" + , (void*)base() + , _getString().c_str() + , getAutoSource()->getContact() + , getString(sourceConstraints).c_str() + , getAutoTarget()->getContact() + , getString(targetConstraints).c_str() + ) << endl; + return false; + } + + return true; + } + + + void AutoHorizontal::_computeTerminal () + { _computeTerminal(_horizontal); } + + + void AutoHorizontal::moveULeft () + { + if ( not getAutoSource()->isCorner() or not getAutoTarget()->isCorner() ) return; + if ( not getAutoSource()->getGCell()->getDown() ) return; + + Session::setInvalidateMask ( Session::RestoreHCon|Session::NetCanonize ); + Session::invalidate ( getNet() ); + + AutoContact* autoSource = getAutoSource(); + AutoContact* autoTarget = getAutoTarget(); + GCell* begin = autoSource->getGCell(); + GCell* end = autoTarget->getGCell(); + + forEach ( Vertical*, isegment, autoSource->getSlaveComponents().getSubSet() ) { + AutoSegment* segment = Session::lookup ( *isegment ); + if ( segment->isLocal() ) { + segment->setGlobal ( true ); + continue; + } + + if ( segment->getAutoSource() == autoSource ) { + begin->addVSegment ( segment ); + } else { + if ( begin->getDown() == segment->getAutoSource()->getGCell() ) { + segment->setGlobal ( false ); + segment->getAutoSource()->invalidate (); + } else + begin->getDown()->removeVSegment ( segment ); + } + } + + forEach ( Vertical*, isegment, autoTarget->getSlaveComponents().getSubSet() ) { + AutoSegment* segment = Session::lookup ( *isegment ); + if ( segment->isLocal() ) { + segment->setGlobal ( true ); + continue; + } + + if ( segment->getAutoSource() == autoTarget ) { + begin->addVSegment ( segment ); + } else { + if ( end->getDown() == segment->getAutoSource()->getGCell() ) { + segment->setGlobal ( false ); + segment->getAutoSource()->invalidate (); + } else + end->getDown()->removeVSegment ( segment ); + } + } + + if ( begin != end ) { + for ( GCell* gcell = begin->getLeft() ; gcell != end ; gcell = gcell->getLeft() ) + gcell->removeHSegment ( this ); + } + + begin = begin->getDown(); + end = end ->getDown(); + + autoSource->setGCell ( begin ); + autoTarget->setGCell ( end ); + if ( begin != end ) { + for ( GCell* gcell = begin->getLeft() ; gcell != end ; gcell = gcell->getLeft() ) + gcell->addHSegment ( this ); + } + + DbU::Unit y = begin->getUSide(Constant::Vertical).getVMax(); + setAxis ( y ); + + Session::revalidateTopology (); + } + + + void AutoHorizontal::moveURight () + { + if ( not getAutoSource()->isCorner() or not getAutoTarget()->isCorner() ) return; + if ( not getAutoSource()->getGCell()->getUp() ) return; + + Session::setInvalidateMask ( Session::RestoreVCon|Session::NetCanonize ); + Session::invalidate ( getNet() ); + + AutoContact* autoSource = getAutoSource(); + AutoContact* autoTarget = getAutoTarget(); + GCell* begin = autoSource->getGCell(); + GCell* end = autoTarget->getGCell(); + + forEach ( Vertical*, isegment, autoSource->getSlaveComponents().getSubSet() ) { + AutoSegment* segment = Session::lookup ( *isegment ); + if ( segment->isLocal() ) { + segment->setGlobal ( true ); + continue; + } + + if ( segment->getAutoTarget() == autoSource ) { + begin->addVSegment ( segment ); + } else { + if ( begin->getUp() == segment->getAutoTarget()->getGCell() ) { + segment->setGlobal ( false ); + segment->getAutoTarget()->invalidate (); + } else + begin->getUp()->removeVSegment ( segment ); + } + } + + forEach ( Vertical*, isegment, autoTarget->getSlaveComponents().getSubSet() ) { + AutoSegment* segment = Session::lookup ( *isegment ); + if ( segment->isLocal() ) { + segment->setGlobal ( true ); + continue; + } + + if ( segment->getAutoTarget() == autoTarget ) { + begin->addVSegment ( segment ); + } else { + if ( end->getUp() == segment->getAutoTarget()->getGCell() ) { + segment->setGlobal ( false ); + segment->getAutoTarget()->invalidate (); + } else + end->getUp()->removeVSegment ( segment ); + } + } + + if ( begin != end ) { + for ( GCell* gcell = begin->getLeft() ; gcell != end ; gcell = gcell->getLeft() ) + gcell->removeHSegment ( this ); + } + + begin = begin->getUp(); + end = end ->getUp(); + + autoSource->setGCell ( begin ); + autoTarget->setGCell ( end ); + if ( begin != end ) { + for ( GCell* gcell = begin->getLeft() ; gcell != end ; gcell = gcell->getLeft() ) + gcell->addHSegment ( this ); + } + + DbU::Unit y = begin->getUSide(Constant::Vertical).getVMin(); + setAxis ( y ); + + Session::revalidateTopology (); + } + + + void AutoHorizontal::_makeDogLeg ( GCell* dogLegGCell, bool upLayer ) + { + DebugSession::open ( getNet(), 110 ); + ltracein(159); + + Session::dogLegReset (); + + AutoContact* autoTarget = getAutoTarget(); + AutoContact* autoSource = getAutoSource(); + GCell* begin = autoSource->getGCell(); + GCell* end = autoTarget->getGCell(); + unsigned int fragmentType = AutoSegment::Global; + unsigned int splittedType = AutoSegment::Global; + + //DbU::Unit dogLegAxis = (detachSource)?dogLegGCell->getXMax():dogLegGCell->getX(); + DbU::Unit dogLegAxis = (dogLegGCell->getXMax() + dogLegGCell->getX()) / 2; + if ( isLocal() ) + dogLegAxis = (getSourceX() + getTargetX()) / 2; + + ltrace(159) << "Detaching Target AutoContact " + << (void*)autoTarget->getContact() << ":" + << autoTarget->getContact() << "." << endl; + if ( end == dogLegGCell ) { + fragmentType = AutoSegment::Local; + } + if ( begin == dogLegGCell ) { + setGlobal ( false ); + splittedType = AutoSegment::Local; + } + + autoTarget->invalidate (); + autoTarget->setInvalidatedTopology ( true ); + + if ( dogLegGCell != end ) { + GCell* gcell = dogLegGCell; + do { + if ( gcell != begin ) + gcell->removeHSegment ( this ); + gcell = gcell->getRight (); + } while ( gcell && (gcell != end) ); + } + + Session::dogLeg ( this ); + + size_t depth = Session::getRoutingGauge()->getLayerDepth ( _horizontal->getLayer() ); + Layer* contactLayer = Session::getRoutingGauge()->getContactLayer ( depth + ((upLayer)?0:-1) ); + const Layer* dogLegLayer = Session::getRoutingGauge()->getRoutingLayer ( depth + ((upLayer)?1:-1) ); + + _horizontal->getTargetHook()->detach (); + + AutoContact* dlContact1 = AutoContact::create ( dogLegGCell, _horizontal->getNet(), contactLayer ); + AutoContact* dlContact2 = AutoContact::create ( dogLegGCell, _horizontal->getNet(), contactLayer ); + AutoSegment* segment1 = AutoVertical::create ( dlContact1 + , dlContact2 + , dogLegLayer + , dogLegAxis + , DbU::lambda(2.0) + , AutoSegment::Local + , false + , false + ); + + ltrace(200) << "New " << (void*)dlContact1->getContact() << ":" << dlContact1->getContact() << "." << endl; + ltrace(200) << "New " << (void*)dlContact2->getContact() << ":" << dlContact2->getContact() << "." << endl; + ltrace(200) << "Session::dogLeg[1] perpand: " << segment1 << endl; + Session::dogLeg ( segment1 ); + + _horizontal->getTargetHook()->attach ( dlContact1->getContact()->getBodyHook() ); + AutoSegment* segment2 = AutoHorizontal::create ( dlContact2 + , autoTarget + , getLayer() + , getY() + , DbU::lambda(2.0) + , fragmentType + , false + , false + ); + segment2->setAxis ( getY(), AxisSet ); + ltrace(200) << "Session::dogLeg[2] new paral: " << segment2 << endl; + ltrace(200) << "Session::dogLeg[0] original: " << this << endl; + Session::dogLeg ( segment2 ); + + setGlobal ( (splittedType == AutoSegment::Global) ); + + if ( (splittedType == AutoSegment::Global) or ( fragmentType == AutoSegment::Global ) ) { + if ( splittedType == AutoSegment::Local ) autoSource->restoreVConnexity ( getY(), true ); + else autoTarget->restoreVConnexity ( getY(), true ); + } + + setTerminal ( false ); + segment2->setTerminal ( false ); + if ( autoSource->getAnchor() and not isGlobal() ) setTerminal ( true ); + if ( autoTarget->getAnchor() and not segment2->isGlobal() ) segment2->setTerminal ( true ); + + segment1->setSlackened ( true ); + segment2->setSlackened ( isSlackened() ); + + Session::invalidate ( getNet() ); + Session::revalidateTopology (); + + ltraceout(159); + DebugSession::close (); + } + + + string AutoHorizontal::_getString () const + { + string s = AutoSegment::_getString(); + return s; + } + + + Record* AutoHorizontal::_getRecord () const + { + Record* record = AutoSegment::_getRecord (); + record->add ( getSlot ( "_horizontal", _horizontal ) ); + + return record; + } + + +} // End of Katabatic namespace. diff --git a/katabatic/src/AutoSegment.cpp b/katabatic/src/AutoSegment.cpp new file mode 100644 index 00000000..bd9f9c2e --- /dev/null +++ b/katabatic/src/AutoSegment.cpp @@ -0,0 +1,1877 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2008, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | K a t a b a t i c - Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Module : "./AutoSegment.cpp" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#include "hurricane/Warning.h" +#include "hurricane/Bug.h" +#include "hurricane/DataBase.h" +#include "hurricane/Technology.h" +#include "hurricane/Horizontal.h" +#include "hurricane/Vertical.h" +#include "crlcore/RoutingGauge.h" + +#include "katabatic/Session.h" +#include "katabatic/AutoContact.h" +#include "katabatic/AutoSegment.h" +#include "katabatic/AutoHorizontal.h" +#include "katabatic/AutoVertical.h" +#include "katabatic/GCell.h" +#include "katabatic/KatabaticEngine.h" + + +namespace { + + + using namespace std; + using namespace CRL; + using namespace Hurricane; + using namespace Katabatic; + + + // --------------------------------------------------------------- + // Local Variables. + + + const char* badAutoSegmentAnchor = + "AutoSegment::create() :\n\n" + " Source and/or target anchor is NOT an (internal error).\n" + " Source: %s, Target: %s"; + + const char* dupAutoSegmentAnchor = + "AutoSegment::create() :\n\n" + " Source and Target anchor are the same : %s (internal error)."; + + const char* badSegment = + "Katabatic::AutoSegment::create () :\n\n" + " Segment between %s and %s\n" + " is neither horizontal nor vertical .\n"; + + const char* badSegmentSource = + "Katabatic::AutoSegment::create () :\n\n" + " Source anchor of segment %s is not a Contact\n" + " (%s)\n"; + + const char* badSegmentTarget = + "Katabatic::AutoSegment::create () :\n\n" + " Source anchor of segment %s is not a Contact\n" + " (%s)\n"; + + const char* mismatchSegmentSource = + "Katabatic::AutoSegment::create () :\n\n" + " Source anchor of segment %s is already an AutoContact\n" + " (%s)\n"; + + const char* mismatchSegmentTarget = + "Katabatic::AutoSegment::create () :\n\n" + " Target anchor of segment %s is already an AutoContact\n" + " (%s)\n"; + + + // --------------------------------------------------------------- + // Local Functions. + + + bool getTerminalInterval ( AutoSegment* autoSegment + , AutoContact* fromContact + , bool isHorizontal + , DbU::Unit& min + , DbU::Unit& max + ) + { + AutoContact* terminalContact = NULL; + + if ( !fromContact ) { + bool found = getTerminalInterval ( autoSegment + , autoSegment->getAutoSource() + , autoSegment->isHorizontal() + , min + , max ); + if ( !found ) + found = getTerminalInterval ( autoSegment + , autoSegment->getAutoTarget() + , autoSegment->isHorizontal() + , min + , max ); + + //if ( !found ) + // cerr << "[ERROR] Cannot find terminal of " << autoSegment << "." << endl; + + return found; + } else { + if ( autoSegment->isGlobal() ) return false; + + ltrace(88) << "Examining " << autoSegment << " " << fromContact << endl; + + if ( autoSegment->getSource() == autoSegment->getTarget() ) { + cerr << Error("Source & Target are the same :\n" + " %s\n %s" + ,getString(autoSegment).c_str() + ,getString(autoSegment->getSource()).c_str()) << endl; + } + + terminalContact = autoSegment->getAutoSource(); + if ( terminalContact == fromContact ) { + terminalContact = autoSegment->getAutoTarget(); + } + + if ( !terminalContact->isTerminal() ) { + AutoSegment* segment = NULL; + size_t segmentCount = 0; + forEach ( Component*, icomponent, terminalContact->getSlaveComponents() ) { + if ( *icomponent == autoSegment->getSegment() ) continue; + + Segment* connex = dynamic_cast(*icomponent); + if ( !connex ) continue; + + segment = Session::lookup ( connex ); + if ( !segment || !segment->isTerminal() ) continue; + + segmentCount++; + } + + if ( segmentCount == 1 ) { + return getTerminalInterval ( segment, terminalContact, isHorizontal, min, max ); + + return false; + } + } else { + ltrace(88) << "Terminal is " << terminalContact << endl; + + Box constraintBox = terminalContact->getConstraintBox(); + if ( isHorizontal ) { + min = constraintBox.getXMin (); + max = constraintBox.getXMax (); + } else { + min = constraintBox.getYMin (); + max = constraintBox.getYMax (); + } + return true; + } + } + + return false; + } + + + // --------------------------------------------------------------- + // Class : "AttractorsMap". + + + class AttractorsMap { + // Constructor. + public: + inline AttractorsMap (); + inline size_t getAttractorsCount () const; + DbU::Unit getLowerMedian () const; + DbU::Unit getUpperMedian () const; + void addAttractor ( DbU::Unit position ); + protected: + map _attractors; + size_t _attractorsCount; + }; + + + inline AttractorsMap::AttractorsMap () + : _attractors(), _attractorsCount(0) + { } + + + inline size_t AttractorsMap::getAttractorsCount () const + { + return _attractorsCount; + } + + + void AttractorsMap::addAttractor ( DbU::Unit position ) + { + _attractors[position]++; + _attractorsCount++; + + ltrace(88) << "add Attractor @" << DbU::getLambda(position) + << " [" << _attractors[position] << "]" << endl; + } + + + DbU::Unit AttractorsMap::getLowerMedian () const + { + size_t median = (_attractorsCount/2) + (_attractorsCount%2); + size_t lower = 0; + + map::const_iterator it = _attractors.begin (); + for ( ; it != _attractors.end() ; it++ ) { + lower += it->second; + if ( lower >= median ) break; + } + + return it->first; + } + + + DbU::Unit AttractorsMap::getUpperMedian () const + { + size_t median = _attractorsCount / 2; + size_t upper = 0; + + map::const_iterator it = _attractors.begin (); + for ( ; it != _attractors.end() ; it++ ) { + upper += it->second; + if ( upper > median ) break; + } + + return it->first; + } + + +} // End of local namespace. + + +namespace Katabatic { + + +// ------------------------------------------------------------------- +// Class : "Katabatic::AutoSegment::CompareCanonical". + + + bool AutoSegment::CompareCanonical::operator() ( const AutoSegment* lhs, const AutoSegment* rhs ) const + { + if ( lhs->isCanonical () xor rhs->isCanonical () ) return lhs->isCanonical(); + if ( lhs->isCollapsed () xor rhs->isCollapsed () ) return rhs->isCollapsed(); + if ( lhs->isSlackenStrap() xor rhs->isSlackenStrap() ) return lhs->isSlackenStrap(); + + if ( lhs->getSourceU() < rhs->getSourceU() ) return true; + if ( lhs->getSourceU() > rhs->getSourceU() ) return false; + + if ( lhs->getLength() > rhs->getLength() ) return true; + if ( lhs->getLength() < rhs->getLength() ) return false; + + if ( lhs->isGlobal () xor rhs->isGlobal () ) return lhs->isGlobal(); + if ( lhs->isTerminal () xor rhs->isTerminal () ) return rhs->isTerminal(); + if ( lhs->isHorizontal() xor rhs->isHorizontal() ) return lhs->isHorizontal(); + + if ( lhs->getAxis() < rhs->getAxis() ) return true; + if ( lhs->getAxis() > rhs->getAxis() ) return false; + + if ( lhs->isFixed() xor rhs->isFixed() ) return lhs->isFixed(); + + return lhs->getId() < rhs->getId(); + } + + +// ------------------------------------------------------------------- +// Class : "Katabatic::AutoSegment::CompareByDepthLength". + + + bool AutoSegment::CompareByDepthLength::operator() ( AutoSegment* lhs, AutoSegment* rhs ) const + { + if ( Session::getRoutingGauge()->getLayerDepth(lhs->getLayer()) + < Session::getRoutingGauge()->getLayerDepth(rhs->getLayer()) ) + return true; + + if ( Session::getRoutingGauge()->getLayerDepth(lhs->getLayer()) + > Session::getRoutingGauge()->getLayerDepth(rhs->getLayer()) ) + return false; + + return AutoSegment::CompareCanonical() ( lhs, rhs ); + } + + +// ------------------------------------------------------------------- +// Class : "Katabatic::AutoSegment". + + + size_t AutoSegment::_allocateds = 0; + unsigned long AutoSegment::_maxId = 0; + + + DbU::Unit AutoSegment::getX () const + { + return getSegment()->getX(); + } + + + DbU::Unit AutoSegment::getY () const + { + return getSegment()->getY(); + } + + + AutoContact* AutoSegment::getOppositeAnchor ( AutoContact* anchor ) const + { + return Session::lookup(static_cast(getOppositeAnchor(anchor->getContact()))); + } + + + Interval& AutoSegment::getOptimal ( Interval& i ) const + { + i.getVMin() = getOptimalMin(); + i.getVMax() = getOptimalMax(); + return i; + } + + + bool AutoSegment::checkInvalidated () const + { + if ( isInvalidated() ) + cerr << Error("%s is invalidated.",getString(this).c_str()) << endl; + + return !isInvalidated(); + } + + + void AutoSegment::invalidate () + { + if ( Session::doDestroyTool() ) return; + + _invalidate (); + forEach ( AutoSegment*, isegment, getCollapseds() ) + isegment->_invalidate (); + } + + + void AutoSegment::_invalidate () + { + if ( !isInvalidated() ) { + ltrace(110) << "AutoSegment::_invalidate() " << this << endl; + + setInvalidated ( true ); + Session::invalidate ( this ); + } + } + + + void AutoSegment::revalidate () + { + ltrace(110) << "AutoSegment::revalidate() " << this << endl; + ltracein(110); + + setPositions (); + setInvalidated ( false ); + + ltraceout(110); + } + + + DbU::Unit AutoSegment::getSlack () const + { + DbU::Unit constraintMin; + DbU::Unit constraintMax; + + getConstraints ( constraintMin, constraintMax ); + + return constraintMax - constraintMin; + } + + + DbU::Unit AutoSegment::getCost ( DbU::Unit axis ) const + { + DbU::Unit optimal = getOptimalMin(); + if ( axis < optimal ) + return optimal - axis; + + optimal = getOptimalMax(); + if ( axis > optimal ) + return axis - optimal; + + return 0; + } + + + AutoSegment* AutoSegment::getCanonical ( DbU::Unit& min, DbU::Unit& max ) + { + min = getSourcePosition (); + max = getTargetPosition (); + + if ( max < min ) swap ( min, max ); + + AutoSegment* canonical = this; + size_t canonicals = isCanonical(); + size_t aligneds = 1; + DbU::Unit collapsedMin; + DbU::Unit collapsedMax; + + forEach ( AutoSegment*, isegment, getCollapseds() ) { + if ( isegment->isCanonical() ) { + canonical = *isegment; + canonicals++; + } + + collapsedMin = isegment->getSourcePosition(); + collapsedMax = isegment->getTargetPosition(); + if ( collapsedMax < collapsedMin ) swap ( collapsedMin, collapsedMax ); + if ( collapsedMin < min ) min = collapsedMin; + if ( collapsedMax > max ) max = collapsedMax; + + aligneds++; + } + + if ( (canonicals > 1) || ( !canonicals && (aligneds > 2) ) ) { + cerr << Bug("AutoSegment::getCanonical(): %p:%s" + "\n Bad canonization: %d canonicals out of %d collapseds." + , base(), _getString().c_str(), canonicals, aligneds ) << endl; + + int count = 0; + cerr << " " << count++ << ": " << this << endl; + forEach ( AutoSegment*, isegment, getCollapseds() ) + cerr << " " << count++ << ": " << *isegment << endl; + } + + return canonical; + } + + + AutoSegments AutoSegment::getOnSourceContact ( unsigned int direction ) + { + return AutoSegments_OnContact + ( this, getSource() ).getSubSet ( AutoSegments_InDirection(direction) ); + } + + + AutoSegments AutoSegment::getOnTargetContact ( unsigned int direction ) + { + return AutoSegments_OnContact + ( this, getTarget() ).getSubSet ( AutoSegments_InDirection(direction) ); + } + + + AutoSegments AutoSegment::getCollapseds ( bool withPerpand ) + { + return AutoSegments_Collapsed ( this, withPerpand ); + } + + + AutoSegments AutoSegment::getCollapsedPerpandiculars () + { + return AutoSegments_CollapsedPerpandicular ( this ); + } + + + bool AutoSegment::isCanonicalStrap () const + { + if ( not isStrap() ) return false; + forEach ( AutoSegment*, isegment, const_cast(this)->getCollapseds() ) { + if ( not isegment->isStrap() ) return false; + } + return true; + } + + + bool AutoSegment::collapse () + { + if ( _isGlobal ) { + cerr << Error("Global %s cannot be collapsed.",getString(this).c_str()) << endl; + return false; + } + if ( _isCollapsed ) return true; + + _isCollapsed = true; + + unsigned int direction = (_isHorizontal) ? Constant::Vertical : Constant::Horizontal; + forEach ( AutoSegment*, isegment, AutoSegments_AnchoredBySource(getAutoSource(),direction) ) { + isegment->setCanonical ( false ); + } + forEach ( AutoSegment*, isegment, AutoSegments_AnchoredBySource(getAutoTarget(),direction) ) { + isegment->setCanonical ( false ); + } + + return true; + } + + + bool AutoSegment::expand () + { + if ( _isGlobal ) { + cerr << Warning("Global %s already uncollapsed.",getString(this).c_str()) << endl; + return false; + } + if ( !_isCollapsed ) { + cerr << Warning("Local %s already uncollapsed.",getString(this).c_str()) << endl; + return true; + } + + _isCollapsed = false; + + canonize (); + + unsigned int direction = (_isHorizontal) ? Constant::Vertical : Constant::Horizontal; + forEach ( AutoSegment*, segment, getOnSourceContact(direction) ) { + segment->canonize (); + } + forEach ( AutoSegment*, segment, getOnTargetContact(direction) ) { + segment->canonize (); + } + + return true; + } + + + bool AutoSegment::toConstraintAxis ( set* processeds ) + { + if ( processeds && (processeds->find(this) != processeds->end()) ) return false; + + DbU::Unit constraintMin; + DbU::Unit constraintMax; + + getConstraints ( constraintMin, constraintMax ); + + if ( allowOutsideGCell() ) { + // Ugly: hard-wired value of the track spacing. + constraintMin -= DbU::lambda(5.0) * 8; + constraintMax += DbU::lambda(5.0) * 8; + } + + if ( getAxis() < constraintMin ) { + setAxis ( constraintMin, Realignate, processeds ); + return true; + } + + if ( getAxis() > constraintMax ) { + setAxis ( constraintMax, Realignate, processeds ); + return true; + } + + return false; + } + + + bool AutoSegment::toOptimalAxis ( set* processeds ) + { + if ( processeds && (processeds->find(this) != processeds->end()) ) return false; + + DbU::Unit constraintMin; + DbU::Unit constraintMax; + + getConstraints ( constraintMin, constraintMax ); + + DbU::Unit optimalMin = max ( min(getOptimalMin(),constraintMax), constraintMin ); + DbU::Unit optimalMax = min ( max(getOptimalMax(),constraintMin), constraintMax ); + + if ( getAxis() < optimalMin ) { +#if defined(CHECK_DETERMINISM) + cerr << "Order: toOptimalMin " + << DbU::getValueString(optimalMin) << " [" + << DbU::getValueString(optimalMin) << ":" + << DbU::getValueString(optimalMax) << "] [" + << DbU::getValueString(constraintMin) << ":" + << DbU::getValueString(constraintMax) << "] " + << this << endl; +#endif + setAxis ( optimalMin, Realignate|AxisSet, processeds ); + return true; + } + + if ( getAxis() > optimalMax ) { +#if defined(CHECK_DETERMINISM) + cerr << "Order: toOptimalMax " + << DbU::getValueString(optimalMin) << " [" + << DbU::getValueString(optimalMin) << ":" + << DbU::getValueString(optimalMax) << "] [" + << DbU::getValueString(constraintMin) << ":" + << DbU::getValueString(constraintMax) << "] " + << this << endl; +#endif + setAxis ( optimalMax, Realignate|AxisSet, processeds ); + return true; + } + +#if defined(CHECK_DETERMINISM) + cerr << "Order: in optimal position " + << DbU::getValueString(optimalMin) << " [" + << DbU::getValueString(optimalMin) << ":" + << DbU::getValueString(optimalMax) << "] [" + << DbU::getValueString(constraintMin) << ":" + << DbU::getValueString(constraintMax) << "] " + << this << endl; +#endif + + return false; + } + + + void AutoSegment::setAxis ( DbU::Unit axis, unsigned int flags, set* processeds ) + { + if ( processeds and (processeds->find(this) != processeds->end()) ) return; + + if ( ( axis != getAxis() ) and isFixed() ) { + cerr << Error("AutoSegment::setAxis(): Cannot move a fixed segment.\n" + " (on: %s)",_getString().c_str()) << endl; + } + + if ( _isUnsetAxis and (flags & AxisSet) ) { + ltrace(200) << "setAxis() - AxisSet flag raised " << this << endl; + _isUnsetAxis = false; + } + if ( ( axis == getAxis() ) and not (flags & Realignate) ) return; + + ltrace(200) << "setAxis() @" + << ((_isHorizontal)?"Y ":"X ") << DbU::getLambda(getAxis()) + << " to " << DbU::getLambda(axis) << " on " << this << endl; + ltracein(80); + + alignate ( axis ); + if ( processeds ) processeds->insert ( this ); + + forEach ( AutoSegment*, isegment, getCollapseds() ) { + isegment->alignate ( getAxis() ); + if ( flags & AxisSet ) isegment->_isUnsetAxis = false; + if ( processeds ) processeds->insert ( *isegment ); + } + + ltraceout(80); + } + + + void AutoSegment::computeOptimal ( set* processeds ) + { + ltrace(89) << "computeOptimal() - " << this << endl; + ltracein(89); + + if ( processeds && (processeds->find(this) != processeds->end()) ) { ltraceout(89); return; } + + if ( _isCollapsed ) { + _optimalMin = 0; + setOptimalMax ( (_isHorizontal) ? _gcell->getBoundingBox().getYMax() + : _gcell->getBoundingBox().getXMax() ); + ltraceout(89); + return; + } + + DbU::Unit minGCell = getOrigin(); + DbU::Unit maxGCell = getExtremity(); + DbU::Unit terminalMin; + DbU::Unit terminalMax; + AttractorsMap attractors; + + AutoContact* anchor = getAutoSource(); + if ( anchor->isTerminal() ) { + Box constraintBox = anchor->getConstraintBox(); + if ( isHorizontal() ) { + terminalMin = constraintBox.getYMin (); + terminalMax = constraintBox.getYMax (); + } else { + terminalMin = constraintBox.getXMin (); + terminalMax = constraintBox.getXMax (); + } + + attractors.addAttractor ( terminalMin ); + if ( terminalMin != terminalMax ) + attractors.addAttractor ( terminalMax ); + } + + anchor = getAutoTarget(); + if ( anchor->isTerminal() ) { + Box constraintBox = anchor->getConstraintBox(); + if ( isHorizontal() ) { + terminalMin = constraintBox.getYMin (); + terminalMax = constraintBox.getYMax (); + } else { + terminalMin = constraintBox.getXMin (); + terminalMax = constraintBox.getXMax (); + } + + attractors.addAttractor ( terminalMin ); + if ( terminalMin != terminalMax ) + attractors.addAttractor ( terminalMax ); + } + + forEach ( AutoSegment*, autoSegment, getCollapsedPerpandiculars() ) { + ltrace(89) << "Perpandicular " << *autoSegment << endl; + ltracein(89); + if ( autoSegment->isLocal() ) { + if ( !autoSegment->isTerminal() ) { ltraceout(89); continue; } + + DbU::Unit terminalMin; + DbU::Unit terminalMax; + + if ( getTerminalInterval ( *autoSegment + , NULL + , isHorizontal() + , terminalMin + , terminalMax ) ) { + attractors.addAttractor ( terminalMin ); + if ( terminalMin != terminalMax ) + attractors.addAttractor ( terminalMax ); + } + } else { + bool isMin = true; + if ( isHorizontal() + && ( autoSegment->getAutoSource()->getGCell()->getRow() == _gcell->getRow() ) ) + isMin = false; + if ( isVertical() + && ( autoSegment->getAutoSource()->getGCell()->getColumn() == _gcell->getColumn() ) ) + isMin = false; + attractors.addAttractor ( (isMin) ? minGCell : maxGCell ); + } + ltraceout(89); + } + + DbU::Unit optimalMin; + DbU::Unit optimalMax; + DbU::Unit constraintMin; + DbU::Unit constraintMax; + getConstraints ( constraintMin, constraintMax ); + + if ( attractors.getAttractorsCount() ) { + ltrace(89) << "Lower Median " << DbU::getLambda(attractors.getLowerMedian()) << endl; + ltrace(89) << "Upper Median " << DbU::getLambda(attractors.getUpperMedian()) << endl; + + optimalMin = attractors.getLowerMedian(); + optimalMax = attractors.getUpperMedian(); + } else { + optimalMin = 0; + optimalMax = (_isHorizontal) ? _gcell->getBoundingBox().getYMax() + : _gcell->getBoundingBox().getXMax(); + } + + setInBound ( constraintMin, constraintMax, optimalMin ); + setInBound ( constraintMin, constraintMax, optimalMax ); + + if ( processeds ) processeds->insert ( this ); + setOptimalMin ( optimalMin ); + setOptimalMax ( optimalMax ); + forEach ( AutoSegment*, autoSegment, getCollapseds() ) { + if ( processeds ) processeds->insert ( *autoSegment ); + autoSegment->setOptimalMin ( optimalMin ); + autoSegment->setOptimalMax ( optimalMax ); + } + + ltraceout(89); + } + + + AutoSegment* AutoSegment::canonize () + { + ltrace(159) << "canonize() - " << this << endl; + + if ( isCanonical() ) { + ltrace(159) << "* " << this << " canonical" << endl; + return this; + } + + AutoSegment* canonical = this; + bool hasCanonical = false; + bool isCanonicalLocal = true; + + forEach ( AutoSegment*, isegment, getCollapseds() ) { + if ( isegment->isGlobal() ) isCanonicalLocal = false; + + if ( isegment->isCanonical() ) { + ltrace(159) << "* " << *isegment << " canonical" << endl; + //return *isegment; + canonical = *isegment; + hasCanonical = true; + break; + } + + if ( !hasCanonical ) { + if ( CompareCanonical()(*isegment,canonical) ) + canonical = *isegment; + } + } + + canonical->setCanonical ( true ); + canonical->setCanonicalLocal ( isCanonicalLocal ); + + // ltrace: 159 + if ( isCanonical() ) cerr << "* " << this << " canonical" << endl; + else cerr << "* " << this << endl; + + forEach ( AutoSegment*, isegment, getCollapseds() ) { + if ( isegment->isCanonical() ) cerr << "| " << *isegment << " canonical" << endl; + else cerr << "| " << *isegment << endl; + } + + return canonical; + } + + + AutoSegment::AutoSegment ( Segment* segment + , bool isHorizontal + , int type + , bool terminal + , bool collapsed + ) + : _isUnsetAxis (true) + , _invalidated (false) + , _isHorizontal (isHorizontal) + , _isTerminal (terminal) + , _isCollapsed (collapsed) + , _isCanonical (false) + , _isFixed (false) + , _strap (false) + , _layerChange (false) + , _slackened (false) + , _slackenStrap (false) + , _allowOutsideGCell(false) + , _id (_maxId++) + , _optimalMin (0) + , _userConstraints (false) + { + //cerr << "AutoSegment::AutoSegment() - " << endl; +#if defined(CHECK_DETERMINISM) + cerr << "Order: AutoSegment::AutoSegment() - " << endl; +#endif + _allocateds++; + + AutoContact* source = Session::lookup(dynamic_cast(segment->getSource())); + AutoContact* target = Session::lookup(dynamic_cast(segment->getTarget())); + + _gcell = source->getGCell(); + setOptimalMax ( (_isHorizontal) ? _gcell->getBoundingBox().getYMax() + : _gcell->getBoundingBox().getXMax() ); + + switch ( type ) { + case AutoSegment::Global: _isGlobal = true; break; + case AutoSegment::Local : _isGlobal = false; break; + case AutoSegment::Guess : + _isGlobal = ( source->getGCell() != target->getGCell() ); + break; + } + + _isCanonicalLocal = !_isGlobal; + + _computeTerminal ( segment ); + //if ( source->isTerminal() or target->isTerminal() ) _isTerminal = true; + + //if ( source->isTerminal() + // and target->isTerminal() + // /*and (segment->getLength() < DbU::lambda(25.0))*/ + // and (source->getGCell() == target->getGCell()) ) { + // _strap = true; + //} + + source->setInvalidatedTopology ( true ); + } + + + void AutoSegment::_preCreate ( Component* source, Component* target ) + { + AutoContact* acSource = Session::lookup(dynamic_cast(source)); + AutoContact* acTarget = Session::lookup(dynamic_cast(target)); + + _preCreate ( acSource, acTarget ); + } + + + void AutoSegment::_preCreate ( AutoContact* source, AutoContact* target ) + { + if ( !source || !target ) + throw Error ( badAutoSegmentAnchor + , ((source)?getString(source).c_str():"NULL") + , ((target)?getString(target).c_str():"NULL") + ); + + if ( source == target ) + throw Error ( dupAutoSegmentAnchor, getString(source).c_str() ); + } + + + void AutoSegment::_postCreate () + { + Session::invalidate ( getNet() ); + Session::link ( this ); + invalidate (); + } + + + void AutoSegment::_preDestroy () + { + ltrace(200) << "AutoSegment::_preDestroy() - " << (void*)this << endl; + ltracein(90); + + Session::unlink ( this ); + ltraceout(90); + } + + + AutoSegment::~AutoSegment () + { + _allocateds--; + } + + + void AutoSegment::_computeTerminal ( Segment* segment ) + { + AutoContact* source = Session::lookup(dynamic_cast(segment->getSource())); + AutoContact* target = Session::lookup(dynamic_cast(segment->getTarget())); + + if ( source->isTerminal() or target->isTerminal() ) _isTerminal = true; + } + + + size_t AutoSegment::getAlignedContacts ( map& innerContacts ) + { + map::iterator icontact; + + innerContacts.clear (); + innerContacts.insert ( make_pair(getAutoSource(),0x1) ); + innerContacts.insert ( make_pair(getAutoTarget(),0x4) ); + + forEach ( AutoSegment*, isegment, getCollapseds() ) { + if ( (icontact = innerContacts.find(isegment->getAutoSource())) != innerContacts.end() ) { + if ( icontact->second & 0x1 ) icontact->second |= 0x2; + else icontact->second |= 0x1; + } else + innerContacts.insert ( make_pair(getAutoSource(),0x1) ); + + if ( (icontact = innerContacts.find(isegment->getAutoTarget())) != innerContacts.end() ) { + if ( icontact->second & 0x4 ) icontact->second |= 0x8; + else icontact->second |= 0x4; + } else + innerContacts.insert ( make_pair(getAutoTarget(),0x4) ); + } + + return innerContacts.size(); + } + + + size_t AutoSegment::getPerpandicularsBound ( set& bounds ) + { + map contacts; + map::iterator icontact; + + getAlignedContacts ( contacts ); + + for ( icontact=contacts.begin() ; icontact != contacts.end() ; icontact++ ) { + if ( (icontact->second == 0x1) or (icontact->second == 0x4) ) { + forEach ( Segment*, isegment, icontact->first->getSlaveComponents().getSubSet() ) { + AutoSegment* autoSegment = Session::lookup ( *isegment ); + if ( !autoSegment ) continue; + if ( autoSegment->getDirection() == getDirection() ) continue; + + bounds.insert ( autoSegment ); + } + } + } + + return bounds.size(); + } + + + Interval AutoSegment::getMinSpanU () + { + map contacts; + map::iterator icontact; + + getAlignedContacts ( contacts ); + + DbU::Unit spanMin = DbU::Min; + DbU::Unit spanMax = DbU::Max; + Interval constraints; + unsigned int direction = Constant::perpandicular(getDirection()); + + for ( icontact=contacts.begin() ; icontact != contacts.end() ; icontact++ ) { + constraints = icontact->first->getUConstraints ( direction ); + if ( icontact->second == 0x1 ) { + spanMin = max ( spanMin, constraints.getVMax() ); + } + if ( icontact->second == 0x4 ) { + spanMax = min ( spanMax, constraints.getVMin() ); + } + } + + return Interval(spanMin,spanMax); + } + + + void AutoSegment::setAllowOutsideGCell ( bool state, bool propagate ) + { + if ( allowOutsideGCell() ) return; + + _setAllowOutsideGCell ( state ); + + if ( propagate ) { + forEach ( AutoSegment*, isegment, getCollapseds() ) { + isegment->_setAllowOutsideGCell ( state ); + } + } + } + + + void AutoSegment::_setAllowOutsideGCell ( bool state ) + { + ltrace(200) << "_setAllowOutsideGCell() - " << this << endl; + _allowOutsideGCell = state; + } + + + bool AutoSegment::canGoOutsideGCell () const + { + ltracein(200); + + bool goOutsideGCell = getAutoSource()->canGoOutsideGCell(this); + goOutsideGCell = goOutsideGCell and getAutoTarget()->canGoOutsideGCell(this); + + if ( !goOutsideGCell ) { + ltraceout(200); + return false; + } + + GCell* sourceGCell = getAutoSource()->getGCell(); + GCell* leftGCell = NULL; + GCell* rightGCell = NULL; + Interval uside; + bool goLeft = false; + bool goRight = false; + + if ( isHorizontal() ) { + uside = sourceGCell->getUSide ( Constant::Vertical ); + leftGCell = sourceGCell->getDown(); + rightGCell = sourceGCell->getUp (); + } else { + uside = sourceGCell->getUSide ( Constant::Horizontal ); + leftGCell = sourceGCell->getLeft (); + rightGCell = sourceGCell->getRight(); + } + + DbU::Unit constraintMin; + DbU::Unit constraintMax; + getConstraints ( constraintMin, constraintMax ); + + if ( leftGCell && (uside.getVMin() >= constraintMin) ) { + ltrace(200) << "Can go Left." << endl; + goLeft = true; + } + // Ugly: Must use the right compensator for VMax. + if ( rightGCell && (uside.getVMax() <= constraintMax)+DbU::lambda(1.0) ) { + ltrace(200) << "Can go Right." << endl; + goRight = true; + } + + goOutsideGCell = goOutsideGCell and (goRight or goLeft); + + // Override. + //goOutsideGCell = !isGlobal() && !isTerminal(); + + ltrace(200) << "AutoSegment::canGoOutsideGCell() - " << goOutsideGCell << endl; + ltraceout(200); + + return goOutsideGCell; + } + + + bool AutoSegment::canDesalignate () + { + ltrace(200) << "AutoSegment::canDesalignate()" << endl; + + map innerContacts; + map::iterator icontact; + + getAlignedContacts ( innerContacts ); + + for ( icontact=innerContacts.begin() ; icontact != innerContacts.end() ; icontact++ ) { + ltrace(200) << "| " << "flags:" << icontact->second + << " " << (void*)icontact->first->base() << ":" << icontact->first << endl; + if ( (icontact->second & 0x5 ) && canDesalignate(icontact->first) ) return true; + //if ( (icontact->second & 0x3 ) && canDesalignate(icontact->first) ) return true; + //if ( (icontact->second & 0x12) && canDesalignate(icontact->first) ) return true; + } + ltrace(200) << "No AutoContact suitable for desalignment." << endl; + + return false; + } + + + void AutoSegment::desalignate () + { + map innerContacts; + map::iterator icontact; + vector segments; + + // Ugly. Must fusion with the inner contact loop. + forEach ( AutoSegment*, isegment, getCollapseds() ) { + segments.push_back ( *isegment ); + } + + invalidate (); + getAlignedContacts ( innerContacts ); + + for ( icontact=innerContacts.begin() ; icontact != innerContacts.end() ; icontact++ ) { + desalignate ( icontact->first ); + //if ( icontact->second & 0x3 ) desalignate ( icontact->first ); + //if ( icontact->second & 0x3 ) desalignate ( icontact->first ); + //if ( icontact->second & 0x12) desalignate ( icontact->first ); + } + + Session::invalidate ( getNet() ); + Session::revalidateTopology (); + } + + + void AutoSegment::changeDepth ( unsigned int depth, bool propagate, bool standAlone ) + { + invalidate (); + Session::invalidate ( getNet() ); + Session::setInvalidateMask ( Session::NetSplitContacts ); + + _changeDepth ( depth, true ); + + if ( propagate ) { + forEach ( AutoSegment*, isegment, getCollapseds() ) { + isegment->_changeDepth ( depth, true ); + } + } + + if ( standAlone ) Session::revalidateTopology(); + } + + + void AutoSegment::_changeDepth ( unsigned int depth, bool withNeighbors ) + { + ltrace(200) << "_changeDepth() - " << this << endl; + ltracein(200); + + const Layer* layer0 = Session::getRoutingGauge()->getRoutingLayer(depth); + if ( getLayer() != layer0 ) { + setLayer ( layer0 ); + + getAutoSource()->invalidate(); + getAutoTarget()->invalidate(); + } + + if ( !withNeighbors ) { + ltraceout(200); + return; + } + + forEach ( Component*, icomponent, getAutoSource()->getSlaveComponents() ) { + if ( *icomponent == base() ) continue; + + Segment* segment = dynamic_cast(*icomponent); + if ( !segment ) continue; + + AutoSegment* autoSegment = Session::lookup ( segment ); + if ( !autoSegment ) continue; + if ( autoSegment->isGlobal () ) continue; + if ( autoSegment->isTerminal() ) continue; + + if ( !( autoSegment->isHorizontal() xor isHorizontal() ) ) { + autoSegment->_changeDepth ( depth, false ); + } else { + autoSegment->_changeDepth ( depth-1, false ); + } + } + + forEach ( Component*, icomponent, getAutoTarget()->getSlaveComponents() ) { + if ( *icomponent == base() ) continue; + + Segment* segment = dynamic_cast(*icomponent); + if ( !segment ) continue; + + AutoSegment* autoSegment = Session::lookup ( segment ); + if ( !autoSegment ) continue; + if ( autoSegment->isGlobal () ) continue; + if ( autoSegment->isTerminal() ) continue; + + if ( !( autoSegment->isHorizontal() xor isHorizontal() ) ) { + autoSegment->_changeDepth ( depth, false ); + } else { + autoSegment->_changeDepth ( depth-1, false ); + } + } + + vector gcells; + getGCells ( gcells ); + for ( size_t i=0 ; iinvalidate (); + } + + ltraceout(200); + } + + + bool AutoSegment::canSlacken ( bool propagate ) + { + ltrace(200) << "AutoSegment::canSlacken()" << endl; + + if ( !isGlobal() && !propagate ) return false; + + if ( _canSlacken() ) return true; + if ( propagate ) { + forEach ( AutoSegment*, isegment, getCollapseds() ) { + if ( isegment->_canSlacken() ) return true; + } + } + + return false; + } + + + void AutoSegment::slacken ( bool propagate ) + { + invalidate (); + + set collapseds; + collapseds.insert ( this ); + + if ( propagate ) { + forEach ( AutoSegment*, isegment, getCollapseds() ) + collapseds.insert ( *isegment ); + } + + set::iterator isegment = collapseds.begin(); + for ( ; isegment != collapseds.end() ; isegment++ ) + (*isegment)->_slacken (); + + Session::invalidate ( getNet() ); + Session::revalidateTopology (); + } + + + bool AutoSegment::canPivotUp ( bool propagate ) + { + ltrace(200) << "AutoSegment::canPivotUp()" << endl; + + //if ( isTerminal() ) return false; + + size_t depth = Session::getRoutingGauge()->getLayerDepth(getLayer()); + if ( depth+2 >= Session::getRoutingGauge()->getDepth() ) return false; + + vector gcells; + getGCells ( gcells ); + for ( size_t i=0 ; ihasFreeTrack(depth) ) return false; + } + + ltrace(200) << getAutoSource() << endl; + ltrace(200) << getAutoTarget() << endl; + ltrace(200) << "min depths, Segment:" << depth + << " S:" << getAutoSource()->getMinDepth() + << " T:" << getAutoTarget()->getMinDepth() << endl; + + if ( getAutoSource()->getMinDepth() < depth ) return false; + if ( getAutoTarget()->getMinDepth() < depth ) return false; + if ( not propagate ) { + ltrace(200) << "AutoSegment::canPivotUp() - true [no propagate]" << endl; + return true; + } + + if ( propagate ) { + forEach ( AutoSegment*, isegment, getCollapseds() ) { + isegment->getGCells ( gcells ); + for ( size_t i=0 ; ihasFreeTrack(depth) ) return false; + } + if ( isegment->getAutoSource()->getMinDepth() < depth ) return false; + if ( isegment->getAutoTarget()->getMinDepth() < depth ) return false; + } + } + + ltrace(200) << "AutoSegment::canPivotUp() - true [propagate]" << endl; + + return true; + } + + + bool AutoSegment::canMoveUp ( bool propagate ) + { + ltrace(200) << "AutoSegment::canMoveUp()" << endl; + + if ( isLayerChange() ) return false; + if ( isTerminal() and isLocal() ) return false; + + size_t depth = Session::getRoutingGauge()->getLayerDepth(getLayer()) + 2; + if ( depth >= Session::getRoutingGauge()->getDepth() ) return false; + + vector gcells; + getGCells ( gcells ); + for ( size_t i=0 ; ihasFreeTrack(depth) ) return false; + } + + if ( isLocal() and not propagate ) { + if ( not getAutoSource()->canMoveUp(this) ) return false; + if ( not getAutoTarget()->canMoveUp(this) ) return false; + return true; + } + + bool hasGlobalSegment = false; + size_t collapseds = 0; + if ( propagate ) { + forEach ( AutoSegment*, isegment, getCollapseds() ) { + collapseds++; + if ( isegment->isGlobal() ) hasGlobalSegment = true; + + isegment->getGCells ( gcells ); + for ( size_t i=0 ; ihasFreeTrack(depth) ) { + ltrace(200) << "Not enough free track in " << gcells[i] << endl; + return false; + } + } + } + } + + return true; + } + + + bool AutoSegment::moveUp ( bool propagate ) + { + if ( !canMoveUp(propagate) ) return false; + + changeDepth ( Session::getRoutingGauge()->getLayerDepth(getLayer()) + 2, propagate ); + + return true; + } + + + bool AutoSegment::canDogLeg ( Interval interval ) + { + ltrace(200) << "AutoSegment::canDogLeg(Interval) " << interval << endl; + + size_t leftDogleg = 0; + size_t rightDogleg = 0; + if ( getSpanU().contains(interval.getVMin()) ) leftDogleg++; + if ( getSpanU().contains(interval.getVMax()) ) rightDogleg++; + + forEach ( AutoSegment*, isegment, getCollapseds() ) { + if ( isegment->getSpanU().contains(interval.getVMin()) ) { + if ( isegment->isFixed() ) return false; + leftDogleg++; + } + if ( isegment->getSpanU().contains(interval.getVMax()) ) { + if ( isegment->isFixed() ) return false; + rightDogleg++; + } + } + + if ( (leftDogleg == 1) and (rightDogleg <= 1) ) return true; + if ( (leftDogleg <= 1) and (rightDogleg == 1) ) return true; + + ltrace(200) << "leftCount:" << leftDogleg << " rightCount:" << rightDogleg << endl; + + return false; + } + + + void AutoSegment::makeDogLeg ( Interval interval, bool upLayer, bool& leftDogleg ) + { + ltrace(200) << "AutoSegment::makeDogLeg(Interval)" << endl; + + size_t leftDoglegCount = 0; + size_t rightDoglegCount = 0; + AutoSegment* leftCandidate = NULL; + AutoSegment* rightCandidate = NULL; + + if ( getSpanU().contains(interval.getVMin()) ) { leftCandidate = this; leftDoglegCount++; } + if ( getSpanU().contains(interval.getVMax()) ) { rightCandidate = this; rightDoglegCount++; } + + forEach ( AutoSegment*, isegment, getCollapseds() ) { + if ( isegment->getSpanU().contains(interval.getVMin()) ) { leftCandidate = *isegment; leftDoglegCount++; } + if ( isegment->getSpanU().contains(interval.getVMax()) ) { rightCandidate = *isegment; rightDoglegCount++; } + } + + leftDogleg = true; + if ( (leftDoglegCount != 1) and (rightDoglegCount != 1) ) return; + if ( !leftDoglegCount ) { + leftDogleg = false; + leftCandidate = rightCandidate; + rightCandidate = NULL; + } + + if ( leftCandidate && rightCandidate ) { + ltrace(200) << "Left Constraint: " << leftCandidate->getSourceConstraints(true) << endl; + ltrace(200) << "Right Constraint: " << rightCandidate->getTargetConstraints(true) << endl; + + if ( leftCandidate ->getTargetConstraints(true).getSize() + < rightCandidate->getSourceConstraints(true).getSize() ) { + leftCandidate = rightCandidate; + leftDogleg = false; + } + } else { + if ( !leftCandidate ) { + leftCandidate = rightCandidate; + leftDogleg = false; + } + } + + if ( leftCandidate ) { + leftCandidate->_makeDogLeg ( getAutoSource()->getGCell(), upLayer ); + + const vector& dogLegs = Session::getDogLegs(); + if ( dogLegs.size() >= 2 ) { + DbU::Unit axis; + if ( leftDogleg ) + axis = interval.getVMin() - DbU::lambda(5.0); // Ugly: Hard-wired track spacing. + else + axis = interval.getVMax() + DbU::lambda(5.0); // Ugly: Hard-wired track spacing. + + ltrace(200) << "AutoSegment::makeDogLeg(): @" << DbU::getValueString(axis) << endl; + dogLegs[1]->setAxis ( axis ); + } + } + } + + + void AutoSegment::makeDogLeg ( GCell* dogLegGCell, bool upLayer ) + { + ltrace(160) << "AutoSegment::makeDogLeg(GCell*)" << endl; + ltracein(160); + + if ( isFixed() ) { + cerr << Error("AutoSegment::makeDogLeg(): Cannot make a dog leg on a fixed segment.\n" + " (on: %s)",_getString().c_str()) << endl; + return; + } + + invalidate (); + + if ( dogLegGCell->getUSide(getDirection()).intersect(getSpanU()) ) { + ltrace(159) << "Dogleg in " << this << endl; + _makeDogLeg ( dogLegGCell, upLayer ); + //Session::revalidate ( getNet() ); + } else { + ltrace(159) << "Looking in aligneds." << endl; + forEach ( AutoSegment*, aligned, getCollapseds() ) { + ltrace(159) << "| Try in " << *aligned << endl; + if ( dogLegGCell->getUSide(getDirection()).intersect(aligned->getSpanU()) ) { + ltrace(159) << "Dogleg in " << *aligned << endl; + aligned->_makeDogLeg ( dogLegGCell, upLayer ); + //Session::revalidate ( getNet() ); + ltraceout(160); + return; + } + } + cerr << Bug("Cannot make a dogleg in %s at %s" + ,_getString().c_str(), getString(dogLegGCell).c_str()) << endl; + } + ltraceout(160); + } + + + bool AutoSegment::_check () const + { + bool coherency = true; + + coherency = coherency && checkInvalidated(); + coherency = coherency && checkPositions(); + coherency = coherency && checkConstraints(); + + return coherency; + } + + + string AutoSegment::_getString () const + { + string s = getSegment()->_getString(); + s.insert ( 1, "id: " ); + s.insert ( 4, getString(_id) ); + s.insert ( s.size()-1, (_isFixed )?" F":" -" ); + s.insert ( s.size()-1, (_strap )? "S": "-" ); + s.insert ( s.size()-1, (_isCanonical)? "C": "-" ); + s.insert ( s.size()-1, (_isCollapsed)? "c": "-" ); + s.insert ( s.size()-1, (_isGlobal) ? "g": "-" ); + s.insert ( s.size()-1, (_isTerminal) ? "t": "-" ); + s.insert ( s.size()-1, (_slackened) ? "S": "-" ); + s.insert ( s.size()-1, (_invalidated)? "i": "-" ); + return s; + } + + + Record* AutoSegment::_getRecord () const + { + Record* record = getSegment()->_getRecord (); + record->add ( getSlot ( "_gcell" , _gcell ) ); + record->add ( getSlot ( "_isHorizontal" , &_isHorizontal ) ); + record->add ( getSlot ( "_isFixed" , &_isFixed ) ); + record->add ( getSlot ( "_strap" , &_strap ) ); + record->add ( getSlot ( "_layerChange" , &_layerChange ) ); + record->add ( getSlot ( "_isCanonical" , &_isCanonical ) ); + record->add ( getSlot ( "_isCollapsed" , &_isCollapsed ) ); + record->add ( getSlot ( "_isGlobal" , &_isGlobal ) ); + record->add ( getSlot ( "_isTerminal" , &_isTerminal ) ); + record->add ( getSlot ( "_slackened" , &_slackened ) ); + record->add ( getSlot ( "_invalidated" , &_invalidated ) ); + record->add ( getSlot ( "_sourcePosition", &_sourcePosition ) ); + record->add ( getSlot ( "_targetPosition", &_targetPosition ) ); + return record; + } + + + AutoSegment* AutoSegment::create ( AutoContact* source + , AutoContact* target + , Segment* hurricaneSegment + ) + { + static Layer* verticalLayer = DataBase::getDB()->getTechnology()->getLayer ( "METAL3" ); + static Layer* horizontalLayer = DataBase::getDB()->getTechnology()->getLayer ( "METAL2" ); + + AutoSegment* segment; + Horizontal* horizontal; + Vertical* vertical; + + Contact* contact = dynamic_cast(hurricaneSegment->getSource()); + AutoContact* autoContact = Session::lookup(contact); + if ( !contact ) { + throw Error ( badSegmentSource, getString(hurricaneSegment).c_str() ); + if ( autoContact && ( autoContact != source ) ) + throw Error ( mismatchSegmentSource + , getString(hurricaneSegment).c_str() + , getString(contact).c_str() ); + } + + contact = dynamic_cast(hurricaneSegment->getTarget()); + autoContact = Session::lookup(contact); + if ( !contact ) { + throw Error ( badSegmentTarget, getString(hurricaneSegment).c_str() ); + if ( autoContact && ( autoContact != target ) ) + throw Error ( mismatchSegmentTarget + , getString(hurricaneSegment).c_str() + , getString(contact).c_str() ); + } + + Hook* hook = hurricaneSegment->getSourceHook(); + hook->detach (); + hook->attach ( source->getBodyHook() ); + + hook = hurricaneSegment->getTargetHook(); + hook->detach (); + hook->attach ( target->getBodyHook() ); + + if ( (horizontal = dynamic_cast(hurricaneSegment) ) ) { + if ( horizontal->getLayer() != horizontalLayer ) { + if ( !Session::getKatabatic()->isGMetal(horizontal->getLayer()) ) + cerr << Warning("Segment %s forced to %s." + ,getString(horizontal).c_str() + ,getString(horizontalLayer).c_str()) << endl; + horizontal->setLayer ( horizontalLayer ); + } + + segment = AutoHorizontal::create ( horizontal + , AutoSegment::Global + , false + , false + ); + } else if ( (vertical = dynamic_cast(hurricaneSegment)) ) { + if ( vertical->getLayer() != verticalLayer ) { + if ( !Session::getKatabatic()->isGMetal(vertical->getLayer()) ) + cerr << Warning("Segment %s forced to %s." + ,getString(vertical).c_str() + ,getString(verticalLayer).c_str()) << endl; + vertical->setLayer ( verticalLayer ); + } + + segment = AutoVertical::create ( vertical + , AutoSegment::Global + , false + , false + ); + } else { + throw Error ( badSegment, getString(source).c_str(), getString(target).c_str() ); + } + + ltrace(99) << "Creating " << segment << endl; + + return segment; + } + + + AutoSegment* AutoSegment::create ( AutoContact* source + , AutoContact* target + , unsigned int dir + , int type + , bool terminal + , bool collapsed + ) + { + //static Layer* verticalLayer = DataBase::getDB()->getTechnology()->getLayer ( "METAL3" ); + //static Layer* horizontalLayer = DataBase::getDB()->getTechnology()->getLayer ( "METAL2" ); + + static const Layer* horizontalLayer = Session::getRoutingLayer ( 1 ); + static const Layer* verticalLayer = Session::getRoutingLayer ( 2 ); + + GCell* gcell; + GCell* end; + AutoSegment* segment; + + if ( dir & Constant::Horizontal ) { + segment = AutoHorizontal::create ( source + , target + , horizontalLayer + , source->getY() + , DbU::lambda(2.0) + , type + , terminal + , collapsed + ); + if ( type == AutoSegment::Global ) { + if ( source->getGCell()->getX() < target->getGCell()->getX() ) { + gcell = source->getGCell()->getRight(); + end = target->getGCell(); + } else { + gcell = target->getGCell()->getRight(); + end = source->getGCell(); + } + for ( ; gcell != end ; gcell = gcell->getRight() ) { + if ( !gcell ) { + cerr << Error("AutoSegment::create() : NULL GCell.") << endl; + break; + } + gcell->addHSegment ( segment ); + } + } + } else if ( dir & Constant::Vertical ) { + segment = AutoVertical::create ( source + , target + , verticalLayer + , source->getX() + , DbU::lambda(2.0) + , type + , terminal + , collapsed + ); + if ( type == AutoSegment::Global ) { + if ( source->getGCell()->getY() < target->getGCell()->getY() ) { + gcell = source->getGCell()->getUp(); + end = target->getGCell(); + } else { + gcell = target->getGCell()->getUp(); + end = source->getGCell(); + } + for ( ; gcell != end ; gcell = gcell->getUp() ) { + if ( !gcell ) { + cerr << Error("AutoSegment::create() : NULL GCell.") << endl; + break; + } + gcell->addVSegment ( segment ); + } + } + } else + throw Error ( badSegment, getString(source).c_str(), getString(target).c_str() ); + + ltrace(99) << "create() " << segment << endl; + + return segment; + } + + + void AutoSegment::destroy () + { + _preDestroy (); + delete this; + } + + + bool AutoSegment::isTopologicalBound ( AutoSegment* seed + , bool superior + , bool isHorizontal ) + { + ltrace(80) << "isTopologicalBound() - " << seed << endl; + ltracein(80); + + set exploreds; + vector stack; + DbU::Unit axis; + + if ( superior ) axis = seed->getTargetU(); + else axis = seed->getSourceU(); + + ltrace(80) << "check for bound " << DbU::getValueString(axis) << endl; + + exploreds.insert ( seed->getAutoSource() ); + exploreds.insert ( seed->getAutoTarget() ); + + if ( seed->getLength() ) { + if ( superior ) stack.push_back ( seed->getAutoTarget() ); + else stack.push_back ( seed->getAutoSource() ); + } else { + stack.push_back ( seed->getAutoTarget() ); + stack.push_back ( seed->getAutoSource() ); + } + + while ( !stack.empty() ) { + AutoContact* currentContact = stack.back(); + stack.pop_back (); + + ltrace(80) << "Exploring: " << (void*)currentContact + << " " << currentContact << endl; + + exploreds.insert ( currentContact ); + + if ( currentContact->getAnchor() ) { ltraceout(80); return true; } + + forEach ( Component*, component, currentContact->getSlaveComponents() ) { + Segment* segment = dynamic_cast(*component); + if ( !segment ) continue; + + AutoSegment* autoSegment = Session::lookup ( segment ); + if ( !autoSegment ) continue; + + if ( !autoSegment->getLength() ) { + AutoContact* contact = autoSegment->getAutoSource(); + if ( contact && ( contact != currentContact ) ) { + if ( exploreds.find(contact) == exploreds.end() ) + stack.push_back ( contact ); + } + + contact = autoSegment->getAutoTarget(); + if ( contact && ( contact != currentContact ) ) { + if ( exploreds.find(contact) == exploreds.end() ) + stack.push_back ( contact ); + } + + continue; + } + + if ( autoSegment->isHorizontal() != isHorizontal ) continue; + + ltrace(80) << "| " << autoSegment << endl; + + if ( superior ) { + if ( autoSegment->getTargetU() > axis ) { ltraceout(80); return true; } + } else { + if ( autoSegment->getSourceU() < axis ) { ltraceout(80); return true; } + } + } + } + + ltraceout(80); + return false; + } + + + unsigned int AutoSegment::getPerpandicularState ( AutoContact* contact + , AutoSegment* source + , AutoSegment* current + , bool isHorizontalMaster + , const Layer* masterLayer ) + { + unsigned int state = 0; + + bool sourcePerpandicular = arePerpandiculars ( isHorizontalMaster, source ); + bool currentPerpandicular = arePerpandiculars ( isHorizontalMaster, current ); + bool contactAlignate + = (contact->isHAlignate() and current->isHorizontal() and isHorizontalMaster) + or (contact->isVAlignate() and !current->isHorizontal() and !isHorizontalMaster); + + if ( not currentPerpandicular and masterLayer and (masterLayer != current->getLayer()) ) + state |= ParallelAndLayerChange; + + if ( currentPerpandicular and !current->isCollapsed() ) + state |= PerpandicularAny; + + if ( sourcePerpandicular ) { + // Source segment is perpandicular to master. + if ( currentPerpandicular and !current->isCollapsed() ) + state |= PerpandicularIndirect; + } else { + // Source segment is parallel to master. + if ( not (currentPerpandicular and current->isCollapsed()) and not contactAlignate ) { + // Current segment is parallel OR expanded. + state |= ParallelOrExpanded; + } + } + + return state; + } + + + void AutoSegment::getTopologicalInfos ( AutoSegment* seed + , vector& collapseds + , vector& perpandiculars + , DbU::Unit& leftBound + , DbU::Unit& rightBound + ) + { + ltrace(80) << "getTopologicalInfos() - " << seed << endl; + + leftBound = DbU::Max; + rightBound = DbU::Min; + + AutoSegmentStack stack; + + stack.push ( seed->getAutoSource(), seed ); + stack.push ( seed->getAutoTarget(), seed ); + + while ( !stack.isEmpty() ) { + AutoContact* sourceContact = stack.getAutoContact (); + AutoSegment* sourceSegment = stack.getAutoSegment (); + + stack.pop (); + + DbU::Unit constraint; + + if ( seed->isHorizontal() ) constraint = sourceContact->getCBXMax(); + else constraint = sourceContact->getCBYMax(); + if ( constraint < leftBound ) leftBound = constraint; + + if ( seed->isHorizontal() ) constraint = sourceContact->getCBXMin(); + else constraint = sourceContact->getCBYMin(); + if ( constraint > rightBound ) rightBound = constraint; + + forEach ( Component*, component, sourceContact->getSlaveComponents() ) { + Segment* segment = dynamic_cast(*component); + if ( ( !segment ) || ( segment == sourceSegment->getSegment() ) ) continue; + + AutoSegment* currentSegment = Session::lookup ( segment ); + if ( !currentSegment ) { + cerr << Error("Can't lookup for %s.",getString(segment).c_str()) << endl; + continue; + } + + unsigned int state = getPerpandicularState ( sourceContact + , sourceSegment + , currentSegment + , seed ); + if ( state & PerpandicularAny ) { + ltrace(79) << "Perpandicular: " << currentSegment << endl; + perpandiculars.push_back ( currentSegment ); + } + if ( state & (PerpandicularIndirect + |ParallelOrExpanded + |ParallelAndLayerChange ) ) { + ltrace(79) << "Reject: " << currentSegment << endl; + continue; + } + + if ( !areAligneds(currentSegment,seed) ) { + collapseds.push_back ( currentSegment ); + ltrace(79) << "collapsed: " << currentSegment << endl; + } + + Component* opposite = segment->getOppositeAnchor ( sourceContact->getContact() ); + AutoContact* targetContact = Session::lookup(static_cast(opposite)); + if ( targetContact ) stack.push ( targetContact, currentSegment ); + } + } + } + + + int AutoSegment::getTerminalCount ( AutoSegment* seed, vector& collapseds ) + { + ltrace(80) << "getTerminalCount() - " << seed << " (+collapseds)" << endl; + + int count = 0; + for ( size_t i=0 ; i < collapseds.size() ; i++ ) { + if ( collapseds[i]->isTerminal() ) + count++; + } + if ( seed->getAutoSource()->isTerminal() ) count++; + if ( seed->getAutoTarget()->isTerminal() ) count++; + + return count; + } + + +} // End of Katabatic namespace. diff --git a/katabatic/src/AutoSegments.cpp b/katabatic/src/AutoSegments.cpp new file mode 100644 index 00000000..1ba4c7f9 --- /dev/null +++ b/katabatic/src/AutoSegments.cpp @@ -0,0 +1,656 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2008, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | K a t a b a t i c - Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Module : "./AutoSegments.cpp" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#include "hurricane/Error.h" +#include "katabatic/AutoContact.h" +#include "katabatic/AutoSegment.h" + + +namespace Katabatic { + + + using namespace std; + using Hurricane::tab; + using Hurricane::inltrace; + using Hurricane::ltracein; + using Hurricane::ltraceout; + using Hurricane::_TName; + using Hurricane::Error; + using Hurricane::ForEachIterator; + using Hurricane::Hook; + using Hurricane::Contact; + + +// ------------------------------------------------------------------- +// Class : "Katabatic::AutoSegmentStack". + + + void AutoSegmentStack::push ( AutoContact* contact, AutoSegment* segment ) + { + ltrace(80) << "Stacking " << contact << " + " << segment << endl; + + push_back(make_pair(contact,segment)); + } + + +// ------------------------------------------------------------------- +// Class : "Katabatic::AutoSegments_OnContact". + + + AutoSegments_OnContact::Locator::Locator ( AutoSegment* master, Contact* contact ) + : AutoSegmentHL() + , _master(master) + , _element(NULL) + { + _hook = contact->getBodyHook()->getPreviousMasterHook(); + progress (); + } + + + AutoSegmentHL* AutoSegments_OnContact::Locator::getClone () const + { + return new Locator(*this); + } + + + AutoSegment* AutoSegments_OnContact::Locator::getElement () const + { + return _element; + } + + + bool AutoSegments_OnContact::Locator::isValid () const + { + return !_hook; + } + + + void AutoSegments_OnContact::Locator::progress () + { + ltrace(80) << "AutoSegments_OnContact::Locator::progress()" << endl; + + while ( _hook && !_hook->isMaster() ) { + _hook = _hook->getNextHook(); + _element = NULL; + + if ( _hook->isMaster() ) { _hook = NULL; break; } + + Segment* segment = dynamic_cast( _hook->getComponent() ); + if ( segment ) _element = Session::lookup ( segment ); + + if ( !_element || (_element == _master) ) continue; + + break; + } + } + + + string AutoSegments_OnContact::Locator::_getString () const + { + string s = "<" + _TName("AutoSegments_OnContact::Locator") + + getString(_element) + + ">"; + return s; + } + + + AutoSegmentHC* AutoSegments_OnContact::getClone () const + { + return new AutoSegments_OnContact(*this); + } + + + AutoSegmentHL* AutoSegments_OnContact::getLocator () const + { + return new Locator(_master,_contact); + } + + + string AutoSegments_OnContact::_getString () const + { + string s = "<" + _TName("AutoSegments_OnContact") + " " + + getString(_master) + + ">"; + return s; + } + + +// ------------------------------------------------------------------- +// Class : "AutoSegments_Collapsed". + + + AutoSegments_Collapsed::Locator::Locator ( AutoSegment* segment, bool withPerpand ) + : AutoSegmentHL() + , _withPerpand(withPerpand) + , _master(segment) + , _stack() + { + if ( not _master ) return; + + AutoContact* contact = segment->getAutoSource(); + if ( contact ) _stack.push ( contact, segment ); + + contact = segment->getAutoTarget(); + if ( contact ) _stack.push ( contact, segment ); + + progress (); + } + + + AutoSegmentHL* AutoSegments_Collapsed::Locator::getClone () const + { + return new Locator(*this); + } + + + bool AutoSegments_Collapsed::Locator::isValid () const + { + return !_stack.isEmpty(); + } + + + void AutoSegments_Collapsed::Locator::progress () + { + ltrace(80) << "AutoSegments_Collapsed::Locator::progress()" << endl; + + while ( !_stack.isEmpty() ) { + AutoContact* sourceContact = _stack.getAutoContact (); + AutoSegment* sourceSegment = _stack.getAutoSegment (); + + _stack.pop (); + + forEach ( Component*, component, sourceContact->getSlaveComponents() ) { + if ( *component == sourceSegment->getSegment() ) continue; + + Segment* segment = dynamic_cast(*component); + if ( !segment ) continue; + + AutoSegment* currentSegment = Session::lookup ( segment ); + if ( !currentSegment ) { + cerr << Error("Can't lookup for %s.",getString(segment).c_str()) << endl; + continue; + } + + unsigned int state = AutoSegment::getPerpandicularState ( sourceContact + , sourceSegment + , currentSegment + , _master + ); + if ( state & (AutoSegment::PerpandicularIndirect + |AutoSegment::ParallelOrExpanded + |AutoSegment::ParallelAndLayerChange ) ) { + ltrace(98) << "Reject: " << currentSegment << endl; + continue; + } + + AutoContact* targetContact = currentSegment->getOppositeAnchor ( sourceContact ); + if ( targetContact ) _stack.push ( targetContact, currentSegment ); + } + + if ( _stack.isEmpty() ) break; + if ( _stack.getAutoSegment() == _master ) continue; + if ( AutoSegment::areAligneds(_stack.getAutoSegment(),_master) || _withPerpand ) break; + } + } + + + string AutoSegments_Collapsed::Locator::_getString () const + { + string s = "<" + _TName("AutoSegments_Collapsed::Locator") + + ">"; + + return s; + } + + + AutoSegmentHC* AutoSegments_Collapsed::getClone () const + { + return new AutoSegments_Collapsed(*this); + } + + + AutoSegmentHL* AutoSegments_Collapsed::getLocator () const + { + return new Locator(_segment,_withPerpand); + } + + + AutoSegment* AutoSegments_Collapsed::Locator::getElement () const + { + return _stack.getAutoSegment(); + } + + + string AutoSegments_Collapsed::_getString () const + { + string s = "<" + _TName("AutoSegments_Collapsed") + " " + + getString(_segment) + + ">"; + return s; + } + + +// ------------------------------------------------------------------- +// Class : "AutoSegments_CollapsedPerpandicular". + + + AutoSegments_CollapsedPerpandicular::Locator::Locator ( AutoSegment* segment ) + : AutoSegmentHL() + , _master(segment) + , _stack() + , _perpandiculars() + { + ltrace(80) << "AutoSegments_CollapsedPerpandicular::Locator::Locator()" << endl; + ltrace(80) << " " << _master << endl; + + if ( not _master ) return; + + AutoContact* contact = segment->getAutoSource(); + if ( contact ) _stack.push ( contact, segment ); + + contact = segment->getAutoTarget(); + if ( contact ) _stack.push ( contact, segment ); + + progress (); + } + + + AutoSegment* AutoSegments_CollapsedPerpandicular::Locator::getElement () const + { + if ( _perpandiculars.empty() ) return NULL; + return _perpandiculars.back (); + } + + + void AutoSegments_CollapsedPerpandicular::Locator::progress () + { + ltrace(80) << "AutoSegments_CollapsedPerpandicular::Locator::progress()" << endl; + + if ( !_perpandiculars.empty() ) _perpandiculars.pop_back (); + if ( !_perpandiculars.empty() ) return; + + while ( !_stack.isEmpty() ) { + AutoContact* sourceContact = _stack.getAutoContact (); + AutoSegment* sourceSegment = _stack.getAutoSegment (); + + _stack.pop (); + + forEach ( Component*, component, sourceContact->getSlaveComponents() ) { + if ( *component == sourceSegment->getSegment() ) continue; + + Segment* segment = dynamic_cast(*component); + if ( !segment ) continue; + + AutoSegment* currentSegment = Session::lookup ( segment ); + if ( !currentSegment ) { + cerr << Error("Can't lookup for %s.",getString(segment).c_str()) << endl; + continue; + } + + ltrace(99) << " Try Perpandicular: " << currentSegment << endl; + unsigned int state = AutoSegment::getPerpandicularState ( sourceContact + , sourceSegment + , currentSegment + , _master + ); + + if ( state & AutoSegment::PerpandicularAny ) { + _perpandiculars.push_back ( currentSegment ); + ltrace(99) << "Stacked Perpandicular: " << currentSegment << endl; + } + if ( state & (AutoSegment::PerpandicularIndirect + |AutoSegment::ParallelOrExpanded + |AutoSegment::ParallelAndLayerChange ) ) + continue; + + ltrace(99) << "Stacked Opposite of: " << currentSegment << endl; + + AutoContact* targetContact = currentSegment->getOppositeAnchor ( sourceContact ); + if ( targetContact ) _stack.push ( targetContact, currentSegment ); + } + + if ( _stack.isEmpty() ) break; + if ( _stack.getAutoSegment() == _master ) continue; + if ( !_perpandiculars.empty() ) break; + } + } + + + AutoSegmentHL* AutoSegments_CollapsedPerpandicular::Locator::getClone () const + { + return new Locator(*this); + } + + + bool AutoSegments_CollapsedPerpandicular::Locator::isValid () const + { + return !_perpandiculars.empty(); + } + + + AutoSegmentHC* AutoSegments_CollapsedPerpandicular::getClone () const + { + return new AutoSegments_CollapsedPerpandicular(*this); + } + + + AutoSegmentHL* AutoSegments_CollapsedPerpandicular::getLocator () const + { + return new Locator(_segment); + } + + + string AutoSegments_CollapsedPerpandicular::Locator::_getString () const + { + string s = "<" + _TName("AutoSegments_CollapsedPerpandicular::Locator") + + ">"; + return s; + } + + + string AutoSegments_CollapsedPerpandicular::_getString () const + { + string s = "<" + _TName("AutoSegments_CollapsedPerpandicular") + " " + + getString(_segment) + + ">"; + return s; + } + + +// ------------------------------------------------------------------- +// Class : "AutoSegments_AnchorOnGCell". + + + AutoSegments_AnchorOnGCell::Locator::Locator ( GCell* fcell, bool sourceAnchor, unsigned int direction ) + : AutoSegmentHL() + , _sourceAnchor(sourceAnchor) + , _direction(direction) + , _itContact(fcell->getContacts()->begin()) + , _itEnd(fcell->getContacts()->end()) + , _hookLocator(NULL) + , _element(NULL) + { + progress (); + } + + + AutoSegments_AnchorOnGCell::Locator::~Locator () + { + if ( _hookLocator ) delete _hookLocator; + } + + + AutoSegment* AutoSegments_AnchorOnGCell::Locator::getElement () const + { + return _element; + } + + + AutoSegmentHL* AutoSegments_AnchorOnGCell::Locator::getClone () const + { + return new Locator(*this); + } + + + bool AutoSegments_AnchorOnGCell::Locator::isValid () const + { + return _element != NULL; + } + + + void AutoSegments_AnchorOnGCell::Locator::progress () + { + ltrace(80) << "AutoSegments_AnchorOnGCell::Locator::progress()" << endl; + ltracein(79); + + while ( true ) { + if ( _hookLocator == NULL ) { + if ( _itContact == _itEnd ) { + ltrace(79) << "No more AutoContacts" << endl; + ltraceout(79); + return; + } + + ltrace(79) << *_itContact << endl; + + _hookLocator = (*_itContact)->getBodyHook()->getSlaveHooks().getLocator(); + _itContact++; + } else { + _hookLocator->progress (); + } + + while ( _hookLocator->isValid() ) { + ltrace(79) << _hookLocator->getElement() << endl; + Hook* hook = dynamic_cast(_hookLocator->getElement()); + if ( hook ) { + _element = Session::lookup ( static_cast(hook->getComponent()) ); + if ( _element->isHorizontal() ) { + if ( _direction & Constant::Horizontal ) { ltraceout(79); return; } + } else + if ( _direction & Constant::Vertical ) { ltraceout(79); return; } + } + _hookLocator->progress(); + } + _hookLocator = NULL; + _element = NULL; + } + + ltraceout(79); + } + + + string AutoSegments_AnchorOnGCell::Locator::_getString () const + { + string s = "<" + _TName("AutoSegments_AnchorOnGCell::Locator") + + ">"; + return s; + } + + + AutoSegmentHC* AutoSegments_AnchorOnGCell::getClone () const + { + return new AutoSegments_AnchorOnGCell(*this); + } + + + AutoSegmentHL* AutoSegments_AnchorOnGCell::getLocator () const + { + return new Locator(_fcell,_sourceAnchor,_direction); + } + + + string AutoSegments_AnchorOnGCell::_getString () const + { + string s = "<" + _TName("AutoSegments_AnchorOnGCell") + " " + + getString(_fcell) + + ">"; + return s; + } + + +// ------------------------------------------------------------------- +// Class : "Katabatic::AutoSegments_AnchoredBySource". + + +AutoSegments_AnchoredBySource::Locator::Locator ( AutoContact* sourceAnchor, unsigned int direction ) + : AutoSegmentHL() + , _direction(direction) + , _hookLocator(NULL) + , _element(NULL) +{ + _contactLocator = sourceAnchor->getCollapseds(_direction).getLocator(); + progress (); +} + + + AutoSegments_AnchoredBySource::Locator::~Locator () + { + if ( _hookLocator ) delete _hookLocator; + if ( _contactLocator ) delete _contactLocator; + } + + + AutoSegment* AutoSegments_AnchoredBySource::Locator::getElement () const + { + return _element; + } + + + AutoSegmentHL* AutoSegments_AnchoredBySource::Locator::getClone () const + { + return new Locator(*this); + } + + + bool AutoSegments_AnchoredBySource::Locator::isValid () const + { + return _element != NULL; + } + + + void AutoSegments_AnchoredBySource::Locator::progress () + { + ltrace(80) << "AutoSegments_AnchoredBySource::Locator::progress()" << endl; + ltracein(79); + + while ( true ) { + if ( _hookLocator == NULL ) { + if ( !_contactLocator->isValid() ) { + ltrace(79) << "No more AutoContacts" << endl; + ltraceout(79); + return; + } + + ltrace(79) << _contactLocator->getElement() << endl; + + _hookLocator = _contactLocator->getElement()->getBodyHook()->getSlaveHooks().getLocator(); + _contactLocator->progress (); + } else { + _hookLocator->progress (); + } + + while ( _hookLocator->isValid() ) { + ltrace(79) << _hookLocator->getElement() << endl; + Hook* hook = dynamic_cast(_hookLocator->getElement()); + if ( hook ) { + _element = Session::lookup ( static_cast(hook->getComponent()) ); + if ( _element->isHorizontal() ) { + if ( _direction & Constant::Horizontal ) { ltraceout(79); return; } + } else + if ( _direction & Constant::Vertical ) { ltraceout(79); return; } + } + _hookLocator->progress(); + } + _hookLocator = NULL; + _element = NULL; + } + + ltraceout(79); + } + + + AutoSegmentHL* AutoSegments_AnchoredBySource::getLocator () const + { + return new Locator(_sourceContact,_direction); + } + + + AutoSegmentHC* AutoSegments_AnchoredBySource::getClone () const + { + return new AutoSegments_AnchoredBySource(*this); + } + + + string AutoSegments_AnchoredBySource::Locator::_getString () const + { + string s = "<" + _TName("AutoSegments_AnchoredBySource::Locator") + + ">"; + return s; + } + + + string AutoSegments_AnchoredBySource::_getString () const + { + string s = "<" + _TName("AutoSegments_AnchoredBySource") + " " + + getString(_sourceContact) + + ">"; + return s; + } + + +// ------------------------------------------------------------------- +// Class : "AutoSegments_IsAccountable". + + + AutoSegmentHF* AutoSegments_IsAccountable::getClone () const + { + return new AutoSegments_IsAccountable(); + } + + + bool AutoSegments_IsAccountable::accept ( AutoSegment* segment ) const + { + return segment->isCanonical() && !segment->isCollapsed(); + } + + + string AutoSegments_IsAccountable::_getString () const + { + return ""; + } + + +// ------------------------------------------------------------------- +// Class : "AutoSegments_InDirection". + + + AutoSegmentHF* AutoSegments_InDirection::getClone () const + { + return new AutoSegments_InDirection(_direction); + } + + + bool AutoSegments_InDirection::accept ( AutoSegment* segment ) const + { + return ( segment->isHorizontal() && (_direction & Constant::Horizontal) ) + || ( segment->isVertical () && (_direction & Constant::Vertical ) ); + } + + + string AutoSegments_InDirection::_getString () const + { + return ""; + } + + + + + +// x-----------------------------------------------------------------x +// | Functions Definitions | +// x-----------------------------------------------------------------x + + +} // End of Katabatic namespace. diff --git a/katabatic/src/AutoVertical.cpp b/katabatic/src/AutoVertical.cpp new file mode 100644 index 00000000..42209c27 --- /dev/null +++ b/katabatic/src/AutoVertical.cpp @@ -0,0 +1,704 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2008, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | K a t a b a t i c - Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Module : "./AutoVertical.cpp" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#include +#include "hurricane/Bug.h" +#include "hurricane/Vertical.h" +#include "crlcore/RoutingGauge.h" +#include "katabatic/AutoContact.h" +#include "katabatic/AutoVertical.h" +#include "katabatic/AutoHorizontal.h" + + +namespace { + + using namespace std; + using namespace Hurricane; + using namespace Katabatic; + + + void slacken ( AutoVertical* segment, bool fromSource ) + { + AutoContact* contact = NULL; + Point slackPoint; + if (fromSource) { + contact = segment->getAutoSource(); + slackPoint = Point ( segment->getSourceX(), segment->getSourceY() ); + } else { + contact = segment->getAutoTarget(); + slackPoint = Point ( segment->getTargetX(), segment->getTargetY() ); + } + if ( !contact ) return; + + forEach ( Horizontal*, ihorizontal, contact->getSlaveComponents().getSubSet() ) { + AutoSegment* autoHorizontal = Session::lookup ( *ihorizontal ); + if ( autoHorizontal ) { + autoHorizontal->invalidate (); + if ( autoHorizontal->isGlobal() ) return; + } + } + + size_t depth = Session::getRoutingGauge()->getLayerDepth ( segment->getLayer() ); + Layer* contactLayer = Session::getRoutingGauge()->getContactLayer ( depth - 1 ); + const Layer* slackLayer = Session::getRoutingGauge()->getRoutingLayer ( depth - 1 ); + + if ( fromSource ) segment->getSourceHook()->detach (); + else segment->getTargetHook()->detach (); + + AutoContact* contact1 = AutoContact::create ( contact->getGCell(), segment->getNet(), contactLayer ); + AutoContact* contact2 = AutoContact::create ( contact->getGCell(), segment->getNet(), contactLayer ); + + AutoSegment* vsegment = AutoVertical::create ( contact + , contact1 + , segment->getLayer() + , slackPoint.getX() + , DbU::lambda(2.0) + , AutoSegment::Local + , true // terminal + , false // collapsed + ); + + AutoSegment* hsegment = AutoHorizontal::create ( contact1 + , contact2 + , slackLayer + , slackPoint.getY() + , DbU::lambda(2.0) + , AutoSegment::Local + , false + , false + ); + + if ( fromSource ) + segment->getSourceHook()->attach ( contact2->getContact()->getBodyHook() ); + else + segment->getTargetHook()->attach ( contact2->getContact()->getBodyHook() ); + contact->restoreHConnexity ( slackPoint.getY(), true ); + + //contact->setHAlignate ( true ); + + hsegment->setSlackenStrap ( true ); + hsegment->setSlackened ( true ); + vsegment->setSlackened ( true ); + + ltrace(200) << "Session::slacken() new paral: " << vsegment << endl; + ltrace(200) << "Session::slacken() perpand: " << hsegment << endl; + ltrace(200) << "Session::slacken() original: " << segment << endl; + } + + +} // End of local namespace. + + +namespace Katabatic { + + + using std::min; + using std::max; + using Hurricane::ltracein; + using Hurricane::ltraceout; + using Hurricane::Error; + using Hurricane::Bug; + + +// ------------------------------------------------------------------- +// Class : "Katabatic::AutoVertical". + + + AutoVertical::AutoVertical ( Vertical* vertical + , int type + , bool terminal + , bool collapsed + ) + : AutoSegment(vertical,false,type,terminal,collapsed) + , _vertical(vertical) + { } + + + void AutoVertical::_postCreate () + { + AutoSegment::_postCreate (); + orient (); + setPositions (); + + AutoContact* source = getAutoSource(); + if ( source->isTerminal() ) source->setX ( _vertical->getX() ); + + AutoContact* target = getAutoTarget(); + if ( target->isTerminal() ) target->setX ( _vertical->getX() ); + + if ( source->getGCell() == target->getGCell() ) { + setGlobal ( false ); + } else { + GCell* gcell; + GCell* end; + + if ( source->getGCell()->getY() < target->getGCell()->getY() ) { + gcell = source->getGCell()->getUp(); + end = target->getGCell(); + } else { + gcell = target->getGCell()->getUp(); + end = source->getGCell(); + } + for ( ; gcell != end ; gcell = gcell->getUp() ) { + if ( !gcell ) { + cerr << Error("AutoSegment::create() : NULL GCell.") << endl; + break; + } + gcell->addVSegment ( this ); + } + } + } + + + void AutoVertical::_preDestroy () + { + ltrace(200) << "AutoVertical::_preDestroy() - " << (void*)this << endl; + ltrace(200) << " " << _getString() << endl; + ltracein(90); + + if ( not Session::doDestroyTool() ) { + AutoContact* source = getAutoSource(); + AutoContact* target = getAutoTarget(); + + if ( source and target and (source->getGCell() != target->getGCell()) ) { + GCell* gcell; + GCell* end; + + if ( source->getGCell()->getY() < target->getGCell()->getY() ) { + gcell = source->getGCell()->getUp(); + end = target->getGCell(); + } else { + gcell = target->getGCell()->getUp(); + end = source->getGCell(); + } + for ( ; gcell != end ; gcell = gcell->getUp() ) { + if ( !gcell ) { + cerr << Error("AutoSegment::_preDestroy() : NULL GCell.") << endl; + break; + } + gcell->removeVSegment ( this ); + } + } + } + + AutoSegment::_preDestroy (); + ltraceout(90); + } + + + AutoVertical::~AutoVertical () + { + if ( Session::doDestroyBaseSegment() and not Session::doDestroyTool() ) { + ltrace(200) << "~AutoVertical() - " << (void*)_vertical << endl; + _vertical->destroy (); + } + } + + + AutoVertical* AutoVertical::create ( Vertical* vertical + , int type + , bool terminal + , bool collapsed + ) + { + AutoSegment::_preCreate ( vertical->getSource(), vertical->getTarget() ); + AutoVertical* autoVertical = new AutoVertical ( vertical, type, terminal, collapsed ); + + autoVertical->_postCreate (); + return autoVertical; + } + + + AutoVertical* AutoVertical::create ( AutoContact* source + , AutoContact* target + , const Layer* layer + , DbU::Unit x + , DbU::Unit width + , int type + , bool terminal + , bool collapsed + ) + { + AutoSegment::_preCreate ( source, target ); + AutoVertical* autoVertical + = new AutoVertical ( Vertical::create ( source->getContact() + , target->getContact() + , layer + , x + , width ), type, terminal, collapsed ); + + autoVertical->_postCreate (); + return autoVertical; + } + + + Interval AutoVertical::getSourceConstraints ( bool native ) const + { + if ( native ) { + Box nativeBox ( getAutoSource()->getNativeConstraintBox() ); + return Interval ( nativeBox.getXMin(), nativeBox.getXMax() ); + } + return Interval ( getAutoSource()->getCBXMin(), getAutoSource()->getCBXMax() ); + } + + + Interval AutoVertical::getTargetConstraints ( bool native ) const + { + if ( native ) { + Box nativeBox ( getAutoTarget()->getNativeConstraintBox() ); + return Interval ( nativeBox.getXMin(), nativeBox.getXMax() ); + } + return Interval ( getAutoTarget()->getCBXMin(), getAutoTarget()->getCBXMax() ); + } + + + bool AutoVertical::getConstraints ( DbU::Unit& constraintMin, DbU::Unit& constraintMax ) const + { + AutoContact* contact = getAutoSource(); + constraintMin = contact->getCBXMin(); + constraintMax = contact->getCBXMax(); + + contact = getAutoTarget(); + constraintMin = max ( constraintMin, contact->getCBXMin() ); + constraintMax = min ( constraintMax, contact->getCBXMax() ); + + constraintMin = max ( constraintMin, getUserConstraints().getVMin() ); + constraintMax = min ( constraintMax, getUserConstraints().getVMax() ); + return true; + } + + + unsigned int AutoVertical::getDirection () const + { return Constant::Vertical; } + + + size_t AutoVertical::getGCells ( vector& gcells ) const + { + vector().swap ( gcells ); + gcells.push_back ( getAutoSource()->getGCell() ); + + GCell* gcell = gcells.front(); + GCell* end = getAutoTarget()->getGCell(); + + while ( gcell != end ) { + gcell = gcell->getUp (); + if ( !gcell ) break; + + gcells.push_back ( gcell ); + } + + return gcells.size(); + } + + + bool AutoVertical::_canSlacken () const + { + Interval sourceConstraints = Interval(getAutoSource()->getCBXMin(),getAutoSource()->getCBXMax()); + Interval targetConstraints = Interval(getAutoTarget()->getCBXMin(),getAutoTarget()->getCBXMax()); + + // Ugly: should uses topRightShrink from GCell. + sourceConstraints.inflate ( 0, /*Katabatic::GCell::getTopRightShrink()*/ DbU::lambda(1.0) ); + targetConstraints.inflate ( 0, /*Katabatic::GCell::getTopRightShrink()*/ DbU::lambda(1.0) ); + + // Ugly: GCell's track number is hardwired. + if ( sourceConstraints.getSize() / DbU::lambda(5.0) < 10 ) return true; + if ( targetConstraints.getSize() / DbU::lambda(5.0) < 10 ) return true; + + return false; + } + + + void AutoVertical::_slacken () + { + AutoContact* contact = getAutoSource(); + Interval constraints = Interval(contact->getCBXMin(),contact->getCBXMax()); + + constraints.inflate ( 0, /*Katabatic::GCell::getTopRightShrink()*/ DbU::lambda(1.0) ); + + // Ugly: GCell's track number is hardwired. + if ( constraints.getSize() / DbU::lambda(5.0) < 10 ) ::slacken ( this, true ); + + contact = getAutoTarget (); + constraints = Interval(contact->getCBXMin(),contact->getCBXMax()); + constraints.inflate ( 0, /*Katabatic::GCell::getTopRightShrink()*/ DbU::lambda(1.0) ); + + if ( constraints.getSize() / DbU::lambda(5.0) < 10 ) ::slacken ( this, false ); + + setSlackened ( true ); + } + + + bool AutoVertical::canDesalignate ( AutoContact* contact ) const + { return contact->canVDesalignate (); } + + + void AutoVertical::desalignate ( AutoContact* contact ) + { contact->vDesalignate(); } + + + void AutoVertical::alignate ( DbU::Unit axis ) + { + if ( _vertical->getX() == axis ) return; + + ltrace(159) << "alignate() " << this << " @X " << DbU::getLambda(axis) << endl; + + _vertical->setX ( axis ); + invalidate (); + + AutoContact* anchor = getAutoSource(); + anchor->invalidate (); + if ( anchor->isTerminal() ) anchor->setX ( axis ); + + anchor = getAutoTarget(); + anchor->invalidate (); + if ( anchor->isTerminal() ) anchor->setX ( axis ); + } + + + void AutoVertical::orient () + { + if ( _vertical->getTargetY() < _vertical->getSourceY() ) + _vertical->invert (); + } + + + void AutoVertical::setPositions () + { + _sourcePosition = _vertical->getSourceY() - Session::getExtensionCap(); + _targetPosition = _vertical->getTargetY() + Session::getExtensionCap(); + } + + + bool AutoVertical::checkPositions () const + { + bool coherency = true; + DbU::Unit sourcePosition = _vertical->getSourceY() - Session::getExtensionCap(); + DbU::Unit targetPosition = _vertical->getTargetY() + Session::getExtensionCap(); + + if ( _sourcePosition != sourcePosition ) { + cerr << Error ( "%s\n Source position incoherency: " + "Shadow: %s, real: %s." + , _getString().c_str() + , DbU::getValueString(_sourcePosition).c_str() + , DbU::getValueString( sourcePosition).c_str() + ) << endl; + coherency = false; + } + + if ( _targetPosition != targetPosition ) { + cerr << Error ( "%s\n Target position incoherency: " + "Shadow: %s, real: %s." + , _getString().c_str() + , DbU::getValueString(_targetPosition).c_str() + , DbU::getValueString( targetPosition).c_str() + ) << endl; + coherency = false; + } + + return coherency; + } + + + bool AutoVertical::checkConstraints () const + { + Interval sourceConstraints = Interval(getAutoSource()->getCBXMin(),getAutoSource()->getCBXMax()); + Interval targetConstraints = Interval(getAutoTarget()->getCBXMin(),getAutoTarget()->getCBXMax()); + + if ( !sourceConstraints.intersect(targetConstraints) ) { + cerr << Error ( "%p:%s\n Constraints incoherency: S:%p:%s, T:%p:%s" + , (void*)base() + , _getString().c_str() + , getAutoSource()->getContact() + , getString(sourceConstraints).c_str() + , getAutoSource()->getContact() + , getString(targetConstraints).c_str() + ) << endl; + return false; + } + + return true; + } + + + void AutoVertical::_computeTerminal () + { _computeTerminal(_vertical); } + + + void AutoVertical::moveULeft () + { + if ( not getAutoSource()->isCorner() or not getAutoTarget()->isCorner() ) return; + if ( not getAutoSource()->getGCell()->getLeft() ) return; + + Session::setInvalidateMask ( Session::RestoreVCon|Session::NetCanonize ); + Session::invalidate ( getNet() ); + + AutoContact* autoSource = getAutoSource(); + AutoContact* autoTarget = getAutoTarget(); + GCell* begin = autoSource->getGCell(); + GCell* end = autoTarget->getGCell(); + + forEach ( Horizontal*, isegment, autoSource->getSlaveComponents().getSubSet() ) { + AutoSegment* segment = Session::lookup ( *isegment ); + if ( segment->isLocal() ) { + segment->setGlobal ( true ); + continue; + } + + if ( segment->getAutoSource() == autoSource ) { + begin->addHSegment ( segment ); + } else { + if ( begin->getLeft() == segment->getAutoSource()->getGCell() ) { + segment->setGlobal ( false ); + segment->getAutoSource()->invalidate (); + } else + begin->getLeft()->removeHSegment ( segment ); + } + } + + forEach ( Horizontal*, isegment, autoTarget->getSlaveComponents().getSubSet() ) { + AutoSegment* segment = Session::lookup ( *isegment ); + if ( segment->isLocal() ) { + segment->setGlobal ( true ); + continue; + } + + if ( segment->getAutoSource() == autoTarget ) { + begin->addHSegment ( segment ); + } else { + if ( end->getLeft() == segment->getAutoSource()->getGCell() ) { + segment->setGlobal ( false ); + segment->getAutoSource()->invalidate (); + } else + end->getLeft()->removeHSegment ( segment ); + } + } + + if ( begin != end ) { + for ( GCell* gcell = begin->getUp() ; gcell != end ; gcell = gcell->getUp() ) + gcell->removeVSegment ( this ); + } + + begin = begin->getLeft(); + end = end ->getLeft(); + + autoSource->setGCell ( begin ); + autoTarget->setGCell ( end ); + if ( begin != end ) { + for ( GCell* gcell = begin->getUp() ; gcell != end ; gcell = gcell->getUp() ) + gcell->addVSegment ( this ); + } + + DbU::Unit x = begin->getUSide(Constant::Horizontal).getVMax(); + setAxis ( x, AxisSet); + + Session::revalidateTopology (); + } + + + void AutoVertical::moveURight () + { + ltrace(200) << "AutoVertical::moveURight()" << endl; + + if ( not getAutoSource()->isCorner() or not getAutoTarget()->isCorner() ) return; + if ( not getAutoSource()->getGCell()->getRight() ) return; + + Session::setInvalidateMask ( Session::RestoreVCon|Session::NetCanonize ); + Session::invalidate ( getNet() ); + + AutoContact* autoSource = getAutoSource(); + AutoContact* autoTarget = getAutoTarget(); + GCell* begin = autoSource->getGCell(); + GCell* end = autoTarget->getGCell(); + + forEach ( Horizontal*, isegment, autoSource->getSlaveComponents().getSubSet() ) { + AutoSegment* segment = Session::lookup ( *isegment ); + if ( segment->isLocal() ) { + segment->setGlobal ( true ); + continue; + } + + if ( segment->getAutoTarget() == autoSource ) { + begin->addHSegment ( segment ); + } else { + if ( begin->getRight() == segment->getAutoTarget()->getGCell() ) { + segment->setGlobal ( false ); + segment->getAutoTarget()->invalidate (); + } else + begin->getRight()->removeHSegment ( segment ); + } + } + + forEach ( Horizontal*, isegment, autoTarget->getSlaveComponents().getSubSet() ) { + AutoSegment* segment = Session::lookup ( *isegment ); + if ( segment->isLocal() ) { + segment->setGlobal ( true ); + continue; + } + + if ( segment->getAutoTarget() == autoTarget ) { + begin->addHSegment ( segment ); + } else { + if ( end->getRight() == segment->getAutoTarget()->getGCell() ) { + segment->setGlobal ( false ); + segment->getAutoTarget()->invalidate (); + } else + end->getRight()->removeHSegment ( segment ); + } + } + + if ( begin != end ) { + for ( GCell* gcell = begin->getUp() ; gcell != end ; gcell = gcell->getUp() ) + gcell->removeVSegment ( this ); + } + + begin = begin->getRight(); + end = end ->getRight(); + autoSource->setGCell ( begin ); + autoTarget->setGCell ( end ); + if ( begin != end ) { + for ( GCell* gcell = begin->getUp() ; gcell != end ; gcell = gcell->getUp() ) + gcell->addVSegment ( this ); + } + + DbU::Unit x = begin->getUSide(Constant::Horizontal).getVMin(); + setAxis ( x, AxisSet ); + + ltrace(200) << "Moved to axis: " << DbU::getValueString(x) << endl; + + Session::revalidateTopology (); + } + + + void AutoVertical::_makeDogLeg ( GCell* dogLegGCell, bool upLayer ) + { + AutoContact* autoSource = getAutoSource(); + AutoContact* autoTarget = getAutoTarget(); + GCell* begin = autoSource->getGCell(); + GCell* end = autoTarget->getGCell(); + unsigned int fragmentType = AutoSegment::Global; + unsigned int splittedType = AutoSegment::Global; + + Session::dogLegReset (); + + //DbU::Unit dogLegAxis = (detachSource)?dogLegGCell->getYMax():dogLegGCell->getY(); + DbU::Unit dogLegAxis = (dogLegGCell->getYMax() + dogLegGCell->getY()) / 2; + if ( isLocal() ) + dogLegAxis = (getSourceY() + getTargetY()) / 2; + + ltrace(159) << "Detaching Target AutoContact." << endl; + if ( end == dogLegGCell ) { + fragmentType = AutoSegment::Local; + } + if ( begin == dogLegGCell ) { + splittedType = AutoSegment::Local; + setGlobal ( false ); + } + + autoTarget->invalidate (); + autoTarget->setInvalidatedTopology ( true ); + + if ( dogLegGCell != end ) { + GCell* gcell = dogLegGCell; + do { + if ( gcell != begin ) + gcell->removeVSegment ( this ); + gcell = gcell->getUp (); + } while ( gcell && (gcell != end) ); + } + + Session::dogLeg ( this ); + + size_t depth = Session::getRoutingGauge()->getLayerDepth ( _vertical->getLayer() ); + Layer* contactLayer = Session::getRoutingGauge()->getContactLayer ( depth + ((upLayer)?0:-1) ); + const Layer* dogLegLayer = Session::getRoutingGauge()->getRoutingLayer ( depth + ((upLayer)?1:-1) ); + + _vertical->getTargetHook()->detach (); + AutoContact* dlContact1 = AutoContact::create ( dogLegGCell, _vertical->getNet(), contactLayer ); + AutoContact* dlContact2 = AutoContact::create ( dogLegGCell, _vertical->getNet(), contactLayer ); + AutoSegment* segment1 = AutoHorizontal::create ( dlContact1 + , dlContact2 + , dogLegLayer + , dogLegAxis + , DbU::lambda(2.0) + , AutoSegment::Local + , false + , false + ); + ltrace(200) << "New " << (void*)dlContact1->getContact() << ":" << dlContact1->getContact() << "." << endl; + ltrace(200) << "New " << (void*)dlContact2->getContact() << ":" << dlContact2->getContact() << "." << endl; + ltrace(200) << "Session::dogLeg() perpand: " << segment1 << endl; + Session::dogLeg ( segment1 ); + + _vertical->getTargetHook()->attach ( dlContact1->getContact()->getBodyHook() ); + AutoSegment* segment2 = AutoVertical::create ( dlContact2 + , autoTarget + , getLayer() + , getX() + , DbU::lambda(2.0) + , fragmentType + , false + , false + ); + segment2->setAxis ( getX(), AxisSet ); + ltrace(200) << "Session::dogLeg() new paral: " << segment2 << endl; + ltrace(200) << "Session::dogLeg() original: " << this << endl; + Session::dogLeg ( segment2 ); + + setGlobal ( (splittedType == AutoSegment::Global) ); + + if ( (splittedType == AutoSegment::Global) or ( fragmentType == AutoSegment::Global ) ) { + if ( splittedType == AutoSegment::Local ) autoSource->restoreHConnexity ( getX(), true ); + else autoTarget->restoreHConnexity ( getX(), true ); + } + + setTerminal ( false ); + segment2->setTerminal ( false ); + if ( autoSource->getAnchor() and not isGlobal() ) setTerminal ( true ); + if ( autoTarget->getAnchor() and not segment2->isGlobal() ) segment2->setTerminal ( true ); + + segment1->setSlackened ( true ); + segment2->setSlackened ( isSlackened() ); + + Session::invalidate ( getNet() ); + Session::revalidateTopology (); + } + + + string AutoVertical::_getString () const + { + string s = AutoSegment::_getString(); + return s; + } + + + Record* AutoVertical::_getRecord () const + { + Record* record = AutoSegment::_getRecord (); + record->add ( getSlot ( "_vertical", _vertical ) ); + return record; + } + + +} // End of Katabatic namespace. diff --git a/katabatic/src/CMakeLists.txt b/katabatic/src/CMakeLists.txt new file mode 100644 index 00000000..be833270 --- /dev/null +++ b/katabatic/src/CMakeLists.txt @@ -0,0 +1,60 @@ + +if ( CHECK_DETERMINISM ) + add_definitions ( -DCHECK_DETERMINISM ) +endif ( CHECK_DETERMINISM ) + + include ( ${QT_USE_FILE} ) + + include_directories ( ${KATABATIC_SOURCE_DIR}/src + ${HURRICANE_INCLUDE_DIR} + ${CORIOLIS_INCLUDE_DIR} + ) + set ( includes katabatic/Configuration.h + katabatic/AutoContact.h katabatic/AutoContacts.h + katabatic/AutoSegment.h katabatic/AutoSegments.h + katabatic/AutoHorizontal.h + katabatic/AutoVertical.h + katabatic/Grid.h katabatic/GridCollections.h + katabatic/GridBox.h + katabatic/GCell.h katabatic/GCells.h + katabatic/GCellGrid.h + katabatic/Session.h + katabatic/KatabaticEngine.h + katabatic/GraphicKatabaticEngine.h + ) + set ( mocIncludes katabatic/GraphicKatabaticEngine.h ) + set ( cpps Configuration.cpp + AutoContact.cpp + AutoContacts.cpp + AutoSegment.cpp + AutoSegments.cpp + AutoHorizontal.cpp + AutoVertical.cpp + Grid.cpp + GCell.cpp + GCellGrid.cpp + PowerRails.cpp + Session.cpp + LayerAssign.cpp + LoadGrByNet.cpp + NetConstraints.cpp + NetOptimals.cpp + KatabaticEngine.cpp + GraphicKatabaticEngine.cpp + ) + qt4_wrap_cpp ( mocCpps ${mocIncludes} ) + + + add_library ( katabatic ${cpps} ${mocCpps} ) + target_link_libraries ( katabatic ${KNIK_LIBRARIES} + ${CORIOLIS_LIBRARIES} + ${HURRICANE_LIBRARIES} + ${HURRICANE_GRAPHICAL_LIBRARIES} + ${QT_LIBRARIES} + ${LEFDEF_LIBRARIES} + ${OA_LIBRARIES} + ) + install ( TARGETS katabatic DESTINATION /lib) + install ( FILES ${includes} + ${mocIncludes} DESTINATION /include/coriolis/katabatic ) + diff --git a/katabatic/src/Configuration.cpp b/katabatic/src/Configuration.cpp new file mode 100644 index 00000000..fb0aa992 --- /dev/null +++ b/katabatic/src/Configuration.cpp @@ -0,0 +1,165 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2008, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | K a t a b a t i c - Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Module : "./Configuartion.cpp" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#include "hurricane/Technology.h" +#include "hurricane/DataBase.h" +#include "katabatic/Configuration.h" + + + +namespace Katabatic { + + + using std::cerr; + using std::endl; + using std::ostringstream; + using Hurricane::tab; + using Hurricane::inltrace; + using Hurricane::Technology; + using Hurricane::DataBase; + + +// ------------------------------------------------------------------- +// Class : "Katabatic::Configuration". + + + Configuration::Configuration () { } + Configuration::~Configuration () { } + + +// ------------------------------------------------------------------- +// Class : "Katabatic::ConfigurationConcrete". + + + ConfigurationConcrete::ConfigurationConcrete ( const RoutingGauge* rg ) + : Configuration() + , _rg (NULL) + , _extensionCap (DbU::lambda(1.5)) + , _saturateRatio (0.80) + , _globalThreshold (29*DbU::lambda(50.0)) // Ugly: direct uses of SxLib gauge. + { + if ( rg ) _rg = rg->getClone(); + + _gmetalh = DataBase::getDB()->getTechnology()->getLayer("gmetalh"); + _gmetalv = DataBase::getDB()->getTechnology()->getLayer("gmetalv"); + _gcontact = DataBase::getDB()->getTechnology()->getLayer("gcontact"); + } + + + ConfigurationConcrete::~ConfigurationConcrete () + { + ltrace(89) << "About to delete attribute _rg (RoutingGauge)." << endl; + _rg->destroy (); + } + + + bool ConfigurationConcrete::isGMetal ( const Layer* layer ) const + { + if ( !layer ) return false; + if ( ( layer != _gmetalh ) + && ( layer != _gmetalv ) + && ( layer != _gcontact ) ) + return false; + + return true; + } + + + size_t ConfigurationConcrete::getDepth () const + { return _rg->getDepth(); } + + + size_t ConfigurationConcrete::getLayerDepth ( const Layer* layer ) const + { return _rg->getLayerDepth(layer); } + + + RoutingGauge* ConfigurationConcrete::getRoutingGauge () const + { return _rg; } + + + RoutingLayerGauge* ConfigurationConcrete::getLayerGauge ( size_t depth ) const + { return _rg->getLayerGauge(depth); } + + + const Layer* ConfigurationConcrete::getRoutingLayer ( size_t depth ) const + { return _rg->getRoutingLayer(depth); } + + + Layer* ConfigurationConcrete::getContactLayer ( size_t depth ) const + { return _rg->getContactLayer(depth); } + + + DbU::Unit ConfigurationConcrete::getExtensionCap () const + { return _extensionCap; } + + + float ConfigurationConcrete::getSaturateRatio () const + { return _saturateRatio; } + + + DbU::Unit ConfigurationConcrete::getGlobalThreshold () const + { return _globalThreshold; } + + + void ConfigurationConcrete::setSaturateRatio ( float ratio ) + { _saturateRatio = ratio; } + + + void ConfigurationConcrete::setGlobalThreshold ( DbU::Unit threshold ) + { _globalThreshold = threshold; } + + + string ConfigurationConcrete::_getTypeName () const + { + return "ConfigurationConcrete"; + } + + + string ConfigurationConcrete::_getString () const + { + ostringstream os; + + os << "<" << _getTypeName() << " " << _rg->getName() << ">"; + + return os.str(); + } + + + Record* ConfigurationConcrete::_getRecord () const + { + Record* record = new Record ( _getString() ); + record->add ( getSlot ( "_rg" , _rg ) ); + record->add ( getSlot ( "_gmetalh" , _gmetalh ) ); + record->add ( getSlot ( "_gmetalv" , _gmetalv ) ); + record->add ( getSlot ( "_gcontact" , _gcontact ) ); + record->add ( getSlot ( "_saturateRatio" , _saturateRatio ) ); + record->add ( DbU::getValueSlot ( "_globalThreshold" , &_globalThreshold ) ); + + return ( record ); + } + + + +} // End of katabatic namespace. diff --git a/katabatic/src/GCell.cpp b/katabatic/src/GCell.cpp new file mode 100644 index 00000000..e9f2dc8c --- /dev/null +++ b/katabatic/src/GCell.cpp @@ -0,0 +1,999 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | K a t a b a t i c - Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Module : "./GCell.cpp" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#include +#include +#include +#include +#include + +#include "hurricane/Bug.h" +#include "hurricane/Warning.h" +#include "hurricane/Layer.h" +#include "hurricane/Horizontal.h" +#include "hurricane/Vertical.h" +#include "crlcore/RoutingGauge.h" +#include "katabatic/AutoContact.h" +#include "katabatic/AutoSegment.h" +#include "katabatic/GCell.h" +#include "katabatic/GCellGrid.h" +#include "katabatic/Session.h" + + +namespace Katabatic { + + + using namespace std; + using Hurricane::roundfp; + using Hurricane::tab; + using Hurricane::ltracein; + using Hurricane::ltraceout; + using Hurricane::inltrace; + using Hurricane::ForEachIterator; + using Hurricane::Warning; + using Hurricane::Bug; + using Hurricane::Horizontal; + using Hurricane::Vertical; + + +// ------------------------------------------------------------------- +// Class : "Katabatic::GCell::CompareByDensity". + + + GCell::CompareByDensity::CompareByDensity ( unsigned int depth ) + : _depth(depth) + { } + + + bool GCell::CompareByDensity::operator() ( GCell* lhs, GCell* rhs ) + { + float difference = roundfp ( lhs->getDensity(_depth) - rhs->getDensity(_depth) ); + if ( difference != 0.0 ) return (difference > 0.0); + + //int difference = floatCompare ( lhs->getDensity(_depth), rhs->getDensity(_depth) ); + //if ( abs(difference) > 1000 ) return difference > 0; + + if ( lhs->getIndex() < rhs->getIndex() ) return true; + return false; + } + + +// ------------------------------------------------------------------- +// Class : "Katabatic::GCell". + + + const Name GCell::_goName = "Katabatic::GCell"; + DbU::Unit GCell::_topRightShrink = 0; + size_t GCell::_allocateds = 0; + + + GCell::GCell ( GCellGrid* gcellGrid, unsigned int index, const Box& box ) + : ExtensionGo (gcellGrid->getCell()) + , _gcellGrid (gcellGrid) + , _index (index) + , _vsegments () + , _hsegments () + , _contacts () + , _box (box) + , _depth (Session::getRoutingGauge()->getDepth()) + , _pinDepth (0) + , _blockages (new float [_depth]) + , _cDensity (0.0) + , _densities (new float [_depth]) + , _saturateDensities (new float [_depth]) + , _segmentCount (0) + , _routedSegmentCount(0) + , _saturated (false) + , _invalid (true) + { + for ( size_t i=0 ; i<_depth ; i++ ) { + _blockages [i] = 0.0; + _densities [i] = 0.0; + _saturateDensities[i] = 0.0; + + if ( Session::getRoutingGauge()->getLayerGauge(i)->getType() == Constant::PinOnly ) + ++_pinDepth; + } + + _allocateds++; + } + + + void GCell::_postCreate () + { + ltrace(90) << "GCell::_postCreate() - " << (void*)this << " " << this << endl; + ltracein(90); + + ExtensionGo::_postCreate (); + + ltraceout(90); + } + + + GCell* GCell::create ( GCellGrid* gcellGrid, unsigned int index, Box box ) + { + if ( !_topRightShrink ) + _topRightShrink = 1 /*DbU::lambda(0.0)*/; + + GCell* gcell = new GCell ( gcellGrid, index, box.inflate(0 + ,0 + ,-_topRightShrink + ,-_topRightShrink) ); + + gcell->_postCreate (); + + return gcell; + } + + + GCell::~GCell () + { + ltrace(90) << "GCell::~GCell()" << endl; + + delete [] _densities; + delete [] _saturateDensities; + + _allocateds--; + } + + + void GCell::_preDestroy () + { + ltrace(90) << "GCell::_preDestroy() - " << (void*)this << " " << this << endl; + ExtensionGo::_preDestroy (); + } + + + bool GCell::isSaturated ( unsigned int depth ) const + { return getDensity(depth) > Session::getSaturateRatio(); } + + + bool GCell::isAboveDensity ( float threshold ) const + { + if (_invalid) const_cast(this)->updateDensity(); + float difference = roundfp ( getDensity() - threshold ); + + //int difference = floatDifference(getDensity(),threshold,10000); + ltrace(190) << "GCell:isAboveDensity() " << threshold << " diff:" << difference << endl; + return (difference > 0.0); + } + + + bool GCell::areDensityConnex ( GCell* a, GCell* b ) + { + ltrace(190) << "GCell:areDensityConnex()" << endl; + + for ( unsigned int i=1 ; igetDepth() ; i++ ) { // Ugly: hard-coded skip METAL1. + //int highDiffa = floatDifference(a->_densities[i],0.6,10000); + //int highDiffb = floatDifference(b->_densities[i],0.6,10000); + + float highDiffa = roundfp ( a->_densities[i] - 0.6 ); + float highDiffb = roundfp ( b->_densities[i] - 0.6 ); + ltrace(190) << "Compare depth " << i + << " " << a->_densities[i] << "," << highDiffa + << " & " << b->_densities[i] << "," << highDiffb << endl; + + if ( (highDiffa > 0) and (highDiffb > 0) ) { + ltrace(190) << "GCell::areDensityConnex() Neighboring high saturated GCell (depth:" << i + << " " << a->_densities[i] << " & " << b->_densities[i] << ")" << endl; + return true; + } + } + return false; + } + + + void GCell::getDensities ( float* densities ) const + { + if (_invalid) const_cast(this)->updateDensity(); + + for ( unsigned int i=0 ; i<_depth ; i++ ) { + densities[i] = _densities[i]; + } + } + + + const Name& GCell::getStaticName () + { return _goName; } + + + size_t GCell::getAllocateds () + { return _allocateds; } + + + DbU::Unit GCell::getTopRightShrink () + { return _topRightShrink; } + + + const Name& GCell::getName () const + { return _goName; } + + + unsigned int GCell::getRow () const + { return _gcellGrid->getRow ( _index ); } + + + unsigned int GCell::getColumn () const + { return _gcellGrid->getColumn ( _index ); } + + + GCell* GCell::getLeft () const + { return getGCellGrid()->getGCellLeft(this); } + + + GCell* GCell::getRight () const + { return getGCellGrid()->getGCellRight(this); } + + + GCell* GCell::getUp () const + { return getGCellGrid()->getGCellUp(this); } + + + GCell* GCell::getDown () const + { return getGCellGrid()->getGCellDown(this); } + + + Interval GCell::getUSide ( unsigned int direction ) const + { + Interval side; + switch ( direction ) { + default: + case Constant::Horizontal: side = Interval(_box.getXMin(),_box.getXMax()); break; + case Constant::Vertical: side = Interval(_box.getYMin(),_box.getYMax()); break; + } + return side; + } + + + AutoSegments GCell::getHStartSegments () + { + return new AutoSegments_AnchorOnGCell (this,true,Constant::Horizontal); + } + + + AutoSegments GCell::getVStartSegments () + { + return new AutoSegments_AnchorOnGCell (this,true,Constant::Vertical); + } + + + AutoSegments GCell::getHStopSegments () + { + return new AutoSegments_AnchorOnGCell (this,false,Constant::Horizontal); + } + + + AutoSegments GCell::getVStopSegments () + { + return new AutoSegments_AnchorOnGCell (this,false,Constant::Vertical); + } + + + float GCell::getHCapacity () const + { + return (float)( _box.getHeight() / DbU::lambda(5.0) + 1 ); + } + + + float GCell::getVCapacity () const + { + return (float)( _box.getWidth () / DbU::lambda(5.0) + 1 ); + } + + + float GCell::getDensity ( bool update ) const + { + if (_invalid and update) const_cast(this)->updateDensity(); + + float density = 0.0; + for ( size_t i=0 ; i<_depth ; i++ ) + density += _densities[i]; + +#if defined(CHECK_DETERMINISM) + cerr << "Order: Sum density " << setprecision(9) << density << endl; + + density /= (float)(_depth-_pinDepth); + cerr << "Order: density " << setprecision(9) << density << endl; + + int intdensity = (int)roundfp(density); + cerr << "Order: rounded density *100 " << setprecision(9) << intdensity << endl; + + density = ((float)(intdensity)) / 100.0; + cerr << "Order: rounded density /100 " << setprecision(9) << density << endl; + + return density; +#else + return roundfp ( density/((float)(_depth-_pinDepth)) ); +#endif + } + + + float GCell::getMaxHVDensity ( bool update ) const + { + if (_invalid and update) const_cast(this)->updateDensity(); + + size_t hplanes = 0; + size_t vplanes = 0; + float hdensity = 0.0; + float vdensity = 0.0; + + for ( size_t i=0 ; i<_depth ; i++ ) { + if ( i%2 ) { hdensity += _densities[i]; ++hplanes; } + else { vdensity += _densities[i]; ++vplanes; } + } + + if (hplanes) hdensity /= hplanes; + if (vplanes) vdensity /= vplanes; + + return (hdensity > vdensity) ? hdensity : vdensity; + } + + + float GCell::getStiffness () const + { + if ( _segmentCount == 0 ) return 0.0; + return roundfp ( (float)_routedSegmentCount / (float)_segmentCount ); + } + + + void GCell::incSegmentCount ( int count ) + { + if ( (count < 0) and ((unsigned int)abs(count) > _segmentCount) ) + _segmentCount = 0; + else + _segmentCount += count; + } + + + void GCell::incRoutedCount ( int count ) + { + if ( (count < 0) and ((unsigned int)abs(count) > _routedSegmentCount) ) + _routedSegmentCount = 0; + else + _routedSegmentCount += count; + } + + + void GCell::addBlockage ( unsigned int depth, float length ) + { + if ( depth >= _depth ) return; + + _blockages[depth] += length; + _invalid = true; + + //cerr << "GCell:addBlockage() " + // << depth << ":" << _blockages[depth] << endl; + } + + + void GCell::removeContact ( AutoContact* ac ) + { + size_t begin = 0; + size_t end = _contacts.size(); + bool found = false; + + for ( ; not found and (begin < end) ; begin++ ) { + if ( _contacts[begin] == ac ) { + _contacts[begin] = _contacts[end-1]; + found = true; + } + } + + if (found) { + ltrace(200) << "remove " << (void*)ac->base() << ":" << ac + << " from " << this << endl; + _contacts.pop_back(); + } else { + cerr << Bug("%p:%s do not belong to %s." + ,ac->base(),getString(ac).c_str(),_getString().c_str()) << endl; + } + +#if 0 + vector::iterator it = _contacts.begin (); + vector::iterator end = _contacts.end (); + for ( ; it != end ; it++ ) + if ( *it == ac ) *it = *(--end); + _contacts.pop_back (); +#endif + } + + + void GCell::removeHSegment ( AutoSegment* segment ) + { + size_t end = _hsegments.size(); + size_t begin = 0; + + for ( ; begin < end ; begin++ ) { + if ( _hsegments[begin] == segment ) { + swap ( _hsegments[begin], _hsegments[--end] ); + } + } + + if ( _hsegments.size() == end ) { + cerr << Bug("%p %s do not go through %s." + ,(void*)segment + ,getString(segment).c_str() + ,_getString().c_str()) << endl; + return; + } + + if ( _hsegments.size() - end > 1 ) + cerr << Bug("%p %s has multiple occurrences of %s." + ,(void*)segment + ,_getString().c_str() + ,getString(segment).c_str()) << endl; + + _hsegments.erase ( _hsegments.begin() + end, _hsegments.end() ); + } + + + void GCell::removeVSegment ( AutoSegment* segment ) + { + size_t end = _vsegments.size(); + size_t begin = 0; + + for ( ; begin < end ; begin++ ) { + if ( _vsegments[begin] == segment ) { + swap ( _vsegments[begin], _vsegments[--end] ); + } + } + + if ( _vsegments.size() == end ) { + cerr << Bug("%p %s do not go through %s." + ,(void*)segment + ,getString(segment).c_str() + ,_getString().c_str()) << endl; + return; + } + + if ( _vsegments.size() - end > 1 ) + cerr << Bug("%p %s has multiple occurrences of %s." + ,(void*)segment + ,_getString().c_str() + ,getString(segment).c_str()) << endl; + + _vsegments.erase ( _vsegments.begin() + end, _vsegments.end() ); + } + + + void GCell::updateContacts () + { + vector::iterator it = _contacts.begin (); + vector::iterator end = _contacts.end (); + for ( ; it != end ; it++ ) (*it)->updateGeometry (); + } + + + size_t GCell::updateDensity () + { + if ( !_invalid ) return (_saturated) ? 1 : 0; + + _saturated = false; + + for ( size_t i=0 ; i<_vsegments.size() ; i++ ) { + if ( _vsegments[i] == NULL ) + cerr << "NULL Autosegment at index " << i << endl; + } + + sort ( _hsegments.begin(), _hsegments.end(), AutoSegment::CompareByDepthLength() ); + sort ( _vsegments.begin(), _vsegments.end(), AutoSegment::CompareByDepthLength() ); + +#if defined(CHECK_DETERMINISM) + cerr << "Order: Update density " << this << endl; + for ( size_t i=0 ; i<_hsegments.size() ; i++ ) cerr << "Order: " << _hsegments[i] << endl; + for ( size_t i=0 ; i<_vsegments.size() ; i++ ) cerr << "Order: " << _vsegments[i] << endl; +#endif + + float hcapacity = getHCapacity (); + float vcapacity = getVCapacity (); + float ccapacity = hcapacity * vcapacity * 4; + DbU::Unit hpenalty = 0 /*_box.getWidth () / 3*/; + DbU::Unit vpenalty = 0 /*_box.getHeight() / 3*/; + DbU::Unit uLengths1 [ _depth ]; + float fLengths1 [ _depth ]; + float fLengths2 [ _depth ]; + + for ( size_t i=0 ; i<_depth ; i++ ) { + fLengths1[i] = 0.0; + fLengths2[i] = 0.0; + } + + // Compute wirelength associated to contacts (in DbU::Unit converted to float). + set processeds; + vector::iterator it = _contacts.begin(); + vector::iterator end = _contacts.end (); + for ( ; it != end ; it++ ) { + for ( size_t i=0 ; i<_depth ; i++ ) uLengths1[i] = 0; + (*it)->getLengths ( uLengths1, processeds ); + for ( size_t i=0 ; i<_depth ; i++ ) { + fLengths1[i] += (float)uLengths1[i]; + switch ( Session::getRoutingGauge()->getLayerDirection(i) ) { + case Constant::Horizontal: fLengths2[i] += (float)(uLengths1[i]+hpenalty); break; + case Constant::Vertical: fLengths2[i] += (float)(uLengths1[i]+vpenalty); break; + } + } + } + + // Transform the wirelength in density (divide by track length, one + // occupied track count for "one"). + for ( size_t i=0 ; i<_depth ; i++ ) { + switch ( Session::getRoutingGauge()->getLayerDirection(i) ) { + case Constant::Horizontal: + fLengths1[i] /= (float)_box.getWidth (); + fLengths2[i] /= (float)_box.getWidth (); + break; + case Constant::Vertical: + fLengths1[i] /= (float)_box.getHeight(); + fLengths2[i] /= (float)_box.getHeight(); + break; + } + } + + // Add the "pass through" horizontal segments. + if ( _hsegments.size() ) { + const Layer* layer = _hsegments[0]->getLayer(); + size_t depth = Session::getRoutingGauge()->getLayerDepth(layer); + size_t count = 0; + for ( size_t i=0 ; i<_hsegments.size() ; i++ ) { + if ( layer != _hsegments[i]->getLayer() ) { + fLengths1[depth] += (float)count; + fLengths2[depth] += (float)count; + + count = 0; + layer = _hsegments[i]->getLayer(); + depth = Session::getRoutingGauge()->getLayerDepth(layer); + } + count++; + } + if ( count ) { + fLengths1[depth] += (float)count; + fLengths2[depth] += (float)count; + } + } + + // Add the "pass through" vertical segments. + if ( _vsegments.size() ) { + const Layer* layer = _vsegments[0]->getLayer(); + size_t depth = Session::getRoutingGauge()->getLayerDepth(layer); + size_t count = 0; + for ( size_t i=0 ; i<_vsegments.size() ; i++ ) { + if ( layer != _vsegments[i]->getLayer() ) { + fLengths1[depth] += (float)count; + fLengths2[depth] += (float)count; + + count = 0; + layer = _vsegments[i]->getLayer(); + depth = Session::getRoutingGauge()->getLayerDepth(layer); + } + count++; + } + if ( count ) { + fLengths1[depth] += (float)count; + fLengths2[depth] += (float)count; + } + } + + // Add the blockages. + for ( size_t i=0 ; i<_depth ; i++ ) { + fLengths1[i] += _blockages[i]; + fLengths2[i] += _blockages[i]; + } + + // Normalize: 0 < d < 1.0 (divide by H/V capacity). + for ( size_t i=0 ; i<_depth ; i++ ) { + switch ( Session::getRoutingGauge()->getLayerDirection(i) ) { + case Constant::Horizontal: + fLengths1[i] /= hcapacity; + fLengths2[i] /= hcapacity; + break; + case Constant::Vertical: + fLengths1[i] /= vcapacity; + fLengths2[i] /= vcapacity; + break; + } + if ( fLengths1[i] > 1.0 ) { + _saturated = true; + //fLengths[i] = 1.0; + } + _densities [i] = fLengths1[i]; + _saturateDensities[i] = fLengths2[i]; + } + + _cDensity = ( (float)_contacts.size() ) / ccapacity; + _invalid = false; + + for ( size_t i=0 ; i<_depth ; i++ ) { + _densities [i] = roundfp ( _densities [i] ); + _saturateDensities[i] = roundfp ( _saturateDensities[i] ); + } + _cDensity = roundfp (_cDensity ); + + checkDensity (); + +#if defined(CHECK_DETERMINISM) + float gdensity = getDensity(); + cerr << "Order: [" << getIndex() << "] " + << getVectorString(_densities,_depth) + << " " << setprecision(9) << gdensity << endl; +#endif + + //_segmentCount = _hsegments.size() + _vsegments.size() + processeds.size(); + + return ( _saturated ) ? 1 : 0 ; + } + + + size_t GCell::checkDensity () const + { + if ( _invalid ) const_cast(this)->updateDensity (); + + if ( !Session::getDemoMode() && Session::getWarnGCellOverload() ) { + for ( size_t i=0 ; i<_depth ; i++ ) { + if ( _densities[i] > 1.0 ) { + cerr << Warning("%s @%dx%d overloaded in %s (M2:%.2f M3:%.2f M4:%.2f M5:%.2f)" + ,_getString().c_str() + ,getColumn() + ,getRow() + ,getString(Session::getRoutingGauge()->getRoutingLayer(i)->getName()).c_str() + ,_densities[1] + ,_densities[2] + ,_densities[3] + ,_densities[4] + ) + << endl; + } + } + } + + return ( _saturated ) ? 1 : 0 ; + } + + + bool GCell::hasFreeTrack ( size_t depth ) const + { + if (_invalid) const_cast(this)->updateDensity(); + +#if DEPRECATED + float capacity; + vector::const_iterator isegment; + vector::const_iterator iend; + + switch ( Session::getRoutingGauge()->getLayerDirection(depth) ) { + case Constant::Horizontal: + iend = _hsegments.end (); + isegment = _hsegments.begin (); + capacity = getHCapacity (); + break; + case Constant::Vertical: + iend = _vsegments.end (); + isegment = _vsegments.begin (); + capacity = getVCapacity (); + break; + } + + size_t count = 0; + for ( ; (isegment != iend) ; isegment++ ) { + unsigned int segmentDepth = Session::getRoutingGauge()->getLayerDepth((*isegment)->getLayer()); + if ( segmentDepth < depth ) continue; + if ( segmentDepth > depth ) break; + count++; + } + + return (capacity - 1.0) >= (float)count; +#endif + + float capacity = 0.0; + switch ( Session::getRoutingGauge()->getLayerDirection(depth) ) { + case Constant::Horizontal: capacity = getHCapacity(); break; + case Constant::Vertical: capacity = getVCapacity(); break; + } + + ltrace(200) << "| hasFreeTrack [" << getIndex() << "] depth:" << depth << " " + << Session::getRoutingGauge()->getRoutingLayer(depth)->getName() + << " " << (_saturateDensities[depth]*capacity) << " vs. " << capacity + << endl; + + return (_saturateDensities[depth]*capacity + 1.0 <= capacity); + } + + + bool GCell::stepDesaturate ( unsigned int depth, set& globalNets ) + { +#if defined(CHECK_DETERMINISM) + cerr << "Order: stepDesaturate [" << getIndex() << "] depth:" << depth << endl; +#endif + + updateDensity (); + + //float density = _densities[depth]; + //float densityUp = _densities[depth+2]; + + if ( !isSaturated(depth) ) return false; + + float capacity; + vector::iterator isegment; + vector::iterator iend; + + switch ( Session::getRoutingGauge()->getLayerDirection(depth) ) { + case Constant::Horizontal: + iend = _hsegments.end (); + isegment = _hsegments.begin (); + capacity = getHCapacity (); + break; + case Constant::Vertical: + iend = _vsegments.end (); + isegment = _vsegments.begin (); + capacity = getVCapacity (); + break; + } + + for ( ; (isegment != iend) ; isegment++ ) { + unsigned int segmentDepth = Session::getRoutingGauge()->getLayerDepth((*isegment)->getLayer()); + + if ( segmentDepth < depth ) continue; + if ( segmentDepth > depth ) break; + + globalNets.insert ( (*isegment)->getNet() ); +#if defined(CHECK_DETERMINISM) + cerr << "Order: Move up " << (*isegment) << endl; +#endif + //cerr << "Move up " << (*isegment) << endl; + (*isegment)->changeDepth ( depth+2, false, false ); + + updateDensity (); + + return true; + } + + return false; + } + + + void GCell::desaturate ( unsigned int depth, set& globalNets ) + { + updateDensity (); + + float density = _densities[depth]; + float densityUp = _densities[depth+2]; + + if ( density < Session::getSaturateRatio() ) return; + + float capacity; + vector::iterator isegment; + vector::iterator iend; + + switch ( Session::getRoutingGauge()->getLayerDirection(depth) ) { + case Constant::Horizontal: + iend = _hsegments.end (); + isegment = _hsegments.begin (); + capacity = getHCapacity (); + break; + default: + case Constant::Vertical: + iend = _vsegments.end (); + isegment = _vsegments.begin (); + capacity = getHCapacity (); + break; + } + + unsigned int overload = (unsigned int)( ( density - Session::getSaturateRatio() ) * capacity ); + unsigned int displaced = 0; + + for ( ; (isegment != iend) && (displaced < overload) ; isegment++ ) { + unsigned int segmentDepth = Session::getRoutingGauge()->getLayerDepth((*isegment)->getLayer()); + + if ( segmentDepth < depth ) continue; + if ( segmentDepth > depth ) break; + + globalNets.insert ( (*isegment)->getNet() ); + (*isegment)->changeDepth ( depth+2, false, false ); + + displaced++; + } + + float desaturated = density - ((float)(displaced)) / capacity; + + cmess2 << " - GCell [" << getIndex() << "] @" << getColumn() << "x" << getRow() + << ":" << setprecision(4) << density + << " -> " << desaturated + << " [displaced:" << displaced + << " cap:" << capacity + << " M+2: " << densityUp + << " -> " << (densityUp + ((float)(displaced)) / capacity) << "]." + << endl; + } + + + bool GCell::checkEdgeSaturation ( float threshold ) const + { + unsigned int edgeUpUsage = 0; + unsigned int edgeRightUsage = 0; + float edgeUpSaturation = 0.0; + float edgeRightSaturation = 0.0; + + if ( getUp() ) { + // Up Edge Density. + edgeUpUsage = _vsegments.size(); + for ( size_t icontact=0 ; icontact < _contacts.size() ; icontact++ ) { + forEach ( Hook*, ihook, _contacts[icontact]->getBodyHook()->getSlaveHooks() ) { + if ( dynamic_cast(*ihook) == NULL ) continue; + + Segment* segment = dynamic_cast((*ihook)->getComponent()); + if ( not segment ) continue; + + AutoSegment* autoSegment = Session::lookup ( segment ); + if ( not autoSegment or autoSegment->isLocal() ) continue; + + edgeUpUsage++; + } + } + edgeUpSaturation = (float)edgeUpUsage/((float)getVCapacity()*2.0); + } + + if ( getRight() ) { + // Right Edge Density. + edgeRightUsage = _vsegments.size(); + for ( size_t icontact=0 ; icontact < _contacts.size() ; icontact++ ) { + forEach ( Hook*, ihook, _contacts[icontact]->getBodyHook()->getSlaveHooks() ) { + if ( dynamic_cast(*ihook) == NULL ) continue; + + Segment* segment = dynamic_cast((*ihook)->getComponent()); + if ( not segment ) continue; + + AutoSegment* autoSegment = Session::lookup ( segment ); + if ( not autoSegment or autoSegment->isLocal() ) continue; + + edgeRightUsage++; + } + } + edgeRightSaturation = (float)edgeRightUsage/((float)getHCapacity()*2.0); + } + + bool overload = false; + if ( (edgeUpSaturation > threshold) or (edgeRightSaturation > threshold) ) { + overload = true; + + cerr << Warning("In %s, (over %.2f) ", _getString().c_str(), threshold); + + ostringstream message; + message << setprecision(3); + if ( edgeUpSaturation > threshold ) + message << "up edge: " << edgeUpUsage << "/" << (getVCapacity()*2.0) + << " " << edgeUpSaturation; + if ( edgeRightSaturation > threshold ) { + if ( message.str().size() ) message << " & "; + message << "right edge: " << edgeRightUsage << "/" << (getVCapacity()*2.0) + << " " << edgeRightSaturation; + } + + cerr << message.str() << "." << endl; + } + + return overload; + } + + + Box GCell::getBoundingBox () const + { + return _box; + } + + + void GCell::translate ( const DbU::Unit&, const DbU::Unit& ) + { + cerr << Warning("Calling GCell::translate() on %s is likely a bug." + ,_getString().c_str()) << endl; + } + + + string GCell::_getString () const + { + Box box = getBoundingBox (); + + ostringstream s; + s << "<" << _getTypeName() << " [" << _index << "] " + << DbU::getValueString(box.getXMin()) << ":" << DbU::getValueString(box.getYMin()) << " " + << DbU::getValueString(box.getXMax()) << ":" << DbU::getValueString(box.getYMax()) << " " + << setprecision(9) +#if not defined(CHECK_DETERMINISM) + << getDensity(false) +#endif + << " S:" << _routedSegmentCount << "/" << _segmentCount + << ">"; + + return s.str(); + } + + + Record* GCell::_getRecord () const + { + Record* record = new Record ( _getString() ); + record->add ( getSlot ( "_gcellGrid" , _gcellGrid ) ); + record->add ( getSlot ( "_index" , &_index ) ); + record->add ( getSlot ( "_vsegments" , &_vsegments ) ); + record->add ( getSlot ( "_hsegments" , &_hsegments ) ); + record->add ( getSlot ( "_contacts" , &_contacts ) ); + record->add ( getSlot ( "_box" , &_box ) ); + record->add ( getSlot ( "_depth" , &_depth ) ); + record->add ( getSlot ( "_saturated" , _saturated ) ); + record->add ( getSlot ( "_segmentCount" , _segmentCount ) ); + record->add ( getSlot ( "_routedSegmentCount", _routedSegmentCount ) ); + record->add ( getSlot ( "_invalid" , _invalid ) ); + + for ( size_t depth=0 ; depth<_depth ; ++depth ) { + record->add ( getSlot ( "_blockages[]", &_blockages[depth] ) ); + } + + for ( size_t depth=0 ; depth<_depth ; ++depth ) { + record->add ( getSlot ( "_densities[]", &_densities[depth] ) ); + } + + for ( size_t depth=0 ; depth<_depth ; ++depth ) { + record->add ( getSlot ( "_saturateDensities[]", &_saturateDensities[depth] ) ); + } + + return record; + } + + + void GCell::_xmlWrite ( ostream& o ) const + { + char line[1024]; + + snprintf ( line, 1024 + , "" + , getColumn() + , getRow() + , DbU::getLambda(getX()) + , DbU::getLambda(getY()) + , getDensity() + , _cDensity + ); + + o << line; + } + + +// ------------------------------------------------------------------- +// Utilities. + + + string getVectorString ( float* v, size_t size ) + { + ostringstream s; + + s << setprecision(9); + for ( size_t i=0 ; i() + , _katabatic(ktbt) + { } + + + void GCellGrid::_postCreate () + { + KnikEngine::KnikEngine* knik; + knik = KnikEngine::get ( getCell() ); + if ( !knik ) + throw Error ( missingKnikEngine, "GCellGrid::_postCreate()", getString(getCell()).c_str() ); + + vector knikGraduations; + + knik->getHorizontalCutLines ( knikGraduations ); + for ( size_t i=0 ; igetVerticalCutLines ( knikGraduations ); + for ( size_t i=0 ; i_postCreate (); + return grid; + } + + + GCellGrid::~GCellGrid () + { } + + + void GCellGrid::_preDestroy () + { + ltrace(90) << "GCellGrid::_preDestroy()" << endl; + ltracein(90); + + vector::iterator it = _gcells.begin(); + vector::iterator end = _gcells.end (); + for ( ; it != end ; it++ ) (*it)->destroy (); + + ltraceout(90); + } + + + Cell* GCellGrid::getCell () const + { + return _katabatic->getCell(); + } + + + void GCellGrid::updateContacts ( bool openSession ) + { + if ( openSession ) Session::open ( _katabatic ); + + forEach ( GCell*, gcell, getGCells() ) + gcell->updateContacts (); + + if ( openSession ) Session::close (); + } + + + size_t GCellGrid::updateDensity () + { + size_t saturateds = 0; + forEach ( GCell*, gcell, getGCells() ) { + saturateds += gcell->updateDensity (); + } + return saturateds; + } + + + size_t GCellGrid::checkDensity () const + { + size_t saturateds = 0; + forEach ( GCell*, gcell, const_cast(this)->getGCells() ) { + saturateds += gcell->checkDensity (); + } + return saturateds; + } + + + bool GCellGrid::checkEdgeSaturation ( float threshold ) const + { + bool overload = false; + forEach ( GCell*, gcell, const_cast(this)->getGCells() ) { + overload = gcell->checkEdgeSaturation(threshold) or overload; + } + return overload; + } + + + string GCellGrid::_getTypeName () const + { + return _TName("GCellGrid"); + } + + + string GCellGrid::_getString () const + { + return "<" + _getTypeName() + " " + + getString(getRows()) + "x" + getString(getColumns()) + ">"; + } + + + void GCellGrid::_xmlWrite ( ostream& o ) + { + updateDensity (); + + o << "getName() << "\">" << endl; + o << "" << endl; + o << "" << endl; + + unsigned int row = 0; + forEach ( GCell*, gcell, getGCells() ) { + if ( gcell->getRow() > row ) { + o << endl; + o << "" << endl; + row = gcell->getRow(); + } + + o << " "; gcell->_xmlWrite ( o ); o << endl; + } + + o << "" << endl; + } + + + Record* GCellGrid::_getRecord () const + { + Record* record = Grid::_getRecord (); + record->add ( getSlot ( "_katabatic", _katabatic ) ); + return record; + } + + + +} // End of Katabatic namespace. diff --git a/katabatic/src/GraphicKatabaticEngine.cpp b/katabatic/src/GraphicKatabaticEngine.cpp new file mode 100644 index 00000000..55a5d4b3 --- /dev/null +++ b/katabatic/src/GraphicKatabaticEngine.cpp @@ -0,0 +1,229 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2008, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | K a t a b a t i c - Routing Toolbox | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./GraphicKatabaticEngine.cpp" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace Katabatic { + + + using namespace std; + using Hurricane::Error; + using Hurricane::Warning; + using Hurricane::Breakpoint; + using Hurricane::DebugSession; + using Hurricane::Net; + using Hurricane::Graphics; + using Hurricane::ColorScale; + using CRL::AllianceFramework; + + + size_t GraphicKatabaticEngine::_references = 0; + GraphicKatabaticEngine* GraphicKatabaticEngine::_singleton = NULL; + + + void GraphicKatabaticEngine::initKatabaticAc ( CellWidget* widget ) + { + //cerr << "GraphicKatabaticEngine::initKatabaticGo()" << endl; + } + + + void GraphicKatabaticEngine::drawKatabaticAc ( CellWidget* widget + , const Go* go + , const BasicLayer* basicLayer + , const Box& box + , const Transformation& transformation + ) + { } + + + void GraphicKatabaticEngine::initKatabaticGCell ( CellWidget* widget ) + { + widget->getDrawingPlanes().setPen ( Qt::NoPen ); + } + + + void GraphicKatabaticEngine::drawKatabaticGCell ( CellWidget* widget + , const Go* go + , const BasicLayer* basicLayer + , const Box& box + , const Transformation& transformation + ) + { + const GCell* gcell = static_cast(go); + + QPainter& painter = widget->getPainter(); + painter.setBrush + ( Graphics::getColorScale(ColorScale::Fire).getBrush((size_t)(gcell->getMaxHVDensity()*255.0) + ,widget->getDarkening()) ); + painter.drawRect ( widget->dbuToDisplayRect(gcell->getBoundingBox()) ); + } + + + KatabaticEngine* GraphicKatabaticEngine::create ( const RoutingGauge* rg, Cell* cell ) + { + KatabaticEngine* ktbt = KatabaticEngine::get ( cell ); + if ( !ktbt ) + ktbt = KatabaticEngine::create ( rg, cell ); + else + cerr << Warning("%s already has a Katabatic engine.",getString(cell).c_str()) << endl; + + return ktbt; + } + + + void GraphicKatabaticEngine::run () + { + static vector routingNets; + + emit cellPreModificated (); + + AllianceFramework* af = AllianceFramework::get (); + KatabaticEngine* ktbt = create ( af->getRoutingGauge(), _viewer->getCell() ); + + //DebugSession::addToTrace ( _viewer->getCell(), "sel" ); + + ktbt->loadGlobalRouting ( LoadGrByNet, routingNets ); + emit cellPostModificated (); + + //Breakpoint::stop ( 0, "Point d'arret:
      LayerAssingByTrunk()
    " + // "Assignment des layers, methode globale." ); + emit cellPreModificated (); + ktbt->layerAssign ( LayerAssignByTrunk ); + emit cellPostModificated (); + + //throw ( "Rend-toi t'est cerné" ); + } + + + void GraphicKatabaticEngine::closeRoute () + { + emit cellPreModificated (); + KatabaticEngine* ktbt = KatabaticEngine::get ( _viewer->getCell() ); + + ktbt->destroy (); + emit cellPostModificated (); + } + + + void GraphicKatabaticEngine::addToMenu ( CellViewer* viewer ) + { + assert ( _viewer == NULL ); + + _viewer = viewer; + + QMenu* prMenu = _viewer->findChild("viewer.menuBar.placeAndRoute"); + if ( !prMenu ) { + QMenuBar* menuBar = _viewer->findChild("viewer.menuBar"); + if ( !menuBar ) { + cerr << Warning("GraphicKatabaticEngine::addToMenu() - No MenuBar in parent widget.") << endl; + return; + } + prMenu = menuBar->addMenu ( tr("P&&R") ); + prMenu->setObjectName ( "viewer.menuBar.placeAndRoute" ); + } + + QAction* fRouteAction = _viewer->findChild("viewer.menuBar.placeAndRoute.finalRoute"); + if ( fRouteAction ) + cerr << Warning("GraphicKatabaticEngine::addToMenu() - Katabatic final router already hooked in.") << endl; + else { + fRouteAction = new QAction ( tr("Katabatic - &Final Route"), _viewer ); + fRouteAction->setObjectName ( "viewer.menuBar.placeAndRoute.finalRoute" ); + fRouteAction->setStatusTip ( tr("Run the Katabatic final router") ); + fRouteAction->setVisible ( true ); + prMenu->addAction ( fRouteAction ); + + QAction* fCloseRouteAction = new QAction ( tr("Close Routing"), _viewer ); + fCloseRouteAction->setObjectName ( "viewer.menuBar.placeAndRoute.closeRoute" ); + fCloseRouteAction->setStatusTip ( tr("Closing Routing") ); + fCloseRouteAction->setVisible ( true ); + prMenu->addAction ( fCloseRouteAction ); + + connect ( fCloseRouteAction, SIGNAL(triggered()), this, SLOT(closeRoute()) ); + connect ( fRouteAction , SIGNAL(triggered()), this, SLOT(run()) ); + } + + connect ( this, SIGNAL(cellPreModificated ()), _viewer->getCellWidget(), SLOT(cellPreModificate ()) ); + connect ( this, SIGNAL(cellPostModificated()), _viewer->getCellWidget(), SLOT(cellPostModificate()) ); + } + + + const Name& GraphicKatabaticEngine::getName () const + { + return KatabaticEngine::staticGetName (); + } + + + GraphicKatabaticEngine* GraphicKatabaticEngine::grab () + { + if ( !_references ) { + _singleton = new GraphicKatabaticEngine (); + } + _references++; + + return _singleton; + } + + + size_t GraphicKatabaticEngine::release () + { + _references--; + if ( !_references ) { + delete _singleton; + _singleton = NULL; + } + return _references; + } + + + GraphicKatabaticEngine::GraphicKatabaticEngine () + : GraphicTool() + , _viewer(NULL) + { + addDrawGo ( "Katabatic::Ac" , initKatabaticAc , drawKatabaticAc ); + addDrawGo ( "Katabatic::GCell", initKatabaticGCell, drawKatabaticGCell ); + } + + + GraphicKatabaticEngine::~GraphicKatabaticEngine () + { } + + +} // End of Katabatic namespace. diff --git a/katabatic/src/Grid.cpp b/katabatic/src/Grid.cpp new file mode 100644 index 00000000..1da6c3c2 --- /dev/null +++ b/katabatic/src/Grid.cpp @@ -0,0 +1,134 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2008, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | K a t a b a t i c - Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Module : "./Grid.cpp" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +# include +# include +# include + +# include "katabatic/Grid.h" + + +namespace Katabatic { + + + using namespace std; + using namespace Hurricane; + + +// ------------------------------------------------------------------- +// Class : "Katabatic::BaseGrid::Axis". + + + void BaseGrid::Axis::sort () + { + std::sort ( _graduations.begin(), _graduations.end() ); + } + + + unsigned int BaseGrid::Axis::getGraduationNumber ( DbU::Unit position, bool& onGraduation ) const + { + vector::const_iterator it = lower_bound ( _graduations.begin() + , _graduations.end() + , position+1 + ); + unsigned int index = distance ( _graduations.begin(), it ) - 1; + + onGraduation = ( _graduations[index] == position ); + + return index; + } + + + string BaseGrid::Axis::_getString () const + { + return "<" + _getTypeName() + " [" + + DbU::getValueString(_graduations.front()) + ":" + + DbU::getValueString(_graduations.back() ) + "] " + + getString(getSize()) + ">"; + } + + + string BaseGrid::Axis::_print () const + { + string repr = "["; + + vector::const_iterator it = _graduations.begin(); + vector::const_iterator end = _graduations.end(); + for ( ; it != end ; it++ ) { + repr += DbU::getValueString(*it); + if ( it+1 != end ) repr += ","; + } + repr += "]"; + + return repr; + } + + + Record* BaseGrid::Axis::_getRecord () const + { + Record* record = new Record ( _getString() ); + record->add ( getSlot ( "_graduations", &_graduations ) ); + + return record; + } + + +// ------------------------------------------------------------------- +// Class : "Katabatic::BaseGrid::Axis". + + + BaseGrid::BaseGrid () : _xGraduations() + , _yGraduations() + , _rows(0) + , _columns(0) + , _rawSize(0) + { } + + + void BaseGrid::_postCreate () + { } + + + BaseGrid::~BaseGrid () + { } + + + void BaseGrid::_preDestroy () + { } + + + Record* BaseGrid::_getRecord () const + { + Record* record = new Record ( _getString() ); + record->add ( getSlot ( "_xGraduations", &_xGraduations ) ); + record->add ( getSlot ( "_yGraduations", &_yGraduations ) ); + record->add ( getSlot ( "_rows" , &_rows ) ); + record->add ( getSlot ( "_columns" , &_columns ) ); + record->add ( getSlot ( "_rawSize" , &_rawSize ) ); + return record; + } + + +} // End of Katabatic namespace. diff --git a/katabatic/src/KatabaticEngine.cpp b/katabatic/src/KatabaticEngine.cpp new file mode 100644 index 00000000..543755f3 --- /dev/null +++ b/katabatic/src/KatabaticEngine.cpp @@ -0,0 +1,913 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2008, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | K a t a b a t i c - Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Module : "./KatabaticEngine.cpp" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#include +#include + +#include "hurricane/DebugSession.h" +#include "hurricane/Bug.h" +#include "hurricane/Error.h" +#include "hurricane/Warning.h" +#include "hurricane/DataBase.h" +#include "hurricane/Technology.h" +#include "hurricane/Layer.h" +#include "hurricane/BasicLayer.h" +#include "hurricane/NetExternalComponents.h" +#include "hurricane/Cell.h" + +#include "crlcore/Utilities.h" +#include "crlcore/AllianceFramework.h" + +#include "katabatic/Session.h" +#include "katabatic/AutoContact.h" +#include "katabatic/AutoSegment.h" +#include "katabatic/GCell.h" +#include "katabatic/GCellGrid.h" +#include "katabatic/KatabaticEngine.h" + + +namespace { + + using namespace Hurricane; + + + struct NetCompareByName { + inline bool operator() ( const Net* lhs, const Net* rhs ) const; + }; + + inline bool NetCompareByName::operator() ( const Net* lhs, const Net* rhs ) const + { + return lhs->getName() < rhs->getName(); + } + + + bool isTopAndBottomConnected ( Segment* segment, set& layers ) + { + ltrace(88) << "* Potential Null Length: " << segment << endl; + ltracein(88); + + Contact* source = dynamic_cast(segment->getSource()); + Contact* target = dynamic_cast(segment->getTarget()); + + layers.clear (); + + if ( source ) { + forEach ( Hook*, ihook, source->getBodyHook()->getSlaveHooks() ) { + ltrace(88) << "* Slave: " << (*ihook)->getComponent() << endl; + if ( (*ihook)->getComponent() == segment ) continue; + layers.insert ( (*ihook)->getComponent()->getLayer() ); + } + } + + if ( target ) { + forEach ( Hook*, ihook, target->getBodyHook()->getSlaveHooks() ) { + ltrace(88) << "* Slave: " << (*ihook)->getComponent() << endl; + if ( (*ihook)->getComponent() == segment ) continue; + layers.insert ( (*ihook)->getComponent()->getLayer() ); + } + } + + size_t supplemental = (layers.find(segment->getLayer()) == layers.end()) ? 1 : 0; + if ( source->getAnchor() || target->getAnchor() ) supplemental++; + +#if 0 + bool bottomConnect = false; + bool topConnect = false; + + if ( source ) { + if ( segment->getLayer() != source->getLayer() ) { + if ( source->getLayer()->getTop() == segment->getLayer() ) { + bottomConnect = true; + ltrace(88) << "Source bottom connected: " << source << endl; + } else { + topConnect = true; + ltrace(88) << "Source top connected: " << source << endl; + } + } + forEach ( Hook*, ihook, source->getBodyHook()->getSlaveHooks() ) { + ltrace(88) << "* Slave: " << (*ihook)->getComponent() << endl; + if ( (*ihook)->getComponent() == segment ) continue; + if ( (*ihook)->getComponent()->getLayer() == segment->getLayer() ) { + if ( bottomConnect ) topConnect = true; + else bottomConnect = true; + break; + } + } + } + + if ( target ) { + if ( segment->getLayer() != target->getLayer() ) { + if ( target->getLayer()->getTop() == segment->getLayer() ) { + bottomConnect = true; + ltrace(88) << "Target bottom connected: " << target << endl; + } else { + topConnect = true; + ltrace(88) << "Target top connected: " << target << endl; + } + } + forEach ( Hook*, ihook, target->getBodyHook()->getSlaveHooks() ) { + ltrace(88) << "* Slave: " << (*ihook)->getComponent() << endl; + if ( (*ihook)->getComponent() == segment ) continue; + if ( (*ihook)->getComponent()->getLayer() == segment->getLayer() ) { + if ( bottomConnect ) topConnect = true; + else bottomConnect = true; + break; + } + } + } +#endif + + ltraceout(88); + + //return topConnect && bottomConnect; + return layers.size()+supplemental > 2; + } + + +} // End of anonymous namespace. + + +namespace Katabatic { + + + using namespace std; + + using Hurricane::tab; + using Hurricane::ltracein; + using Hurricane::ltraceout; + using Hurricane::inltrace; + using Hurricane::DebugSession; + using Hurricane::ForEachIterator; + using Hurricane::Bug; + using Hurricane::Error; + using Hurricane::Warning; + using Hurricane::DataBase; + using Hurricane::Technology; + using Hurricane::Layer; + using Hurricane::BasicLayer; + using Hurricane::NetExternalComponents; + using CRL::AllianceFramework; + + +// ------------------------------------------------------------------- +// Global Variables. + + + const char* missingKTBT = + "%s :\n\n" + " Cell %s do not have any Katabatic (or not yet created).\n"; + + const char* badMethod = + "%s :\n\n" + " No method id %ud (Cell %s).\n"; + + const char* lookupFailed = + "Katabatic::Extension::getDatas(Segment*) :\n\n" + " Cannot find AutoSegment associated to %s (internal error).\n"; + + + +// ------------------------------------------------------------------- +// Class : "Katabatic::KatabaticEngine". + + + Name KatabaticEngine::_toolName = "Katabatic"; + + + KatabaticEngine* KatabaticEngine::get ( const Cell* cell ) + { + return static_cast(ToolEngine::get(cell,staticGetName())); + } + + + const Name& KatabaticEngine::staticGetName () + { + return _toolName; + } + + + const Name& KatabaticEngine::getName () const + { + return _toolName; + } + + + KatabaticEngine::KatabaticEngine ( const RoutingGauge* gauge, Cell* cell ) + : ToolEngine (cell) + , _timer () + , _state (StateCreation) + , _destroyBaseContact(true) + , _destroyBaseSegment(false) + , _demoMode (false) + , _warnGCellOverload (false) + , _configuration (gauge) + , _gcellGrid (NULL) + , _routingNets () + { } + + + void KatabaticEngine::_postCreate () + { + ToolEngine::_postCreate (); + } + + + void KatabaticEngine::createDetailedGrid () + { + _gcellGrid = GCellGrid::create ( this ); + Session::revalidate (); + } + + + KatabaticEngine* KatabaticEngine::create ( const RoutingGauge* gauge, Cell* cell ) + { + ltrace(90) << "KatabaticEngine::create() - " << cell << endl; + + KatabaticEngine* katabatic = new KatabaticEngine ( gauge, cell ); + + katabatic->_postCreate (); + + return katabatic; + } + + + KatabaticEngine::~KatabaticEngine () + { } + + + void KatabaticEngine::_preDestroy () + { + ltrace(90) << "Katabatic::_preDestroy ()" << endl; + ltracein(90); + + if ( getState() < Katabatic::StateGutted ) + setState ( Katabatic::StatePreDestroying ); + + _gutKatabatic (); + _state = StateGutted; + + ltrace(89) << "About to delete base class ToolEngine." << endl; + ToolEngine::_preDestroy (); + + ltrace(89) << "Exiting Katabatic::_preDestroy()." << endl; + ltraceout(90); + + cmess2 << " - GCells := " << GCell::getAllocateds() << endl; + cmess2 << " - AutoContacts := " << AutoContact::getAllocateds() << endl; + cmess2 << " - AutoSegments := " << AutoSegment::getAllocateds() << endl; + cmess2 << " - SegmentEnds := " << AutoContact::getSegmentEndAllocateds() << endl; + } + + + void KatabaticEngine::_gutKatabatic () + { + Session::open ( this ); + + _destroyBaseContact = false; + _destroyBaseSegment = false; + + if ( _state == StateDriving ) { + ltracein(90); + ltrace(90) << "Saving AutoContacts/AutoSegments." << endl; + + cmess1 << " o Driving Hurricane data-base." << endl; + cmess1 << " - AutoSegments := " << AutoSegment::getAllocateds() << endl; + cmess1 << " - AutoContacts := " << AutoContact::getAllocateds() << endl; + + forEach ( Net*, inet, _cell->getNets() ) + _saveNet ( *inet ); + + //_autoContactLut.clear (); + + ltraceout(90); + } + + if ( _state < StateGutted ) { + ltrace(90) << "Gutting Katabatic." << endl; + _state = StateGutted; + _destroyBaseContact = true; + + _destroyAutoSegments (); + _destroyAutoContacts (); + + if ( _gcellGrid ) { + _gcellGrid->destroy (); + _gcellGrid = NULL; + } + } + + Session::close (); + } + + + AutoSegment* KatabaticEngine::_lookup ( Segment* segment ) const + { + AutoSegmentLut::const_iterator it = _autoSegmentLut.find ( segment ); + if ( it == _autoSegmentLut.end() ) return NULL; + + return (*it).second; + } + + + void KatabaticEngine::_link ( AutoSegment* autoSegment ) + { + if ( _state > StateActive ) return; + _autoSegmentLut [ autoSegment->getSegment() ] = autoSegment; + } + + + void KatabaticEngine::_unlink ( AutoSegment* autoSegment ) + { + if ( _state > StateDriving ) return; + + AutoSegmentLut::iterator it = _autoSegmentLut.find ( autoSegment->getSegment() ); + if ( it != _autoSegmentLut.end() ) + _autoSegmentLut.erase ( it ); + } + + + AutoContact* KatabaticEngine::_lookup ( Contact* contact ) const + { + AutoContactLut::const_iterator it = _autoContactLut.find ( contact ); + if ( it == _autoContactLut.end() ) { + return NULL; + } + return (*it).second; + } + + + void KatabaticEngine::_link ( AutoContact* autoContact ) + { + if ( _state > StateActive ) return; + _autoContactLut [ autoContact->base() ] = autoContact; + } + + + void KatabaticEngine::_unlink ( AutoContact* autoContact ) + { + if ( _state > StateActive ) return; + + AutoContactLut::iterator it = _autoContactLut.find ( autoContact->getContact() ); + if ( it != _autoContactLut.end() ) + _autoContactLut.erase ( it ); + } + + + void KatabaticEngine::xmlWriteGCellGrid ( const string& fileName ) + { + ofstream file ( fileName.c_str() ); + + xmlWriteGCellGrid ( file ); + + file.close (); + } + + + void KatabaticEngine::xmlWriteGCellGrid ( ostream& o ) + { + if ( _gcellGrid ) + _gcellGrid->_xmlWrite ( o ); + else + cerr << Error("Cannot dump GCellGrid: not allocated yet.") << endl; + } + + + void KatabaticEngine::startMeasures () + { + _timer.resetIncrease (); + _timer.start (); + } + + + void KatabaticEngine::stopMeasures () + { + _timer.stop (); + } + + + void KatabaticEngine::printMeasures () const + { + cmess1 << " - Done in " << Timer::getStringTime(_timer.getCombTime()) + << " [+" << Timer::getStringMemory(_timer.getIncrease()) << "]." << endl; + cmess1 << " (raw measurements : " << _timer.getCombTime() + << "s [+" << (_timer.getIncrease()>>10) << "Ko/" + << (_timer.getMemorySize()>>10) << "Ko])" << endl; + } + + + bool KatabaticEngine::_check ( const char* message ) const + { + bool coherency = true; + if ( message ) + cerr << " o checking Katabatic DB (" << message << ")." << endl; + + AutoSegmentLut::const_iterator it = _autoSegmentLut.begin (); + AutoSegmentLut::const_iterator end = _autoSegmentLut.end (); + for ( ; it != end ; it++ ) + coherency = coherency && it->second->_check(); + + vector::const_iterator itGCell = _gcellGrid->getGCellVector()->begin(); + vector::const_iterator endGCell = _gcellGrid->getGCellVector()->end(); + for ( ; itGCell != endGCell ; itGCell++ ) { + vector::const_iterator itAutoContact = (*itGCell)->getContacts()->begin(); + vector::const_iterator endAutoContact = (*itGCell)->getContacts()->end(); + for ( ; itAutoContact != endAutoContact ; itAutoContact++ ) { + (*itAutoContact)->checkTopology (); + } + } + + if ( message ) + cerr << " - completed." << endl; + + return coherency; + } + + + void KatabaticEngine::refresh ( bool openSession ) + { + if ( _gcellGrid ) _gcellGrid->updateContacts ( openSession ); + } + + + void KatabaticEngine::_destroyAutoSegments () + { + ltrace(90) << "Katabatic::_destroyAutoSegments ()" << endl; + + size_t expandeds = 0; + + AutoSegmentLut::iterator it = _autoSegmentLut.begin (); + AutoSegmentLut::iterator end = _autoSegmentLut.end (); + for ( ; it != end ; it++ ) { + if ( !it->second->isCollapsed() ) expandeds++; + it->second->destroy (); + } + if ( _state == StateDriving ) + cerr << " - Expandeds := " << expandeds << endl; + + _autoSegmentLut.clear (); + } + + + void KatabaticEngine::_destroyAutoContacts () + { + ltrace(90) << "Katabatic::_destroyAutoContacts ()" << endl; + + AutoContactLut::iterator it = _autoContactLut.begin (); + AutoContactLut::iterator end = _autoContactLut.end (); + for ( ; it != end ; it++ ) + it->second->destroy (); + + _autoContactLut.clear (); + } + + + Configuration* KatabaticEngine::getConfiguration () + { return &_configuration; } + + + void KatabaticEngine::loadGlobalRouting ( unsigned int method, vector& nets ) + { + if ( _state < StateGlobalLoaded ) + throw Error ("KatabaticEngine::loadGlobalRouting() : global routing not present yet."); + + if ( _state > StateGlobalLoaded ) + throw Error ("KatabaticEngine::loadGlobalRouting() : global routing already loaded."); + + AllianceFramework* af = AllianceFramework::get (); + if ( nets.empty() ) { + forEach ( Net*, net, _cell->getNets() ) { + if ( net->getType() == Net::Type::POWER ) continue; + if ( net->getType() == Net::Type::GROUND ) continue; + if ( net->getType() == Net::Type::CLOCK ) continue; + if ( af->isOBSTACLE(net->getName()) ) continue; + _routingNets.push_back ( *net ); + } + } else { + vector::iterator it = nets.begin(); + for ( ; it != nets.end() ; it++ ) { + if ( ( (*it)->getType() == Net::Type::POWER ) + || ( (*it)->getType() == Net::Type::GROUND ) + || ( (*it)->getType() == Net::Type::CLOCK ) + || ( af->isOBSTACLE((*it)->getName()) ) ) { + cerr << Warning("%s is not a routable net, removed from set.",getString(*it).c_str()) << endl; + } else + _routingNets.push_back ( *it ); + } + } + + switch ( method ) { + case LoadGrByNet: _loadGrByNet(); break; + case LoadGrByGCell: + default: + throw Error ( badMethod + , "Katabatic::loadGlobalRouting()" + , method + , getString(_cell).c_str() + ); + } + + _state = StateActive; + } + + + void KatabaticEngine::finalizeLayout () + { + ltrace(90) << "Katabatic::finalizeLayout()" << endl; + if ( _state > StateDriving ) return; + + _state = StateDriving; + + startMeasures (); + _gutKatabatic (); + stopMeasures (); + printMeasures (); + + _state = StateGutted; + } + + + void KatabaticEngine::_alignate ( Net* net ) + { + DebugSession::open ( net, 99 ); + + ltrace(100) << "Katabatic::_alignate ( " << net << " )" << endl; + ltracein(99); + + //cmess2 << " - " << getString(net) << endl; + + set exploredSegments; + vector unexploreds; + vector aligneds; + + forEach ( Component*, icomponent, net->getComponents() ) { + Segment* segment = dynamic_cast(*icomponent); + if ( segment ) { + AutoSegment* seedSegment = Session::lookup ( segment ); + if ( seedSegment ) unexploreds.push_back ( seedSegment ); + } + } + sort ( unexploreds.begin(), unexploreds.end(), AutoSegment::CompareCanonical() ); + + for ( size_t i=0 ; igetSegment()) == exploredSegments.end() ) { + ltrace(99) << "New chunk from: " << seedSegment << endl; + aligneds.push_back ( seedSegment ); + + forEach ( AutoSegment*, collapsed, seedSegment->getCollapseds() ) { + ltrace(99) << "Aligned: " << *collapsed << endl; + aligneds.push_back ( *collapsed ); + exploredSegments.insert ( collapsed->getSegment() ); + } + + ltracein(99); + sort ( aligneds.begin(), aligneds.end(), AutoSegment::CompareCanonical() ); + + ltrace(99) << "Seed: " << (void*)aligneds[0]->base() << " " << aligneds[0] << endl; + for ( size_t j=1 ; jbase()) << " " << aligneds[j] << endl; + } + + ltrace(159) << "Align on " << aligneds[0] + << " " << DbU::getLambda(aligneds[0]->getAxis()) << endl; + aligneds[0]->setAxis ( aligneds[0]->getAxis(), Realignate|AxisSet ); + aligneds.clear (); + + ltraceout(99); + } + } + + ltraceout(99); + + DebugSession::close (); + } + + + void KatabaticEngine::_canonize ( Net* net ) + { + DebugSession::open ( net, 99 ); + + ltrace(100) << "Katabatic::_canonize ( " << net << " )" << endl; + ltracein(99); + + //cmess2 << " - " << getString(net) << endl; + + set exploredSegments; + vector unexploreds; + vector aligneds; + + forEach ( Component*, icomponent, net->getComponents() ) { + Segment* segment = dynamic_cast(*icomponent); + if ( segment ) { + AutoSegment* seedSegment = Session::lookup ( segment ); + if ( seedSegment ) + unexploreds.push_back ( seedSegment ); + } + } + sort ( unexploreds.begin(), unexploreds.end(), AutoSegment::CompareCanonical() ); + + for ( size_t i=0 ; igetSegment()) == exploredSegments.end() ) { + ltrace(99) << "New chunk from: " << (void*)seedSegment->base() << ":" << seedSegment << endl; + aligneds.push_back ( seedSegment ); + + bool isCanonicalLocal = seedSegment->isLocal(); + forEach ( AutoSegment*, collapsed, seedSegment->getCollapseds() ) { + ltrace(99) << "Aligned: " << (void*)collapsed->base() << ":" << *collapsed << endl; + aligneds.push_back ( *collapsed ); + exploredSegments.insert ( collapsed->getSegment() ); + + if ( collapsed->isGlobal() ) isCanonicalLocal = false; + } + + ltracein(99); + sort ( aligneds.begin(), aligneds.end(), AutoSegment::CompareCanonical() ); + + aligneds[0]->setCanonical ( true ); + aligneds[0]->setCanonicalLocal ( isCanonicalLocal ); + ltrace(99) << "Canonical: " << (void*)aligneds[0]->base() << ":" << aligneds[0] << endl; + + for ( size_t j=1 ; jsetCanonical ( false ); + ltrace(99) << "Secondary: " << (void*)(aligneds[j]->base()) << ":" << aligneds[j] << endl; + } + + ltrace(159) << "Align on " << aligneds[0] + << " " << DbU::getLambda(aligneds[0]->getAxis()) << endl; + aligneds[0]->setAxis ( aligneds[0]->getAxis(), Realignate|AxisSet ); + aligneds.clear (); + ltraceout(99); + } + } + + ltraceout(99); + + DebugSession::close (); + } + + + void KatabaticEngine::_computeNetTerminals ( Net* net ) + { + DebugSession::open ( net, 88 ); + + ltrace(100) << "Katabatic::_computeNetTerminals ( " << net << " )" << endl; + ltracein(99); + + vector segments; + forEach ( Segment*, segment, net->getSegments() ) { + AutoSegment* autoSegment = Session::lookup ( *segment ); + if ( !autoSegment ) continue; + if ( autoSegment->isInvalidated() ) autoSegment->_computeTerminal(); + } + + ltraceout(99); + + DebugSession::close (); + } + + + void KatabaticEngine::_saveNet ( Net* net ) + { + DebugSession::open ( net, 88 ); + + ltrace(90) << "Katabatic::_saveNet() " << net << endl; + ltracein(90); + + vector autoContacts; + + forEach ( Contact*, icontact, net->getContacts() ) { + AutoContact* autoContact = Session::lookup ( *icontact ); + if ( autoContact ) + autoContacts.push_back ( autoContact ); + } + + ltrace(90) << "Breaking/Deleting AutoContacts." << endl; + vector::iterator it = autoContacts.begin(); + for ( ; it != autoContacts.end() ; it++ ) { + ltrace(90) << "Examining " << (void*)*it << " " << (*it) << endl; + ltracein(90); + ltrace(90) << "In " << (void*)((*it)->getGCell()) << " - " + << (*it)->getGCell() << endl; + + (*it)->breakUp (); + // AutoContacts are destroyed through the tool. + //(*it)->destroy (); + + ltraceout(90); + } + + + ltrace(90) << "Deleting zero-length segments." << endl; + + vector nullSegments; + set connectedLayers; + + forEach ( Segment*, segment, net->getSegments() ) { + if ( segment->getLength() ) { + if ( net->isExternal() ) { + NetExternalComponents::setExternal ( *segment ); + } + continue; + } + + if ( not isTopAndBottomConnected(*segment,connectedLayers) ) { + nullSegments.push_back ( *segment ); + ltrace(90) << "* Null Length: " << *segment << endl; + } + } + + setDestroyBaseSegment ( true ); + for ( size_t i = 0 ; i < nullSegments.size() ; i++ ) { + Contact* source = dynamic_cast(nullSegments[i]->getSource()); + Contact* target = dynamic_cast(nullSegments[i]->getTarget()); + + if ( source->getAnchor() ) { + if ( target->getAnchor() ) { + continue; + //cerr << Bug("Both source & target are anchored while deleting zero-length segment:\n" + // " %s.",getString(nullSegments[i]).c_str()) << endl; + } else + swap ( source, target ); + } + + ltrace(90) << "Deleting: " << nullSegments[i] << endl; + if ( isTopAndBottomConnected(nullSegments[i],connectedLayers) ) { + ltrace(90) << "Deletion cancelled, no longer top or bottom connected." << endl; + continue; + } + + ltrace(90) << "* Source: " << (void*)source << " " << source << endl; + ltrace(90) << "* Target: " << (void*)target << " " << target << endl; + + const Layer* layer = DataBase::getDB()->getTechnology() + ->getViaBetween ( *connectedLayers.begin(), *connectedLayers.rbegin() ); + + ltrace(90) << *connectedLayers.begin() << " + " << *connectedLayers.rbegin() << endl; + ltrace(90) << "* Shrink layer: " << layer << endl; + if ( !layer ) { + cerr << Error("NULL contact layer while deleting %s." + ,getString(nullSegments[i]).c_str()) << endl; + continue; + } + + Session::lookup ( nullSegments[i] )->destroy (); + + vector slaveHooks; + Hook* masterHook = source->getBodyHook()->getPreviousMasterHook(); + + while ( masterHook->getNextHook() != source->getBodyHook() ) { + slaveHooks.push_back ( masterHook->getNextHook() ); + ltrace(90) << "* detach: " + << (void*)masterHook->getNextHook()->getComponent() + << " " << masterHook->getNextHook()->getComponent() << endl; + masterHook->getNextHook()->detach (); + } + source->destroy (); + + masterHook = target->getBodyHook (); + for ( size_t j=0 ; j < slaveHooks.size() ; j++ ) { + slaveHooks[j]->attach ( masterHook ); + } + + ltrace(90) << (void*)target << " " << target << " setLayer: " << layer << endl; + target->setLayer ( layer ); + } + setDestroyBaseSegment ( false ); + + ltraceout(90); + DebugSession::close (); + } + + + void KatabaticEngine::_check ( Net* net ) const + { + ltrace(200) << "Checking " << net << endl; + ltracein(200); + forEach ( Segment*, isegment, net->getComponents().getSubSet() ) { + AutoSegment* autoSegment = _lookup ( *isegment ); + ltrace(200) << autoSegment << endl; + if ( autoSegment ) { + AutoContact* autoContact = autoSegment->getAutoSource(); + ltrace(200) << autoContact << endl; + if ( autoContact ) autoContact->checkTopology (); + + autoContact = autoSegment->getAutoTarget(); + ltrace(200) << autoContact << endl; + if ( autoContact ) autoContact->checkTopology (); + } + } + ltraceout(200); + } + + + void KatabaticEngine::_print ( Net* net ) const + { + cerr << "Order: Components of " << net << endl; + + vector segments; + forEach ( Segment*, isegment, net->getComponents().getSubSet() ) { + AutoSegment* autoSegment = _lookup ( *isegment ); + if ( autoSegment ) + segments.push_back ( autoSegment ); + } + + sort ( segments.begin(), segments.end(), AutoSegment::CompareCanonical() ); + + Interval constraints; + for ( size_t i=0 ; igetConstraints ( constraints ); + cerr << "Order: " << i + << " " << segments[i]->isCanonical() + << " " << segments[i]->isCollapsed() + << " " << setw(6) << DbU::getValueString(segments[i]->getSourceU()) + << " " << setw(6) << DbU::getValueString(segments[i]->getLength()) + << " " << segments[i]->isGlobal() + << " " << segments[i]->isTerminal() + << " " << segments[i]->isHorizontal() + << " " << setw(6) << DbU::getValueString(segments[i]->getAxis()) + << " " << segments[i]->isFixed() + << " [" << DbU::getValueString(constraints.getVMin()) + << ":" << DbU::getValueString(constraints.getVMax()) + << "] " << segments[i] + << endl; + } + } + + + void KatabaticEngine::_print () const + { +#if defined(CHECK_DETERMINISM) + cerr << "Order: Nets components." << endl; +#endif + + vector nets; + forEach ( Net*, inet, getCell()->getNets() ) { + nets.push_back ( *inet ); + } + + sort ( nets.begin(), nets.end(), NetCompareByName() ); + +#if defined(CHECK_DETERMINISM) + for ( size_t i=0 ; igetName () << " " << _configuration.getRoutingGauge()->getName() << ">"; + + return ( os.str() ); + } + + + Record* KatabaticEngine::_getRecord () const + { + Record* record = ToolEngine::_getRecord (); + record->add ( getSlot ( "_demoMode" , _demoMode ) ); + record->add ( getSlot ( "_state" , _state ) ); + record->add ( getSlot ( "_configuration" , &_configuration ) ); + record->add ( getSlot ( "_gcellGrid" , _gcellGrid ) ); + record->add ( getSlot ( "_routingNets" , &_routingNets ) ); + record->add ( getSlot ( "_autoContactLut" , &_autoContactLut ) ); + record->add ( getSlot ( "_autoSegmentLut" , &_autoSegmentLut ) ); + + return ( record ); + } + + +} // End of Katabatic namespace. diff --git a/katabatic/src/LayerAssign.cpp b/katabatic/src/LayerAssign.cpp new file mode 100644 index 00000000..c499a145 --- /dev/null +++ b/katabatic/src/LayerAssign.cpp @@ -0,0 +1,282 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | K a t a b a t i c - Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Module : "./LayerAssign.cpp" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#include +#include + +#include "hurricane/Bug.h" +#include "hurricane/Warning.h" +#include "hurricane/DebugSession.h" +#include "hurricane/Net.h" +#include "hurricane/NetExternalComponents.h" +#include "hurricane/Layer.h" +#include "hurricane/RoutingPad.h" +#include "hurricane/Pad.h" +#include "hurricane/Plug.h" +#include "hurricane/Instance.h" +#include "hurricane/Vertical.h" +#include "hurricane/Horizontal.h" + +#include "crlcore/RoutingGauge.h" + +#include "katabatic/AutoContact.h" +#include "katabatic/AutoSegment.h" +#include "katabatic/GCellGrid.h" +#include "katabatic/KatabaticEngine.h" + + +namespace Katabatic { + + using Hurricane::DebugSession; + using Hurricane::ltracein; + using Hurricane::ltraceout; + using Hurricane::ForEachIterator; + using Hurricane::Warning; + + + void KatabaticEngine::_splitContactsOfNet ( Net* net ) + { + DebugSession::open ( net, 90 ); + + ltrace(100) << "Katabatic::_splitContactsOfNet ( " << net << " )" << endl; + ltracein(99); + + Session::invalidate ( net ); + set globalContacts; + + forEach ( Segment*, isegment, net->getSegments() ) { + if ( ( (*isegment)->getLayer() == Session::getRoutingLayer(3) ) + || ( (*isegment)->getLayer() == Session::getRoutingLayer(4) ) ) { + AutoContact* contact = Session::lookup ( dynamic_cast((*isegment)->getSource()) ); + if ( contact ) globalContacts.insert ( contact ); + + contact = Session::lookup ( dynamic_cast((*isegment)->getTarget()) ); + if ( contact ) globalContacts.insert ( contact ); + } + } + + set::iterator it = globalContacts.begin(); + for ( ; it != globalContacts.end() ; it++ ) { + (*it)->split (); + } + + ltraceout(99); + + DebugSession::close (); + } + + + void KatabaticEngine::_desaturate ( unsigned int depth, set& globalNets ) + { + if ( depth+2 >= Session::getRoutingGauge()->getDepth() ) { + cerr << Warning("Katabatic::_desaturate(): %s, no remaining upper layers." + ,getString(Session::getRoutingGauge()->getRoutingLayer(depth)->getName()).c_str() + ) << endl; + return; + } + + cmess1 << " o Desaturate layer " + << Session::getRoutingGauge()->getRoutingLayer(depth)->getName() << endl; + + vector gcells = *(_gcellGrid->getGCellVector()); + + bool optimized = true; + while ( optimized ) { + optimized = false; + sort ( gcells.begin(), gcells.end(), GCell::CompareByDensity(depth) ); + for ( size_t i=0 ; iisSaturated ( depth ) ) break; + + optimized = gcells[i]->stepDesaturate ( depth, globalNets ); + if ( optimized ) break; + } + } + } + + + void KatabaticEngine::_layerAssignByLength ( Net* net, unsigned long& total, unsigned long& global, set& globalNets ) + { + DebugSession::open ( net, 90 ); + + ltrace(100) << "Katabatic::_layerAssignByLength ( " << net << " )" << endl; + ltracein(99); + + bool isGlobal = false; + set globalContacts; + + forEach ( Segment*, isegment, net->getSegments() ) { + total++; + if ( (*isegment)->getLength() > getGlobalThreshold() ) { + if ( !isGlobal ) { + isGlobal = true; + globalNets.insert ( net ); + //cmess2 << " - " << getString(net) << endl; + } + + global++; + if ( (*isegment)->getLayer() == Session::getRoutingLayer(1) ) (*isegment)->setLayer ( Session::getRoutingLayer(3) ); + if ( (*isegment)->getLayer() == Session::getRoutingLayer(2) ) (*isegment)->setLayer ( Session::getRoutingLayer(4) ); + } + } + + ltraceout(99); + + DebugSession::close (); + } + + + void KatabaticEngine::_layerAssignByLength ( unsigned long& total, unsigned long& global, set& globalNets ) + { + cmess1 << " o Assign Layer (simple wirelength)." << endl; + + for ( size_t i=0 ; i < _routingNets.size() ; i++ ) + _layerAssignByLength ( _routingNets[i], total, global, globalNets ); + } + + + void KatabaticEngine::_layerAssignByTrunk ( Net* net, unsigned long& total, unsigned long& global, set& globalNets ) + { + DebugSession::open ( net, 90 ); + + ltrace(100) << "Katabatic::_layerAssignByTrunk ( " << net << " )" << endl; + ltracein(99); + + bool isGlobal = false; + unsigned long netGlobal = 0; + unsigned long netTotal = 0; + set globalContacts; + + forEach ( Segment*, isegment, net->getSegments() ) { + netTotal++; + + if ( (*isegment)->getLength() > getGlobalThreshold() ) { + isGlobal = true; + netTotal = 0; + globalNets.insert ( net ); + break; + } + } + + if ( isGlobal ) { + //cmess2 << " - " << getString(net) << endl; + + forEach ( Segment*, isegment, net->getSegments() ) { + netTotal++; + + AutoSegment* autoSegment = Session::lookup ( *isegment ); + if ( autoSegment && !autoSegment->isTerminal() ) { + netGlobal++; + + ltrace(99) << "Migrate to M4/M5: " << autoSegment << endl; + if ( autoSegment->isHorizontal() ) autoSegment->setLayer ( Session::getRoutingLayer(3) ); + if ( autoSegment->isVertical () ) autoSegment->setLayer ( Session::getRoutingLayer(4) ); + } + } + } + + total += netTotal; + global += netGlobal; + + ltraceout(99); + + DebugSession::close (); + } + + + void KatabaticEngine::_layerAssignByTrunk ( unsigned long& total, unsigned long& global, set& globalNets ) + { + cmess1 << " o Assign Layer (whole net trunk)." << endl; + + for ( size_t i=0 ; i < _routingNets.size() ; i++ ) + _layerAssignByTrunk ( _routingNets[i], total, global, globalNets ); + } + + + void KatabaticEngine::layerAssign ( unsigned int method ) + { + set globalNets; + + unsigned long total = 0; + unsigned long global = 0; + + startMeasures (); + Session::open ( this ); + + switch ( method ) { + case LayerAssignByLength: _layerAssignByLength(total,global,globalNets); break; + case LayerAssignByTrunk: _layerAssignByTrunk (total,global,globalNets); break; + case NoNetLayerAssign: break; + default: + stopMeasures (); + Session::close (); + throw Error ( badMethod + , "Katabatic::layerAssign()" + , method + , getString(_cell).c_str() + ); + } + + set::iterator inet = globalNets.begin(); + for ( ; inet != globalNets.end() ; inet++ ) + _splitContactsOfNet ( *inet ); + globalNets.clear (); + + Session::revalidate (); + + for ( int i=0 ; i < 3 ; i++ ) { + _desaturate ( 1, globalNets ); + _desaturate ( 2, globalNets ); + + globalNets.clear (); + + Session::revalidate (); + if ( !_gcellGrid->updateDensity () ) break; + } + //refresh ( false ); + +#if defined(CHECK_DATABASE) + _check ( "after layer assignment" ); +#endif +#if defined(CHECK_DETERMINISM) + for ( size_t i=0 ; i < _routingNets.size() ; i++ ) + _print ( _routingNets[i] ); +#endif + + Session::setWarnGCellOverload ( true ); + _gcellGrid->checkDensity (); + + Session::close (); + + stopMeasures (); + printMeasures (); + + cmess2 << " - Total segments : " << total << endl; + cmess2 << " - Global segments : " << global << endl; + cmess2 << " - Ratio : " + << ((float)global/(float)total)*100.0 << "%." << endl; + } + + +} // End of Katabatic namespace. diff --git a/katabatic/src/LoadGrByNet.cpp b/katabatic/src/LoadGrByNet.cpp new file mode 100644 index 00000000..bca0d66e --- /dev/null +++ b/katabatic/src/LoadGrByNet.cpp @@ -0,0 +1,2378 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2008, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | K a t a b a t i c - Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Module : "./LoadGrByNet.cpp" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#include +#include + +#include "hurricane/Bug.h" +#include "hurricane/Error.h" +#include "hurricane/Warning.h" +#include "hurricane/DebugSession.h" +#include "hurricane/Layer.h" +#include "hurricane/Technology.h" +#include "hurricane/DataBase.h" +#include "hurricane/Net.h" +#include "hurricane/NetExternalComponents.h" +#include "hurricane/RoutingPad.h" +#include "hurricane/RoutingPads.h" +#include "hurricane/Pad.h" +#include "hurricane/Plug.h" +#include "hurricane/Instance.h" +#include "hurricane/Vertical.h" +#include "hurricane/Horizontal.h" + +#include "crlcore/RoutingGauge.h" + +#include "katabatic/AutoContact.h" +#include "katabatic/AutoSegment.h" +#include "katabatic/GCellGrid.h" +#include "katabatic/KatabaticEngine.h" + + +namespace { + + /*! \defgroup loadGlobalRouting 2. Global Routing Loading (internal) + * + * This module documents how the global routing built by \c Knik is + * loaded into the \c Katabatic data-base. It is intented for developpers + * only. + */ + + //! \addtogroup loadGlobalRouting + //! \{ + + /*! \enum GCellConfiguration::Topology + * set of flags used to build the topology of a GCell. + * \see GCellConfiguration::_topology + */ + + /*! \var GCellConfiguration::GLOBAL_VERTICAL_END + * The GCell has exactly one global, which is either from the north + * or south side. + */ + + /*! \var GCellConfiguration::GLOBAL_HORIZONTAL_END + * The GCell has exactly one global, which is either from the east + * or west side. + */ + + /*! \var GCellConfiguration::GLOBAL_HORIZONTAL + * The GCell has exactly two global, which are east \& west + * (straight horizontal). + */ + + /*! \var GCellConfiguration::GLOBAL_VERTICAL + * The GCell has exactly two global, which are north \& south + * (straight vertical). + */ + + /*! \var GCellConfiguration::GLOBAL_BEND + * The GCell has exactly two global, which are perpandicular. + * For example : east \& south. + */ + + /*! \var GCellConfiguration::GLOBAL_FORK + * The GCell has three or four globals. + */ + + /*! \var GCellConfiguration::GLOBAL_END + * Mask value : the GCell has one global, either vertical or horizontal. + */ + + /*! \var GCellConfiguration::GLOBAL_SPLIT + * Mask value used by some functions as a mask argument to + * _GCell_GlobalContacts() tell if AutoContact must be splitted or not. + * + */ + + + /*! \union GCellConfiguration::UState + * \brief State of the GCellConfiguration (\b internal). + * + * This union allows the GCellConfiguration to be accessed as + * separate fields : + *

      + *
    • \b UState.fields.globals : number of \b GLOBAL AutoSegment. + *
    • \b UState.fields.L1 : number of terminal in \e metal1. + *
    • \b UState.fields.L2 : number of terminal in \e metal2. + *
    • \b UState.fields.L3 : number of terminal in \e metal3. + *
    + * And as a unique integer value : + *
      + *
    • \b UState.state : composite variable, to be used in \c switches. + *
    + * This implementation mixing \c union and \c struct should be portable, + * I've faith in compilers :-) + * + * \see GCellConfiguration. + */ + + + /*! \class GCellConfiguration + * \brief Build the wiring for a Net inside a GCell (\b internal). + * + * \see \ref buildRules. + */ + + /*! \var UState GCellConfiguration::_state; + * An integer value summarizing the state of the \c GCell. It counts + * global wires, and \c Plug/Pin by layer. + */ + + /*! \var unsigned int GCellConfiguration::_topology; + * An integer value summarizing the topology of the globals AutoSegment + * of the GCell. + * + * \see Topology, _GCell_GlobalContacts(). + */ + + /*! \var Net* GCellConfiguration::_net; + * The current \c Net we are building (guessed from the \c fromSplitter). + */ + + /*! \var CGell* GCellConfiguration::_gcell; + * The \c GCell in which we are (guessed from the \c GCell). + */ + + /*! \var unsigned int GCellConfiguration::_fromHook; + * By which side of the \c GCell are we coming in. + */ + + /*! \var AutoContact* GCellConfiguration::_sourceContact; + * The AutoContact from the previously processed \c GCell. + */ + + /*! \var AutoContact* GCellConfiguration::_southWestContact; + * The South West AutoContact of the current \c GCell. + */ + + /*! \var AutoContact* GCellConfiguration::_northEastContact; + * The North East AutoContact of the current \c GCell. + * (may be equal to _southWestContact, if there's only one AutoContact). + */ + + /*! \var Hook* GCellConfiguration::_east; + * The SplitterContact of the east side of the \c GCell (may be \c NULL + * if none is present). + */ + + /*! \var Hook* GCellConfiguration::_west; + * The SplitterContact of the west side of the \c GCell (may be \c NULL + * if none is present). + */ + + /*! \var Hook* GCellConfiguration::_north; + * The SplitterContact of the north side of the \c GCell (may be \c NULL + * if none is present). + */ + + /*! \var Hook* GCellConfiguration::_south; + * The SplitterContact of the south side of the \c GCell (may be \c NULL + * if none is present). + */ + + /*! \var vector GCellConfiguration::_routingPads; + * The table of \c RoutingPad associated to \c Plug/Pin. + */ + + /*! \function GCellConfiguration::GCellConfiguration ( GCellGrid* gcellGrid, Hook* fromHook, AutoContact* sourceContact=NULL ) + * \param gcellGrid The \c GCell where we are. + * \param fromHook From where do we enter the \c GCell. + * \param sourceContact The global routing AutoContact from the previously + * processed \c GCell. May be \c NULL for the first + * \c GCell of a \c Net. + * + * Constructor (see \ref secUsingGCell). + */ + + /*! \function unsigned int GCellConfiguration::getStateG () const; + * \return The composite state value. + */ + + /*! \function void GCellConfiguration::construct ( ForkStack& forks ); + * Build the GCell wires (see \ref secUsingGCell). + */ + + /*! \function void GCellConfiguration::_GCell_GlobalContacts ( bool split, AutoContact* southWestContact=NULL, AutoContact* northEastContact=NULL ); + * create AutoContact needed for global wiring. If \e split is + * \False one contact is created and set into both _southWestContact + * _northEastContact. Otherwise two separated contacts are created. + * + * \see GCellConfiguration::_topology, Topology. + */ + + /*! \function AutoContact* GCellConfiguration::_GCell_rp_L2H ( RoutingPad* rp, AutoContact* target=NULL, bool hcollapse=false ) + * \param rp Source RoutingPad. + * \param target Ending AutoContact (created if needed). + * \param hcollapse collapse the horizontal AutoSegment. + * + * Draw horizontal AutoSegment from the center of a RoutingPad. + * \image html GCellConfiguration-10.png "_GCell_rp_L2H" + * \image latex GCellConfiguration-10.pdf "_GCell_rp_L2H" width=0.2\textwidth + */ + + /*! \function AutoContact* GCellConfiguration::_GCell_rp_L2H_L3V ( RoutingPad* rp, AutoContact* target=NULL, bool hcollapse=false, bool vcollapse=false ) + * \param rp Source RoutingPad. + * \param target Ending AutoContact (created if needed). + * \param hcollapse collapse the horizontal AutoSegment. + * \param vcollapse collapse the vertical AutoSegment. + * + * Draw a simple bend from the center of a RoutingPad. The horizontal + * AutoSegment comes first (starting from the source). Both AutoSegments + * are flagged as \e terminal. + * \image html GCellConfiguration-11.png "_GCell_rp_L2H_L3V" + * \image latex GCellConfiguration-11.pdf "_GCell_rp_L2H_L3V" width=0.2\textwidth + */ + + /*! \function AutoContact* GCellConfiguration::_GCell_rp_StairCaseH ( RoutingPad* rp1, RoutingPad* rp2 ) + * + * Draw an horizontal staircase (\b HVH) between two RoutingPad. + * \image html GCellConfiguration-12.png "_GCell_rp_StairCaseH" + * \image latex GCellConfiguration-12.pdf "_GCell_rp_StairCaseH" width=0.4\textwidth + */ + + /*! \function AutoContact* GCellConfiguration::_GCell_rp_StairCaseV ( RoutingPad* rp1, RoutingPad* rp2 ) + * Draw a vertical staircase (\b VHV) between two RoutingPad. + * \image html GCellConfiguration-13.png "_GCell_rp_StairCaseV" + * \image latex GCellConfiguration-13.pdf "_GCell_rp_StairCaseV" width=0.1\textwidth + */ + + /*! \function AutoContact* GCellConfiguration::_GCell_L3V_L2H ( AutoContact* source, AutoContact* target=NULL, bool hcollapse=false, bool vcollapse=false, bool terminal=false ) + * \param source The starting AutoContact. + * \param target The ending AutoContact (created if needed). + * \param hcollapse collapse the horizontal AutoSegment. + * \param vcollapse collapse the vertical AutoSegment. + * \param terminal collapse the horizontal AutoSegment. + * + * Draw a simple bend source to target AutoContact. If target is \e NULL, create + * the target. The \e terminal parameter will apply to both horizontal \& vertical + * AutoSegment. The horizontal AutoSegment comes first. + * \image html GCellConfiguration-15.png "_GCell_L3V_L2H" + * \image latex GCellConfiguration-15.pdf "_GCell_L3V_L2H" width=0.2\textwidth + */ + + /*! \function AutoContact* GCellConfiguration::_GCell_L2H_L3V ( AutoContact* source, AutoContact* target=NULL, bool hcollapse=false, bool vcollapse=false, bool terminal=false ) + * \param source The starting AutoContact. + * \param target The ending AutoContact (created if needed). + * \param hcollapse collapse the horizontal AutoSegment. + * \param vcollapse collapse the vertical AutoSegment. + * \param terminal collapse the horizontal AutoSegment. + * + * Draw a simple bend source to target AutoContact. If target is \e NULL, create + * the target. The \e terminal parameter will apply to both horizontal \& vertical + * AutoSegment. The vertical AutoSegment comes first. + * \image html GCellConfiguration-16.png "_GCell_L2H_L3V" + * \image latex GCellConfiguration-16.pdf "_GCell_L2H_L3V" width=0.2\textwidth + */ + + /*! \function void GCellConfiguration::_GCell_1G_1L1 () + * Optimized topology for one \e metal1 terminal and one global AutoSegment. + */ + + /*! \function void GCellConfiguration::_GCell_1G_xL1 () + * + * Topology for one global AutoSegment and any number of \e metal1 terminals. + * \image html GCellConfiguration-3.png "_GCell_1G_xL1" + * \image latex GCellConfiguration-3.pdf "_GCell_1G_xL1" width=0.8\textwidth + */ + + /*! \function void GCellConfiguration::_GCell_xG_xL1_xL3 () + * + * Topology for two or more global AutoSegment and any number of \e metal1 or + * \e metal3 terminals. They share the same topology since they are are both + * vertical and connected through \e metal2. + * + * Building rules : + *
      + *
    • Global AutoContact are always splitted except when in the + * \e Bend topology. + *
    • Local terminal AutoSegment are always attached to the South + * West AutoContact except in the Straight Horizontal + * topology or when there is no South global segment. + *
    + * + * \image html GCellConfiguration-14.png "Straight Horizontal" + * \image html GCellConfiguration-21.png "Straight Vertical \& Fork (L1 horizontal)" + * \image html GCellConfiguration-22.png "Forks (L1 horizontal)" + * \image html GCellConfiguration-23.png "Forks (L1 vertical)" + * \image html GCellConfiguration-24.png "Bend" + * \image latex GCellConfiguration-14.pdf "Straight Horizontal" width=0.4\textwidth + * \image latex GCellConfiguration-21.pdf "Straight Vertical (L1 horizontal)" width=0.8\textwidth + * \image latex GCellConfiguration-22.pdf "Forks (L1 horizontal)" width=0.8\textwidth + * \image latex GCellConfiguration-23.pdf "Forks (L1 vertical)" width=0.8\textwidth + * \image latex GCellConfiguration-24.pdf "Bend" width=0.4\textwidth + */ + + /*! \function void GCellConfiguration::_GCell_xG_xL2() + * + * Topology for any global AutoSegment and any number of \e metal2 terminals. + * + * Building rules : + *
      + *
    • Global AutoContact are always splitteds, except for the + * \e Bend and \e End topology. + *
    • Anchor the local connecting AutoContact on the biggest + * \RoutingPad, except for the Straight Horizontal + * and the \e End (horizontal) topology. In thoses cases, + * uses the leftmost or rightmost \RoutingPad. + *
    • Prefers vertical AutoSegment to start from the \RoutingPad, + * this needs East and/or West global to be present. + *
    + * + * \image html GCellConfiguration-30.png "Straight H/V" + * \image html GCellConfiguration-31.png "Forks with East \& West" + * \image html GCellConfiguration-32.png "Forks without East or West" + * \image html GCellConfiguration-33.png "Complete Fork" + * \image html GCellConfiguration-34.png "All Bends" + * \image html GCellConfiguration-35.png "East or West End" + * \image html GCellConfiguration-36.png "North or South End" + * \image latex GCellConfiguration-30.pdf "Straight H/V" width=0.95\textwidth + * \image latex GCellConfiguration-31.pdf "Forks with East \& West" width=0.95\textwidth + * \image latex GCellConfiguration-32.pdf "Forks without East or West" width=0.95\textwidth + * \image latex GCellConfiguration-33.pdf "Complete Fork" width=0.48\textwidth + * \image latex GCellConfiguration-34.pdf "All Bends" width=0.48\textwidth + * \image latex GCellConfiguration-35.pdf "East or West End" width=0.95\textwidth + * \image latex GCellConfiguration-36.pdf "North or South End" width=0.48\textwidth + */ + + /*! \function void GCellConfiguration::_GCell_xG_1L1_1L2 () + * + * Topology for one or more global AutoSegment, one \e metal1 and one + * \e metal2 terminals. + * + * Building rules : + *
      + *
    • Global AutoContact are always splitted except when in the + * \e Bend or \e End topology. + *
    • Local terminal AutoSegment are always attached to an + * AutoContact with one vertical global, the South West + * whenever possible (South global present). + *
    + * + * \image html GCellConfiguration-40.png "End H/V" + * \image html GCellConfiguration-41.png "Straight H/V" + * \image html GCellConfiguration-42.png "Forks without East or West" + * \image html GCellConfiguration-43.png "Forks without North or South" + * \image html GCellConfiguration-44.png "Complete Fork" + * \image html GCellConfiguration-45.png "Any Bend" + * \image latex GCellConfiguration-40.pdf "End H/V" width=0.95\textwidth + * \image latex GCellConfiguration-41.pdf "Straight H/V" width=0.95\textwidth + * \image latex GCellConfiguration-42.pdf "Forks without East or West" width=0.95\textwidth + * \image latex GCellConfiguration-43.pdf "Forks without North or South" width=0.95\textwidth + * \image latex GCellConfiguration-44.pdf "Complete Fork" width=0.48\textwidth + * \image latex GCellConfiguration-45.pdf "Any Bend" width=0.48\textwidth + */ + + + /*! \class SortRpByX + * \brief \c RoutingPad \b Compare functor (\b internal) + */ + + /*! \function inline SortRpByX::SortRpByX ( bool decreasing ); + * \param decreasing Tells if the sort is done in decreasing order. + * + * This object is a \c Compare functor for the \c sort \c algorithm + * over \c STL container made of \c RoutingPad pointers. If \c decreasing + * is false the container elements will be sorted by increasing X + * coordinates. Otherwise the sort is decreasing. + * + * See GCellConfiguration class. + */ + + + /*! \class SortRpByY + * \brief \c RoutingPad \b Compare functor (\b internal) + */ + /*! \function inline SortRpByY::SortRpByY ( bool decreasing ); + * \param decreasing Tells if the sort is done in decreasing order. + * + * This object is a \c Compare functor for the \c sort \c algorithm + * over \c STL container made of \c RoutingPad pointers. If \c decreasing + * is false the container elements will be sorted by increasing Y + * coordinates. Otherwise the sort is decreasing. + * + * See GCellConfiguration class. + */ + + + /* \function RoutingPad* lookupOrCreate ( Plug* plug ); + * \param plug A net's plug. + * \return A RoutingPad associated to the plug. + * + * create a \RoutingPad for the plug or find an already created + * one. To keep track + */ + + /* \function RoutingPad* getRoutingPad ( Plug* plug, const Box& boundingBox ); + * \param plug A net's plug. + * \param boundingBox An area. + * \return A RoutingPad associated to the plug. + * + * creates a RoutingPad built on plug. Select the best external + * component of the master net to uses : the largest component + * in the highest layer in the given boundingBox area. + * + * If no component is found under the boundingBox area a + * warning is issued and a component outside the area will be + * used. + */ + + /* \function RoutingPad* getRoutingPad ( Pin* pin ); + * \param pin A net's pin. + * \return A RoutingPad associated to the pin. + * + * Unlike for the RoutingPad from a plug, there is no choice + * for the external component : it's the pin itself. + */ + + /* \function bool arePerpandicular ( unsigned int dir1, unsigned int dir2 ); + * \param dir1 First direction. + * \param dir2 Second direction. + * \return \True if the two direction are perpandiculars. As it proceed + * with bits operators first and second direction could contains + * other flags than \HORIZONTAL and \VERTICAL. + */ + + /* \function unsigned int areOppositeSPs ( SplitterContact* spc1, SplitterContact* spc2 ); + * \param spc1 First SplitterContact. + * \param spc2 Second SplitterContact. + * \return \True if the two SplitterContact are from the opposites Fences + * of a Nimbox. + */ + + /* \function Point getEastPosition ( RoutingPad* rp ); + * \return Between the source and target point, the one with the greatest + * X coordinate (source, if equal). + */ + + /* \function Point getWestPosition ( RoutingPad* rp ); + * \return Between the source and target point, the one with the lowest + * X coordinate (target, if equal). + */ + + /* \function Point getNorthPosition ( RoutingPad* rp ); + * \return Between the source and target point, the one with the greatest + * Y coordinate (source, if equal). + */ + + /* \function Point getSouthPosition ( RoutingPad* rp ); + * \return Between the source and target point, the one with the lowest + * Y coordinate (target, if equal). + */ + + /*! \function void singleGCell ( KatabaticEngine* ktbt, Net* net ); + * \param ktbt A Katabatic \ToolEngine (gives the grid). + * \param net The net for which to build the topology. + * + * This function handle the special case where a whole net + * is included inside only one GCell. + * + * \important For the time being we assumes that the net is a two + * terminal net only. If this is not the case the topology + * will be incomplete an so the routing. + */ + + + /*! \class ForkStack + * \brief Stack of \c Hook / AutoContact (\b internal). + * + * A simple stack of pair of \c Hook / AutoContact. It's used + * to handle the recursivity while building a Net's initial wiring in + * _loadNetGlobalRouting(). + */ + + /*! \function void ForkStack::push ( Hook* from, AutoContact* contact ); + * Stack a new pair of \c Hook / AutoContact. + */ + + /*! \function void ForkStack::pop (); + * Pop an element. The popped element is \b not returned, it's contents are lost. + */ + + /*! \function Hook* ForkStack::getFrom () const; + * \return The \c Hook on top of the stack. \c NULL if + * the stack is empty. + */ + + /*! \function Contact* ForkStack::getContact () const; + * \return The \c Contact on top of the stack. \c NULL if + * the stack is empty. + */ + + //! \} + + + /*! \defgroup buildRules 1. Rules for building wires (internal) + * + * + * \section secACConf AutoContact configurations. + * + * In this section we details how an AutoContact resise itself, and + * introduce some terminology. + * + * First we distinguish two kinds of segments attached to an AutoContact, + * segments that crosses the GCell boundary are considered as global + * and others are locals. + * + * As globals AutoSegments crosses the GCell boundaries, when their + * extention is adjusted by the AutoContact we have the guarantee that + * they will span from the border of the GCell to the AutoContact. + * The AutoContact relies strongly on this hypothesis. + * + * The configuration of an AutoContact is computed in two stages : + *
      + *
    1. We compute the smallest box enclosing all the intersections of + * global segments axis, this box is drawn in red in the figures + * below. We refers this box as the "Junction Box". + * In some cases the enclosing box is not sufficent to make additionnal + * connections with the local segments (see figures G2.1 and G3.1), + * only in those case we take them in account in the junction box. + *
    2. In the second stage we extend the local segments to reach the + * skeleton made by globals segments. In most cases, we do not have + * choices for the extension, but in G4.3 and G4.4. + *
    + * + * orientation meaning : (west, east, south and north) + *
      + *
    • For global segments, it indicates which side of the GCell it + * crosses. + *
    • For local segments, it tells it's relative position to the + * junction box. An horizontal segment will be south if it's axis + * is inferior to the YMin of the junction box and north otherwise. + * In the same way a vertical segment will be west if is axis is + * inferior to the XMin of the junction box and east otherwise. + *
    + * + * \image html AutoContactG1-1.png "One Global Routing" + * \image html AutoContactG2-1.png "Two Global Routing" + * \image html AutoContactG3-1.png "Three Global Routing" + * \image html AutoContactG3-2.png "Three Global Routing" + * \image html AutoContactG4-1.png "Four Global Routing" + * \image html AutoContactG4-2.png "Four Global Routing" + * \image html AutoContactG4-3.png "Four Global Routing" + * \image latex AutoContactG1-1.pdf "One Global Routing" width=0.3\textwidth + * \image latex AutoContactG2-1.pdf "Two Global Routing" width=0.8\textwidth + * \image latex AutoContactG3-1.pdf "Three Global Routing" width=0.8\textwidth + * \image latex AutoContactG3-2.pdf "Three Global Routing" width=0.8\textwidth + * \image latex AutoContactG4-1.pdf "Four Global Routing" width=0.8\textwidth + * \image latex AutoContactG4-2.pdf "Four Global Routing" width=0.8\textwidth + * \image latex AutoContactG4-3.pdf "Four Global Routing" width=0.8\textwidth + * + * + * The "four sides" box problem : + * + * In cases G4.3 and G4.4 we must uses three sides of the junction box + * to perform the connection. To minimize wirelength we uses the two small + * sides and one of the long size. Which one is the question... For the + * moment we systematically choose the lower one (that is west or south). + * A problem arises when, by displacing segments, the router change which + * side is the shortest one. A Solution to this problem is proposed + * in \ref ssecFaultyAutoContact. + * + * + * \section secSegStruct Routing Segments Organisation. + * + * Router movements : + *
      + *
    • Horizontal segments : only translated vertically, + * extensions are not changed, the segment do not + * shrink neither grow. + *
    • Vertical segments : only translated horizontally. + * Extensions remains the same. + *
    + * + * Autocontact adjustements : + * + * When an horizontal segment is vertically moved, vertical ones + * that are linked to it through AutoContact must have their + * extension adapted : either shrinked or elongated. + * + * \image html AutoContact-2.png "Segment Structure" + * \image html AutoContact-3.png "Segment Displacement" + * \image latex AutoContact-2.pdf "Segment Structure" width=0.5\textwidth + * \image latex AutoContact-3.pdf "Segment Displacement" width=0.5\textwidth + * + * + * \subsection ssecFaultyAutoContact AutoContact Geometry restrictions. + * + * \important The property we want to emphasis here is that whenever a + * segment is moved by the router the size of it's + * source or target extensions must not change. Only the + * extensions of segments perpandicularly connected to it will + * change. + * Unfortunatly, not all topologies will ensure that property. + * The following figures shows all those invalid topologies, and + * their correct counterparts. We are looking here from an AutoContact + * point of view : how does the AutoContact resizes when an AutoSegment + * moves. + * + * First case + * + * Three globals (\b G1, \b G2, \b G3) and one local + * (\b L1). \b L1 is perpandicular to \b G1 and \b G3. According to the + * AutoContact sizing specification, \b L1 will be extended to reach + * either \b G1 or \b G3, according to it's relative position from + * \b G2. Problem arises when the router moves \b L1 and crosses the + * position of \b G2. In the figure below, \b L1 is moved up so it + * will extend to \b G3 instead of \b G1. So \b L1 horizontal size + * will change as it is moved. + * + * \image html AutoContactG3-3.png "Three Globals : Problem" + * \image latex AutoContactG3-3.pdf "Three Globals : Problem" width=0.8\textwidth + * + * To avoid the problem, simply split \b AC1 in two AutoContact (\b AC-SW \& + * \b AC-NE). This way, \b L1 will always be extented to reach the same + * global AutoSegment (here : \b G1). + * + * \image html AutoContactG3-4.png "Three Globals : Solution" + * \image latex AutoContactG3-4.pdf "Three Globals : Solution" width=0.8\textwidth + * + * Second case + * + * Four globals (\b G1 to \b G4). This is the + * four side box problem (see \ref secACConf). To minimize wirelength, + * the \b AC1 AutoContact will uses only three side of the junction box : + * the two shortest and one of the longest. The problem shows when \b G3 + * is moved to the right changing shortest and longest sides. + * \b G2 is then shrinked (which is not a problem because it's perpandicular + * to \b G3), and \b G3 is extended, which is the problem. + * + * \image html AutoContactG4-4.png "Four Globals : Problem" + * \image latex AutoContactG4-4.pdf "Four Globals : Problem" width=0.8\textwidth + * + * As for the first case, we choose to split the \b AC1 AutoContact in two + * (\b AC-SW \& \b AC-NE) and link them with one local AutoSegment (horizontal). + * We arbitrarily group the globals in a South West AutoContact + * (\b AC-SW) and North East AutoContact (\b AC-NE). The connexion + * between them is horizontal because there is slighly more horizontal + * resources. + * + * \image html AutoContactG4-5.png "Four Globals : Solution" + * \image latex AutoContactG4-5.pdf "Four Globals : Solution" width=0.8\textwidth + * + * \important We now can express a more synthetic building rule : an AutoContact + * must never contain more than two global segments. + * This rule allow a simpler managment mechanism for the AutoContact + * self sizing procedure (i.e. : speedup). + * + * + * \subsection ssecFaultyTopologies Topologies Leading to Gaps. + * + * First Case + * + * The figure "incomplete AutoContact 1" shows how two contiguous local + * AutoSegments could lead to a gap in the AutoContact generated + * geometry. The local AutoSegment \b L2 is the only vertical component of + * the red AutoContact, thus it's source point will be moved to ensure + * the vertical connection between \b G1 and \b G2. In the other hand, + * the target of \b L2 is bound by the horizontal position of \b L1. + * So, if \b G2 (or \b G1) is moved above \b L1 a gap will appear whithin the + * AutoContact geometry. + * + * \image html GCellConfiguration-1.png "incomplete AutoContact 1" + * \image latex GCellConfiguration-1.pdf "incomplete AutoContact 1" width=0.8\textwidth + * + * To avoid this problem, the red AutoContact have to be split in two + * AutoContacts linked together though a third local AutoSegment \b L3, + * as shown on figure "Correct topology". Note that, in this figure we + * present an unlikely case : most of the time \b L3 will have a zero + * size, and if not, would uses the same track as \b L2. The \b L3 AutoSegment + * will have the correct length because is source moves with \b G2 and it's + * target with \b G1 (or the other way around, according to the relative + * horizontal positions of \b G1 and \b G2). Another point to note is that + * there can only be (at most) two global horizontal AutoSegment, one on + * left and one on the right. And finally, one say that we could have + * suppressed the \b L2 AutoSegment, but in this case it would forces + * the alignement of either \b G1 or \b G2 with \b L1, which could be a + * severe constraint. + * + * \image html GCellConfiguration-2.png "Correct Topology 1" + * \image latex GCellConfiguration-2.pdf "Correct Topology 1" width=0.8\textwidth + * + * Second Case + * + * The following figure "Invalid Configuration 2" illustrate the problem + * that arises when a local AutoSegment is used to connect more than two + * vertical AutoSegments. In other words, is not a mere "dog leg" (double bend). + * This implies that on a least one supporting AutoContact there is more + * than one vertical AutoSegment attached (\e AC2 in our case). + * + * As per definition, the \e L4 AutoSegment has it's source X position sets + * by \e AC1 and it's target X position sets by \e AC2. On \e AC1 there will + * be no problems : the X position is given by \e L3 and we always can + * extend \e L4 to reach it. On the other end, for \e AC2, as the connexity + * is ensured only by extending/shrinking the AutoSegment target X position + * we will never be able to reach both \e L7 \& L6 as they are on either + * side of \e L3. Only one of them will be reached, \e L6 or \e L7 + * depending on how the AutoContact will expand. + * + * To avoid this problem, we introduce the AutoContact horizontal and/or + * vertical locking. For instance, when an AutoContact is vertically + * locked (says \e AC2), then \e L6 \& \e L7 will be kept at the same + * X coordinate. Note that this is not done by the AutoContact itself + * but rather by declaring \e L6 \& \e L7 as collapsed (as if they where + * connected through a collapsed horizontal AutoSegment). + * + * \image html GCellConfiguration-20.png "incomplete Topology 2 (detail)" + * \image latex GCellConfiguration-20.pdf "incomplete Topology 2 (detail)" width=0.8\textwidth + * + * \image html GCellConfiguration-18.png "incomplete Topology 2 (context)" + * \image latex GCellConfiguration-18.pdf "incomplete Topology 2 (context)" width=0.8\textwidth + * + * \image html GCellConfiguration-19.png "Correct Topology 2" + * \image latex GCellConfiguration-19.pdf "Correct Topology 2" width=0.8\textwidth + * + * For more details about the AutoSegment collapsing whereabouts, see + * \ref collapseCanonical. + * + * + * \section secLegalCatalog Catalog of Legal Topologies. + * + * Summarize the set of legal topologies regarding the following + * rules : + *
      + *
    • Rule 1 : An AutoContact must have at least one + * horizontal and one vertical attached to it. With the only + * expeption of those anchored on RoutingPad. + *
    • Rule 2 : An AutoContact must never have more than + * two global AutoSegment. With the only exception of + * AutoContacts with exactly three globals (and no locals). + *
    • Rule 3 : When the side of a Junction Box is made + * of a local AutoSegment, perpandicular AutoSegments must be + * locked together. + *
    • Rule 4 : AutoContact with two globals and any number + * of local must be lockeds in at least one direction. + *
    + * + * Topologies for Dog-Leg (no-fork). + * + * First figure illustrate why rule 1 is needed. Second, the dog + * leg general case, and the latest how to circumvent rule 1 by + * collapsing \b L2. + * + * \image html LegalConstruct-1.png "Legal Construct : dog leg" + * \image latex LegalConstruct-1.pdf "Legal Construct : dog leg" width=0.8\textwidth + * + * Topologies for Elementary Local Fork. + * + * Illustrate how to build local fork, according to the number of global + * AutoSegments part of the fork. First and second case with the side of + * the Junction Box made of a global AutoSegment : no constraint. + * Third case : the side of the Junction Box is made of a local + * AutoSegment, then perpandicular AutoSegment on \b AC2 must be + * linked (here : vertical link) in compliance with Rule 3. + * + * \image html LegalConstruct-2.png "Legal Construct : elementary local fork" + * \image latex LegalConstruct-2.pdf "Legal Construct : elementary local fork" width=0.8\textwidth + * + * Topologies for Global Fork (3 branches). + * + * To comply with Rule 2, we must split the AutoContact in two : + * the South West (\b AC-SW) and North East (\b AC-NE). Whenever it's possible + * we join them through an horizontal AutoSegment. It's not possible if either + * \b G2 or \b G3 is missing. + * + * \image html LegalConstruct-4.png "Legal Construct : Global fork (3 branches, 1)" + * \image html LegalConstruct-5.png "Legal Construct : Global fork (3 branches, 2)" + * \image latex LegalConstruct-4.pdf "Legal Construct : Global fork (3 branches, 1)" width=0.8\textwidth + * \image latex LegalConstruct-5.pdf "Legal Construct : Global fork (3 branches, 2)" width=0.8\textwidth + * + * Topology for Global Fork (4 branches). + * + * Only one possibility, as shown in the figure below. Two AutoContact + * \b AC-SW \& \b AC-NE, and one horizontal AutoSegment. + * + * \image html LegalConstruct-6.png "Legal Construct : Global fork (4 branches)" + * \image latex LegalConstruct-6.pdf "Legal Construct : Global fork (4 branches)" width=0.8\textwidth + * + * \important If there are local connections inside a global fork, the local + * AutoSegment \b L1 will be replaced by a more complex topology. + * + * + * \section secGCellConfiguration Using GCellConfiguration + * + * After the global routing stage, the final router needs to achieve + * the routing topology in each GCell, for each Net. + * This wiring must connect the global wires (that crosses the + * GCell boundary) with any number of local terminals. + * + * This object is the atomic action of a recursive walk through + * the \c GCells of a \c Net. The recursivity is handled through + * a stack : see \c ForkStack. + * + * This classes uses a dictionnary of pre-defined shapes to build + * the interconnect. The dictionnary relies on the following + * hypothesis : + *
      + *
    1. The GCell is one slice height. This implies + * that in almost all cases, internal terminals in the same + * layer can be ordered form left to right. + *
    2. If there is two or more horizontal terminals, they are + * most likely aligned. + *
    3. If there is two or more vertical terminals they are + * not on top of each other, but rather side by side + *
    4. If there are terminals in layer other than M1, we must + * route through it. + *
    + * + * + * \section secUsingGCell Using a GCellConfiguration object + * + * Obviously, we need the Nimbus global routing structure to be present, as we + * uses \c Splitter to progress through the global routing. Using a + * GCellConfiguration is simple enough : + * + *
      + *
    • create a new GCellConfiguration. At this time we must + * supply the \c GCell to be processed, the \Splitter from which the + * \c GCell is entered and optionally a source AutoContact (from the + * previously processed \c GCell). The constructor go through the + * Net's ring inside the \GCell, finding \SplitterContact, \Plug and + * \Pin. Location of \SplitterContact are stored according to + * their positions (east/west/north/south), \RoutingPad are created + * for each \c Plug/Pin and stored into a \vector. The \c _state and + * \c _topology values are also computed, summarizing respectively + * the number of globals and locals (by layers) and the geometry of + * globals (end, straight, bend, fork) + * + *
    • The second step is to call the construct() method. \c construct() + * works in three steps : + * + *
        + *
      1. Draw the internal wiring of the \c GCell, using the appropriate + * \c _GCell_xG_xLx() fonction. + * + * Calls \c _GCell_GlobalContacts(), which create the south west + * (\c _southWestContact ) AutoContact and, if needed the north east + * one (\c _northEastContact ). If only \c _southWestContact is created, + * \c _northEastContact is set to the same value (i.e. is never \NULL). + * Those AutoContacts will supply the support for global \c AutoSegment + * (AutoSegment that goes to and from this \c GCell ). + * + * If the \c GCell has no internal terminal, then only global wiring + * has to be created, and no \c _GCell_xG_xLx() function is + * to be call. All we have to do is to call the \c _GCell_GlobalContacts(). + * function. And in the case we go through the GCell in straight line + * (aligned \c Splitter) we don't even do that. + * + *
      2. Draw the global routing from to previous \c GCell to the + * current one. That is from \c _sourceContact to \c _southWestContact + * or \c _northEastContact according to where we came from. + * + *
      3. Stack the pair of \c SplitterContact/AutoContact into + * the forks stack, except the one we come from (tagged by + * the \c _fromSP ). Here again, we stack either \c _southWestContact + * or \c _northEastContact according to where we came from. + *
      + *
    + */ + + + using namespace std; + using namespace CRL; + using namespace Hurricane; + using namespace Katabatic; + + + // --------------------------------------------------------------- + // Local Enum/Types. + + + enum SegmentSide { SegmentSouth = (1<<0) + , SegmentNorth = (1<<1) + , SegmentWest = (1<<2) + , SegmentEast = (1<<3) + }; + + + // --------------------------------------------------------------- + // Local Variables. + + + const char* invalidGCell = + "Katabatic::GCellConfiguration () :\n\n" + " No GCell under point.\n"; + + const char* mismatchGCell = + "Katabatic::GCellConfiguration () :\n\n" + " Contacts under two different GCells.\n"; + + const char* missingGCell = + "Katabatic::GCellConfiguration () :\n\n" + " No Contact in GCell.\n"; + + + map __routingPadAutoSegments; + + + // --------------------------------------------------------------- + // LoadGrByNet Local Classes. + + + struct NetCompareByName { + inline bool operator() ( const Net* lhs, const Net* rhs ) const; + }; + + inline bool NetCompareByName::operator() ( const Net* lhs, const Net* rhs ) const + { + return lhs->getName() < rhs->getName(); + } + + + // --------------------------------------------------------------- + // LoadGrByNet Local Functions. + + + void lookupClear () + { + __routingPadAutoSegments.clear (); + } + + + void setIsRoutingPadSmall ( RoutingPad* rp, bool& hsmall, bool& vsmall, bool& punctual ) + { + Point source = rp->getSourcePosition(); + Point target = rp->getTargetPosition(); + + DbU::Unit width = abs ( target.getX() - source.getX() ); + DbU::Unit height = abs ( target.getY() - source.getY() ); + + hsmall = ( width < DbU::lambda(15.0)); + vsmall = ( height < DbU::lambda(15.0)); + punctual = (width == 0) && (height == 0); + } + + + Hook* getSegmentOppositeHook ( Hook* hook ) + { + Segment* segment = static_cast( hook->getComponent() ); + return segment->getOppositeHook ( hook ); + } + + + unsigned int getSegmentHookType ( Hook* hook ) + { + Horizontal* horizontal = dynamic_cast( hook->getComponent() ); + if ( horizontal ) { + if ( horizontal->getSourceX() > horizontal->getTargetX() ) + cerr << Warning("Bad orientation of %s",getString(horizontal).c_str()) << endl; + + if ( dynamic_cast(hook) ) + return SegmentEast; + return SegmentWest; + } + Vertical* vertical = dynamic_cast( hook->getComponent() ); + if ( vertical->getSourceY() > vertical->getTargetY() ) + cerr << Warning("Bad orientation of %s",getString(vertical).c_str()) << endl; + + if ( dynamic_cast(hook) ) + return SegmentNorth; + return SegmentSouth; + } + + + // --------------------------------------------------------------- + // Class : "SortRpByX". + + + class SortRpByX { + public: + inline SortRpByX ( bool decreasing ); + inline bool operator() ( RoutingPad* rp1, RoutingPad* rp2 ); + protected: + bool _decreasing; + }; + + + inline SortRpByX::SortRpByX ( bool decreasing ) + : _decreasing(decreasing) + { } + + + inline bool SortRpByX::operator() ( RoutingPad* rp1, RoutingPad* rp2 ) + { + DbU::Unit x1 = rp1->getCenter().getX(); + DbU::Unit x2 = rp2->getCenter().getX(); + + if ( x1 == x2 ) return false; + return _decreasing xor ( x1 < x2 ); + } + + + // --------------------------------------------------------------- + // Class : "SortRpByY". + + + class SortRpByY { + public: + inline SortRpByY ( bool decreasing ); + inline bool operator() ( RoutingPad* rp1, RoutingPad* rp2 ); + protected: + bool _decreasing; + }; + + + inline SortRpByY::SortRpByY ( bool decreasing ) + : _decreasing(decreasing) + { } + + + inline bool SortRpByY::operator() ( RoutingPad* rp1, RoutingPad* rp2 ) + { + DbU::Unit y1 = rp1->getCenter().getY(); + DbU::Unit y2 = rp2->getCenter().getY(); + + if ( y1 == y2 ) return false; + return _decreasing xor ( y1 < y2 ); + } + + + // --------------------------------------------------------------- + // Class : "ForkStack". + + + class ForkStack { + public: + inline void push ( Hook* from, AutoContact* contact ); + inline void pop (); + inline Hook* getFrom () const; + inline AutoContact* getContact () const; + private: + struct Element { + Hook* _from; + AutoContact* _contact; + inline Element ( Hook* from, AutoContact* contact ); + }; + private: + list _stack; + }; + + + inline ForkStack::Element::Element ( Hook* from, AutoContact* contact ) : _from(from), _contact(contact) {} + inline void ForkStack::pop () { if ( !_stack.empty() ) _stack.pop_back(); } + inline Hook* ForkStack::getFrom () const { return _stack.empty() ? NULL : _stack.back()._from; } + inline AutoContact* ForkStack::getContact () const { return _stack.empty() ? NULL : _stack.back()._contact; } + + + inline void ForkStack::push ( Hook* from, AutoContact* contact ) + { + ltrace(80) << " Stacking " << (void*)from << " " << from << " + " << contact << endl; + _stack.push_back(Element(from,contact)); + } + + + // --------------------------------------------------------------- + // Class : "GGellConfiguration". + + + class GCellConfiguration { + + public: + // Methods. + GCellConfiguration ( GCellGrid* gcellGrid + , Hook* fromHook + , AutoContact* sourceContact=NULL ); + void construct ( ForkStack& forks ); + inline unsigned int getStateG () const; + inline GCell* getGCell () const; + static bool _GCell_rp_AutoContacts ( GCell* gcell + , RoutingPad* rp + , AutoContact*& source + , AutoContact*& target + , bool haccess ); + static AutoContact* _GCell_rp_Access ( GCell* gcell + , RoutingPad* rp + , bool haccess + , bool forceVSmall ); + static AutoContact* _GCell_rp_L2H ( GCell* gcell + , RoutingPad* rp + , AutoContact* target =NULL + , bool hcollapse=false ); + static AutoContact* _GCell_rp_L2H_L3V ( GCell* gcell + , RoutingPad* rp + , AutoContact* target =NULL + , bool hcollapse=false + , bool vcollapse=false ); + static void _GCell_rp_StairCaseH ( GCell* gcell + , RoutingPad* rp1 + , RoutingPad* rp2 ); + static void _GCell_rp_StairCaseV ( GCell* gcell + , RoutingPad* rp1 + , RoutingPad* rp2 ); + static AutoContact* _GCell_L3V_L2H ( GCell* gcell + , Net* net + , AutoContact* source + , AutoContact* target =NULL + , bool hcollapse=false + , bool vcollapse=false + , bool terminal =false ); + static AutoContact* _GCell_L2H_L3V ( GCell* gcell + , Net* net + , AutoContact* source + , AutoContact* target =NULL + , bool hcollapse=false + , bool vcollapse=false + , bool terminal =false ); + protected: + // Internal Methods. + void _GCell_GlobalContacts ( bool split + , AutoContact* southWestContact=NULL + , AutoContact* northEastContact=NULL ); + void _GCell_1G_1L1 (); + void _GCell_1G_xL1 (); + void _GCell_xG_xL1_xL3 (); + void _GCell_xG_1L1_1L2 (); + void _GCell_xG_xL2 (); + void _GCell_1G_1L3 (); + void _GCell_xG_xL3 (); + + protected: + // State Values. + enum State { GCELL_0G = 0 + , GCELL_2G = 2 + , GCELL_3G = 3 + , GCELL_4G = 4 + , GCELL_0G_2L1 = 0+(2<<3) + , GCELL_1G_1L1 = 1+(1<<3) + , GCELL_1G_2L1 = 1+(2<<3) + , GCELL_1G_3L1 = 1+(3<<3) + , GCELL_1G_4L1 = 1+(4<<3) + , GCELL_1G_1L2 = 1+(1<<6) + , GCELL_1G_2L2 = 1+(2<<6) + , GCELL_1G_3L2 = 1+(3<<6) + , GCELL_1G_4L2 = 1+(4<<6) + , GCELL_1G_1L3 = 1+(1<<9) + , GCELL_1G_2L3 = 1+(2<<9) + , GCELL_1G_3L3 = 1+(3<<9) + , GCELL_1G_4L3 = 1+(4<<9) + , GCELL_1G_1L1_1L2 = 1+(1<<3)+(1<<6) + , GCELL_1G_1L1_1L3 = 1+(1<<3)+(1<<9) + , GCELL_2G_1L1 = 2+(1<<3) + , GCELL_2G_2L1 = 2+(2<<3) + , GCELL_2G_3L1 = 2+(3<<3) + , GCELL_2G_4L1 = 2+(4<<3) + , GCELL_2G_1L2 = 2+(1<<6) + , GCELL_2G_2L2 = 2+(2<<6) + , GCELL_2G_3L2 = 2+(3<<6) + , GCELL_2G_4L2 = 2+(4<<6) + , GCELL_2G_1L3 = 2+(1<<9) + , GCELL_2G_2L3 = 2+(2<<9) + , GCELL_2G_3L3 = 2+(3<<9) + , GCELL_2G_4L3 = 2+(4<<9) + , GCELL_2G_1L1_1L2 = 2+(1<<3)+(1<<6) + , GCELL_3G_1L1 = 3+(1<<3) + , GCELL_3G_2L1 = 3+(2<<3) + , GCELL_3G_3L1 = 3+(3<<3) + , GCELL_3G_4L1 = 3+(4<<3) + , GCELL_3G_1L2 = 3+(1<<6) + , GCELL_3G_1L3 = 3+(1<<9) + , GCELL_3G_2L3 = 3+(2<<9) + , GCELL_3G_3L3 = 3+(3<<9) + , GCELL_3G_4L3 = 3+(4<<9) + , GCELL_4G_1L1 = 4+(1<<3) + , GCELL_4G_2L1 = 4+(2<<3) + , GCELL_4G_1L3 = 4+(1<<9) + }; + + protected: + // Topologies Flags/Values. + enum Topology { GLOBAL_VERTICAL_END = (1<<0) + , GLOBAL_HORIZONTAL_END = (1<<1) + , GLOBAL_HORIZONTAL = (1<<2) + , GLOBAL_VERTICAL = (1<<3) + , GLOBAL_BEND = (1<<4) + , GLOBAL_FORK = (1<<5) + , GLOBAL_END = GLOBAL_VERTICAL_END | GLOBAL_HORIZONTAL_END + , GLOBAL_SPLIT = GLOBAL_HORIZONTAL | GLOBAL_VERTICAL | GLOBAL_FORK + }; + + protected: + // State Attribute. + union UState { + unsigned int state; + struct { + unsigned int globals : 3; + unsigned int L1 : 3; + unsigned int L2 : 3; + unsigned int L3 : 3; + } fields; + }; + + // Attributes. + protected: + UState _state; + unsigned int _topology; + Net* _net; + GCell* _gcell; + AutoContact* _sourceContact; + AutoContact* _southWestContact; + AutoContact* _northEastContact; + Hook* _fromHook; + Hook* _east; + Hook* _west; + Hook* _north; + Hook* _south; + vector _routingPads; + }; + + + inline unsigned int GCellConfiguration::getStateG () const { return _state.fields.globals; } + inline GCell* GCellConfiguration::getGCell () const { return _gcell; } + + + GCellConfiguration::GCellConfiguration ( GCellGrid* gcellGrid + , Hook* fromHook + , AutoContact* sourceContact ) + : _state() + , _topology(0) + , _gcell(NULL) + , _sourceContact(sourceContact) + , _southWestContact(NULL) + , _northEastContact(NULL) + , _fromHook(fromHook) + , _east(NULL) + , _west(NULL) + , _north(NULL) + , _south(NULL) + , _routingPads() + { + ltrace(99) << "GCellConfiguration::GCellConfiguration ()" << endl; + ltracein(99); + ltrace(99) << getString(fromHook) << endl; + ltrace(99) << sourceContact << endl; + + Segment* fromSegment = static_cast ( _fromHook->getComponent() ); + + _net = fromSegment->getNet (); + _state.state = 0; + + forEach ( Hook*, hook, fromHook->getHooks() ) { + Segment* toSegment = dynamic_cast(hook->getComponent()); + if ( toSegment ) { + switch ( getSegmentHookType(*hook) ) { + case SegmentWest: _west = *hook; break; + case SegmentEast: _east = *hook; break; + case SegmentSouth: _south = *hook; break; + case SegmentNorth: _north = *hook; break; + } + _state.fields.globals++; + } else { + RoutingPad* rp = dynamic_cast(hook->getComponent()); + + if ( rp ) { + const Layer* layer = rp->getLayer(); + if ( layer == Session::getRoutingLayer(0) ) _state.fields.L1++; // M1 V + else if ( layer == Session::getRoutingLayer(1) ) _state.fields.L2++; // M2 H + else if ( layer == Session::getRoutingLayer(2) ) _state.fields.L3++; // M3 V + else if ( layer == Session::getRoutingLayer(3) ) _state.fields.L2++; // M4 H + else if ( layer == Session::getRoutingLayer(4) ) _state.fields.L3++; // M5 V + else { + cerr << Warning ( "Terminal layer %s of %s is not managed yet (ignored)." + , getString(layer->getName()).c_str() + , getString(rp).c_str() ) + << endl; + continue; + } + + ltrace(99) << "RoutingPad " << rp << endl; + _routingPads.push_back ( rp ); + } else { + Contact* contact = dynamic_cast(hook->getComponent()); + if ( contact ) { + GCell* gcell = gcellGrid->getGCell ( contact->getCenter() ); + ltrace(99) << gcell << " guessed from " << contact << endl; + if ( !gcell ) + throw Error ( invalidGCell ); + if ( !_gcell ) _gcell = gcell; + else if ( _gcell != gcell ) { + throw Error ( mismatchGCell ); + } + } + } + } + } + + if (_state.fields.globals == 1) { + if ( _north || _south ) _topology |= GLOBAL_VERTICAL_END; + else _topology |= GLOBAL_HORIZONTAL_END; + } else if (_state.fields.globals == 2) { + if ( _east && _west ) _topology |= GLOBAL_HORIZONTAL; + else if ( _north && _south ) _topology |= GLOBAL_VERTICAL; + else _topology |= GLOBAL_BEND; + } else { + _topology |= GLOBAL_FORK; + } + + ltraceout(99); + + if ( !_gcell ) throw Error ( missingGCell ); + } + + + void GCellConfiguration::construct ( ForkStack& forks ) + { + ltrace(99) << "GCellConfiguration::construct () [" << _state.state << "] in " << _gcell << endl; + ltracein(99); + + bool straightLine = false; + + switch ( _state.state ) { + case GCELL_1G_1L1: _GCell_1G_1L1 (); break; + case GCELL_1G_2L1: + case GCELL_1G_3L1: + case GCELL_1G_4L1: _GCell_1G_xL1 (); break; + case GCELL_1G_1L2: + case GCELL_1G_2L2: + case GCELL_1G_3L2: + case GCELL_1G_4L2: _GCell_xG_xL2 (); break; + case GCELL_1G_1L3: _GCell_1G_1L3 (); break; + case GCELL_1G_2L3: + case GCELL_1G_3L3: + case GCELL_1G_4L3: _GCell_xG_xL3 (); break; + case GCELL_1G_1L1_1L2: _GCell_xG_1L1_1L2 (); break; + case GCELL_1G_1L1_1L3: _GCell_1G_xL1 (); break; + case GCELL_2G_1L1: + case GCELL_2G_2L1: + case GCELL_2G_3L1: + case GCELL_2G_4L1: + case GCELL_3G_1L1: + case GCELL_3G_2L1: + case GCELL_3G_3L1: + case GCELL_3G_4L1: + case GCELL_3G_2L3: + case GCELL_3G_3L3: + case GCELL_3G_4L3: + case GCELL_4G_1L1: + case GCELL_4G_2L1: _GCell_xG_xL1_xL3 (); break; + case GCELL_2G_1L2: + case GCELL_2G_2L2: + case GCELL_2G_3L2: + case GCELL_2G_4L2: + case GCELL_3G_1L2: _GCell_xG_xL2 (); break; + case GCELL_2G_1L3: + case GCELL_2G_2L3: + case GCELL_2G_3L3: + case GCELL_2G_4L3: + case GCELL_3G_1L3: _GCell_xG_xL3 (); break; + case GCELL_2G_1L1_1L2: _GCell_xG_1L1_1L2 (); break; + case GCELL_2G: + if ( (_east && _west) || (_north && _south) ) { + straightLine = true; + break; + } + case GCELL_3G: + _GCell_GlobalContacts ( false ); + break; + case GCELL_4G: + _GCell_GlobalContacts ( true ); + AutoSegment::create ( _southWestContact + , _northEastContact + , Constant::Horizontal + , AutoSegment::Local + , false + , false + ); + break; + default: + cerr << Bug("Unmanaged Configuration [%d] = [%d+%d+%d+%d] %s" + ,_state.state + ,_state.fields.globals + ,_state.fields.L1 + ,_state.fields.L2 + ,_state.fields.L3 + ,_net->_getString().c_str() + ) << endl; + _GCell_GlobalContacts ( false ); + } + + if ( straightLine ) { + cerr << Error("Straight aligned segments (ignored)") << endl; + ltraceout(99); + return; + } + + if ( _sourceContact ) { + AutoContact* targetContact + = ( getSegmentHookType(_fromHook) & (SegmentNorth|SegmentEast) ) + ? _northEastContact : _southWestContact ; + AutoSegment* globalSegment = AutoSegment::create ( _sourceContact + , targetContact + , static_cast( _fromHook->getComponent() ) + ); + + if ( globalSegment->isHorizontal() + and ( (Session::getRoutingGauge()->getLayerDepth(_sourceContact->getLayer()->getBottom()) > 1) + or (Session::getRoutingGauge()->getLayerDepth(targetContact ->getLayer()->getBottom()) > 1)) ) { + globalSegment->setLayer ( Session::getRoutingLayer(3) ); + ltrace(99) << "Source:" << _sourceContact << endl; + ltrace(99) << "Target:" << targetContact << endl; + ltrace(99) << "Moving up global:" << globalSegment << endl; + } + + if ( _state.fields.globals < 2 ) { + ltraceout(99); + return; + } + } else + _fromHook = NULL; + + if ( _east && (_fromHook != _east) ) { + Hook* toHook = getSegmentOppositeHook ( _east ); + ltrace(99) << "Pushing " << getString(toHook) << endl; + ltrace(99) << "Pushing " << _northEastContact << endl; + forks.push ( toHook, _northEastContact ); + } + if ( _west && (_fromHook != _west) ) { + Hook* toHook = getSegmentOppositeHook ( _west ); + ltrace(99) << "Pushing " << getString(toHook) << endl; + ltrace(99) << "Pushing " << _southWestContact << endl; + forks.push ( toHook, _southWestContact ); + } + if ( _north && (_fromHook != _north) ) { + Hook* toHook = getSegmentOppositeHook ( _north ); + ltrace(99) << "Pushing " << getString(toHook) << endl; + ltrace(99) << "Pushing " << _northEastContact << endl; + forks.push ( toHook, _northEastContact ); + } + if ( _south && (_fromHook != _south) ) { + Hook* toHook = getSegmentOppositeHook ( _south ); + ltrace(99) << "Pushing " << getString(toHook) << endl; + ltrace(99) << "Pushing " << _southWestContact << endl; + forks.push ( toHook, _southWestContact ); + } + + ltraceout(99); + } + + + void GCellConfiguration::_GCell_GlobalContacts ( bool split + , AutoContact* southWestContact + , AutoContact* northEastContact + ) + { + ltrace(99) << "GlobalContacts(" << split << ")" << endl; + + if ( southWestContact ) + _southWestContact = southWestContact; + else { + _southWestContact = AutoContact::create ( _gcell, _net, Session::getContactLayer(1) ); + } + + if ( split ) { + if ( northEastContact ) + _northEastContact = northEastContact; + else { + _northEastContact = AutoContact::create ( _gcell, _net, Session::getContactLayer(1) ); + } + } else + _northEastContact = _southWestContact; + } + + + bool GCellConfiguration::_GCell_rp_AutoContacts ( GCell* gcell + , RoutingPad* rp + , AutoContact*& source + , AutoContact*& target + , bool haccess + ) + { + ltrace(99) << "_GCell_rp_AutoContacts()" << endl; + ltracein(99); + + const Layer* rpLayer = Session::getContactLayer(0); + Point sourcePosition = rp->getSourcePosition(); + Point targetPosition = rp->getTargetPosition(); + unsigned int direction = Session::getRoutingGauge()->getLayerDirection(rp->getLayer()); + + source = target = NULL; + + // Non-M1 terminal. + if ( rp->getLayer() != Session::getRoutingLayer(0) ) { + map::iterator irp = __routingPadAutoSegments.find ( rp ); + if ( irp != __routingPadAutoSegments.end() ) { + source = irp->second->getAutoSource(); + target = irp->second->getAutoTarget(); + } else { + // Non-M1 Fixed protection. + if ( sourcePosition.getX() > targetPosition.getX() ) swap ( sourcePosition, targetPosition ); + if ( sourcePosition.getY() > targetPosition.getY() ) swap ( sourcePosition, targetPosition ); + + GCell* sourceGCell = Session::getKatabatic()->getGCellGrid()->getGCell ( sourcePosition ); + GCell* targetGCell = Session::getKatabatic()->getGCellGrid()->getGCell ( targetPosition ); + + source = AutoContact::fromRp ( sourceGCell + , rp + , rp->getLayer() + , sourcePosition + , DbU::lambda(1.0), DbU::lambda(1.0) + , true + ); + + target = AutoContact::fromRp ( targetGCell + , rp + , rp->getLayer() + , targetPosition + , DbU::lambda(1.0), DbU::lambda(1.0) + , true + ); + + unsigned int segmentType + = (sourceGCell == targetGCell) ? AutoSegment::Local : AutoSegment::Global; + + AutoSegment* segment = AutoSegment::create ( source + , target + , direction + , segmentType + , true + , false + ); + segment->setFixed ( true ); + __routingPadAutoSegments.insert ( make_pair(rp,segment) ); + + // Associate a M2 fixed protection to punctual M3 terminals. + if ( ( rp->getLayer() == Session::getRoutingLayer(2) ) + and ( sourcePosition == targetPosition ) ) { + AutoContact* sourceM2 = AutoContact::fromRp ( sourceGCell + , rp + , Session::getContactLayer(1) + , sourcePosition + , DbU::lambda(1.0), DbU::lambda(1.0) + , true + ); + + AutoContact* targetM2 = AutoContact::fromRp ( sourceGCell + , rp + , Session::getContactLayer(1) + , targetPosition + , DbU::lambda(1.0), DbU::lambda(1.0) + , true + ); + + AutoSegment* segmentM2 = AutoSegment::create ( sourceM2 + , targetM2 + , Constant::Horizontal + , AutoSegment::Local + , true + , false + ); + segmentM2->setFixed ( true ); + } + } + + if ( not (haccess xor (direction == Constant::Horizontal)) ) { + ltraceout(99); + return true; + } + } + + // Punctual M1. + if ( ( rp->getLayer() == Session::getRoutingLayer(0) ) + and ( sourcePosition == targetPosition ) ) { + map::iterator irp = __routingPadAutoSegments.find ( rp ); + if ( irp == __routingPadAutoSegments.end() ) { + GCell* sourceGCell = Session::getKatabatic()->getGCellGrid()->getGCell ( sourcePosition ); + + source = AutoContact::fromRp ( sourceGCell + , rp + , Session::getContactLayer(0) + , sourcePosition + , DbU::lambda(1.0), DbU::lambda(1.0) + , true + ); + + target = AutoContact::fromRp ( sourceGCell + , rp + , Session::getContactLayer(0) + , targetPosition + , DbU::lambda(1.0), DbU::lambda(1.0) + , true + ); + + AutoSegment* segment = AutoSegment::create ( source + , target + , Constant::Horizontal + , AutoSegment::Local + , true + , false + ); + segment->setFixed ( true ); + __routingPadAutoSegments.insert ( make_pair(rp,segment) ); + } + } + + if ( rp->getLayer() != Session::getRoutingLayer(0) ) + rpLayer = Session::getContactLayer(1); + + source = target = AutoContact::fromRp ( gcell + , rp + , rpLayer + , rp->getCenter() + , DbU::lambda(1.0), DbU::lambda(1.0) + ); + ltraceout(99); + return false; + } + + + AutoContact* GCellConfiguration::_GCell_rp_Access ( GCell* gcell, RoutingPad* rp, bool haccess, bool forceVSmall ) + { + ltrace(99) << "_GCell_rp_Access()" << endl; + ltracein(99); + + AutoContact* rpContactSource; + AutoContact* rpContactTarget; + bool hsmall; + bool vsmall; + bool punctual; + + setIsRoutingPadSmall ( rp, hsmall, vsmall, punctual ); + vsmall = vsmall || forceVSmall; + + _GCell_rp_AutoContacts ( gcell, rp, rpContactSource, rpContactTarget, haccess ); + + if ( not haccess and hsmall ) { + AutoContact* subContact1 = AutoContact::create ( gcell, rp->getNet(), Session::getContactLayer(1) ); + AutoSegment::create ( rpContactSource + , subContact1 + , Constant::Horizontal + , AutoSegment::Local + , true + , false + ); + rpContactSource = subContact1; + } + + ltraceout(99); + + return rpContactSource; + } + + + AutoContact* GCellConfiguration::_GCell_rp_L2H ( GCell* gcell, RoutingPad* rp, AutoContact* target, bool hcollapse ) + { + ltrace(99) << "rp_L2H " << rp << endl; + + AutoContact* rpContactSource; + AutoContact* rpContactTarget; + unsigned int segmentType = AutoSegment::Local; + + if ( _GCell_rp_AutoContacts(gcell,rp,rpContactSource,rpContactTarget,true) ) { + if ( gcell->getIndex() > rpContactSource->getGCell()->getIndex() ) + swap ( rpContactSource, rpContactTarget ); + if ( gcell->getIndex() != rpContactSource->getGCell()->getIndex() ) + segmentType = AutoSegment::Global; + } + + if ( !target ) + target = AutoContact::create ( gcell, rp->getNet(), Session::getContactLayer(1) ); + + AutoSegment::create ( rpContactSource, target, Constant::Horizontal, segmentType, true, hcollapse ); + + return target; + } + + + AutoContact* GCellConfiguration::_GCell_rp_L2H_L3V ( GCell* gcell, RoutingPad* rp, AutoContact* target, bool hcollapse, bool vcollapse ) + { + ltrace(99) << "rp_L2H+L3V " << rp << endl; + ltracein(99); + + AutoContact* source = _GCell_rp_L2H ( gcell, rp, NULL, hcollapse ); + + if ( !target ) { + target = AutoContact::create ( gcell, rp->getNet(), Session::getContactLayer(1) ); + } + + AutoSegment::create ( source, target, Constant::Vertical, AutoSegment::Local, true, vcollapse ); + + ltraceout(99); + + return target; + } + + + void GCellConfiguration::_GCell_rp_StairCaseH ( GCell* gcell, RoutingPad* rp1, RoutingPad* rp2 ) + { + ltrace(99) << "_GCell_rp_StairCaseH()" << endl; + + if ( rp1->getCenter().getX() > rp2->getCenter().getX() ) + swap ( rp1, rp2 ); + + AutoContact* rp1ContactSource; + AutoContact* rp1ContactTarget; + AutoContact* rp2ContactSource; + AutoContact* rp2ContactTarget; + const Layer* viaLayer; + + _GCell_rp_AutoContacts ( gcell, rp1, rp1ContactSource, rp1ContactTarget, true ); + _GCell_rp_AutoContacts ( gcell, rp2, rp2ContactSource, rp2ContactTarget, true ); + + if ( rp1ContactTarget->getY() == rp2ContactSource->getY() ) { + ltrace(99) << "Aligned horizontal routing pads : straight wire" << endl; + + viaLayer = rp1->getLayer (); + AutoSegment::create ( rp1ContactTarget + , rp2ContactSource + , Constant::Horizontal + , AutoSegment::Local + , true + ); + return; + } + + viaLayer = Session::getContactLayer(1); + + AutoContact* subContact1 = AutoContact::create ( gcell, rp1->getNet(), Session::getContactLayer(1) ); + AutoContact* subContact2 = AutoContact::create ( gcell, rp1->getNet(), Session::getContactLayer(1) ); + + AutoSegment::create ( rp1ContactTarget, subContact1 , Constant::Vertical , AutoSegment::Local, true ); + AutoSegment::create ( subContact1 , subContact2 , Constant::Horizontal, AutoSegment::Local, true ); + AutoSegment::create ( subContact1 , rp2ContactSource, Constant::Vertical , AutoSegment::Local, true ); + } + + + void GCellConfiguration::_GCell_rp_StairCaseV ( GCell* gcell, RoutingPad* rp1, RoutingPad* rp2 ) + { + ltrace(99) << "_GCell_rp_StairCaseV()" << endl; + + if ( rp1->getCenter().getY() > rp2->getCenter().getY() ) + swap ( rp1, rp2 ); + + AutoContact* rp1ContactSource; + AutoContact* rp1ContactTarget; + AutoContact* rp2ContactSource; + AutoContact* rp2ContactTarget; + const Layer* viaLayer; + + _GCell_rp_AutoContacts ( gcell, rp1, rp1ContactSource, rp1ContactTarget, false ); + _GCell_rp_AutoContacts ( gcell, rp2, rp2ContactSource, rp2ContactTarget, false ); + + if ( rp1ContactTarget->getX() == rp2ContactSource->getX() ) { + ltrace(99) << "Aligned vertical routing pads : straight wire" << endl; + + viaLayer = rp1->getLayer (); + AutoSegment::create ( rp1ContactTarget + , rp2ContactSource + , Constant::Vertical + , AutoSegment::Local + , true + ); + return; + } + + viaLayer = Session::getContactLayer(1); + + AutoContact* subContact1 = AutoContact::create ( gcell, rp1->getNet(), Session::getContactLayer(1) ); + AutoContact* subContact2 = AutoContact::create ( gcell, rp1->getNet(), Session::getContactLayer(1) ); + + AutoSegment::create ( rp1ContactTarget, subContact1 , Constant::Horizontal, AutoSegment::Local, true ); + AutoSegment::create ( subContact1 , subContact2 , Constant::Vertical , AutoSegment::Local, true ); + AutoSegment::create ( subContact2 , rp2ContactSource, Constant::Horizontal, AutoSegment::Local, true ); + } + + + AutoContact* GCellConfiguration::_GCell_L3V_L2H ( GCell* gcell + , Net* net + , AutoContact* source + , AutoContact* target + , bool hcollapse + , bool vcollapse + , bool terminal ) + { + AutoContact* subContact = AutoContact::create ( gcell, net, Session::getContactLayer(1) ); + + AutoSegment::create ( source, subContact, Constant::Vertical, AutoSegment::Local, terminal, vcollapse ); + + if ( !target ) + target = AutoContact::create ( gcell, net, Session::getContactLayer(1) ); + + AutoSegment::create ( subContact, target, Constant::Horizontal, AutoSegment::Local, terminal, hcollapse ); + + return target; + } + + + AutoContact* GCellConfiguration::_GCell_L2H_L3V ( GCell* gcell + , Net* net + , AutoContact* source + , AutoContact* target + , bool hcollapse + , bool vcollapse + , bool terminal ) + { + AutoContact* subContact = AutoContact::create ( gcell, net, Session::getContactLayer(1) ); + + AutoSegment::create ( source, subContact, Constant::Horizontal, AutoSegment::Local, terminal, hcollapse ); + + if ( !target ) { + target = AutoContact::create ( gcell, net, Session::getContactLayer(1) ); + } + + AutoSegment::create ( subContact, target, Constant::Vertical, AutoSegment::Local, terminal, vcollapse ); + + return target; + } + + + void GCellConfiguration::_GCell_1G_1L1 () + { + ltrace(99) << "_GCell_1G_1L1() [Managed Configuration - Optimized] " << _topology << endl; + ltracein(99); + + Hook* globalHook = NULL; + if ( _east ) globalHook = _east; + else if ( _west ) globalHook = _west; + else if ( _north ) globalHook = _north; + else if ( _south ) globalHook = _south; + + //Segment* globalSegment = dynamic_cast(globalHook->getComponent()); + //DbU::Unit length = (globalSegment) ? globalSegment->getLength() : 0; + + AutoContact* rpContact = _GCell_rp_Access ( _gcell + , _routingPads[0] + , (_topology & GLOBAL_HORIZONTAL_END) + , false //(length > DbU::lambda(50.0*2)) + ); + _GCell_GlobalContacts ( false, rpContact ); + + ltraceout(99); + } + + + void GCellConfiguration::_GCell_1G_xL1 () + { + ltrace(99) << "_GCell_1G_" << _state.fields.L1 << "L1() [Managed Configuration]" << endl; + ltracein(99); + + AutoContact* subContact = NULL; + if ( _topology & GLOBAL_VERTICAL_END ) { + ltrace(99) << "Global Vertical End" << endl; + + _southWestContact = AutoContact::create ( _gcell, _net, Session::getContactLayer(1) ); + //_southWestContact->setHAlignate ( true ); + + sort ( _routingPads.begin(), _routingPads.end(), SortRpByX(false) ); // increasing X. + for ( unsigned int i = 0 ; i < _routingPads.size() ; i++ ) { + subContact = _GCell_rp_Access ( _gcell, _routingPads[i], true, false ); + AutoSegment::create ( _southWestContact, subContact, Constant::Horizontal, AutoSegment::Local, true, false ); + } + } else { + ltrace(99) << "Global Horizontal End" << endl; + + if ( _east ) sort ( _routingPads.begin(), _routingPads.end(), SortRpByX(false) ); // increasing X. + else sort ( _routingPads.begin(), _routingPads.end(), SortRpByX(true ) ); // decreasing X. + + for ( unsigned int i = 0 ; i < _routingPads.size() ; i++ ) { + _southWestContact = _GCell_rp_Access ( _gcell, _routingPads[i], true, false ); + _southWestContact->setHAlignate ( true ); + + if ( i ) + AutoSegment::create ( subContact, _southWestContact, Constant::Horizontal, AutoSegment::Local, true, false ); + + subContact = _southWestContact; + } + } + + _northEastContact = _southWestContact; + + ltraceout(99); + } + + + void GCellConfiguration::_GCell_xG_1L1_1L2 () + { + ltrace(99) << "_GCell_xG_1L1_1L2() [Managed Configuration]" << endl; + ltracein(99); + + RoutingPad* rpL1; + RoutingPad* rpL2; + if ( _routingPads[0]->getLayer() == Session::getRoutingLayer(0) ) { + rpL1 = _routingPads[0]; + rpL2 = _routingPads[1]; + } else { + rpL1 = _routingPads[1]; + rpL2 = _routingPads[0]; + } + ltrace(99) << "rpL1 := " << rpL1 << endl; + ltrace(99) << "rpL2 := " << rpL2 << endl; + + AutoContact* rpL1ContactSource; + AutoContact* rpL1ContactTarget; + AutoContact* rpL2ContactSource; + AutoContact* rpL2ContactTarget; + + _GCell_rp_AutoContacts ( _gcell, rpL1, rpL1ContactSource, rpL1ContactTarget, true ); + AutoContact* subContact = AutoContact::create ( _gcell, _net, Session::getContactLayer(1) ); + AutoSegment::create ( rpL1ContactSource, subContact, Constant::Horizontal, AutoSegment::Local, true ); + + _GCell_rp_AutoContacts ( _gcell, rpL2, rpL2ContactSource, rpL2ContactTarget, false ); + AutoSegment::create ( rpL2ContactSource, subContact, Constant::Vertical, AutoSegment::Local, true ); + + if ( _state.fields.globals > 0 ) { + _GCell_rp_AutoContacts ( _gcell, rpL2, _southWestContact, subContact, (_south == NULL) ); + if ( _state.fields.globals > 2 ) { + _GCell_rp_AutoContacts ( _gcell, rpL2, _northEastContact, subContact, (_north == NULL) ); + } else + _northEastContact = _southWestContact; + } + + ltraceout(99); + } + + + void GCellConfiguration::_GCell_xG_xL1_xL3 () + { + ltrace(99) << "_GCell_xG_" << _state.fields.L1 + << "L1_" << _state.fields.L3 + << "L3() [G:" << _state.fields.globals << " Managed Configuration]" << endl; + ltracein(99); + ltrace(99) << "_topology: " << _topology << endl; + ltrace(99) << "_north: " << _north << endl; + ltrace(99) << "_south: " << _south << endl; + ltrace(99) << "_east: " << _east << endl; + ltrace(99) << "_west: " << _west << endl; + + bool hsmall = false; + bool vsmall = false; + bool punctual = false; + AutoSegment* segment = NULL; + + sort ( _routingPads.begin(), _routingPads.end(), SortRpByX(false) ); // increasing X. + if ( _topology & GLOBAL_HORIZONTAL ) { + AutoContact* subContact1 = NULL; + AutoContact* subContact2 = NULL; + for ( unsigned int i = 0 ; i < _routingPads.size() ; i++ ) { + subContact1 = _GCell_rp_Access ( _gcell, _routingPads[i], true, false ); + subContact1->setHAlignate ( true ); + + if ( i ) { + segment = AutoSegment::create ( subContact1 + , subContact2 + , Constant::Horizontal + , AutoSegment::Local + , true + , false ); + segment->setStrap ( true ); + } else + _southWestContact = subContact1; + + subContact2 = subContact1; + } + _northEastContact = subContact1; + } else { + ltrace(99) << "Not straight horizontal " << _south << endl; + + _GCell_GlobalContacts ( _topology & GLOBAL_SPLIT ); + AutoContact* localContact = (_south) ? _southWestContact : _northEastContact; + //localContact->setHAlignate ( true ); + + for ( unsigned int i = 0 ; i < _routingPads.size() ; i++ ) { + AutoContact* rpContact = _GCell_rp_Access ( _gcell, _routingPads[i], true, false ); + segment = AutoSegment::create ( rpContact + , localContact + , Constant::Horizontal + , AutoSegment::Local + , true + , false ); + setIsRoutingPadSmall ( _routingPads[i], hsmall, vsmall, punctual ); + if ( not vsmall ) segment->setStrap ( true ); + } + + if ( _topology & (GLOBAL_VERTICAL|GLOBAL_FORK) ) { + ltrace(99) << "Global Vertical/Global fork " << _south << endl; + + unsigned int direction = (not _south or not _north) ? Constant::Vertical : Constant::Horizontal; + segment = AutoSegment::create ( _southWestContact + , _northEastContact + , direction + , AutoSegment::Local + , false + , false + ); + segment->setStrap ( true ); + + if ( direction == Constant::Vertical ) { + if ( !_south ) _northEastContact->setVAlignate ( true ); + else _southWestContact->setVAlignate ( true ); + } + } + } + + ltraceout(99); + } + + + void GCellConfiguration::_GCell_xG_xL2 () + { + ltrace(99) << "_GCell_" + << _state.fields.globals << "G_" + << _state.fields.L2 << "L2() [Managed Configuration - x]" << endl; + ltracein(99); + + unsigned int lastRP = _routingPads.size() - 1; + RoutingPad* biggestRP = _routingPads[lastRP]; + + sort ( _routingPads.begin(), _routingPads.end(), SortRpByX(false) ); // increasing X. + + for ( unsigned int i = 0 ; i < lastRP ; i++ ) { + _GCell_rp_StairCaseH ( _gcell, _routingPads[i], _routingPads[i+1] ); + if ( _routingPads[i]->getBoundingBox().getWidth() + > biggestRP->getBoundingBox().getWidth() ) + biggestRP = _routingPads[i]; + } + + RoutingPad* leftRP = biggestRP; + RoutingPad* rightRP = biggestRP; + + switch ( _topology ) { + case GLOBAL_VERTICAL_END: break; + case GLOBAL_HORIZONTAL_END: + if ( _west ) leftRP = _routingPads[0]; + if ( _east ) leftRP = _routingPads[lastRP]; + rightRP = leftRP; + break; + case GLOBAL_HORIZONTAL: + leftRP = _routingPads[0]; + rightRP = _routingPads[lastRP]; + break; + case GLOBAL_VERTICAL: break; + case GLOBAL_BEND: break; + case GLOBAL_FORK: break; + } + + AutoContact* subContact; + if ( leftRP == rightRP ) { + _GCell_rp_AutoContacts ( _gcell, leftRP, _southWestContact, _northEastContact, (_south == NULL) && (_north == NULL) ); + //_northEastContact = _southWestContact; + } else { + ltrace(99) << "Using separate global contacts" << endl; + _GCell_rp_AutoContacts ( _gcell, leftRP , _southWestContact, subContact, (_south == NULL) ); + _GCell_rp_AutoContacts ( _gcell, rightRP, subContact, _northEastContact, (_north == NULL) ); + ltrace(99) << "leftRp: " << leftRP->getCenter() << " " << leftRP << endl; + ltrace(99) << "rightRp: " << rightRP->getCenter() << " " << rightRP << endl; + } + + ltraceout(99); + } + + + void GCellConfiguration::_GCell_1G_1L3 () + { + ltrace(99) << "_GCell_1G_1L3() [Optimised Configuration]" << endl; + ltracein(99); + + bool useEnds = (_north != NULL) or (_south != NULL); + + _GCell_rp_AutoContacts ( _gcell + , _routingPads[0] + , _southWestContact + , _northEastContact + , not useEnds + ); + + ltrace(99) << "_southWest: " << _southWestContact << endl; + ltrace(99) << "_northEast: " << _northEastContact << endl; + + if ( useEnds ) { + ltrace(99) << "Using Ends" << endl; + if ( _north != NULL ) { + ltrace(99) << _gcell << endl; + ltrace(99) << "Using _northEast, _north: " << _north << endl; + ltrace(99) << " _south: " << _south << endl; + _southWestContact = _northEastContact; + } + + //AutoContact* subContact = AutoContact::create ( _gcell, _net, Session::getContactLayer(1) ); + //AutoSegment::create ( _southWestContact, subContact, Constant::Horizontal, AutoSegment::Local, true ); + + //_southWestContact = _northEastContact = subContact; + } else { + if ( _routingPads[0]->getBoundingBox().getHeight() < DbU::lambda(15) ) { + AutoContact* subContact = AutoContact::create ( _gcell, _net, Session::getContactLayer(1) ); + AutoSegment::create ( _southWestContact, subContact, Constant::Vertical, AutoSegment::Local, true ); + + _southWestContact = _northEastContact = subContact; + } + } + ltraceout(99); + } + + + void GCellConfiguration::_GCell_xG_xL3 () + { + ltrace(99) << "_GCell_xG_" << _state.fields.L3 + << "L3() [Managed Configuration]" << endl; + ltracein(99); + + AutoContact* unusedContact; + + if ( _south ) sort ( _routingPads.begin(), _routingPads.end(), SortRpByY(false) ); // increasing Y. + else sort ( _routingPads.begin(), _routingPads.end(), SortRpByY(true ) ); // decreasing Y. + + for ( unsigned int i = 1 ; i < _routingPads.size() ; i++ ) { + _GCell_rp_StairCaseV ( _gcell, _routingPads[i-1], _routingPads[i] ); + } + + if ( _west or _south ) { + _GCell_rp_AutoContacts ( _gcell, _routingPads[0], _southWestContact, unusedContact, false ); + // _southWestContact = AutoContact::fromRp ( _gcell + // , _routingPads[0] + // , Session::getContactLayer(1) + // , _routingPads[0]->getCenter() + // , DbU::lambda(1.0), DbU::lambda(1.0) + // ); + } + + if ( _west and not _south ) { + AutoContact* subContact = AutoContact::create ( _gcell, _net, Session::getContactLayer(1) ); + + AutoSegment::create ( subContact, _southWestContact, Constant::Vertical, AutoSegment::Local, true ); + _southWestContact = subContact; + } + + if ( _east or _north ) { + _GCell_rp_AutoContacts ( _gcell, _routingPads[0], unusedContact, _northEastContact, false ); + // _northEastContact = AutoContact::fromRp ( _gcell + // , _routingPads[_routingPads.size()-1] + // , Session::getContactLayer(1) + // , _routingPads[_routingPads.size()-1]->getCenter() + // , DbU::lambda(1.0), DbU::lambda(1.0) + // ); + } + + if ( _east and not _north ) { + AutoContact* subContact = AutoContact::create ( _gcell, _net, Session::getContactLayer(1) ); + + AutoSegment::create ( subContact, _northEastContact, Constant::Vertical, AutoSegment::Local, true ); + _northEastContact = subContact; + } + + if ( !_southWestContact ) _southWestContact = _northEastContact; + if ( !_northEastContact ) _northEastContact = _southWestContact; + + ltraceout(99); + } + + + void singleGCell ( KatabaticEngine* ktbt, Net* net ) + { + ltrace(99) << "singleGCell () " << net << endl; + ltracein(99); + + vector routingPads; + + forEach ( RoutingPad*, irp, net->getRoutingPads() ) { + routingPads.push_back ( *irp ); + } + + if ( routingPads.size() < 2 ) { + cerr << Error("For %s, less than two Plugs/Pins (%d)." + ,getString(net).c_str() + ,routingPads.size()) << endl; + ltraceout(99); + return; + } + + if ( routingPads.size() > 2 ) { + cerr << Error("For %s, more than two Plugs/Pins (%d) in single GCell." + ,getString(net).c_str() + ,routingPads.size()) << endl; + ltraceout(99); + return; + } + + GCell* gcell = ktbt->getGCellGrid()->getGCell ( routingPads[0]->getCenter() + , routingPads[1]->getCenter() ); + + if ( !gcell ) { + cerr << Error("No GCell under %s.",getString(routingPads[0]).c_str()) << endl; + ltraceout(99); + return; + } + + ltrace(80) << "singleGCell " << gcell << endl; + + AutoContact* dummy = NULL; + AutoContact* source = NULL; + AutoContact* target = NULL; + GCellConfiguration::_GCell_rp_AutoContacts ( gcell, routingPads[0], source, dummy, true ); + GCellConfiguration::_GCell_rp_AutoContacts ( gcell, routingPads[1], target, dummy, true ); + + // AutoContact* source = AutoContact::fromRp ( gcell + // , routingPads[0] + // , Session::getContactLayer(0) + // , routingPads[0]->getCenter() + // , DbU::lambda(1.0), DbU::lambda(1.0) + // ); + // AutoContact* target = AutoContact::fromRp ( gcell + // , routingPads[1] + // , Session::getContactLayer(0) + // , routingPads[1]->getCenter() + // , DbU::lambda(1.0), DbU::lambda(1.0) + // ); + + Box sourceBox = source->getNativeConstraintBox (); + Box targetBox = target->getNativeConstraintBox (); + + if ( ( sourceBox.getYMax() < targetBox.getYMin() ) + || ( sourceBox.getYMin() > targetBox.getYMax() ) ) { + AutoContact* subContact1 = AutoContact::create ( gcell, net, Session::getContactLayer(1) ); + AutoSegment::create ( source, subContact1, Constant::Vertical, AutoSegment::Local, true ); + + AutoContact* subContact2 = AutoContact::create ( gcell, net, Session::getContactLayer(1) ); + AutoSegment::create ( target, subContact2, Constant::Vertical, AutoSegment::Local, true ); + + AutoSegment::create ( subContact1, subContact2, Constant::Horizontal, AutoSegment::Local, false ); + } else + AutoSegment::create ( source, target, Constant::Horizontal, AutoSegment::Local, true ); + + ltraceout(99); + } + + +} // End of anonymous namespace. + + + + +namespace Katabatic { + + + using Hurricane::DebugSession; + using Hurricane::Error; + using Hurricane::Warning; + using Hurricane::Bug; + + + void KatabaticEngine::_loadGrByNet () + { + cmess1 << " o Loading Nets global routing from Knik." << endl; + + startMeasures (); + Session::open ( this ); + + sort ( _routingNets.begin(), _routingNets.end(), NetCompareByName() ); + for ( size_t i=0 ; i < _routingNets.size() ; i++ ) + _loadNetGlobalRouting ( _routingNets[i] ); + + Session::revalidate (); + + for ( size_t i=0 ; i < _routingNets.size() ; i++ ) + _toOptimals ( _routingNets[i] ); + + Session::revalidate (); + +#if defined(CHECK_DATABASE) + _check ( "after Katabatic loading" ); +#endif + + _print (); + //_gcellGrid->checkEdgeSaturation ( 0.60 ); + Session::close (); + + stopMeasures (); + printMeasures (); + } + + + void KatabaticEngine::_loadNetGlobalRouting ( Net* net ) + { + DebugSession::open ( net, 80 ); + + ltrace(100) << "Katabatic::_loadNetGlobalRouting ( " << net << " )" << endl; + ltracein(99); + + cmess2 << " - " << net << endl; + + ForkStack forks; + Hook* sourceHook = NULL; + AutoContact* sourceContact = NULL; + + lookupClear (); + + RoutingPads routingPads = net->getRoutingPads (); + if ( routingPads.getSize() < 2 ) { +#if 0 + if ( !getDemoMode() ) + cmess2 << Warning("Net \"%s\" have less than 2 plugs/pins (ignored)." + ,getString(net->getName()).c_str()) << endl; +#endif + ltraceout(99); + return; + } + + ltracein(99); + Hook* startHook = NULL; + GCell* lowestGCell = NULL; + ltrace(99) << "Start RoutingPad Ring" << endl; + forEach ( RoutingPad*, startRp, routingPads ) { + forEach ( Hook*, ihook, startRp->getBodyHook()->getHooks() ) { + ltrace(99) << "Component " << ihook->getComponent() << endl; + Segment* segment = dynamic_cast(ihook->getComponent()); + + if ( segment ) { + GCellConfiguration gcellConf ( getGCellGrid(), *ihook, NULL ); + if ( gcellConf.getStateG() == 1 ) { + if ( !lowestGCell || (lowestGCell->getIndex() > gcellConf.getGCell()->getIndex()) ) { + ltrace(99) << "Starting from GCell " << gcellConf.getGCell() << endl; + lowestGCell = gcellConf.getGCell(); + startHook = *ihook; + } + break; + } + } + } + // Comment the next line to enable the lowest GCell search. + //if ( startHook ) break; + } + ltraceout(99); + + if ( !startHook ) { singleGCell ( this, net ); ltraceout(99); return; } + + GCellConfiguration startGCellConf ( getGCellGrid(), startHook, NULL ); + startGCellConf.construct ( forks ); + + sourceHook = forks.getFrom (); + sourceContact = forks.getContact (); + forks.pop (); + + while ( sourceHook ) { + GCellConfiguration gcellConf ( getGCellGrid(), sourceHook, sourceContact ); + gcellConf.construct ( forks ); + + sourceHook = forks.getFrom (); + sourceContact = forks.getContact (); + forks.pop (); + } + + lookupClear (); + + ltraceout(99); + + DebugSession::close (); + } + + +} // End of Katabatic namespace. diff --git a/katabatic/src/NetConstraints.cpp b/katabatic/src/NetConstraints.cpp new file mode 100644 index 00000000..46e20205 --- /dev/null +++ b/katabatic/src/NetConstraints.cpp @@ -0,0 +1,367 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2008, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | K a t a b a t i c - Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Module : "./NetConstraints.cpp" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#include +#include + +#include "hurricane/DebugSession.h" +#include "hurricane/BasicLayer.h" +#include "hurricane/Net.h" +#include "hurricane/NetExternalComponents.h" +#include "hurricane/RoutingPad.h" +#include "hurricane/Pad.h" +#include "hurricane/Plug.h" +#include "hurricane/Instance.h" +#include "hurricane/Vertical.h" +#include "hurricane/Horizontal.h" +#include "hurricane/Cell.h" + +#include "katabatic/AutoContact.h" +#include "katabatic/AutoSegment.h" +#include "katabatic/Session.h" +#include "katabatic/KatabaticEngine.h" + + +namespace { + + + //! \addtogroup NetConstraints + //! \{ + + /*! \function void propagateConstraintFromRp ( RoutingPad* rp ) + * \param rp The \c RoutingPad starting point. + * + * Do a full constraint propagation starting from this \c RoutingPad. + */ + + /*! \function void propagateConstraint ( AutoContactStack& segmentStack, DbU::Unit constraintMin, DbU::Unit constraintMax, unsigned int direction ) + * \param segmentStack A vector of \c AutoSegment. + * \param constraintMin The interval lower bound. + * \param constraintMax The interval upper bound. + * \param direction The propagation direction. + * + * Propagate the constraint in the appropriate direction through the vector + * of \c AutoSegments and any other linked through collapse. + */ + + //! \} + + + using namespace std; + using namespace CRL; + using namespace Hurricane; + using namespace Katabatic; + + +// ----------------------------------------------------------------- +// Local Functions. + + + void propagateConstraint ( AutoContactStack& segmentStack + , DbU::Unit constraintMin + , DbU::Unit constraintMax + , unsigned int direction + ) + { + ltracein(99); + + while ( !segmentStack.isEmpty() ) { + AutoContact* sourceContact = segmentStack.getAutoContact (); + Segment* sourceSegment = segmentStack.getSegment (); + + segmentStack.pop (); + + if ( sourceContact->isAlignate(direction) ) { + ltrace(99) << "Apply to (source): " << (void*)sourceContact->base() << ":" << sourceContact << endl; + sourceContact->restrictConstraintBox ( constraintMin, constraintMax, direction ); + } + + AutoSegment* sourceAutoSegment = Session::lookup ( sourceSegment ); + + forEach ( Component*, icomponent, sourceContact->getSlaveComponents() ) { + if ( *icomponent == sourceSegment ) continue; + + Segment* targetSegment = dynamic_cast(*icomponent); + if ( !targetSegment ) continue; + + AutoSegment* targetAutoSegment = Session::lookup ( targetSegment ); + if ( !targetAutoSegment ) { + const BasicLayer* basicLayer = dynamic_cast(targetSegment->getLayer()); + if ( basicLayer && basicLayer->getMaterial() != BasicLayer::Material::metal ) + continue; + + cerr << Error("Can't lookup for ",getString(targetSegment).c_str()) << endl; + continue; + } + + AutoContact* targetContact = Session::lookup + ( dynamic_cast(targetAutoSegment->getOppositeAnchor(sourceContact->base())) ); + + if ( sourceAutoSegment && targetAutoSegment ) { + unsigned int state = AutoSegment::getPerpandicularState + ( sourceContact + , sourceAutoSegment + , targetAutoSegment + , (direction & Constant::Horizontal)?true:false + ); + + if ( !( state & (AutoSegment::PerpandicularIndirect + |AutoSegment::ParallelOrExpanded + |AutoSegment::ParallelAndLayerChange )) ) { + segmentStack.push ( targetContact, targetSegment ); + + if ( targetAutoSegment + && (targetAutoSegment->getDirection() == direction) + && targetContact->isAlignate(direction) ) { + ltrace(99) << "Apply to (target): " << (void*)targetContact->base() << ":" << targetContact << endl; + targetContact->restrictConstraintBox ( constraintMin, constraintMax, direction ); + } + continue; + } + } + + } + } + + ltraceout(99); + ltrace(99) << "Finished propagating." << endl; + } + + + void propagateConstraintFromRp ( RoutingPad* rp ) + { + ltrace(99) << "propagateConstraintFromRp() - " << (void*)rp << " " << rp << endl; + + forEach ( Component*, icomponent, rp->getSlaveComponents() ) { + ltrace(99) << "slave: " << *icomponent << endl; + AutoContact* contact = Session::lookup ( dynamic_cast(*icomponent) ); + if ( contact ) { + ltrace(99) << "Start slave: " << (void*)contact->getContact() << ":" << contact << endl; + + set collapsedContactsSet; + AutoContactStack collapsedContactsStack; + AutoContactStack verticalSegmentsStack; + AutoContactStack horizontalSegmentsStack; + + collapsedContactsStack.push ( contact, NULL ); + collapsedContactsSet.insert ( contact ); + + // Find all AutoContacts directly collapeds on the RoutingPad. + while ( !collapsedContactsStack.isEmpty() ) { + AutoContact* sourceContact = collapsedContactsStack.getAutoContact (); + Segment* sourceSegment = collapsedContactsStack.getSegment (); + Segment* segment; + + collapsedContactsStack.pop (); + + forEach ( Component*, icomponent2, sourceContact->getSlaveComponents() ) { + bool isHorizontal = true; + segment = dynamic_cast(*icomponent2); + if ( !segment && (segment = dynamic_cast(*icomponent2)) ) + isHorizontal = false; + if ( !segment || (segment == sourceSegment) ) continue; + + AutoSegment* autoSegment = Session::lookup ( segment ); + if ( !autoSegment ) { + const BasicLayer* basicLayer = dynamic_cast(segment->getLayer()); + if ( basicLayer && basicLayer->getMaterial() != BasicLayer::Material::metal ) + continue; + cerr << Error("Can't lookup for %s.",getString(segment).c_str()) << endl; + continue; + } + + ltrace(99) << "Examining: " << autoSegment << endl; + + AutoContact* targetContact = Session::lookup + ( dynamic_cast(autoSegment->getOppositeAnchor(sourceContact->base())) ); + + if ( targetContact ) { + if ( !autoSegment->isCollapsed() ) { + if ( isHorizontal ) { + ltrace(99) << "On horizontal stack " << (void*)segment << ":" << segment << endl; + horizontalSegmentsStack.push ( targetContact, segment ); + } else { + ltrace(99) << "On vertical stack " << (void*)segment << ":" << segment << endl; + verticalSegmentsStack.push ( targetContact, segment ); + } + } else { + ltrace(99) << "On collapsed stack " << (void*)segment << ":" << segment << endl; + collapsedContactsStack.push ( targetContact, segment ); + collapsedContactsSet.insert ( targetContact ); + } + } + } + } + + // compute constraint on all AutoContacts collapseds, + // then sets all the constraint Box to the intersection. + ltrace(99) << "Computing constraint:" << endl; + ltracein(99); + set::iterator it = collapsedContactsSet.begin(); + set::iterator end = collapsedContactsSet.end(); + ltrace(99) << *it << " " << (*it)->getConstraintBox() << endl; + Box constraintBox = (*it++)->getConstraintBox (); + for ( ; it != end ; it++ ) { + (*it)->intersectConstraintBox ( constraintBox ); + ltrace(99) << *it << " " << constraintBox << endl; + } + + if ( constraintBox.isEmpty() ) { + cerr << "[ERROR] incompatible segment collapse for " << rp << endl; + ltraceout(99); + break; + } + ltraceout(99); + + ltrace(99) << "Applying constraint " << constraintBox << " to:" << endl; + ltracein(99); + it = collapsedContactsSet.begin(); + for ( ; it != end ; it++ ) { + ltrace(99) << *it << endl; + (*it)->setConstraintBox ( constraintBox ); + } + ltraceout(99); + + // Propagate constraint through horizontally bound segments. + ltrace(99) << "Propagate constraint on horizontal segments" << endl; + propagateConstraint ( horizontalSegmentsStack + , constraintBox.getYMin() + , constraintBox.getYMax() + , Constant::Horizontal ); + + // Propagate constraint through vertically bound segments. + ltrace(99) << "Propagate constraint on vertical segments" << endl; + propagateConstraint ( verticalSegmentsStack + , constraintBox.getXMin() + , constraintBox.getXMax() + , Constant::Vertical ); + } + } + + ltrace(99) << "propagateConstraintFromRp() - Exit" << endl; + } + + +} // End of local namespace. + + + + +namespace Katabatic { + + + using Hurricane::Cell; + + + void KatabaticEngine::_computeNetConstraints ( Net* net ) + { + DebugSession::open ( net ); + + ltrace(100) << "Katabatic::_computeNetConstraints ( " << net << " )" << endl; + ltracein(99); + + //cmess2 << " - " << net << endl; + + vector routingPads; + forEach ( Component*, icomponent, net->getComponents() ) { + Contact* contact = dynamic_cast(*icomponent); + if ( contact ) { + AutoContact* autoContact = Session::lookup ( contact ); + if ( autoContact ) + autoContact->restoreNativeConstraintBox (); + } else { + RoutingPad* routingPad = dynamic_cast(*icomponent); + if ( routingPad ) routingPads.push_back ( routingPad ); + } + } + + for ( size_t i=0 ; i processeds; + forEach ( Segment*, isegment, net->getSegments() ) { + AutoSegment* autoSegment = Session::lookup ( *isegment ); + if ( !autoSegment ) continue; + autoSegment->toConstraintAxis ( &processeds ); + } + + ltraceout(99); + + DebugSession::close (); + } + + + void KatabaticEngine::_collapseNets ( Nets nets, unsigned int depth ) + { + forEach ( Net*, inet, nets ) + _collapseNet ( *inet, depth ); + } + + + void KatabaticEngine::_collapseNet ( const Name& name, unsigned int depth ) + { + Net* net = getCell()->getNet ( name ); + + if ( !net ) { + cerr << Error("No net %s in %s" + ,getString(name).c_str() + ,getString(getCell()).c_str()) << endl; + return; + } + + _collapseNet ( net ); + } + + + void KatabaticEngine::_collapseNet ( Net* net, unsigned int depth ) + { + ltrace(100) << "Katabatic::_collapseNet ( " << net << " )" << endl; + ltracein(99); + + forEach ( Component*, icomponent, net->getComponents() ) { + RoutingPad* routingPad = dynamic_cast(*icomponent); + if ( routingPad ) { + ltrace(99) << "RoutingPad " << routingPad << endl; + forEach ( Component*, islaveComponent, routingPad->getSlaveComponents() ) { + ltrace(99) << "SlaveComponent " << *islaveComponent << endl; + Segment* segment = dynamic_cast(*islaveComponent); + if ( segment ) { + AutoSegment* autoSegment = Session::lookup ( segment ); + if ( !autoSegment ) continue; + + if ( autoSegment->isLocal() ) { + ltrace(99) << "Collapsing " << autoSegment << endl; + autoSegment->collapse (); + } + } + } // islaveComponent. + } + } // icomponent. + + ltraceout(99); + } + + +} // End of Katabatic namespace. diff --git a/katabatic/src/NetOptimals.cpp b/katabatic/src/NetOptimals.cpp new file mode 100644 index 00000000..2bcfbea1 --- /dev/null +++ b/katabatic/src/NetOptimals.cpp @@ -0,0 +1,105 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2008, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | K a t a b a t i c - Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Module : "./NetOptimals.cpp" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#include +#include + +#include "hurricane/DebugSession.h" +#include "hurricane/Net.h" +#include "hurricane/Segment.h" +#include "katabatic/Session.h" +#include "katabatic/AutoSegment.h" +#include "katabatic/KatabaticEngine.h" + + +namespace Katabatic { + + + using namespace std; + using Hurricane::tab; + using Hurricane::ltracein; + using Hurricane::ltraceout; + using Hurricane::inltrace; + using Hurricane::ForEachIterator; + using Hurricane::Net; + using Hurricane::Segment; + using Hurricane::DebugSession; + + + void KatabaticEngine::_computeNetOptimals ( Net* net ) + { + DebugSession::open ( net, 88 ); + + ltrace(100) << "Katabatic::_computeNetOptimals ( " << net << " )" << endl; + ltracein(99); + + //cmess2 << " - " << net << endl; + + vector segments; + forEach ( Segment*, segment, net->getSegments() ) { + AutoSegment* autoSegment = Session::lookup ( *segment ); + if ( !autoSegment ) continue; + segments.push_back ( autoSegment ); + } + sort ( segments.begin(), segments.end(), AutoSegment::CompareCanonical() ); + + set processeds; + for ( size_t i=0 ; icomputeOptimal ( &processeds ); + + ltraceout(99); + + DebugSession::close (); + } + + + void KatabaticEngine::_toOptimals ( Net* net, bool onlyNew ) + { + DebugSession::open ( net, 88 ); + + ltrace(100) << "Katabatic::_toOptimals ( " << net << " )" << endl; + ltracein(99); + + //cmess2 << " - " << net << endl; + + vector segments; + forEach ( Segment*, segment, net->getSegments() ) { + AutoSegment* autoSegment = Session::lookup ( *segment ); + if ( not autoSegment ) continue; + segments.push_back ( autoSegment ); + } + sort ( segments.begin(), segments.end(), AutoSegment::CompareCanonical() ); + + set processeds; + for ( size_t i=0 ; itoOptimalAxis ( &processeds ); + + ltraceout(99); + + DebugSession::close (); + } + + +} // End of Katabatic namespace. diff --git a/katabatic/src/PowerRails.cpp b/katabatic/src/PowerRails.cpp new file mode 100644 index 00000000..c972c662 --- /dev/null +++ b/katabatic/src/PowerRails.cpp @@ -0,0 +1,513 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | K a t a b a t i c - Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Header : "./PowerRails.cpp" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#include + +#include "hurricane/Warning.h" +#include "hurricane/DataBase.h" +#include "hurricane/Technology.h" +#include "hurricane/Horizontal.h" +#include "hurricane/Vertical.h" +#include "hurricane/Net.h" +#include "hurricane/NetExternalComponents.h" +#include "hurricane/Cell.h" +#include "hurricane/Instance.h" +#include "crlcore/RoutingLayerGauge.h" +#include "crlcore/RoutingGauge.h" +#include "katabatic/KatabaticEngine.h" + + +namespace { + + + using namespace std; + using namespace Hurricane; + + +// ------------------------------------------------------------------- +// Class : "::RailSegment". + + + class RailSegment { + public: + RailSegment ( DbU::Unit axis, DbU::Unit width ); + inline DbU::Unit getAxis () const; + inline DbU::Unit getMin () const; + inline DbU::Unit getMax () const; + inline const Interval& getSpan () const; + inline DbU::Unit getWidth () const; + void merge ( DbU::Unit ); + void doLayout ( Cell*, Net*, const Layer*, Constant::Direction ) const; + private: + DbU::Unit _axis; + DbU::Unit _width; + Interval _span; + }; + + + RailSegment::RailSegment ( DbU::Unit axis, DbU::Unit width ) + : _axis (axis) + , _width(width) + , _span () + { } + + + inline DbU::Unit RailSegment::getAxis () const { return _axis; } + inline DbU::Unit RailSegment::getMin () const { return _span.getVMin(); } + inline DbU::Unit RailSegment::getMax () const { return _span.getVMax(); } + inline const Interval& RailSegment::getSpan () const { return _span; } + inline DbU::Unit RailSegment::getWidth () const { return _width; } + inline void RailSegment::merge ( DbU::Unit bound ) { _span.merge(bound); } + + + void RailSegment::doLayout ( Cell* cell, Net* net, const Layer* layer, Constant::Direction direction ) const + { + Segment* segment = NULL; + + switch ( direction ) { + case Constant::Horizontal: + segment = Horizontal::create ( net + , layer + , _axis + , _width + , _span.getVMin() + , _span.getVMax() ); + break; + case Constant::Vertical: + segment = Vertical::create ( net + , layer + , _axis + , _width + , _span.getVMin() + , _span.getVMax() ); + break; + } + + if ( segment ) + NetExternalComponents::setExternal ( segment ); + } + + +// ------------------------------------------------------------------- +// Class : "::PowerRail". + + + class PowerRail { + public: + struct CompareByAxis : binary_function { + bool operator() ( const PowerRail* lhs, const PowerRail* rhs ); + }; + public: + PowerRail ( Net::Type, const Layer*, Constant::Direction, DbU::Unit axis ); + ~PowerRail (); + inline Net::Type getType () const; + inline const Layer* getLayer () const; + inline DbU::Unit getAxis () const; + void merge ( DbU::Unit width, DbU::Unit min, DbU::Unit max ); + void doLayout ( Cell*, Net* powerNet, Net* groundNet ) const; + private: + Net::Type _type; + const Layer* _layer; + Constant::Direction _direction; + DbU::Unit _axis; + list _segments; + }; + + + PowerRail::PowerRail ( Net::Type type, const Layer* layer, Constant::Direction direction, DbU::Unit axis ) + : _type (type) + , _layer (layer) + , _direction(direction) + , _axis (axis) + , _segments () + { } + + + PowerRail::~PowerRail () + { + while ( !_segments.empty() ) { + delete _segments.front (); + _segments.pop_front (); + } + } + + + inline Net::Type PowerRail::getType () const { return _type; } + inline const Layer* PowerRail::getLayer () const { return _layer; } + inline DbU::Unit PowerRail::getAxis () const { return _axis; } + + + void PowerRail::merge ( DbU::Unit width, DbU::Unit min, DbU::Unit max ) + { + RailSegment* inserted = NULL; + + list::iterator isegment = _segments.begin(); + for ( ; (isegment != _segments.end()) && !inserted ; isegment++ ) { + if ( (*isegment)->getWidth() != width ) continue; + + if ( (*isegment)->getMin() > max ) { + inserted = new RailSegment ( _axis, width ); + inserted->merge ( min ); + inserted->merge ( max ); + _segments.insert ( isegment, inserted ); + + break; + } + if ( (*isegment)->getMax() < min ) { + continue; + } + + inserted = *isegment; + (*isegment)->merge ( min ); + (*isegment)->merge ( max ); + + list::iterator imerge = isegment; + if ( imerge != _segments.end() ) imerge++; + + while ( imerge != _segments.end() ) { + if ( (*imerge)->getMin() > (*isegment)->getMax() ) break; + + (*isegment)->merge ( (*imerge)->getMax() ); + + delete *imerge; + _segments.erase ( imerge ); + imerge = isegment; + imerge++; + } + + break; + } + + if ( !inserted ) { + inserted = new RailSegment ( _axis, width ); + inserted->merge ( min ); + inserted->merge ( max ); + _segments.insert ( _segments.end(), inserted ); + } + } + + + void PowerRail::doLayout ( Cell* cell, Net* powerNet, Net* groundNet ) const + { + //const Layer* layer = DataBase::getDB()->getTechnology()->getLayer("METAL1"); + + Net* railNet = (_type == Net::Type::POWER) ? powerNet : groundNet; + + list::const_iterator isegment = _segments.begin(); + for ( ; isegment != _segments.end() ; isegment++ ) + (*isegment)->doLayout ( cell, railNet, _layer, _direction ); + } + + + bool PowerRail::CompareByAxis::operator() ( const PowerRail* lhs, const PowerRail* rhs ) + { return lhs->getAxis() < rhs->getAxis(); } + + +// ------------------------------------------------------------------- +// Class : "::PowerPlane". + + + class PowerPlane { + public: + PowerPlane ( const Layer* ); + ~PowerPlane (); + inline const Layer* getLayer () const; + size_t find ( DbU::Unit axis, Constant::Direction ) const; + void merge ( Net::Type, Constant::Direction, DbU::Unit axis, DbU::Unit width, DbU::Unit min, DbU::Unit max ); + void doLayout ( Cell* cell, Net* powerNet, Net* groundNet ) const; + private: + const Layer* _layer; + vector _hrails; + vector _vrails; + }; + + + PowerPlane::PowerPlane ( const Layer* layer ) + : _layer (layer) + , _hrails() + , _vrails() + { } + + + PowerPlane::~PowerPlane () + { + while ( !_hrails.empty() ) { + delete _hrails.back(); + _hrails.pop_back (); + } + while ( !_vrails.empty() ) { + delete _vrails.back(); + _vrails.pop_back (); + } + } + + + size_t PowerPlane::find ( DbU::Unit axis, Constant::Direction direction ) const + { + PowerRail bound(Net::Type::GROUND,NULL,Constant::Horizontal,axis); + + if ( direction == Constant::Horizontal ) { + vector::const_iterator it + = lower_bound(_hrails.begin(),_hrails.end(),&bound,PowerRail::CompareByAxis()); + return it - _hrails.begin(); + } + + vector::const_iterator it + = lower_bound(_vrails.begin(),_vrails.end(),&bound,PowerRail::CompareByAxis()); + return it - _vrails.begin(); + } + + + void PowerPlane::merge ( Net::Type type + , Constant::Direction direction + , DbU::Unit axis + , DbU::Unit width + , DbU::Unit rmin + , DbU::Unit rmax + ) + { + vector* rails; + + switch ( direction ) { + case Constant::Vertical : rails = &_vrails; break; + case Constant::Horizontal: + default: + rails = &_hrails; break; + } + + size_t i = find ( axis, direction ); + if ( ( i == rails->size() ) || ( (*rails)[i]->getAxis() != axis ) ) { + PowerRail* rail = new PowerRail (type,_layer,direction,axis); + rail->merge ( width, rmin, rmax ); + rails->push_back ( rail ); + sort ( rails->begin(), rails->end(), PowerRail::CompareByAxis() ); + } else { + if ( (*rails)[i]->getType() != type ) { + cerr << Error("Short between power rails at %d.",DbU::getValueString(axis).c_str()) << endl; + return; + } + (*rails)[i]->merge ( width, rmin, rmax ); + } + } + + + void PowerPlane::doLayout ( Cell* cell, Net* powerNet, Net* groundNet ) const + { + for ( size_t i=0 ; i<_hrails.size() ; i++ ) + _hrails[i]->doLayout ( cell, powerNet, groundNet ); + + for ( size_t i=0 ; i<_vrails.size() ; i++ ) + _vrails[i]->doLayout ( cell, powerNet, groundNet ); + } + + +// ------------------------------------------------------------------- +// Class : "::PowerRail". + + + class PowerGrid { + public: + PowerGrid ( Cell* ); + ~PowerGrid (); + PowerPlane* getPlane ( const Layer* ); + void merge ( const Transformation&, Horizontal* ); + void merge ( const Transformation&, Vertical* ); + void doLayout () const; + private: + Cell* _cell; + Net* _powerNet; + Net* _groundNet; + map _planes; + }; + + + PowerGrid::PowerGrid ( Cell* cell ) + : _cell (cell) + , _powerNet (NULL) + , _groundNet(NULL) + , _planes () + { + forEach ( Net*, inet, _cell->getNets() ) { + if ( (inet->getType() == Net::Type::POWER) ) { + if ( !inet->isExternal() ) { + cerr << Warning("Ignoring non-external power net %s." + ,getString(*inet).c_str()) << endl; + continue; + } + _powerNet = *inet; + break; + } + } + if ( !_powerNet ) + cerr << Error("Missing POWER net in Cell %s.",getString(_cell->getName()).c_str()) << endl; + + forEach ( Net*, inet, _cell->getNets() ) { + if ( inet->getType() == Net::Type::GROUND ) { + if ( !inet->isExternal() ) { + cerr << Warning("Ignoring non-external ground net %s." + ,getString(*inet).c_str()) << endl; + continue; + } + _groundNet = *inet; + break; + } + } + if ( !_groundNet ) + cerr << Error("Missing GROUND net in Cell %s.",getString(_cell->getName()).c_str()) << endl; + } + + + PowerGrid::~PowerGrid () + { + map::iterator iplane = _planes.begin(); + for ( ; iplane != _planes.end() ; iplane++ ) + delete iplane->second; + } + + + PowerPlane* PowerGrid::getPlane ( const Layer* layer ) + { + map::iterator iplane = _planes.find(layer); + if ( iplane != _planes.end() ) + return iplane->second; + + PowerPlane* plane = new PowerPlane ( layer ); + _planes.insert ( make_pair(layer,plane) ); + + return plane; + } + + + void PowerGrid::merge ( const Transformation& transformation, Horizontal* horizontal ) + { + PowerPlane* plane = getPlane ( horizontal->getLayer() ); + + Point source = horizontal->getSourcePosition(); + Point target = horizontal->getTargetPosition(); + transformation.applyOn ( source ); + transformation.applyOn ( target ); + + if ( source.getX() > target.getX() ) swap ( source, target ); + plane->merge ( horizontal->getNet()->getType() + , Constant::Horizontal + , source.getY() + , horizontal->getWidth() + , source.getX() + , target.getX() + ); + } + + + void PowerGrid::merge ( const Transformation& transformation, Vertical* vertical ) + { + PowerPlane* plane = getPlane ( vertical->getLayer() ); + + Point source = vertical->getSourcePosition(); + Point target = vertical->getTargetPosition(); + transformation.applyOn ( source ); + transformation.applyOn ( target ); + + if ( source.getY() > target.getY() ) swap ( source, target ); + plane->merge ( vertical->getNet()->getType() + , Constant::Vertical + , source.getX() + , vertical->getWidth() + , source.getY() + , target.getY() + ); + } + + + void PowerGrid::doLayout () const + { + map::const_iterator iplane = _planes.begin (); + for ( ; iplane != _planes.end() ; iplane++ ) + iplane->second->doLayout ( _cell, _powerNet, _groundNet ); + } + + + void copyUpPowerRails ( const Transformation& pathTransf + , Cell* instanceCell + , PowerGrid& powerGrid + ) + { + forEach ( Net*, inet, instanceCell->getNets() ) { + switch ( inet->getType() ) { + case Net::Type::POWER: + case Net::Type::GROUND: + break; + default: + continue; + } + + forEach ( Component*, icomponent, inet->getComponents() ) { + if ( !NetExternalComponents::isExternal(*icomponent) ) continue; + + Horizontal* horizontal = dynamic_cast(*icomponent); + if ( horizontal ) + powerGrid.merge ( pathTransf, horizontal ); + else { + Vertical* vertical = dynamic_cast(*icomponent); + if ( vertical ) + powerGrid.merge ( pathTransf, vertical ); + } + } + } + + forEach ( Instance*, iinstance, instanceCell->getInstances() ) { + + Transformation instanceTransf = iinstance->getTransformation(); + pathTransf.applyOn ( instanceTransf ); + + copyUpPowerRails ( instanceTransf, iinstance->getMasterCell(), powerGrid ); + } + } + + +} // End of local namespace. + + +namespace Katabatic { + + + using Hurricane::Point; + using Hurricane::Horizontal; + using Hurricane::Net; + using Hurricane::Cell; + using Hurricane::Instance; + + + void KatabaticEngine::makePowerRails () + { + PowerGrid powerGrid ( getCell() ); + + Transformation topTransformation; // ID. + copyUpPowerRails ( topTransformation, getCell(), powerGrid ); + + powerGrid.doLayout (); + } + + +} // End of Katabatic namespace. diff --git a/katabatic/src/Session.cpp b/katabatic/src/Session.cpp new file mode 100644 index 00000000..49a1f6a2 --- /dev/null +++ b/katabatic/src/Session.cpp @@ -0,0 +1,438 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2008, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | K a t a b a t i c - Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Module : "./Session.cpp" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#include +#include + +#include "hurricane/Error.h" +#include "hurricane/Horizontal.h" +#include "hurricane/Vertical.h" +#include "hurricane/Cell.h" +#include "hurricane/UpdateSession.h" +#include "crlcore/RoutingGauge.h" +#include "katabatic/Session.h" +#include "katabatic/AutoContact.h" +#include "katabatic/AutoSegment.h" +#include "katabatic/AutoSegment.h" +#include "katabatic/GCellGrid.h" +#include "katabatic/KatabaticEngine.h" + + +namespace { + + + const char* reopenSession = + "Session::open() :\n\n" + " Session already open for %s (internal error)."; + + const char* openSessionError = + "%s :\n\n" + " Session has not been opened (internal error)."; + + +} // End of local namespace. + + + + +namespace Katabatic { + + + using namespace std; + using Hurricane::tab; + using Hurricane::ltracein; + using Hurricane::ltraceout; + using Hurricane::inltrace; + using Hurricane::Error; + using Hurricane::ForEachIterator; + using Hurricane::UpdateSession; + using Hurricane::Horizontal; + using Hurricane::Vertical; + using Hurricane::Cell; + + +// ------------------------------------------------------------------- +// Class : "Katabatic::Session". + + + Session* Session::_session = NULL; + + + Session* Session::get ( const char* message ) + { + if ( not _session and message ) + throw Error ( openSessionError, message ); + return _session; + } + + + Session::Session ( KatabaticEngine* ktbt ) + : _katabatic (ktbt) + , _technology (ktbt->getRoutingGauge()->getTechnology()) + , _routingGauge (ktbt->getRoutingGauge()) + , _autoContacts () + , _autoSegments () + , _revalidateds () + , _dogLegs () + , _netInvalidateds () + , _netRevalidateds () + , _invalidateMask (0) + { } + + + void Session::_postCreate () + { + UpdateSession::open (); + _session = this; + } + + + Session::~Session () + { } + + + size_t Session::_preDestroy () + { + size_t count = 0; + if ( _katabatic->getState() <= StateActive ) { + _revalidate (); + + if ( _katabatic->getGCellGrid() ) + _katabatic->getGCellGrid()->updateDensity (); + } + UpdateSession::close(); + + return count; + } + + + bool Session::_doDestroyBaseContact () { return _katabatic->doDestroyBaseContact(); } + bool Session::_doDestroyBaseSegment () { return _katabatic->doDestroyBaseSegment(); } + bool Session::_doDestroyTool () { return _katabatic->doDestroyTool(); } + Configuration* Session::_getConfiguration () { return _katabatic->getConfiguration(); } + + + void Session::_splitContacts () + { + ltrace(110) << "Katabatic::Session::_splitContacts()" << endl; + ltracein(110); + + for ( size_t i=0; i<_autoContacts.size() ; i++ ) + _autoContacts[i]->split (); + + ltraceout(110); + } + + + void Session::_restoreVCon () + { + ltrace(110) << "Katabatic::Session::_restoreVCon()" << endl; + ltracein(110); + + for ( size_t i=0; i<_autoContacts.size() ; i++ ) { + DbU::Unit y = DbU::Max; + forEach ( Horizontal*, isegment, _autoContacts[i]->getSlaveComponents().getSubSet() ) { + y = isegment->getY(); + } + _autoContacts[i]->restoreVConnexity ( y, true ); + } + + ltraceout(110); + } + + + void Session::_restoreHCon () + { + ltrace(110) << "Katabatic::Session::_restoreHCon()" << endl; + ltracein(110); + + for ( size_t i=0; i<_autoContacts.size() ; i++ ) { + DbU::Unit x = DbU::Max; + forEach ( Vertical*, isegment, _autoContacts[i]->getSlaveComponents().getSubSet() ) { + x = isegment->getX(); + } + _autoContacts[i]->restoreHConnexity ( x, true ); + } + + ltraceout(110); + } + + + void Session::_canonize () + { + ltrace(110) << "Katabatic::Session::_canonize()" << endl; + ltracein(110); + + set exploredSegments; + vector aligneds; + + sort ( _autoSegments.begin(), _autoSegments.end(), AutoSegment::CompareCanonical() ); + + for ( size_t i=0 ; i<_autoSegments.size() ; i++ ) { + AutoSegment* seedSegment = _autoSegments[i]; + + if ( exploredSegments.find(seedSegment->getSegment()) == exploredSegments.end() ) { + ltrace(110) << "New chunk from: " << seedSegment << endl; + aligneds.push_back ( seedSegment ); + + bool isCanonicalLocal = seedSegment->isLocal(); + forEach ( AutoSegment*, collapsed, seedSegment->getCollapseds() ) { + ltrace(110) << "Aligned: " << *collapsed << endl; + aligneds.push_back ( *collapsed ); + exploredSegments.insert ( collapsed->getSegment() ); + + if ( collapsed->isGlobal() ) isCanonicalLocal = false; + } + + ltracein(110); + sort ( aligneds.begin(), aligneds.end(), AutoSegment::CompareCanonical() ); + + if ( aligneds.size() > 1 ) { + if ( not AutoSegment::CompareCanonical() ( aligneds[0], aligneds[1] ) ) { + cerr << "Ambiguous canonization: " << aligneds[0]->base() << endl; + cerr << "Ambiguous canonization: " << aligneds[1]->base() << endl; + } + } + + aligneds[0]->setCanonical ( true ); + aligneds[0]->setCanonicalLocal ( isCanonicalLocal ); + ltrace(110) << "Canonical: " << aligneds[0] << endl; + + for ( size_t j=1 ; jsetCanonical ( false ); + ltrace(110) << "Secondary: " << aligneds[j] << endl; + } + + ltrace(159) << "Align @" << DbU::getLambda(aligneds[0]->getAxis()) + << " on " << aligneds[0] << endl; + + aligneds[0]->setAxis ( aligneds[0]->getAxis(), Realignate ); + aligneds.clear (); + ltraceout(110); + } + } + + ltraceout(110); + } + + + void Session::_revalidateTopology () + { + ltrace(110) << "Katabatic::Session::_revalidateTopology()" << endl; + ltracein(110); + + if ( not _netInvalidateds.empty() ) { + set::iterator inet = _netInvalidateds.begin(); + + if ( _invalidateMask & NetSplitContacts ) { + _splitContacts (); + _invalidateMask &= ~NetSplitContacts; + } + + if ( _invalidateMask & RestoreVCon ) { + _restoreVCon (); + _invalidateMask &= ~RestoreVCon; + } + + if ( _invalidateMask & RestoreHCon ) { + _restoreVCon (); + _invalidateMask &= ~RestoreHCon; + } + + if ( _invalidateMask & NetCanonize ) { + for ( ; inet != _netInvalidateds.end() ; inet++ ) { + ltrace(110) << "Katabatic::Session::_revalidateTopoplogy(Net*)" << *inet << endl; + + _katabatic->_computeNetConstraints ( *inet ); + _katabatic->_computeNetOptimals ( *inet ); + _katabatic->_computeNetTerminals ( *inet ); + } + _canonize (); + + for ( size_t i=0 ; i<_autoSegments.size() ; ++i ) { + if ( _autoSegments[i]->isUnsetAxis() + and _autoSegments[i]->isCanonical() ) { + _autoSegments[i]->toOptimalAxis (); + } + } + _invalidateMask &= ~NetCanonize; + } + } + + ltraceout(110); + } + + + size_t Session::_revalidate () + { + ltrace(110) << "Katabatic::Session::revalidate()" << endl; + ltracein(110); + + size_t count = 0; + + _revalidateTopology (); + _netRevalidateds.clear (); + _netRevalidateds.swap ( _netInvalidateds ); + + ltrace(110) << "AutoContacts Revalidate (after canonize)." << endl; + for ( size_t i=0 ; i < _autoContacts.size() ; i++, count++ ) + _autoContacts[i]->revalidate (); + _autoContacts.clear (); + + ltrace(110) << "AutoSegments Revalidate (after canonize)." << endl; + for ( size_t i=0 ; i < _autoSegments.size() ; i++, count++ ) + _autoSegments[i]->revalidate (); + _revalidateds.clear (); + _autoSegments.swap ( _revalidateds ); + _dogLegs.clear (); + + ltrace(110) << "AutoSegments/AutoContacts queued deletion." << endl; + bool destroySegment = _katabatic->setDestroyBaseSegment ( true ); + bool destroyContact = _katabatic->setDestroyBaseContact ( true ); + set::iterator isegment = _destroyedSegments.begin(); + for ( ; isegment != _destroyedSegments.end() ; isegment++ ) { + AutoContact* source = (*isegment)->getAutoSource(); + AutoContact* target = (*isegment)->getAutoTarget(); + (*isegment)->destroy (); + if (source and source->canDestroy(true)) source->destroy (); + if (target and target->canDestroy(true)) target->destroy (); + } + _katabatic->setDestroyBaseSegment ( destroySegment ); + _katabatic->setDestroyBaseContact ( destroyContact ); + set().swap ( _destroyedSegments ); + + ltraceout(110); + + return count; + } + + + Session* Session::open ( KatabaticEngine* ktbt ) + { + ltrace(110) << "Session::open()" << endl; + + if ( _session ) { + if ( _session->_katabatic != ktbt ) + throw Error ( reopenSession, getString(_session->getKatabatic()).c_str() ); + + return _session; + } + + Session* session = new Session ( ktbt ); + session->_postCreate (); + + return session; + } + + + size_t Session::close () + { + ltrace(110) << "Session::close()" << endl; + ltracein(110); + + if ( !_session ) throw Error ( openSessionError, "Session::Close()" ); + + size_t count = _session->_preDestroy (); + + delete _session; + _session = NULL; + + ltraceout(110); + + return count; + } + + + bool Session::getDemoMode () + { return get("getDemoMode()")->_katabatic->getDemoMode(); } + + + float Session::getSaturateRatio () + { return get("getSaturateRatio()")->_katabatic->getSaturateRatio(); } + + + bool Session::getWarnGCellOverload () + { return get("getWarnGCellOverload()")->_katabatic->getWarnGCellOverload(); } + + + void Session::setWarnGCellOverload ( bool state ) + { get("getWarnGCellOverload()")->_katabatic->setWarnGCellOverload(state); } + + + DbU::Unit Session::getExtensionCap () + { return getConfiguration()->getExtensionCap(); } + + + const Layer* Session::getRoutingLayer ( size_t depth ) + { return getConfiguration()->getRoutingLayer(depth); } + + + const Layer* Session::getContactLayer ( size_t depth ) + { return getConfiguration()->getContactLayer(depth); } + + + void Session::link ( AutoContact* autoContact ) + { return get("link(AutoContact*)")->_katabatic->_link ( autoContact ); } + + + void Session::link ( AutoSegment* autoSegment ) + { return get("link(AutoSegment*)")->_katabatic->_link ( autoSegment ); } + + + void Session::unlink ( AutoContact* autoContact ) + { return get("unlink(AutoContact*)")->_katabatic->_unlink ( autoContact ); } + + + void Session::unlink ( AutoSegment* autoSegment ) + { return get("unlink(AutoSegment*)")->_katabatic->_unlink ( autoSegment ); } + + + AutoContact* Session::lookup ( Contact* contact ) + { return get("lookup(Contact*)")->_katabatic->_lookup ( contact ); } + + + AutoSegment* Session::lookup ( Segment* segment ) + { return get("lookup(Segment*)")->_katabatic->_lookup ( segment ); } + + + string Session::_getString () const + { + return "<" + _getTypeName() + " " + + getString(_katabatic->getCell()->getName()) + + ">"; + } + + + Record* Session::_getRecord () const + { + Record* record = new Record ( _getString() ); + record->add ( getSlot ( "_katabatic" , _katabatic ) ); + record->add ( getSlot ( "_autoContacts", &_autoContacts ) ); + record->add ( getSlot ( "_autoSegments", &_autoSegments ) ); + return record; + } + + +} // End of Katabatic namespace. diff --git a/katabatic/src/katabatic/AutoContact.h b/katabatic/src/katabatic/AutoContact.h new file mode 100644 index 00000000..e77176e9 --- /dev/null +++ b/katabatic/src/katabatic/AutoContact.h @@ -0,0 +1,359 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2008, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | K a t a b a t i c - Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Header : "./AutoContact.h" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#ifndef __KATABATIC_AUTOCONTACT__ +#define __KATABATIC_AUTOCONTACT__ + +#include + +#include "hurricane/Contact.h" +#include "hurricane/ExtensionGo.h" + +namespace Hurricane { + class RoutingPad; +} + +#include "katabatic/AutoContacts.h" +#include "katabatic/GCell.h" + + +namespace Katabatic { + + + using std::cerr; + using std::endl; + using Hurricane::tab; + using Hurricane::inltrace; + using Hurricane::Name; + using Hurricane::Net; + using Hurricane::Component; + using Hurricane::Components; + using Hurricane::Layer; + using Hurricane::Contact; + using Hurricane::RoutingPad; + using Hurricane::ExtensionGo; + + class GCell; + class KatabaticEngine; + + + +// ------------------------------------------------------------------- +// Class : "Katabatic::VirtualContacts". + + + class VirtualContacts { + public: + // Methods. + inline VirtualContacts (); + inline Box getBoundingBox () const; + void merge ( const Point& , const Layer* ); + inline void clear (); + + public: + // Sub-Class. + class VC { + public: + inline VC ( const Point& , const Layer* ); + inline const Point& getPoint () const; + inline const Layer* getLayer () const; + void merge ( const Layer* layer ); + friend bool operator== ( const VC& lhs, const VC& rhs ); + protected: + Point _point; + const Layer* _layer; + }; + + protected: + // Attributes. + Box _boundingBox; + vector _vcs; + }; + + +// Inline Functions. + inline VirtualContacts::VirtualContacts () : _boundingBox(), _vcs() {} + inline Box VirtualContacts::getBoundingBox () const { return _boundingBox; } + inline void VirtualContacts::clear () { _vcs.clear(); _boundingBox.makeEmpty(); } + inline VirtualContacts::VC::VC ( const Point& p, const Layer* l ) : _point(p), _layer(l) {} + inline const Point& VirtualContacts::VC::getPoint () const { return _point; } + inline const Layer* VirtualContacts::VC::getLayer () const { return _layer; } + + +// ------------------------------------------------------------------- +// Class : "Katabatic::AutoContact". + + + class AutoContact : public ExtensionGo { + + public: + static AutoContact* fromRp ( GCell* gcell + , RoutingPad* routingPad + , const Layer* layer + , Point point + , DbU::Unit width + , DbU::Unit height + , bool fixed=false + ); + public: + // Constructor & Destructor. + static AutoContact* create ( GCell* gcell + , Net* net + , const Layer* layer + , bool hAlignate=false + , bool vAlignate=false + ); + static AutoContact* create ( GCell* gcell + , RoutingPad* rp + , const Layer* layer + , const DbU::Unit dx + , const DbU::Unit dy + , const DbU::Unit width + , const DbU::Unit height + , bool hAlignate=false + , bool vAlignate=false + , bool fixed=false + ); + public: + // Wrapped Contact Accessors. + inline Hook* getBodyHook (); + inline Hook* getAnchorHook (); + inline Component* getAnchor () const; + inline Net* getNet () const; + inline const Layer* getLayer () const; + inline DbU::Unit getX () const; + inline DbU::Unit getY () const; + inline DbU::Unit getDx () const; + inline DbU::Unit getDy () const; + inline Point getCenter () const; + inline Point getPosition () const; + inline DbU::Unit getWidth () const; + inline DbU::Unit getHalfWidth () const; + inline DbU::Unit getHeight () const; + inline DbU::Unit getHalfHeight () const; + inline Components getSlaveComponents () const; + // Wrapped Contact Modifiers. + inline void setLayer ( const Layer* ); + inline void setWidth ( DbU::Unit ); + inline void setHeight ( DbU::Unit ); + inline void setSizes ( DbU::Unit width, DbU::Unit height ); + inline void setX ( DbU::Unit ); + inline void setY ( DbU::Unit ); + inline void setPosition ( DbU::Unit width, DbU::Unit height ); + inline void setPosition ( const Point& ); + inline void setDx ( DbU::Unit ); + inline void setDy ( DbU::Unit ); + inline void setOffset ( DbU::Unit dx, DbU::Unit dy ); + virtual void translate ( const DbU::Unit& tx, const DbU::Unit& ty ); + // Accessors. + static size_t getSegmentEndAllocateds (); + static size_t getAllocateds (); + static const Name& getStaticName (); + virtual const Name& getName () const; + inline size_t getId () const; + inline Contact* base () const; + inline Contact* getContact () const; + virtual Box getBoundingBox () const; + inline GCell* getGCell () const; + unsigned int getMinDepth () const; + bool canDestroy ( bool error=false ) const; + inline bool isInvalidated () const; + inline bool isCorner () const; + inline bool isFixed () const; + inline bool isTerminal () const; + bool isAlignate ( unsigned int direction ) const; + inline bool isHAlignate () const; + inline bool isVAlignate () const; + bool isHExtended (); + bool isVExtended (); + bool canGoOutsideGCell ( const AutoSegment* ); + bool canHDesalignate (); + bool canVDesalignate (); + bool canMoveUp ( AutoSegment* moved ) const; + void getLengths ( DbU::Unit* lengths, set& ); + Box getNativeConstraintBox () const; + Interval getUConstraints ( unsigned int direction ) const; + inline DbU::Unit getCBXMin () const; + inline DbU::Unit getCBXMax () const; + inline DbU::Unit getCBYMin () const; + inline DbU::Unit getCBYMax () const; + inline Box getConstraintBox () const; + Box& intersectConstraintBox ( Box& box ) const; + // Modifiers. + inline void setInvalidated ( bool state ); + inline void setCorner ( bool state ); + inline void setFixed ( bool state ); + inline void setTerminal ( bool state ); + inline void setHAlignate ( bool state ); + inline void setVAlignate ( bool state ); + void computeAlignate (); + void invalidate (); + void revalidate (); + void updateGeometry (); + inline void setInvalidatedTopology ( bool state ); + void revalidateTopology (); + void checkTopology (); + void setGCell ( GCell* ); + inline void setCBXMin ( DbU::Unit xMin ); + inline void setCBXMax ( DbU::Unit xMax ); + inline void setCBYMin ( DbU::Unit yMin ); + inline void setCBYMax ( DbU::Unit yMax ); + void setConstraintBox ( const Box& box ); + void restrictConstraintBox ( DbU::Unit constraintMin + , DbU::Unit constraintMax + , unsigned int direction ); + void restoreNativeConstraintBox (); + void breakUp (); + void split (); + bool hDesalignate (); + bool vDesalignate (); + void restoreHConnexity ( DbU::Unit x, bool split=false ); + void restoreVConnexity ( DbU::Unit y, bool split=false ); + // Collections. + AutoContacts getCollapseds ( unsigned int direction ); + // Inspector Management. + Record* _getRecord () const; + virtual string _getString () const; + virtual string _getTypeName () const { return "Katabatic::AutoContact"; }; + + private: + // Internal: Attributes. + static size_t _maxId; + static size_t _allocateds; + static const Name _goName; + protected: + size_t _id; + Contact* _contact; + GCell* _gcell; + bool _invalid; + bool _invalidTopology; + bool _isTerminal; + bool _fixed; + bool _hAlignate; + bool _vAlignate; + bool _isCorner; + int _dxMin : 8; + int _dxMax : 8; + int _dyMin : 8; + int _dyMax : 8; + VirtualContacts _subContacts; + + protected: + // Constructors & Destructors. + AutoContact ( GCell* gcell + , Contact* contact + , bool hAlignate=false + , bool vAlignate=false + ); + virtual ~AutoContact (); + virtual void _postCreate (); + virtual void _preDestroy (); + private: + AutoContact ( const AutoContact& ); + AutoContact& operator= ( const AutoContact& ); + + protected: + inline int _getDeltaMin ( DbU::Unit x, DbU::Unit xMin ); + inline int _getDeltaMax ( DbU::Unit x, DbU::Unit xMin, DbU::Unit xMax ); + }; + + +// Wrapped Contact Inline Functions. + inline Hook* AutoContact::getBodyHook () { return _contact->getBodyHook(); } + inline Hook* AutoContact::getAnchorHook () { return _contact->getAnchorHook(); } + inline Component* AutoContact::getAnchor () const { return _contact->getAnchor(); } + inline Net* AutoContact::getNet () const { return _contact->getNet(); } + inline const Layer* AutoContact::getLayer () const { return _contact->getLayer(); } + inline DbU::Unit AutoContact::getX () const { return _contact->getX(); } + inline DbU::Unit AutoContact::getY () const { return _contact->getY(); } + inline DbU::Unit AutoContact::getDx () const { return _contact->getDx(); } + inline DbU::Unit AutoContact::getDy () const { return _contact->getDy(); } + inline Point AutoContact::getCenter () const { return _contact->getCenter(); } + inline Point AutoContact::getPosition () const { return _contact->getPosition(); } + inline DbU::Unit AutoContact::getWidth () const { return _contact->getWidth(); } + inline DbU::Unit AutoContact::getHalfWidth () const { return _contact->getHalfWidth(); } + inline DbU::Unit AutoContact::getHeight () const { return _contact->getHeight(); } + inline DbU::Unit AutoContact::getHalfHeight () const { return _contact->getHalfHeight(); } + inline Components AutoContact::getSlaveComponents () const { return _contact->getSlaveComponents(); } + inline void AutoContact::setLayer ( const Layer* layer ) { return _contact->setLayer(layer); } + inline void AutoContact::setWidth ( DbU::Unit w ) { return _contact->setWidth(w); } + inline void AutoContact::setHeight ( DbU::Unit h ) { return _contact->setHeight(h); } + inline void AutoContact::setSizes ( DbU::Unit w, DbU::Unit h ) { return _contact->setSizes(w,h); } + inline void AutoContact::setX ( DbU::Unit x ) { return _contact->setX(x); } + inline void AutoContact::setY ( DbU::Unit y ) { return _contact->setY(y); } + inline void AutoContact::setPosition ( DbU::Unit x, DbU::Unit y ) { return _contact->setPosition(x,y); } + inline void AutoContact::setPosition ( const Point& p ) { return _contact->setPosition(p); } + inline void AutoContact::setDx ( DbU::Unit dx ) { return _contact->setDx(dx); } + inline void AutoContact::setDy ( DbU::Unit dy ) { return _contact->setDy(dy); } + inline void AutoContact::setOffset ( DbU::Unit dx, DbU::Unit dy ) { return _contact->setOffset(dx,dy); } +// Inline Functions. + inline size_t AutoContact::getId () const { return _id; } + inline Contact* AutoContact::base () const { return _contact; } + inline Contact* AutoContact::getContact () const { return _contact; } + inline GCell* AutoContact::getGCell () const { return _gcell; } + inline bool AutoContact::isInvalidated () const { return _invalid; } + inline bool AutoContact::isCorner () const { return _isCorner; } + inline bool AutoContact::isFixed () const { return _fixed; } + inline bool AutoContact::isTerminal () const { return _isTerminal; } + inline bool AutoContact::isHAlignate () const { return _hAlignate; } + inline bool AutoContact::isVAlignate () const { return _vAlignate; } + inline DbU::Unit AutoContact::getCBXMin () const { return DbU::lambda(_dxMin) + _gcell->getX(); } + inline DbU::Unit AutoContact::getCBXMax () const { return DbU::lambda(_dxMax) + _gcell->getX(); } + inline DbU::Unit AutoContact::getCBYMin () const { return DbU::lambda(_dyMin) + _gcell->getY(); } + inline DbU::Unit AutoContact::getCBYMax () const { return DbU::lambda(_dyMax) + _gcell->getY(); } + inline Box AutoContact::getConstraintBox () const { return Box(getCBXMin(),getCBYMin(),getCBXMax(),getCBYMax()); } + inline void AutoContact::setInvalidated ( bool state ) { _invalid = state; } + inline void AutoContact::setInvalidatedTopology ( bool state ) { _invalidTopology = state; } + inline void AutoContact::setCorner ( bool state ) { _isCorner = state; } + inline void AutoContact::setFixed ( bool state ) { _fixed = state; } + inline void AutoContact::setTerminal ( bool state ) { _isTerminal = state; } + inline void AutoContact::setHAlignate ( bool state ) { _hAlignate = state; } + inline void AutoContact::setVAlignate ( bool state ) { _vAlignate = state; } + inline void AutoContact::setCBXMin ( DbU::Unit xMin ) { _dxMin = _getDeltaMin(xMin,_gcell->getX()); } + inline void AutoContact::setCBXMax ( DbU::Unit xMax ) { _dxMax = _getDeltaMax(xMax,_gcell->getX(),_gcell->getXMax()); } + inline void AutoContact::setCBYMin ( DbU::Unit yMin ) { _dyMin = _getDeltaMin(yMin,_gcell->getY()); } + inline void AutoContact::setCBYMax ( DbU::Unit yMax ) { _dyMax = _getDeltaMax(yMax,_gcell->getY(),_gcell->getYMax()); } + inline int AutoContact::_getDeltaMin ( DbU::Unit x, DbU::Unit xMin ) { if (xxMax) x=xMax; return (int)DbU::getLambda(x-xMin); } + +//templateinline void Swap ( Type& a, Type& b ) { Type swp = a; a = b; b = swp; } + templateinline void order ( Type& a, Type& b ) { if (a>b) swap(a,b); } + + inline DbU::Unit setInBound ( DbU::Unit lower, DbU::Unit upper, DbU::Unit& value ) + { + if ( lower > value ) value = lower; + if ( upper < value ) value = upper; + + return value; + } + + +} // End of Katabatic namespace. + + +INSPECTOR_P_SUPPORT(Katabatic::AutoContact); + + +#endif // __KATABATIC_AUTOCONTACT__ diff --git a/katabatic/src/katabatic/AutoContacts.h b/katabatic/src/katabatic/AutoContacts.h new file mode 100644 index 00000000..dd1113f8 --- /dev/null +++ b/katabatic/src/katabatic/AutoContacts.h @@ -0,0 +1,165 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2008, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | K a t a b a t i c - Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Header : "./AutoContacts.h" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + + + +#ifndef __KATABATIC_AUTOCONTACTS__ +#define __KATABATIC_AUTOCONTACTS__ + +#include +#include +#include + +#include "hurricane/Collection.h" + +namespace Hurricane { + class Contact; + class Segment; +} + + +namespace Katabatic { + + + using std::map; + using std::list; + using std::pair; + using std::string; + using Hurricane::Locator; + using Hurricane::Collection; + using Hurricane::GenericLocator; + using Hurricane::GenericCollection; + using Hurricane::GenericFilter; + using Hurricane::Contact; + using Hurricane::Segment; + + class AutoContact; + class AutoSegment; + + +// ------------------------------------------------------------------- +// Collections. + + + typedef Hurricane::Locator AutoContactHL; + typedef Hurricane::Collection AutoContactHC; + typedef GenericCollection AutoContacts; + typedef GenericLocator AutoContactLocator; + typedef GenericFilter AutoContactFilter; + typedef map AutoContactLut; + + +// ------------------------------------------------------------------- +// Class : "Katabatic::AutoContactStack". + + + class AutoContactStack : protected list > { + public: + inline bool isEmpty () const; + inline size_t getSize () const; + void push ( AutoContact*, Segment* ); + inline void pop (); + inline AutoContact* getAutoContact () const; + inline Segment* getSegment () const; + }; + + + inline bool AutoContactStack::isEmpty () const { return empty(); } + inline size_t AutoContactStack::getSize () const { return size(); } + inline void AutoContactStack::pop () { if ( !empty() ) pop_back(); } + inline AutoContact* AutoContactStack::getAutoContact () const { return empty() ? NULL : back().first; } + inline Segment* AutoContactStack::getSegment () const { return empty() ? NULL : back().second; } + + +// ------------------------------------------------------------------- +// Class : "Katabatic::AutoContacts_Collapsed". + + + class AutoContacts_Collapsed : public AutoContactHC { + + public: + // Sub-Class: Locator. + class Locator : public AutoContactHL { + public: + inline Locator ( AutoContact*, unsigned int direction ); + inline Locator ( const Locator& ); + virtual AutoContact* getElement () const; + virtual AutoContactHL* getClone () const; + virtual bool isValid () const; + virtual void progress (); + virtual string _getString () const; + protected: + unsigned int _direction; + AutoContactStack _stack; + }; + + public: + // AutoContacts_Collapsed Methods. + inline AutoContacts_Collapsed ( AutoContact*, unsigned int direction ); + inline AutoContacts_Collapsed ( const AutoContacts_Collapsed& ); + virtual AutoContactHC* getClone () const; + virtual AutoContactHL* getLocator () const; + virtual string _getString () const; + + public: + // AutoContacts_Collapsed Attributes. + AutoContact* _contact; + unsigned int _direction; + }; + + + AutoContacts_Collapsed::Locator::Locator ( AutoContact* contact + , unsigned int direction ) + : AutoContactHL() + , _stack() + { + _stack.push(contact,NULL); + } + + + AutoContacts_Collapsed::Locator::Locator ( const Locator &locator ) + : AutoContactHL() + , _stack(locator._stack) + { } + + + AutoContacts_Collapsed::AutoContacts_Collapsed ( AutoContact* contact, unsigned int direction ) + : AutoContactHC() + , _contact(contact) + , _direction(direction) + { } + + + AutoContacts_Collapsed::AutoContacts_Collapsed ( const AutoContacts_Collapsed& autocontacts ) + : AutoContactHC() + , _contact(autocontacts._contact) + , _direction(autocontacts._direction) + { } + + +} // End of Katabatic namespace. + + +#endif // __KATABATIC_AUTOCONTACTS__ diff --git a/katabatic/src/katabatic/AutoHorizontal.h b/katabatic/src/katabatic/AutoHorizontal.h new file mode 100644 index 00000000..3ee7a10b --- /dev/null +++ b/katabatic/src/katabatic/AutoHorizontal.h @@ -0,0 +1,119 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2008, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | K a t a b a t i c - Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Header : "./AutoHorizontal.h" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#ifndef __KATABATIC_AUTOHORIZONTAL__ +#define __KATABATIC_AUTOHORIZONTAL__ + +#include "hurricane/Horizontal.h" +#include "katabatic/AutoSegment.h" + + +namespace Katabatic { + + +// ------------------------------------------------------------------- +// Class : "AutoHorizontal". + + + class AutoHorizontal : public AutoSegment { + using AutoSegment::_computeTerminal; + + public: + // Constructors. + static AutoHorizontal* create ( Horizontal* horizontal + , int type + , bool terminal=false + , bool collapsed=false + ); + static AutoHorizontal* create ( AutoContact* source + , AutoContact* target + , const Layer* layer + , DbU::Unit y + , DbU::Unit width + , int type + , bool terminal=false + , bool collapsed=false + ); + // Predicates. + virtual bool canDesalignate ( AutoContact* ) const; + virtual bool _canSlacken () const; + // Accessors. + virtual Segment* base () { return _horizontal; }; + virtual Segment* base () const { return _horizontal; }; + virtual Segment* getSegment () { return _horizontal; }; + virtual Segment* getSegment () const { return _horizontal; }; + virtual Horizontal* getHorizontal () { return _horizontal; }; + virtual DbU::Unit getSourceU () const { return _horizontal->getSourceX(); }; + virtual DbU::Unit getTargetU () const { return _horizontal->getTargetX(); }; + virtual DbU::Unit getDuSource () const { return _horizontal->getDxSource(); }; + virtual DbU::Unit getDuTarget () const { return _horizontal->getDxTarget(); }; + virtual Interval getSpanU () const { return Interval(_horizontal->getSourceX(),_horizontal->getTargetX()); }; + virtual bool getConstraints ( DbU::Unit& min , DbU::Unit& max ) const; + virtual Interval getSourceConstraints ( bool native=false ) const; + virtual Interval getTargetConstraints ( bool native=false ) const; + virtual unsigned int getDirection () const; + virtual size_t getGCells ( vector& ) const; + // Modifiers. + virtual void setDuSource ( DbU::Unit du ) { _horizontal->setDxSource(du); }; + virtual void setDuTarget ( DbU::Unit du ) { _horizontal->setDxTarget(du); }; + virtual void alignate ( DbU::Unit axis ); + virtual void orient (); + virtual void setPositions (); + virtual bool checkPositions () const; + virtual bool checkConstraints () const; + virtual void _computeTerminal (); + virtual void moveURight (); + virtual void moveULeft (); + virtual void _makeDogLeg ( GCell*, bool upLayer ); + virtual void desalignate ( AutoContact* ); + virtual void _slacken (); + // Inspector Management. + virtual Record* _getRecord () const; + virtual string _getString () const; + virtual string _getTypeName () const { return "AutoHorizontal"; }; + + // Internal: Attributes. + protected: + Horizontal* _horizontal; + + // Internal: Constructors. + protected: + AutoHorizontal ( Horizontal* horizontal + , int type + , bool terminal + , bool collapsed ); + virtual ~AutoHorizontal (); + virtual void _postCreate (); + virtual void _preDestroy (); + private: + AutoHorizontal ( const AutoHorizontal& ); + AutoHorizontal& operator= ( const AutoHorizontal& ); + }; + + +} // End of Katabatic namespace. + + +#endif // __KATABATIC_AUTOHORIZONTAL__ diff --git a/katabatic/src/katabatic/AutoSegment.h b/katabatic/src/katabatic/AutoSegment.h new file mode 100644 index 00000000..64d3ad93 --- /dev/null +++ b/katabatic/src/katabatic/AutoSegment.h @@ -0,0 +1,478 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2008, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | K a t a b a t i c - Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Header : "./AutoSegment.h" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#ifndef __KATABATIC_AUTOSEGMENT__ +#define __KATABATIC_AUTOSEGMENT__ + +#include +#include +#include +#include + +#include "hurricane/Interval.h" +#include "hurricane/Segment.h" +#include "hurricane/Components.h" +#include "hurricane/Contact.h" +namespace Hurricane { + class Layer; + class Horizontal; + class Vertical; + class Cell; +} + +#include "katabatic/GCell.h" +#include "katabatic/AutoSegments.h" +#include "katabatic/Session.h" + + +namespace Katabatic { + + + using std::set; + using std::cerr; + using std::endl; + using std::binary_function; + using Hurricane::tab; + using Hurricane::inltrace; + using Hurricane::Interval; + using Hurricane::Layer; + using Hurricane::Components; + using Hurricane::Horizontal; + using Hurricane::Vertical; + using Hurricane::Cell; + + + enum AutoSegmentFlags { Realignate=0x1, AxisSet=0x2 }; + + +// ------------------------------------------------------------------- +// Class : "AutoSegment". + + + class AutoSegment { + + public: + // Types. + typedef std::tr1::function< void(AutoSegment*) > RevalidateCb_t; + // Enumerations. + enum Type { Global = 1 + , Local = 2 + , Guess = 3 + }; + enum PerpandicularState { PerpandicularAny = (1<<0) + , PerpandicularIndirect = (1<<1) + , ParallelOrExpanded = (1<<2) + , ParallelAndLayerChange = (1<<3) + }; + + + public: + struct CompareId : public binary_function { + inline bool operator() ( const AutoSegment* lhs, const AutoSegment* rhs ) const; + }; + public: + struct CompareCanonical : public binary_function { + bool operator() ( const AutoSegment* lhs, const AutoSegment* rhs ) const; + }; + public: + struct CompareByDepthLength : public binary_function { + bool operator() ( AutoSegment* lhs, AutoSegment* rhs ) const; + }; + + public: + // Utilities. + static bool isTopologicalBound ( AutoSegment* seed + , bool superior + , bool isHorizontal + ); + static inline bool arePerpandiculars ( AutoSegment* a, AutoSegment* b ); + static inline bool arePerpandiculars ( bool isHorizontalA, AutoSegment* b ); + static inline bool areAligneds ( AutoSegment* a, AutoSegment* b ); + static unsigned int getPerpandicularState ( AutoContact* contact + , AutoSegment* source + , AutoSegment* current + , bool isHorizontalMaster + , const Layer* masterLayer=NULL + ); + static inline unsigned int getPerpandicularState ( AutoContact* contact + , AutoSegment* source + , AutoSegment* current + , AutoSegment* master + ); + static void getTopologicalInfos ( AutoSegment* seed + , vector& collapseds + , vector& perpandiculars + , DbU::Unit& leftBound + , DbU::Unit& rightBound + ); + static int getTerminalCount ( AutoSegment* seed + , vector& collapseds + ); + static inline int getTerminalCount ( AutoSegment* seed ); + static size_t getAllocateds () { return _allocateds; }; + static inline unsigned long getMaxId (); + // Constructors & Destructor. + static AutoSegment* create ( AutoContact* source + , AutoContact* target + , Segment* hurricaneSegment + ); + static AutoSegment* create ( AutoContact* source + , AutoContact* target + , unsigned int dir + , int type + , bool terminal=false + , bool collapsed=false + ); + void destroy (); + // Wrapped Segment Functions. + virtual Segment* base () = 0; + virtual Segment* base () const = 0; + virtual Segment* getSegment () = 0; + virtual Segment* getSegment () const = 0; + virtual Horizontal* getHorizontal () { return NULL; }; + virtual Vertical* getVertical () { return NULL; }; + inline Cell* getCell () const; + inline Net* getNet () const; + inline const Layer* getLayer () const; + inline Box getBoundingBox () const; + inline Hook* getSourceHook (); + inline Hook* getTargetHook (); + inline Contact* getSource () const; + inline Contact* getTarget () const; + inline Component* getOppositeAnchor ( Component* ) const; + inline Components getAnchors () const; + virtual DbU::Unit getX () const; + virtual DbU::Unit getY () const; + inline DbU::Unit getWidth () const; + inline DbU::Unit getLength () const; + inline DbU::Unit getSourcePosition () const; + inline DbU::Unit getTargetPosition () const; + inline DbU::Unit getSourceX () const; + inline DbU::Unit getSourceY () const; + inline DbU::Unit getTargetX () const; + inline DbU::Unit getTargetY () const; + inline void invert (); + // Predicates. + inline bool isHorizontal () const; + inline bool isVertical () const; + inline bool isInvalidated () const; + inline bool isGlobal () const; + inline bool isLocal () const; + inline bool isCanonicalLocal () const; + inline bool isTerminal () const; + inline bool isCollapsed () const; + inline bool isCanonical () const; + inline bool isFixed () const; + inline bool isStrap () const; + bool isCanonicalStrap () const; + inline bool isLayerChange () const; + inline bool isAccountable () const; + inline bool isUnsetAxis () const; + inline bool isSlackened () const; + inline bool isSlackenStrap () const; + inline bool allowOutsideGCell () const; + bool canDesalignate (); + virtual bool canDesalignate ( AutoContact* ) const = 0; + bool canMoveUp ( bool propagate=false ); + bool canPivotUp ( bool propagate=false ); + bool canSlacken ( bool propagate=false ); + virtual bool _canSlacken () const = 0; + bool canGoOutsideGCell () const; + // Accessors. + inline unsigned long getId () const; + virtual unsigned int getDirection () const = 0; + inline GCell* getGCell () const; + virtual size_t getGCells ( vector& ) const = 0; + inline AutoContact* getAutoSource () const; + inline AutoContact* getAutoTarget () const; + AutoContact* getOppositeAnchor ( AutoContact* ) const; + size_t getAlignedContacts ( map& ); + size_t getPerpandicularsBound ( set& ); + inline DbU::Unit getAxis () const; + virtual DbU::Unit getSourceU () const = 0; + virtual DbU::Unit getTargetU () const = 0; + virtual DbU::Unit getDuSource () const = 0; + virtual DbU::Unit getDuTarget () const = 0; + inline DbU::Unit getOrigin () const; + inline DbU::Unit getExtremity () const; + virtual Interval getSpanU () const = 0; + Interval getMinSpanU (); + virtual Interval getSourceConstraints ( bool native=false ) const = 0; + virtual Interval getTargetConstraints ( bool native=false ) const = 0; + virtual bool getConstraints ( DbU::Unit& min, DbU::Unit& max ) const = 0; + inline bool getConstraints ( Interval& i ) const; + inline const Interval& getUserConstraints () const; + virtual DbU::Unit getSlack () const; + inline DbU::Unit getOptimalMin () const; + inline DbU::Unit getOptimalMax () const; + Interval& getOptimal ( Interval& i ) const; + virtual DbU::Unit getCost ( DbU::Unit axis ) const; + virtual AutoSegment* getCanonical ( DbU::Unit& min , DbU::Unit& max ); + inline AutoSegment* getCanonical ( Interval& i ); + // Collections & Filters. + AutoSegments getOnSourceContact ( unsigned int direction ); + AutoSegments getOnTargetContact ( unsigned int direction ); + AutoSegments getCollapseds ( bool withPerpand=false ); + AutoSegments getCollapsedPerpandiculars (); + static AutoSegmentFilter getIsAccountable () { return new AutoSegments_IsAccountable(); }; + // Static Modifiers. + static void setDestroyMode ( bool ); + // Modifiers. + inline void setGlobal ( bool ); + inline void setCanonicalLocal ( bool ); + inline void setCanonical ( bool ); + inline void setTerminal ( bool ); + inline void setFixed ( bool ); + inline void setStrap ( bool ); + inline void setLayerChange ( bool ); + inline void setSlackened ( bool ); + inline void setSlackenStrap ( bool ); + void setAllowOutsideGCell ( bool state, bool propagate=false ); + void _setAllowOutsideGCell ( bool ); + inline void setLayer ( const Layer* layer ); + void setAxis ( DbU::Unit axis + , unsigned int flags=AxisSet + , set* processeds=NULL ); + virtual void setDuSource ( DbU::Unit du ) = 0; + virtual void setDuTarget ( DbU::Unit du ) = 0; + virtual void orient () = 0; + virtual void setPositions () = 0; + virtual bool checkPositions () const = 0; + virtual bool checkConstraints () const = 0; + inline void mergeUserConstraints ( const Interval& ); + inline void resetUserConstraints (); + virtual void invalidate (); + void revalidate (); + bool collapse (); + bool expand (); + bool toConstraintAxis ( set* processeds=NULL ); + bool toOptimalAxis ( set* processeds=NULL ); + virtual void alignate ( DbU::Unit axis ) = 0; + inline void setOptimalMin ( DbU::Unit min ); + inline void setOptimalMax ( DbU::Unit max ); + void computeOptimal ( set* processeds=NULL ); + void _computeTerminal ( Segment* ); + virtual void _computeTerminal () = 0; + virtual bool checkInvalidated () const; + AutoSegment* canonize (); + void changeDepth ( unsigned int depth + , bool propagate =false + , bool standAlone=true + ); + void _changeDepth ( unsigned int depth, bool withNeighbors ); + bool moveUp ( bool propagate=false ); + virtual void moveULeft () = 0; + virtual void moveURight () = 0; + void slacken ( bool propagate=false ); + virtual void _slacken () = 0; + bool canDogLeg ( Interval ); + void makeDogLeg ( Interval, bool upLayer, bool& leftDogleg ); + void makeDogLeg ( GCell*, bool upLayer ); + virtual void _makeDogLeg ( GCell*, bool upLayer ) = 0; + virtual void desalignate ( AutoContact* ) = 0; + void desalignate (); + bool _check () const; + // Inspector Management. + virtual Record* _getRecord () const = 0; + virtual string _getString () const = 0; + virtual string _getTypeName () const = 0; + + protected: + // Internal: Static Attributes. + static size_t _allocateds; + static bool _destroyBase; + static bool _destroyTool; + static unsigned long _maxId; + // Internal: Attributes. + GCell* _gcell; + bool _isUnsetAxis; + bool _invalidated; + bool _isHorizontal; + bool _isGlobal; + bool _isCanonicalLocal; + bool _isTerminal; + bool _isCollapsed; + bool _isCanonical; + bool _isFixed; + bool _strap; + bool _layerChange; + bool _slackened; + bool _slackenStrap; + bool _allowOutsideGCell; + const unsigned long _id; + unsigned int _optimalMin : 8; + unsigned int _optimalMax : 8; + DbU::Unit _sourcePosition; + DbU::Unit _targetPosition; + Interval _userConstraints; + + // Internal: Constructors & Destructors. + protected: + AutoSegment ( Segment* segment + , bool isHorizontal + , int type + , bool terminal + , bool collapsed + ); + virtual ~AutoSegment (); + static void _preCreate ( Component* source, Component* target ); + static void _preCreate ( AutoContact* source, AutoContact* target ); + virtual void _postCreate (); + virtual void _preDestroy (); + private: + AutoSegment ( const AutoSegment& ); + AutoSegment& operator= ( const AutoSegment& ); + private: + inline void setInvalidated ( bool state ); + void _invalidate (); + + }; + + +// Inline Functions. + inline unsigned long AutoSegment::getId () const { return _id; } + inline Cell* AutoSegment::getCell () const { return getSegment()->getCell(); } + inline Net* AutoSegment::getNet () const { return getSegment()->getNet(); } + inline const Layer* AutoSegment::getLayer () const { return getSegment()->getLayer(); } + inline Box AutoSegment::getBoundingBox () const { return getSegment()->getBoundingBox(); } + inline Hook* AutoSegment::getSourceHook () { return getSegment()->getSourceHook(); } + inline Hook* AutoSegment::getTargetHook () { return getSegment()->getTargetHook(); } + inline Contact* AutoSegment::getSource () const { return static_cast(getSegment()->getSource()); } + inline Contact* AutoSegment::getTarget () const { return static_cast(getSegment()->getTarget()); } + inline Component* AutoSegment::getOppositeAnchor ( Component* anchor ) const { return getSegment()->getOppositeAnchor(anchor); }; + inline DbU::Unit AutoSegment::getSourcePosition () const { return _sourcePosition; } + inline DbU::Unit AutoSegment::getTargetPosition () const { return _targetPosition; } + inline DbU::Unit AutoSegment::getSourceX () const { return getSegment()->getSourceX(); } + inline DbU::Unit AutoSegment::getSourceY () const { return getSegment()->getSourceY(); } + inline DbU::Unit AutoSegment::getTargetX () const { return getSegment()->getTargetX(); } + inline DbU::Unit AutoSegment::getTargetY () const { return getSegment()->getTargetY(); } + inline DbU::Unit AutoSegment::getWidth () const { return getSegment()->getWidth(); } + inline DbU::Unit AutoSegment::getLength () const { return getSegment()->getLength(); } + inline void AutoSegment::invert () { getSegment()->invert(); } + inline GCell* AutoSegment::getGCell () const { return _gcell; } + inline AutoContact* AutoSegment::getAutoSource () const { return Session::lookup(getSource()); } + inline AutoContact* AutoSegment::getAutoTarget () const { return Session::lookup(getTarget()); } + inline bool AutoSegment::getConstraints ( Interval& i ) const { return getConstraints(i.getVMin(),i.getVMax()); } + inline AutoSegment* AutoSegment::getCanonical ( Interval& i ) { return getCanonical(i.getVMin(),i.getVMax()); } + inline DbU::Unit AutoSegment::getAxis () const { return _isHorizontal?getSegment()->getY():getSegment()->getX(); } + inline DbU::Unit AutoSegment::getOrigin () const { return _isHorizontal?_gcell->getY():_gcell->getX(); } + inline DbU::Unit AutoSegment::getExtremity () const { return _isHorizontal?_gcell->getYMax():_gcell->getXMax(); } + inline DbU::Unit AutoSegment::getOptimalMin () const { return DbU::lambda(_optimalMin) + getOrigin(); } + inline DbU::Unit AutoSegment::getOptimalMax () const { return DbU::lambda(_optimalMax) + getOrigin(); } + inline const Interval& AutoSegment::getUserConstraints () const { return _userConstraints; } + + inline bool AutoSegment::isInvalidated () const { return _invalidated; } + inline bool AutoSegment::isHorizontal () const { return _isHorizontal; } + inline bool AutoSegment::isVertical () const { return !_isHorizontal; } + inline bool AutoSegment::isGlobal () const { return _isGlobal; } + inline bool AutoSegment::isCanonicalLocal () const { return _isCanonicalLocal; } + inline bool AutoSegment::isLocal () const { return !_isGlobal; } + inline bool AutoSegment::isTerminal () const { return _isTerminal; } + inline bool AutoSegment::isCollapsed () const { return _isCollapsed; } + inline bool AutoSegment::isCanonical () const { return _isCanonical; } + inline bool AutoSegment::isFixed () const { return _isFixed; } + inline bool AutoSegment::isStrap () const { return _strap; } + inline bool AutoSegment::isLayerChange () const { return _layerChange; } + inline bool AutoSegment::isAccountable () const { return _isCanonical && !_isCollapsed; } + inline bool AutoSegment::isUnsetAxis () const { return _isUnsetAxis; } + inline bool AutoSegment::isSlackened () const { return _slackened; } + inline bool AutoSegment::isSlackenStrap () const { return _slackenStrap; } + inline bool AutoSegment::allowOutsideGCell () const { return _allowOutsideGCell; } + + inline void AutoSegment::setLayer ( const Layer* layer ) { invalidate(); getSegment()->setLayer(layer); } + inline void AutoSegment::setInvalidated ( bool state ) { _invalidated = state; } + inline void AutoSegment::setGlobal ( bool state ) { _isGlobal = state; } + inline void AutoSegment::setCanonicalLocal ( bool state ) { _isCanonicalLocal = state; } + inline void AutoSegment::setTerminal ( bool state ) { _isTerminal = state; } + inline void AutoSegment::setFixed ( bool state ) { _isFixed = state; } + inline void AutoSegment::setStrap ( bool state ) { _strap = state; } + inline void AutoSegment::setLayerChange ( bool state ) { _layerChange = state; } + inline void AutoSegment::setSlackened ( bool state ) { _slackened = state; } + inline void AutoSegment::setSlackenStrap ( bool state ) { _slackenStrap = state; } + inline void AutoSegment::setOptimalMin ( DbU::Unit min ) { _optimalMin = (unsigned int)DbU::getLambda(min-getOrigin()); } + inline void AutoSegment::setOptimalMax ( DbU::Unit max ) { _optimalMax = (unsigned int)DbU::getLambda(max-getOrigin()); } + inline void AutoSegment::mergeUserConstraints ( const Interval& constraints ) { _userConstraints.intersection(constraints); } + inline void AutoSegment::resetUserConstraints () { _userConstraints = Interval(false); } + + + inline bool AutoSegment::CompareId::operator() ( const AutoSegment* lhs, const AutoSegment* rhs ) const + { return lhs->getId() < rhs->getId(); } + + inline void AutoSegment::setCanonical ( bool state ) + { + if ( _isCanonical != state ) { + //ltrace(159) << "canonical:" << state << " " << (void*)this << " " << _getString() << endl; + _isCanonical = state; + } + } + + inline unsigned long AutoSegment::getMaxId () + { return _maxId; } + + inline bool AutoSegment::arePerpandiculars ( AutoSegment* a, AutoSegment* b ) + { return a->isHorizontal() != b->isHorizontal(); } + + inline bool AutoSegment::arePerpandiculars ( bool isHorizontalA, AutoSegment* b ) + { return isHorizontalA != b->isHorizontal(); } + + inline bool AutoSegment::areAligneds ( AutoSegment* a, AutoSegment* b ) + { return a->isHorizontal() == b->isHorizontal(); } + + inline unsigned int AutoSegment::getPerpandicularState ( AutoContact* contact + , AutoSegment* source + , AutoSegment* current + , AutoSegment* master ) + { + return getPerpandicularState ( contact, source, current, master->isHorizontal(), master->getLayer() ); + } + + + inline int AutoSegment::getTerminalCount ( AutoSegment* seed ) + { + ltrace(80) << "getTerminalCount() - " << seed << endl; + + vector collapseds; + vector perpandiculars; + DbU::Unit leftBound; + DbU::Unit rightBound; + + getTopologicalInfos ( seed + , collapseds + , perpandiculars + , leftBound + , rightBound + ); + + return getTerminalCount ( seed, collapseds ); + } + + +} // End of Katabatic namespace. + + +INSPECTOR_P_SUPPORT(Katabatic::AutoSegment); + + +# endif // __KATABATIC_AUTOSEGMENT__ diff --git a/katabatic/src/katabatic/AutoSegments.h b/katabatic/src/katabatic/AutoSegments.h new file mode 100644 index 00000000..d8562cbd --- /dev/null +++ b/katabatic/src/katabatic/AutoSegments.h @@ -0,0 +1,471 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2008, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | K a t a b a t i c - Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Header : "./AutoSegments.h" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#ifndef __KATABATIC_AUTOSEGMENTS_H__ +#define __KATABATIC_AUTOSEGMENTS_H__ + +#include +#include +#include +#include +#include "hurricane/Collection.h" +#include "hurricane/DbU.h" +#include "hurricane/Box.h" + +namespace Hurricane { + class Hook; + class Component; + class Contact; + class Segment; + class Net; +} + + +namespace Katabatic { + + + using std::string; + using std::pair; + using std::list; + using std::vector; + using std::map; + + using Hurricane::Record; + using Hurricane::DbU; + using Hurricane::Box; + using Hurricane::Hook; + using Hurricane::Component; + using Hurricane::Contact; + using Hurricane::Segment; + using Hurricane::Net; + using Hurricane::Filter; + using Hurricane::Locator; + using Hurricane::Collection; + using Hurricane::GenericFilter; + using Hurricane::GenericLocator; + using Hurricane::GenericCollection; + + class AutoContact; + class AutoSegment; + class GCell; + + +// ------------------------------------------------------------------- +// Collections. + + + typedef Hurricane::Filter AutoSegmentHF; + typedef Hurricane::Locator AutoSegmentHL; + typedef Hurricane::Collection AutoSegmentHC; + typedef GenericCollection AutoSegments; + typedef GenericLocator AutoSegmentLocator; + typedef GenericFilter AutoSegmentFilter; + typedef map AutoSegmentLut; + + +// ------------------------------------------------------------------- +// Class : "Katabatic::AutoSegmentStack". + + + class AutoSegmentStack : protected list > { + public: + inline bool isEmpty () const; + inline size_t getSize () const; + void push ( AutoContact*, AutoSegment* ); + inline void pop (); + inline AutoContact* getAutoContact () const; + inline AutoSegment* getAutoSegment () const; + }; + + + inline bool AutoSegmentStack::isEmpty () const { return empty(); }; + inline size_t AutoSegmentStack::getSize () const { return size(); }; + inline void AutoSegmentStack::pop () { if ( !empty() ) pop_back(); }; + inline AutoContact* AutoSegmentStack::getAutoContact () const { return empty() ? NULL : back().first; }; + inline AutoSegment* AutoSegmentStack::getAutoSegment () const { return empty() ? NULL : back().second; }; + + +// ------------------------------------------------------------------- +// Class : "Katabatic::AutoSegments_OnContact". + + + class AutoSegments_OnContact : public AutoSegmentHC { + + public: + // Sub-Class: Locator. + class Locator : public AutoSegmentHL { + public: + Locator ( AutoSegment* master, Contact* contact ); + inline Locator ( const Locator& ); + virtual AutoSegment* getElement () const; + virtual AutoSegmentHL* getClone () const; + virtual bool isValid () const; + virtual void progress (); + virtual string _getString () const; + protected: + AutoSegment* _master; + Hook* _hook; + AutoSegment* _element; + }; + + public: + // AutoSegments_OnContact Methods. + inline AutoSegments_OnContact ( AutoSegment* master, Contact* contact ); + inline AutoSegments_OnContact ( const AutoSegments_OnContact& ); + virtual AutoSegmentHC* getClone () const; + virtual AutoSegmentHL* getLocator () const; + virtual string _getString () const; + + protected: + // AutoSegments_OnContact Attributes. + AutoSegment* _master; + Contact* _contact; + }; + + + inline AutoSegments_OnContact::Locator::Locator ( const Locator &locator ) + : AutoSegmentHL() + , _master(locator._master) + , _hook(locator._hook) + , _element(locator._element) + { } + + + inline AutoSegments_OnContact::AutoSegments_OnContact ( AutoSegment* master, Contact* contact ) + : AutoSegmentHC() + , _master(master) + , _contact(contact) + { } + + + inline AutoSegments_OnContact::AutoSegments_OnContact ( const AutoSegments_OnContact& segments ) + : AutoSegmentHC() + , _master(segments._master) + , _contact(segments._contact) + { } + + +// ------------------------------------------------------------------- +// Class : "AutoSegments_Collapsed". + + + class AutoSegments_Collapsed : public AutoSegmentHC { + + public: + // Sub-Class: Locator. + class Locator : public AutoSegmentHL { + public: + inline Locator ( AutoSegment* segment , bool withPerpand ); + inline Locator ( const Locator &locator ); + virtual AutoSegment* getElement () const; + virtual AutoSegmentHL* getClone () const; + virtual bool isValid () const; + virtual void progress (); + virtual string _getString () const; + protected: + bool _withPerpand; + AutoSegment* _master; + AutoSegmentStack _stack; + }; + + public: + // AutoSegments_Collapsed Methods. + AutoSegments_Collapsed ( AutoSegment*, bool withPerpand=false ); + AutoSegments_Collapsed ( const AutoSegments_Collapsed& ); + virtual AutoSegmentHC* getClone () const; + virtual AutoSegmentHL* getLocator () const; + virtual string _getString () const; + + protected: + // AutoSegments_Collapsed Attributes. + bool _withPerpand; + AutoSegment* _segment; + }; + + + inline AutoSegments_Collapsed::Locator::Locator ( const Locator &locator ) + : AutoSegmentHL() + , _withPerpand(locator._withPerpand) + , _master(locator._master) + , _stack(locator._stack) + { } + + + inline AutoSegments_Collapsed::AutoSegments_Collapsed ( AutoSegment* segment, bool withPerpand ) + : AutoSegmentHC() + , _withPerpand(withPerpand) + , _segment(segment) + { } + + + inline AutoSegments_Collapsed::AutoSegments_Collapsed ( const AutoSegments_Collapsed& autosegments ) + : AutoSegmentHC() + , _withPerpand(autosegments._withPerpand) + , _segment(autosegments._segment) + { } + + +// ------------------------------------------------------------------- +// Class : "AutoSegments_CollapsedPerpandicular". + + + class AutoSegments_CollapsedPerpandicular : public AutoSegmentHC { + + public: + // Sub-Class: Locator. + class Locator : public AutoSegmentHL { + public: + Locator ( AutoSegment* segment ); + inline Locator ( const Locator& ); + virtual AutoSegment* getElement () const; + virtual AutoSegmentHL* getClone () const; + virtual bool isValid () const; + virtual void progress (); + virtual string _getString () const; + protected: + AutoSegment* _master; + AutoSegmentStack _stack; + vector _perpandiculars; + }; + + public: + // AutoSegments_CollapsedPerpandicular Methods. + inline AutoSegments_CollapsedPerpandicular ( AutoSegment* segment ); + inline AutoSegments_CollapsedPerpandicular ( const AutoSegments_CollapsedPerpandicular& ); + virtual AutoSegmentHC* getClone () const; + virtual AutoSegmentHL* getLocator () const; + virtual string _getString () const; + + protected: + // AutoSegments_CollapsedPerpandicular Attributes. + AutoSegment* _segment; + }; + + + inline AutoSegments_CollapsedPerpandicular::Locator::Locator ( const Locator& locator ) + : AutoSegmentHL() + , _master(locator._master) + , _stack(locator._stack) + , _perpandiculars() + { } + + + inline AutoSegments_CollapsedPerpandicular::AutoSegments_CollapsedPerpandicular + ( AutoSegment* segment ) + : AutoSegmentHC() + , _segment(segment) + { } + + + inline AutoSegments_CollapsedPerpandicular::AutoSegments_CollapsedPerpandicular + ( const AutoSegments_CollapsedPerpandicular& autosegments ) + : AutoSegmentHC() + , _segment(autosegments._segment) + { } + + +// ------------------------------------------------------------------- +// Class : "AutoSegments_AnchorOnGCell". + + + class AutoSegments_AnchorOnGCell : public AutoSegmentHC { + + public: + // Sub-Class: Locator. + class Locator : public AutoSegmentHL { + public: + Locator ( GCell* fcell, bool sourceAnchor, unsigned int direction ); + inline Locator ( const Locator& ); + virtual ~Locator (); + virtual AutoSegment* getElement () const; + virtual AutoSegmentHL* getClone () const; + virtual bool isValid () const; + virtual void progress (); + virtual string _getString () const; + protected: + bool _sourceAnchor; + unsigned int _direction; + vector::const_iterator _itContact; + vector::const_iterator _itEnd; + Hurricane::Locator* _hookLocator; + AutoSegment* _element; + }; + + public: + // AutoSegments_CollapsedPerpandicular Methods. + inline AutoSegments_AnchorOnGCell ( GCell* fcell, bool sourceAnchor, unsigned int direction ); + inline AutoSegments_AnchorOnGCell ( const AutoSegments_AnchorOnGCell& ); + virtual AutoSegmentHC* getClone () const; + virtual AutoSegmentHL* getLocator () const; + virtual string _getString () const; + + public: + // AutoSegments_CollapsedPerpandicular Attributes. + GCell* _fcell; + unsigned int _direction; + bool _sourceAnchor; + }; + + + inline AutoSegments_AnchorOnGCell::Locator::Locator ( const Locator &locator ) + : AutoSegmentHL() + , _sourceAnchor(locator._sourceAnchor) + , _direction(locator._direction) + , _itContact(locator._itContact) + , _itEnd(locator._itEnd) + , _hookLocator(locator._hookLocator->getClone()) + , _element(locator._element) + { } + + + inline AutoSegments_AnchorOnGCell::AutoSegments_AnchorOnGCell + ( GCell* fcell, bool sourceAnchor, unsigned int direction ) + : AutoSegmentHC() + , _fcell(fcell) + , _direction(direction) + , _sourceAnchor(sourceAnchor) + { } + + + inline AutoSegments_AnchorOnGCell::AutoSegments_AnchorOnGCell + ( const AutoSegments_AnchorOnGCell& autosegments ) + : AutoSegmentHC() + , _fcell(autosegments._fcell) + , _direction(autosegments._direction) + , _sourceAnchor(autosegments._sourceAnchor) + { } + + +// ------------------------------------------------------------------- +// Class : "AutoSegments_AnchoredBySource". + + + class AutoSegments_AnchoredBySource : public AutoSegmentHC { + + public: + // Sub-Class: Locator. + class Locator : public AutoSegmentHL { + public: + Locator ( AutoContact* sourceAnchor, unsigned int direction ); + inline Locator ( const Locator& ); + virtual ~Locator (); + virtual AutoSegment* getElement () const; + virtual AutoSegmentHL* getClone () const; + virtual bool isValid () const; + virtual void progress (); + virtual string _getString () const; + protected: + unsigned int _direction; + Hurricane::Locator* _contactLocator; + Hurricane::Locator* _hookLocator; + AutoSegment* _element; + }; + + // Constructors. + public: + // AutoSegments_AnchoredBySource Methods. + inline AutoSegments_AnchoredBySource ( AutoContact* sourceContact, unsigned int direction ); + inline AutoSegments_AnchoredBySource ( const AutoSegments_AnchoredBySource& ); + virtual AutoSegmentHC* getClone () const; + virtual AutoSegmentHL* getLocator () const; + virtual string _getString () const; + + protected: + // AutoSegments_AnchoredBySource Attributes. + unsigned int _direction; + AutoContact* _sourceContact; + + }; + + + inline AutoSegments_AnchoredBySource::Locator::Locator ( const Locator &locator ) + : AutoSegmentHL() + , _direction(locator._direction) + , _contactLocator(locator._contactLocator->getClone()) + , _hookLocator(locator._hookLocator->getClone()) + , _element(locator._element) + { } + + + inline AutoSegments_AnchoredBySource::AutoSegments_AnchoredBySource + ( AutoContact* sourceContact, unsigned int direction ) + : AutoSegmentHC() + , _direction(direction) + , _sourceContact(sourceContact) + { } + + + inline AutoSegments_AnchoredBySource::AutoSegments_AnchoredBySource + ( const AutoSegments_AnchoredBySource& autosegments ) + : AutoSegmentHC() + , _direction(autosegments._direction) + , _sourceContact(autosegments._sourceContact) + { } + + +// ------------------------------------------------------------------- +// Class : "AutoSegments_IsAccountable". + + + class AutoSegments_IsAccountable : public AutoSegmentHF { + public: + virtual AutoSegmentHF* getClone () const; + virtual bool accept ( AutoSegment* ) const; + virtual string _getString () const; + }; + + +// ------------------------------------------------------------------- +// Class : "AutoSegments_InDirection". + + + class AutoSegments_InDirection : public AutoSegmentHF { + public: + inline AutoSegments_InDirection ( unsigned int direction ); + inline AutoSegments_InDirection ( const AutoSegments_InDirection& ); + virtual AutoSegmentHF* getClone () const; + virtual bool accept ( AutoSegment* segment ) const; + virtual string _getString () const; + protected: + unsigned int _direction; + }; + + + inline AutoSegments_InDirection::AutoSegments_InDirection ( unsigned int direction ) + : AutoSegmentHF() + , _direction(_direction) + {} + + + inline AutoSegments_InDirection::AutoSegments_InDirection ( const AutoSegments_InDirection& filter ) + : AutoSegmentHF() + , _direction(filter._direction) + {} + + +} // End of Katabatic namespace. + + +# endif diff --git a/katabatic/src/katabatic/AutoVertical.h b/katabatic/src/katabatic/AutoVertical.h new file mode 100644 index 00000000..38b9788f --- /dev/null +++ b/katabatic/src/katabatic/AutoVertical.h @@ -0,0 +1,119 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2008, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | K a t a b a t i c - Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Header : "./AutoVertical.h" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#ifndef __KATABATIC_AUTOVERTICAL__ +#define __KATABATIC_AUTOVERTICAL__ + +#include "hurricane/Vertical.h" +#include "katabatic/AutoSegment.h" + + +namespace Katabatic { + + +// ------------------------------------------------------------------- +// Class : "AutoVertical". + + + class AutoVertical : public AutoSegment { + using AutoSegment::_computeTerminal; + + public: + // Constructors. + static AutoVertical* create ( Vertical* vertical + , int type + , bool terminal=false + , bool collapsed=false + ); + static AutoVertical* create ( AutoContact* source + , AutoContact* target + , const Layer* layer + , DbU::Unit x + , DbU::Unit width + , int type + , bool terminal=false + , bool collapsed=false + ); + // Predicates. + virtual bool _canSlacken () const; + virtual bool canDesalignate ( AutoContact* ) const; + // Accessors. + virtual Segment* base () { return _vertical; }; + virtual Segment* base () const { return _vertical; }; + virtual Segment* getSegment () { return _vertical; }; + virtual Segment* getSegment () const { return _vertical; }; + virtual Vertical* getVertical () { return _vertical; }; + virtual DbU::Unit getSourceU () const { return _vertical->getSourceY(); }; + virtual DbU::Unit getTargetU () const { return _vertical->getTargetY(); }; + virtual DbU::Unit getDuSource () const { return _vertical->getDySource(); }; + virtual DbU::Unit getDuTarget () const { return _vertical->getDyTarget(); }; + virtual Interval getSpanU () const { return Interval(_vertical->getSourceY(),_vertical->getTargetY()); }; + virtual bool getConstraints ( DbU::Unit& min, DbU::Unit& max ) const; + virtual Interval getSourceConstraints ( bool native=false ) const; + virtual Interval getTargetConstraints ( bool native=false ) const; + virtual unsigned int getDirection () const; + virtual size_t getGCells ( vector& ) const; + // Modifiers. + virtual void setDuSource ( DbU::Unit du ) { _vertical->setDySource(du); }; + virtual void setDuTarget ( DbU::Unit du ) { _vertical->setDyTarget(du); }; + virtual void alignate ( DbU::Unit axis ); + virtual void orient (); + virtual void setPositions (); + virtual bool checkPositions () const; + virtual bool checkConstraints () const; + virtual void _computeTerminal (); + virtual void moveURight (); + virtual void moveULeft (); + virtual void _makeDogLeg ( GCell*, bool upLayer ); + virtual void desalignate ( AutoContact* ); + virtual void _slacken (); + // Inspector Management. + virtual Record* _getRecord () const; + virtual string _getString () const; + virtual string _getTypeName () const { return "AutoVertical"; }; + + protected: + // Internal: Attributes. + Vertical* _vertical; + + // Constructors. + protected: + AutoVertical ( Vertical* vertical + , int type + , bool terminal + , bool collapsed ); + virtual ~AutoVertical (); + virtual void _postCreate (); + virtual void _preDestroy (); + private: + AutoVertical ( const AutoVertical& ); + AutoVertical& operator= ( const AutoVertical& ); + }; + + +} // End of Katabatic namespace. + + +#endif // __KATABATIC_AUTOHORIZONTAL__ diff --git a/katabatic/src/katabatic/Configuration.h b/katabatic/src/katabatic/Configuration.h new file mode 100644 index 00000000..7f227225 --- /dev/null +++ b/katabatic/src/katabatic/Configuration.h @@ -0,0 +1,132 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2008, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | K a t a b a t i c - Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Header : "./Configuration.h" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#ifndef __KATABATIC_CONFIGURATION__ +#define __KATABATIC_CONFIGURATION__ + +#include + +#include "hurricane/DbU.h" +namespace Hurricane { + class Layer; +} + +#include "crlcore/RoutingGauge.h" +namespace CRL { + class RoutingLayerGauge; +} + + +namespace Katabatic { + + + using std::string; + using Hurricane::Record; + using Hurricane::Layer; + using Hurricane::DbU; + using CRL::RoutingGauge; + using CRL::RoutingLayerGauge; + + +// ------------------------------------------------------------------- +// Class : "Katabatic::Configuration" (decorator). + + + class Configuration { + public: + // Constructor & Destructor. + Configuration (); + virtual ~Configuration (); + // Methods. + virtual bool isGMetal ( const Layer* ) const = 0; + virtual size_t getDepth () const = 0; + virtual size_t getLayerDepth ( const Layer* ) const = 0; + virtual RoutingGauge* getRoutingGauge () const = 0; + virtual RoutingLayerGauge* getLayerGauge ( size_t depth ) const = 0; + virtual const Layer* getRoutingLayer ( size_t depth ) const = 0; + virtual Layer* getContactLayer ( size_t depth ) const = 0; + virtual DbU::Unit getExtensionCap () const = 0; + virtual float getSaturateRatio () const = 0; + virtual DbU::Unit getGlobalThreshold () const = 0; + virtual void setSaturateRatio ( float ) = 0; + virtual void setGlobalThreshold ( DbU::Unit ) = 0; + virtual Record* _getRecord () const = 0; + virtual string _getString () const = 0; + virtual string _getTypeName () const = 0; + private: + Configuration ( const Configuration& ); + Configuration& operator= ( const Configuration& ); + }; + + +// ------------------------------------------------------------------- +// Class : "Katabatic::ConfigurationConcrete". + + + class ConfigurationConcrete : public Configuration { + public: + // Constructor & Destructor. + ConfigurationConcrete ( const RoutingGauge* ); + virtual ~ConfigurationConcrete (); + // Methods. + virtual bool isGMetal ( const Layer* ) const; + virtual size_t getDepth () const; + virtual size_t getLayerDepth ( const Layer* ) const; + virtual RoutingGauge* getRoutingGauge () const; + virtual RoutingLayerGauge* getLayerGauge ( size_t depth ) const; + virtual const Layer* getRoutingLayer ( size_t depth ) const; + virtual Layer* getContactLayer ( size_t depth ) const; + virtual DbU::Unit getExtensionCap () const; + virtual float getSaturateRatio () const; + virtual DbU::Unit getGlobalThreshold () const; + virtual void setSaturateRatio ( float ); + virtual void setGlobalThreshold ( DbU::Unit ); + virtual Record* _getRecord () const; + virtual string _getString () const; + virtual string _getTypeName () const; + + protected: + // Attributes. + const Layer* _gmetalh; + const Layer* _gmetalv; + const Layer* _gcontact; + RoutingGauge* _rg; + DbU::Unit _extensionCap; + float _saturateRatio; + DbU::Unit _globalThreshold; + private: + ConfigurationConcrete ( const ConfigurationConcrete& ); + ConfigurationConcrete& operator= ( const ConfigurationConcrete& ); + }; + + +} // End of Katabatic namespace. + + +INSPECTOR_P_SUPPORT(Katabatic::Configuration); +INSPECTOR_P_SUPPORT(Katabatic::ConfigurationConcrete); + + +#endif // __KATABATIC_CONFIGURATION__ diff --git a/katabatic/src/katabatic/ContactWrapper.h b/katabatic/src/katabatic/ContactWrapper.h new file mode 100644 index 00000000..e7f25904 --- /dev/null +++ b/katabatic/src/katabatic/ContactWrapper.h @@ -0,0 +1,113 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2008, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | K a t a b a t i c - Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Header : "./ContactWrapper.h" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#ifndef __KATABATIC_CONTACT_WRAPPER__ +#define __KATABATIC_CONTACT_WRAPPER__ + + +#include "hurricane/Contact.h" + + +namespace Katabatic { + + using Hurricane::Hook; + using Hurricane::Component; + using Hurricane::DbU; + using Hurricane::Point; + using Hurricane::Layer; + using Hurricane::Contact; + + +// ------------------------------------------------------------------- +// Template Class : "Katabatic::ContactWrapper". + + template + class ContactWrapper { + public: + // Accessors. + inline BaseContact* getBase (); + inline Hook* getBodyHook (); + inline Hook* getAnchorHook (); + inline Component* getAnchor () const; + inline DbU::Unit getDx () const; + inline DbU::Unit getDy () const; + inline DbU::Unit getWidth () const; + inline DbU::Unit getHalfWidth () const; + inline DbU::Unit getHeight () const; + inline DbU::Unit getHalfHeight () const; + public: + // Modifiers. + inline void setLayer ( const Layer* ); + inline void setWidth ( DbU::Unit ); + inline void setHeight ( DbU::Unit ); + inline void setSizes ( DbU::Unit width, Dbu::Unit height ); + inline void setX ( DbU::Unit ); + inline void setY ( DbU::Unit ); + inline void setPosition ( DbU::Unit width, Dbu::Unit height ); + inline void setPosition ( const Point& ); + inline void setDx ( DbU::Unit ); + inline void setDy ( DbU::Unit ); + inline void setOffset ( DbU::Unit dx, Dbu::Unit dy ); + protected: + // Attribute. + BaseContact* _contact; + protected: + // Constructor & Destructors. + inline ContactWrapper ( BaseContact* ); + private: + ContactWrapper& ContactWrapper ( const ContactWrapper& ); + ContactWrapper& operator= ( const ContactWrapper& ); + }; + + +// Inline Functions. + inline BaseContact* ContactWrapper::getBase () { return _contact; } + inline Hook* ContactWrapper::getBodyHook () { return _contact->getBodyHook(); } + inline Hook* ContactWrapper::getAnchorHook () { return _contact->getAnchorHook(); } + inline Component* ContactWrapper::getAnchor () const { return _contact->getAnchor(); } + inline DbU::Unit ContactWrapper::getDx () const { return _contact->getDx(); } + inline DbU::Unit ContactWrapper::getDy () const { return _contact->getDy(); } + inline DbU::Unit ContactWrapper::getWidth () const { return _contact->getWidth(); } + inline DbU::Unit ContactWrapper::getHalfWidth () const { return _contact->getHalfWidth(); } + inline DbU::Unit ContactWrapper::getHeight () const { return _contact->getHeight(); } + inline DbU::Unit ContactWrapper::getHalfHeight () const { return _contact->getHalfHeight(); } + inline void ContactWrapper::setLayer ( const Layer* layer ) { return _contact->setLayer(layer); } + inline void ContactWrapper::setWidth ( DbU::Unit w ) { return _contact->setWidth(w); } + inline void ContactWrapper::setHeight ( DbU::Unit h ) { return _contact->setHeight(h); } + inline void ContactWrapper::setSizes ( DbU::Unit w, Dbu::Unit h ) { return _contact->setSizes(w,h); } + inline void ContactWrapper::setX ( DbU::Unit x ) { return _contact->setX(x); } + inline void ContactWrapper::setY ( DbU::Unit y ) { return _contact->setY(y); } + inline void ContactWrapper::setPosition ( DbU::Unit x, Dbu::Unit y ) { return _contact->setPosition(x,y); } + inline void ContactWrapper::setPosition ( const Point& p ) { return _contact->setPosition(p); } + inline void ContactWrapper::setDx ( DbU::Unit dx ) { return _contact->setDx(dx); } + inline void ContactWrapper::setDy ( DbU::Unit dy ) { return _contact->setDy(dy); } + inline void ContactWrapper::setOffset ( DbU::Unit dx, Dbu::Unit dy ) { return _contact->setOffset(dx,dy); } + inline ContactWrapper::ContactWrapper ( BaseContact* contact ) : _contact(contact) { } + + +} // End of Katabatic namespace. + + +#endif // __KATABATIC_CONTACT_WRAPPER__ diff --git a/katabatic/src/katabatic/GCell.h b/katabatic/src/katabatic/GCell.h new file mode 100644 index 00000000..d6ea6c31 --- /dev/null +++ b/katabatic/src/katabatic/GCell.h @@ -0,0 +1,254 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | K a t a b a t i c - Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Header : "./GCell.h" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#ifndef __KATABATIC_GCELL__ +#define __KATABATIC_GCELL__ + +#include +#include +#include +#include + +#include "hurricane/DbU.h" +#include "hurricane/Point.h" +#include "hurricane/Box.h" +#include "hurricane/Interval.h" +#include "hurricane/ExtensionGo.h" +namespace Hurricane { + class Name; +} + +#include "crlcore/RoutingLayerGauge.h" +#include "katabatic/AutoSegments.h" + + +namespace Katabatic { + + + using std::set; + using std::vector; + using std::ostream; + using std::binary_function; + using Hurricane::_TName; + using Hurricane::Record; + using Hurricane::Name; + using Hurricane::DbU; + using Hurricane::Point; + using Hurricane::Box; + using Hurricane::Interval; + using Hurricane::ExtensionGo; + + class GCellGrid; + class AutoContact; + class AutoSegment; + + +// ------------------------------------------------------------------- +// Class : "Katabatic::GCell". + + + class GCell : public ExtensionGo { + + public: + class CompareByDensity : public binary_function { + public: + CompareByDensity ( unsigned int depth ); + bool operator() ( GCell* lhs, GCell* rhs ); + private: + unsigned int _depth; + }; + + public: + // Static Utilities. + static bool areDensityConnex ( GCell* a, GCell* b ); + // Static Accessors. + static size_t getAllocateds (); + static DbU::Unit getTopRightShrink (); + static const Name& getStaticName (); + virtual const Name& getName () const; + // Accessors. + inline bool isSaturated () const; + bool isSaturated ( unsigned int depth ) const; + inline bool isValid () const; + bool isAboveDensity ( float threshold ) const; + bool hasFreeTrack ( size_t depth ) const; + inline GCellGrid* getGCellGrid () const; + inline unsigned int getDepth () const; + inline unsigned int getIndex () const; + unsigned int getRow () const; + unsigned int getColumn () const; + void getDensities ( float* ) const; + virtual void translate ( const DbU::Unit&, const DbU::Unit& ); + virtual Box getBoundingBox () const; + inline Point getCenter () const; + inline DbU::Unit getX () const; + inline DbU::Unit getY () const; + inline DbU::Unit getXMax () const; + inline DbU::Unit getYMax () const; + Interval getUSide ( unsigned int ) const; + GCell* getLeft () const; + GCell* getRight () const; + GCell* getUp () const; + GCell* getDown () const; + float getHCapacity () const; + float getVCapacity () const; + inline float getCDensity ( bool update=true ) const; + inline float getDensity ( unsigned int depth, bool update=true ) const; + float getDensity ( bool update=true ) const; + float getMaxHVDensity ( bool update=true ) const; + float getStiffness () const; + inline unsigned int getSegmentCount () const; + inline unsigned int getRoutedCount () const; + inline vector* getVSegments (); + inline vector* getHSegments (); + inline vector* getContacts (); + AutoSegments getHStartSegments (); + AutoSegments getVStartSegments (); + AutoSegments getHStopSegments (); + AutoSegments getVStopSegments (); + inline AutoSegments getStartSegments ( unsigned int direction ); + inline AutoSegments getStopSegments ( unsigned int direction ); + size_t checkDensity () const; + bool checkEdgeSaturation ( float threshold ) const; + // Modifiers. + void incSegmentCount ( int count ); + void incRoutedCount ( int count ); + void addBlockage ( unsigned int depth, float ); + inline void addVSegment ( AutoSegment* ); + inline void addHSegment ( AutoSegment* ); + inline void addContact ( AutoContact* ); + void removeVSegment ( AutoSegment* ); + void removeHSegment ( AutoSegment* ); + void removeContact ( AutoContact* ); + void updateContacts (); + size_t updateDensity (); + void desaturate ( unsigned int depth, set& ); + bool stepDesaturate ( unsigned int depth, set& ); + inline void invalidate (); + // Inspector Management. + Record* _getRecord () const; + string _getString () const; + inline string _getTypeName () const; + void _xmlWrite ( ostream& o ) const; + + private: + // Static Attributes. + static const Name _goName; + static size_t _allocateds; + static DbU::Unit _topRightShrink; + // Attributes. + GCellGrid* _gcellGrid; + unsigned int _index; + vector _vsegments; + vector _hsegments; + vector _contacts; + Box _box; + size_t _depth; + size_t _pinDepth; + float* _blockages; + float _cDensity; + float* _densities; + float* _saturateDensities; + unsigned int _segmentCount; + unsigned int _routedSegmentCount; + bool _saturated; + bool _invalid; + + protected: + // Constructors & Destructors. + GCell ( GCellGrid* gcellGrid + , unsigned int index + , const Box& box + ); + inline ~GCell (); + inline void _postCreate (); + inline void _preDestroy (); + static GCell* create ( GCellGrid* gcellGrid + , unsigned int index + , Box box + ); + private: + GCell ( const GCell& ); + GCell& operator= ( const GCell& ); + + friend class GCellGrid; + }; + + +// Inline Functions. + inline bool GCell::isSaturated () const { return _saturated; } + inline bool GCell::isValid () const { return !_invalid; } + inline GCellGrid* GCell::getGCellGrid () const { return _gcellGrid; } + inline unsigned int GCell::getDepth () const { return _depth; } + inline unsigned int GCell::getIndex () const { return _index; } + inline Point GCell::getCenter () const { return _box.getCenter(); } + inline DbU::Unit GCell::getX () const { return _box.getXMin(); } + inline DbU::Unit GCell::getY () const { return _box.getYMin(); } + inline DbU::Unit GCell::getXMax () const { return _box.getXMax(); } + inline DbU::Unit GCell::getYMax () const { return _box.getYMax(); } + inline vector* GCell::getVSegments () { return &_vsegments; } + inline vector* GCell::getHSegments () { return &_hsegments; } + inline vector* GCell::getContacts () { return &_contacts; } + inline unsigned int GCell::getSegmentCount () const { return _segmentCount; } + inline unsigned int GCell::getRoutedCount () const { return _routedSegmentCount; } + inline string GCell::_getTypeName () const { return _TName("GCell"); } + inline void GCell::invalidate () { _invalid = true; } + + inline AutoSegments GCell::getStartSegments ( unsigned int direction ) + { return (direction&Constant::Horizontal) ? getHStartSegments() : getVStartSegments(); } + + inline AutoSegments GCell::getStopSegments ( unsigned int direction ) + { return (direction&Constant::Horizontal) ? getHStopSegments() : getVStopSegments(); } + + inline float GCell::getCDensity ( bool update ) const + { if (_invalid and update) const_cast(this)->updateDensity(); return _cDensity; } + + inline float GCell::getDensity ( unsigned int depth, bool update ) const + { if (_invalid and update) const_cast(this)->updateDensity(); return _densities[depth]; } + + inline void GCell::addVSegment ( AutoSegment* segment ) + { invalidate(); _vsegments.push_back(segment); } + + inline void GCell::addHSegment ( AutoSegment* segment ) + { invalidate(); _hsegments.push_back(segment); } + + inline void GCell::addContact ( AutoContact* contact ) + { invalidate(); _contacts.push_back(contact); } + + +// ------------------------------------------------------------------- +// Utilities. + + + string getVectorString ( float*, size_t ); + + +} // End of Katabatic namespace. + + +INSPECTOR_P_SUPPORT(Katabatic::GCell); + + +#endif // __KATABATIC_GCELL__ diff --git a/katabatic/src/katabatic/GCellGrid.h b/katabatic/src/katabatic/GCellGrid.h new file mode 100644 index 00000000..518edb14 --- /dev/null +++ b/katabatic/src/katabatic/GCellGrid.h @@ -0,0 +1,90 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2008, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | K a t a b a t i c - Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Header : "./GCellGrid.h" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#ifndef __KATABATIC_GCELL_GRID__ +#define __KATABATIC_GCELL_GRID__ + +namespace Hurricane { + class Cell; +} + +#include "katabatic/Grid.h" +#include "katabatic/GCell.h" + + +namespace Katabatic { + + + using Hurricane::Cell; + using Hurricane::_TName; + + class KatabaticEngine; + + +// ------------------------------------------------------------------- +// Class : "Katabatic::GCellGrid". + + + class GCellGrid : public Grid { + + public: + Cell* getCell () const; + void updateContacts ( bool openSession=true ); + size_t checkDensity () const; + size_t updateDensity (); + bool checkEdgeSaturation ( float threshold ) const; + void _xmlWrite ( ostream& ); + virtual Record* _getRecord () const; + virtual string _getString () const; + virtual string _getTypeName () const; + + // Attributes. + protected: + KatabaticEngine* _katabatic; + + // Constructors & Destructors. + protected: + GCellGrid ( KatabaticEngine* ); + virtual ~GCellGrid (); + void _postCreate (); + void _preDestroy (); + static GCellGrid* create ( KatabaticEngine* ); + private: + GCellGrid ( const GCellGrid& ); + GCellGrid& operator= ( const GCellGrid& ); + + // Friends. + friend class KatabaticEngine; + }; + + +} // End of Katabatic namespace. + + +INSPECTOR_P_SUPPORT(Katabatic::GCellGrid); + + + +#endif // __KATABATIC_GCELL_GRID__ diff --git a/katabatic/src/katabatic/GCells.h b/katabatic/src/katabatic/GCells.h new file mode 100644 index 00000000..ad6d8bb8 --- /dev/null +++ b/katabatic/src/katabatic/GCells.h @@ -0,0 +1,63 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2008, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | K a t a b a t i c - Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Header : "./GCells.h" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + + + +#ifndef __KATABATIC_GCELLS__ +#define __KATABATIC_GCELLS__ + +#include "hurricane/Collections.h" + + +namespace Katabatic { + + + using Hurricane::Locator; + using Hurricane::Collection; + using Hurricane::GenericLocator; + using Hurricane::GenericCollection; + using Hurricane::GenericFilter; + + +// ------------------------------------------------------------------- +// Forward declarations. + + + class GCell; + + +// ------------------------------------------------------------------- +// Collections. + + + typedef GenericCollection GCells; + typedef GenericLocator GCellLocator; + typedef GenericFilter GCellFilter; + + +} // End of Katabatic namespace. + + +#endif // __KATABATIC_GCELLS__ diff --git a/katabatic/src/katabatic/GraphicKatabaticEngine.h b/katabatic/src/katabatic/GraphicKatabaticEngine.h new file mode 100644 index 00000000..79356620 --- /dev/null +++ b/katabatic/src/katabatic/GraphicKatabaticEngine.h @@ -0,0 +1,105 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2008, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | K a t a b a t i c - Routing Toolbox | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./GraphicKatabaticEngine.h" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + + +#ifndef __KATABATIC_GRAPHIC_KATABATIC_ENGINE__ +#define __KATABATIC_GRAPHIC_KATABATIC_ENGINE__ + +#include + +namespace Hurricane { + class Go; + class BasicLayer; + class Transformation; + class CellWidget; + class CellViewer; +} + +#include "crlcore/GraphicToolEngine.h" +namespace CRL { + class RoutingGauge; +} + +#include "katabatic/KatabaticEngine.h" + + +namespace Katabatic { + + using Hurricane::Go; + using Hurricane::Box; + using Hurricane::BasicLayer; + using Hurricane::Transformation; + using Hurricane::CellWidget; + using Hurricane::CellViewer; + using CRL::RoutingGauge; + using CRL::GraphicTool; + + +// ------------------------------------------------------------------- +// Class : "CRL::GraphicKatabaticEngine". + + + class GraphicKatabaticEngine : public GraphicTool { + Q_OBJECT; + + public: + static KatabaticEngine* create ( const RoutingGauge*, Cell* ); + static void initKatabaticAc ( CellWidget* ); + static void drawKatabaticAc ( CellWidget* + , const Go* + , const BasicLayer* + , const Box& + , const Transformation& + ); + static void initKatabaticGCell ( CellWidget* ); + static void drawKatabaticGCell ( CellWidget* + , const Go* + , const BasicLayer* + , const Box& + , const Transformation& + ); + static GraphicKatabaticEngine* grab (); + virtual const Name& getName () const; + virtual size_t release (); + virtual void addToMenu ( CellViewer* ); + public slots: + void run (); + void closeRoute (); + + protected: + static size_t _references; + static GraphicKatabaticEngine* _singleton; + CellViewer* _viewer; + protected: + GraphicKatabaticEngine (); + virtual ~GraphicKatabaticEngine (); + }; + + + +} // End of Katabatic namespace. + + +#endif // __KATABATIC_GRAPHIC_KATABATIC_ENGINE__ diff --git a/katabatic/src/katabatic/Grid.h b/katabatic/src/katabatic/Grid.h new file mode 100644 index 00000000..fb39af77 --- /dev/null +++ b/katabatic/src/katabatic/Grid.h @@ -0,0 +1,340 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2008, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | K a t a b a t i c - Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Header : "./Grid.h" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#ifndef __KATABATIC_GRID__ +#define __KATABATIC_GRID__ + +#include +#include + +#include "hurricane/Point.h" +#include "hurricane/Box.h" +#include "hurricane/Collection.h" + + +namespace Katabatic { + + + using std::string; + using std::vector; + using Hurricane::_TName; + using Hurricane::Record; + using Hurricane::DbU; + using Hurricane::Point; + using Hurricane::Box; + using Hurricane::Collection; + using Hurricane::GenericCollection; + using Hurricane::getCollection; + + +// ------------------------------------------------------------------- +// Class : "Katabatic::BaseGrid". + + + class BaseGrid { + + public: + class Axis; + public: + inline void destroy (); + // Accessors. + inline unsigned int getColumns () const; + inline unsigned int getRows () const; + inline unsigned int getRawSize () const; + inline unsigned int getIndex ( unsigned int c, unsigned int r ) const; + inline unsigned int getRow ( unsigned int ) const; + inline unsigned int getColumn ( unsigned int ) const; + inline const Axis& getXGrads () const; + inline const Axis& getYGrads () const; + // Inspector Managment. + virtual Record* _getRecord () const; + virtual string _getString () const = 0; + + public: + // Sub-Class Grid::Axis. + class Axis { + public: + // Modifiers. + inline void addGraduation ( DbU::Unit ); + void sort (); + // Accessors. + inline unsigned int getSize () const; + unsigned int getGraduationNumber ( DbU::Unit pos, bool& onGraduation ) const; + // Operators. + inline DbU::Unit& operator[] ( unsigned int i ); + // Inspector Management. + Record* _getRecord () const; + string _getString () const; + inline string _getTypeName () const; + string _print () const; + protected: + // Attributes. + vector _graduations; + }; + + protected: + // Attributes. + Axis _xGraduations; + Axis _yGraduations; + unsigned int _rows; + unsigned int _columns; + unsigned int _rawSize; + + // Constructors & Destructors. + protected: + BaseGrid (); + virtual ~BaseGrid (); + virtual void _postCreate (); + virtual void _preDestroy (); + private: + BaseGrid ( const BaseGrid& ); + BaseGrid& operator= ( const BaseGrid& ); + }; + + +// Inline Functions. + inline void BaseGrid::Axis::addGraduation ( DbU::Unit graduation ) { _graduations.push_back(graduation); } + inline unsigned int BaseGrid::Axis::getSize () const { return _graduations.size(); } + inline DbU::Unit& BaseGrid::Axis::operator[] ( unsigned int i ) { return _graduations[i]; } + inline string BaseGrid::Axis::_getTypeName () const { return _TName("BaseGrid::Axis"); } + + inline void BaseGrid::destroy () { _preDestroy(); delete this; } + inline unsigned int BaseGrid::getColumns () const { return _columns; }; + inline unsigned int BaseGrid::getRows () const { return _rows; }; + inline unsigned int BaseGrid::getRawSize () const { return getColumns() * getRows(); } + inline unsigned int BaseGrid::getIndex ( unsigned int c, unsigned int r ) const { return c+(r*getColumns()); } + inline unsigned int BaseGrid::getRow ( unsigned int i ) const { return i / getColumns(); } + inline unsigned int BaseGrid::getColumn ( unsigned int i ) const { return i % getColumns(); } + + inline const BaseGrid::Axis& BaseGrid::getXGrads () const { return _xGraduations; } + inline const BaseGrid::Axis& BaseGrid::getYGrads () const { return _yGraduations; } + + +// ------------------------------------------------------------------- +// Template Class : "Katabatic::Grid". + + + template + class Grid : public BaseGrid { + + public: + // Accessors. + inline GCellT* getGCell ( unsigned int index ) const; + inline GCellT* getGCell ( const Point p ) const; + inline GCellT* getGCell ( const Point p1, const Point p2 ) const; + inline GCellT* getGCellLeft ( const GCellT* gcell ) const; + inline GCellT* getGCellRight ( const GCellT* gcell ) const; + inline GCellT* getGCellUp ( const GCellT* gcell ) const; + inline GCellT* getGCellDown ( const GCellT* gcell ) const; + inline vector* getGCellVector (); + // Collections & Filters. + inline GenericCollection getGCells (); + inline GenericCollection getGCellsColumn ( unsigned int column + , unsigned int rowStart + , unsigned int rowStop ); + inline GenericCollection getGCellsRow ( unsigned int row + , unsigned int columnStart + , unsigned int columnStop ); + // Inspector Managment. + virtual Record* _getRecord () const; + + protected: + // Attributes. + vector _gcells; + + // Constructors & Destructors. + protected: + inline Grid (); + virtual ~Grid (); + private: + Grid ( const Grid& ); + Grid& operator= ( const Grid& ); + }; + + +} // End of Katabatic namespace. + + +#include "katabatic/GridCollections.h" +#include "katabatic/GridBox.h" + + +namespace Katabatic { + + +// Inline Functions. + + template + Grid::Grid () : BaseGrid() + , _gcells() + { } + + + template + Grid::~Grid () + { } + + + template + GCellT* Grid::getGCell ( unsigned int index ) const + { + if ( ( index < 0 ) || ( index >= _rawSize ) ) return NULL; + + return _gcells [ index ]; + } + + + template + GCellT* Grid::getGCell ( const Point p ) const + { + bool onColumn; + bool onRow; + + unsigned int column = _xGraduations.getGraduationNumber ( p.getX(), onColumn ); + unsigned int row = _yGraduations.getGraduationNumber ( p.getY(), onRow ); + + return getGCell ( getIndex(column,row) ); + } + + + template + GCellT* Grid::getGCell ( const Point p1, const Point p2 ) const + { + bool onColumn1; + bool onColumn2; + bool onRow1; + bool onRow2; + + unsigned int column1 = _xGraduations.getGraduationNumber ( p1.getX(), onColumn1 ); + unsigned int column2 = _xGraduations.getGraduationNumber ( p2.getX(), onColumn2 ); + unsigned int row1 = _yGraduations.getGraduationNumber ( p1.getY(), onRow1 ); + unsigned int row2 = _yGraduations.getGraduationNumber ( p2.getY(), onRow2 ); + + if ( row1 != row2 ) { + if ( onRow1 ) row1 = row2; + } + + if ( column1 != column2 ) { + if ( onColumn1 ) column1 = column2; + } + + return getGCell ( getIndex(column1,row1) ); + } + + + template + GCellT* Grid::getGCellLeft ( const GCellT* gcell) const + { + if ( !gcell ) return NULL; + + unsigned int index = gcell->getIndex(); + if ( !getColumn(index) ) return NULL; + + return getGCell ( index - 1 ); + } + + + template + GCellT* Grid::getGCellRight ( const GCellT* gcell) const + { + if ( !gcell ) return NULL; + + unsigned int index = gcell->getIndex(); + if ( getColumn(index) >= getColumns()-1 ) return NULL; + + return getGCell ( index + 1 ); + } + + + template + GCellT* Grid::getGCellUp ( const GCellT* gcell) const + { + if ( !gcell ) return NULL; + + unsigned int index = gcell->getIndex(); + if ( getRow(index) >= getRows()-1 ) return NULL; + + return getGCell ( index + getColumns() ); + } + + + template + GCellT* Grid::getGCellDown ( const GCellT* gcell) const + { + if ( !gcell ) return NULL; + + unsigned int index = gcell->getIndex(); + if ( !getRow(index) ) return NULL; + + return getGCell ( index - getColumns() ); + } + + + template + inline vector* Grid::getGCellVector () + { + return &_gcells; + } + + + template + inline GenericCollection Grid::getGCells () + { + return getCollection(_gcells); + } + + template + inline GenericCollection Grid::getGCellsColumn ( unsigned int column + , unsigned int rowStart + , unsigned int rowStop ) + { + return Grid_Column(this,column,rowStart,rowStop); + } + + template + inline GenericCollection Grid::getGCellsRow ( unsigned int row + , unsigned int columnStart + , unsigned int columnStop ) + { + return Grid_Row(this,row,columnStart,columnStop); + } + + + template + Record* Grid::_getRecord () const + { + Record* record = BaseGrid::_getRecord (); + record->add ( getSlot ( "_gcells", &_gcells ) ); + return record; + } + + +} // End of Katabatic namespace. + + +INSPECTOR_P_SUPPORT(Katabatic::BaseGrid::Axis); + + +#endif // __KATABATIC_GRID__ diff --git a/katabatic/src/katabatic/GridBox.h b/katabatic/src/katabatic/GridBox.h new file mode 100644 index 00000000..370281a1 --- /dev/null +++ b/katabatic/src/katabatic/GridBox.h @@ -0,0 +1,240 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | K a t a b a t i c - Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Header : "./GridBox.h" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#ifndef __KATABATIC_GRID_BOX__ +#define __KATABATIC_GRID_BOX__ + +#ifndef __KATABATIC_GRID__ +#error "GridBox.h must be included only through Grid.h." +#endif + +#include + +#include "hurricane/Error.h" +#include "crlcore/RoutingLayerGauge.h" + + +namespace Katabatic { + + + using Hurricane::Error; + using std::min; + using std::max; + + +// ------------------------------------------------------------------- +// Template Class : "Katabatic::GridBox". + + + template + class GridBox { + + public: + static GridBox* create ( Grid* grid + , unsigned int columnMin + , unsigned int rowMin + , unsigned int columnMax + , unsigned int rowMax + ); + inline Grid* getGrid () const; + inline unsigned int getColumnMin () const; + inline unsigned int getColumnMax () const; + inline unsigned int getRowMin () const; + inline unsigned int getRowMax () const; + inline unsigned int getRows () const; + inline unsigned int getColumns () const; + inline Box getArea () const; + inline Point getCenter () const; + inline DbU::Unit getXMin () const; + inline DbU::Unit getYMin () const; + inline DbU::Unit getXMax () const; + inline DbU::Unit getYMax () const; + inline void getChannelBox ( unsigned int direction + , DbU::Unit& channelMin + , DbU::Unit& channelMax + , DbU::Unit& channelLeft + , DbU::Unit& channelRight + , bool inclusive=false + ) const; + inline GenericCollection getSlice ( unsigned int direction, unsigned int slice ); + inline GenericCollection getGCells (); + inline string _getTypeName () const; + inline string _getString () const; + inline Record* _getRecord () const; + + protected: + // Attributes. + Grid* _grid; + Box _area; + unsigned int _columnMin; + unsigned int _columnMax; + unsigned int _rowMin; + unsigned int _rowMax; + + protected: + // Constructors & Destructors. + GridBox ( Grid* grid + , unsigned int columnMin + , unsigned int rowMin + , unsigned int columnMax + , unsigned int rowMax + ); + private: + GridBox ( const GridBox& ); + GridBox& operator= ( const GridBox& ); + + }; + + + template inline Grid* GridBox::getGrid () const { return _grid; } + template inline unsigned int GridBox::getColumnMin () const { return _columnMin; } + template inline unsigned int GridBox::getColumnMax () const { return _columnMax; } + template inline unsigned int GridBox::getRowMin () const { return _rowMin; } + template inline unsigned int GridBox::getRowMax () const { return _rowMax; } + template inline unsigned int GridBox::getRows () const { return _rowMax - _rowMin; } + template inline unsigned int GridBox::getColumns () const { return _columnMax - _columnMin; } + template inline Box GridBox::getArea () const { return _area; } + template inline Point GridBox::getCenter () const { return _area.getCenter(); } + template inline DbU::Unit GridBox::getXMin () const { return _area.getXMin(); } + template inline DbU::Unit GridBox::getYMin () const { return _area.getYMin(); } + template inline DbU::Unit GridBox::getXMax () const { return _area.getXMax(); } + template inline DbU::Unit GridBox::getYMax () const { return _area.getYMax(); } + template inline GenericCollection + GridBox::getGCells () { return new Grid_Area(_grid,_columnMin,_rowMin,_columnMax,_rowMax); } + template inline string GridBox::_getTypeName () const { return "Katabatic::GridBox"; } + + + + + + template + GridBox::GridBox ( Grid* grid + , unsigned int columnMin + , unsigned int rowMin + , unsigned int columnMax + , unsigned int rowMax + ) + : _grid (grid) + , _columnMin(columnMin) + , _columnMax(columnMax) + , _rowMin (rowMin) + , _rowMax (rowMax) + { + GCellT* fcellBL = _grid->getGCell(_grid->getIndex(_columnMin ,_rowMin )); + GCellT* fcellTR = _grid->getGCell(_grid->getIndex(_columnMax-1,_rowMax-1)); + + _area = Box ( fcellBL->getX(), fcellBL->getY(), fcellTR->getXMax(), fcellTR->getYMax() ); + } + + + template + GridBox* GridBox::create ( Grid* grid + , unsigned int columnMin + , unsigned int rowMin + , unsigned int columnMax + , unsigned int rowMax + ) + { + columnMin = min ( columnMin, grid->getColumns() ); + rowMin = min ( rowMin , grid->getRows () ); + columnMax = min ( columnMax, grid->getColumns() ); + rowMax = min ( rowMax , grid->getRows () ); + + if ( (columnMin >= columnMax) || (rowMin >= rowMax) ) + throw Error("GridBox::create(): Empty GridBox requested <%u:%u %u:%u>." + ,columnMin,rowMin,columnMax,rowMax); + + return new GridBox ( grid, columnMin, rowMin, columnMax, rowMax ); + } + + + template + void GridBox::getChannelBox ( unsigned int direction + , DbU::Unit& channelMin + , DbU::Unit& channelMax + , DbU::Unit& channelLeft + , DbU::Unit& channelRight + , bool inclusive + ) const + { + if ( direction & Constant::Horizontal ) { + channelMin = getYMin() + DbU::lambda( inclusive?0:0.1 ); + channelMax = getYMax(); + channelLeft = getXMin() + DbU::lambda( inclusive?0:0.1 ); + channelRight = getXMax(); + } else { + channelMin = getXMin() + DbU::lambda( inclusive?0:0.1 ); + channelMax = getXMax(); + channelLeft = getYMin() + DbU::lambda( inclusive?0:0.1 ); + channelRight = getYMax(); + } + } + + + template + GenericCollection GridBox::getSlice ( unsigned int direction, unsigned int slice ) + { + if ( direction & Constant::Horizontal ) { + unsigned int columnMin = min ( _columnMin+slice , _columnMax ); + unsigned int columnMax = min ( _columnMin+slice+1, _columnMax ); + + return new Grid_Area ( _grid, columnMin, _rowMin, columnMax, _rowMax ); + } + + unsigned int rowMin = min ( _rowMin+slice , _rowMax ); + unsigned int rowMax = min ( _rowMin+slice+1, _rowMax ); + + return new Grid_Area ( _grid, _columnMin, rowMin, _columnMax, rowMax ); + } + + + template + string GridBox::_getString () const + { + return "<" + _getTypeName() + " " + + getString(getColumnMin()) + ":" + getString(getRowMin()) + " " + + getString(getColumnMax()) + ":" + getString(getRowMax()) + + ">"; + } + + + template + Record* GridBox::_getRecord () const + { + Record* record = new Record ( _getString() ); + record->add ( getSlot ( "_area" , &_area ) ); + record->add ( getSlot ( "_columnMin", &_columnMin ) ); + record->add ( getSlot ( "_columnMax", &_columnMax ) ); + record->add ( getSlot ( "_rowMin" , &_rowMin ) ); + record->add ( getSlot ( "_rowMax" , &_rowMax ) ); + + return record; + } + + +} // End of Katabatic namespace. + + +#endif // __KATABATIC_GRID_BOX__ diff --git a/katabatic/src/katabatic/GridCollections.h b/katabatic/src/katabatic/GridCollections.h new file mode 100644 index 00000000..2be7daa7 --- /dev/null +++ b/katabatic/src/katabatic/GridCollections.h @@ -0,0 +1,602 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2008, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | K a t a b a t i c - Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Header : "./GridCollections.h" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + + + +#ifndef __KATABATIC_GRID_COLLECTIONS__ +#define __KATABATIC_GRID_COLLECTIONS__ + +#ifndef __KATABATIC_GRID__ +#error "GridCollections.h must be included only through Grid.h." +#endif + +#include "hurricane/Collection.h" + + +namespace Katabatic { + + + using Hurricane::_TName; + using Hurricane::Locator; + using Hurricane::Collection; + using Hurricane::GenericLocator; + using Hurricane::GenericCollection; + using Hurricane::GenericFilter; + + +// ------------------------------------------------------------------- +// Template Class : "Katabatic::Grid_Column". + + + template + class Grid_Column : public Collection { + + public: + // Sub-Class: Locator. + class Locator : public Hurricane::Locator { + public: + Locator ( const Grid* grid + , unsigned int start + , unsigned int stop ); + Locator ( const Locator& ); + virtual Hurricane::Locator* getClone () const; + virtual GCellT* getElement () const; + Grid* getGrid () const; + virtual bool isValid () const; + virtual void progress (); + virtual string _getString () const; + + protected: + const Grid* _grid; + unsigned int _index; + unsigned int _stop; + }; + + public: + // Grid_Column Methods. + Grid_Column ( const Grid* grid + , unsigned int column + , unsigned int rowStart + , unsigned int rowStop + ); + Grid_Column ( const Grid_Column& ); + virtual Collection* getClone () const; + virtual Hurricane::Locator* getLocator () const; + virtual string _getString () const; + + protected: + // Grid_Column Attributes. + const Grid* _grid; + unsigned int _start; + unsigned int _stop; + + }; + + +// Grid_Column Locator Part. + template + Grid_Column::Locator::Locator ( const Grid* grid + , unsigned int start + , unsigned int stop ) + : Hurricane::Locator() + , _grid(grid) + , _index(start) + , _stop(stop) + { } + + + template + Grid_Column::Locator::Locator ( const Locator& locator ) + : Hurricane::Locator() + , _grid(locator._grid) + , _index(locator._index) + , _stop(locator._stop) + { }; + + + template + GCellT* Grid_Column::Locator::getElement () const + { + return _grid->getGCell ( _index ); + } + + + template + void Grid_Column::Locator::progress () + { + _index += _grid->getColumns (); + } + + + template + Hurricane::Locator* Grid_Column::Locator::getClone () const + { + return new Locator(*this); + } + + + template + bool Grid_Column::Locator::isValid () const + { + return _index < _stop; + } + + + template + Grid* Grid_Column::Locator::getGrid () const + { + return _grid; + } + + + template + string Grid_Column::Locator::_getString () const + { + string s = "<" + _TName("Grid_Column::Locator") + + getString(_grid) + + ">"; + return s; + } + + +// Grid_Column Collection Part. + template + Grid_Column::Grid_Column ( const Grid* grid + , unsigned int column + , unsigned int rowStart + , unsigned int rowStop + ) + : Collection() + , _grid(grid) + , _start(grid->getIndex(column,rowStart)) + , _stop (grid->getIndex(column,rowStop)) + { + if ( ( column >= _grid->getColumns() ) + || ( rowStart >= _grid->getRows() ) + || ( rowStart >= rowStop ) ) { + _start = 1; + _stop = 0; + } else { + _start = grid->getIndex ( column, rowStart ); + _stop = grid->getIndex ( column, min(rowStop,grid->getRows()) ); + } + } + + + template + Grid_Column::Grid_Column ( const Grid_Column& gridColumn ) + : Collection() + , _grid(gridColumn._grid) + , _start(gridColumn._start) + , _stop(gridColumn._stop) + { } + + + template + Collection* Grid_Column::getClone () const + { + return new Grid_Column(*this); + } + + + template + Hurricane::Locator* Grid_Column::getLocator () const + { + return new Locator(_grid,_start,_stop); + } + + + template + string Grid_Column::_getString () const + { + string s = "<" + _TName("Grid_Column") + " " + + getString(_grid) + " " + + getString(_grid->getColumn(_start)) + " [" + + getString(_grid->getRow(_start)) + ":" + + getString(_grid->getRow(_stop)) + "]" + + ">"; + return s; + } + + +// ------------------------------------------------------------------- +// Remplate Class : "Grid_Row". + + + template + class Grid_Row : public Collection { + + public: + // Sub-Class : Locator. + class Locator : public Hurricane::Locator { + public: + Locator ( const Grid* grid + , unsigned int start + , unsigned int stop ); + Locator ( const Locator& ); + virtual GCellT* getElement () const; + virtual Hurricane::Locator* getClone () const; + virtual bool isValid () const; + virtual void progress (); + Grid* getGrid () const; + virtual string _getString () const; + protected: + const Grid* _grid; + unsigned int _index; + unsigned int _stop; + }; + + public: + // Grid_Row Methods. + Grid_Row ( const Grid* grid + , unsigned int row + , unsigned int columnStart + , unsigned int columnStop + ); + Grid_Row ( const Grid_Row& ); + virtual Collection* getClone () const; + virtual Hurricane::Locator* getLocator () const; + virtual string _getString () const; + + protected: + // Grid_Row Attributes. + const Grid* _grid; + unsigned int _start; + unsigned int _stop; + }; + + +// Grid_Column Locator Part. + template + Grid_Row::Locator::Locator ( const Grid* grid + , unsigned int start + , unsigned int stop ) + : Hurricane::Locator() + , _grid(grid) + , _index(start) + , _stop(stop) + { } + + + template + Grid_Row::Locator::Locator ( const Locator& locator ) + : Hurricane::Locator() + , _grid(locator._grid) + , _index(locator._index) + , _stop(locator._stop) + { } + + + template + GCellT* Grid_Row::Locator::getElement () const + { + return _grid->getGCell ( _index ); + } + + + template + Hurricane::Locator* Grid_Row::Locator::getClone () const + { + return new Locator(*this); + } + + + template + bool Grid_Row::Locator::isValid () const + { + return _index < _stop; + } + + + template + void Grid_Row::Locator::progress () + { + _index++; + } + + + template + Grid* Grid_Row::Locator::getGrid () const + { + return _grid; + } + + + template + string Grid_Row::Locator::_getString () const + { + string s = "<" + _TName("Grid_Row::Locator") + + getString(_grid) + + ">"; + + return s; + } + + +// Grid_Column Collection Part. + template + Grid_Row::Grid_Row ( const Grid* grid + , unsigned int row + , unsigned int columnStart + , unsigned int columnStop + ) + : Collection() + , _grid(grid) + { + if ( ( row >= _grid->getRows() ) + || ( columnStart >= _grid->getColumns() ) + || ( columnStart >= columnStop ) ) { + _start = 1; + _stop = 0; + } else { + _start = grid->getIndex ( columnStart, row ); + _stop = grid->getIndex ( min(columnStop,grid->getColumns()), row ); + } + } + + + template + Grid_Row::Grid_Row ( const Grid_Row& gridRow ) + : Collection() + , _grid(gridRow._grid) + , _start(gridRow._start) + , _stop(gridRow._stop) + { } + + + template + Collection* Grid_Row::getClone () const + { + return new Grid_Row(*this); + } + + + template + Hurricane::Locator* Grid_Row::getLocator () const + { + return new Locator(_grid,_start,_stop); + } + + + template + string Grid_Row::_getString () const + { + string s = "<" + _TName("Grid_Row") + " " + + getString(_grid) + " " + + getString(_grid->getRow(_start)) + " [" + + getString(_grid->getColumn(_start)) + ":" + + getString(_grid->getColumn(_stop)) + "]" + + ">"; + return s; + } + + +// ------------------------------------------------------------------- +// Template Class : "Grid_Area". + + + template + class Grid_Area : public Collection { + + public: + // Sub-Class : Locator. + class Locator : public Hurricane::Locator { + public: + Locator ( const Grid* grid + , unsigned int columnStart + , unsigned int rowStart + , unsigned int colummStop + , unsigned int rowStop ); + Locator ( const Locator& ); + ~Locator (); + virtual GCellT* getElement () const; + virtual Hurricane::Locator* getClone () const; + virtual bool isValid () const; + virtual void progress (); + virtual string _getString () const; + protected: + const Grid* _grid; + unsigned int _rowStart; + unsigned int _rowStop; + unsigned int _column; + unsigned int _columnStop; + Hurricane::Locator* _columnLocator; + }; + + public: + // Grid_Area Methods. + Grid_Area ( const Grid* grid + , unsigned int columnStart + , unsigned int rowStart + , unsigned int columnStop + , unsigned int rowStop + ); + Grid_Area ( const Grid_Area& ); + virtual Collection* getClone () const; + virtual Hurricane::Locator* getLocator () const; + virtual string _getString () const; + + public: + // Grid_Area Attributes. + const Grid* _grid; + unsigned int _columnStart; + unsigned int _columnStop; + unsigned int _rowStart; + unsigned int _rowStop; + }; + + +// Grid_Area Locator Part. + template + Grid_Area::Locator::Locator ( const Grid* grid + , unsigned int columnStart + , unsigned int rowStart + , unsigned int columnStop + , unsigned int rowStop + ) + : _grid(grid) + , _rowStart(rowStart) + , _rowStop(rowStop) + , _column(columnStart) + , _columnStop(columnStop) + { + _columnLocator = new typename Grid_Column::Locator ( _grid + , _grid->getIndex(_column,rowStart) + , _grid->getIndex(_column,rowStop ) ); + if ( !_columnLocator->isValid() ) _column = _columnStop; + } + + + template + Grid_Area::Locator::Locator ( const Locator& locator ) + : Hurricane::Locator() + , _grid(locator._grid) + , _rowStart(locator._rowStart) + , _rowStop(locator._rowStop) + , _column(locator._column) + , _columnStop(locator._columnStop) + , _columnLocator(_columnLocator->getClone()) + { } + + + template + Grid_Area::Locator::~Locator () + { + if (_columnLocator) delete _columnLocator; + } + + + template + Hurricane::Locator* Grid_Area::Locator::getClone () const + { + return new Locator(*this); + } + + + template + GCellT* Grid_Area::Locator::getElement () const + { + return _columnLocator->getElement(); + } + + + template + void Grid_Area::Locator::progress () + { + if ( !isValid() ) return; + + _columnLocator->progress(); + if ( !_columnLocator->isValid() ) { + delete _columnLocator; + _columnLocator = NULL; + + + _column += 1; + if ( !isValid() ) return; + + _columnLocator = new typename Grid_Column::Locator ( _grid + , _grid->getIndex(_column,_rowStart) + , _grid->getIndex(_column,_rowStop ) ); + } + } + + + template + bool Grid_Area::Locator::isValid () const + { + return _column < _columnStop; + } + + + template + string Grid_Area::Locator::_getString () const + { + string s = "<" + _TName("Grid_Area::Locator") + + getString(_grid) + + ">"; + return s; + } + + +// Grid_Area Collection Part. + template + Grid_Area::Grid_Area ( const Grid* grid + , unsigned int columnStart + , unsigned int rowStart + , unsigned int columnStop + , unsigned int rowStop + ) + : Collection() + , _grid(grid) + , _columnStart(columnStart) + , _columnStop(columnStop) + , _rowStart(rowStart) + , _rowStop(rowStop) + { } + + + template + Grid_Area::Grid_Area ( const Grid_Area& fcells ) + : Collection() + , _grid(fcells._grid) + , _columnStart(fcells._columnStart) + , _columnStop(fcells._columnStop) + , _rowStart(fcells._rowStart) + , _rowStop(fcells._rowStop) + { } + + + template + Collection* Grid_Area::getClone () const + { + return new Grid_Area(*this); + } + + + template + Hurricane::Locator* Grid_Area::getLocator () const + { + return new Locator(_grid,_columnStart,_rowStart,_columnStop,_rowStop); + } + + + template + string Grid_Area::_getString () const + { + string s = "<" + _TName("Grid_Area") + " " + + getString(_grid) + " " + + ">"; + return s; + } + + +} // End of Katabatic namespace. + + +#endif // __KATABATIC_GRID_COLLECTIONS__ diff --git a/katabatic/src/katabatic/KatabaticEngine.h b/katabatic/src/katabatic/KatabaticEngine.h new file mode 100644 index 00000000..055debef --- /dev/null +++ b/katabatic/src/katabatic/KatabaticEngine.h @@ -0,0 +1,258 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | K a t a b a t i c - Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Header : "./KatabaticEngine.h" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#ifndef __KATABATIC_KATABATIC_ENGINE__ +#define __KATABATIC_KATABATIC_ENGINE__ + +#include +#include +#include +#include + +#include "hurricane/Timer.h" +#include "hurricane/DbU.h" +#include "hurricane/Nets.h" + +namespace Hurricane { + class Name; + class Layer; + class Cell; +} + +#include "crlcore/ToolEngine.h" + +namespace CRL { + class RoutingGauge; + class RoutingLayerGauge; +} + +#include "katabatic/Configuration.h" +#include "katabatic/AutoContacts.h" +#include "katabatic/AutoSegments.h" + + +namespace Katabatic { + + + using std::ostream; + using std::string; + using std::vector; + using std::set; + using Hurricane::Timer; + using Hurricane::Name; + using Hurricane::Layer; + using Hurricane::Net; + using Hurricane::Nets; + using Hurricane::Cell; + using CRL::RoutingGauge; + using CRL::RoutingLayerGauge; + using CRL::ToolEngine; + + class GCellGrid; + + +// ------------------------------------------------------------------- +// Enumerations + + + enum LoadGRMethod { LoadGrByNet = 1 + , LoadGrByGCell = 2 + }; + + enum LayerAssignMethod { LayerAssignByLength = 1 + , LayerAssignByTrunk = 2 + , NoNetLayerAssign = 3 + }; + + enum EngineState { StateCreation = 1 + , StateGlobalLoaded + , StateActive + , StateDriving + , StatePreDestroying + , StateGutted + }; + + +// ------------------------------------------------------------------- +// Class : "KatabaticEngine". + + + class KatabaticEngine : public ToolEngine { + + public: + // Constructor. + static KatabaticEngine* create ( const RoutingGauge*, Cell* ); + // Accessors. + static KatabaticEngine* get ( const Cell* ); + static const Name& staticGetName (); + inline bool doDestroyBaseContact () const; + inline bool doDestroyBaseSegment () const; + inline bool doDestroyTool () const; + virtual const Name& getName () const; + inline EngineState getState () const; + inline bool getDemoMode (); + inline bool getWarnGCellOverload (); + inline Configuration* getKatabaticConfiguration (); + virtual Configuration* getConfiguration (); + inline RoutingGauge* getRoutingGauge () const; + inline RoutingLayerGauge* getLayerGauge ( size_t depth ) const; + inline const Layer* getRoutingLayer ( size_t depth ) const ; + inline Layer* getContactLayer ( size_t depth ) const ; + inline GCellGrid* getGCellGrid () const; + inline const vector& getRoutingNets () const; + inline DbU::Unit getGlobalThreshold () const; + inline float getSaturateRatio () const; + inline DbU::Unit getExtensionCap () const; + void xmlWriteGCellGrid ( ostream& ); + void xmlWriteGCellGrid ( const string& ); + inline bool isGMetal ( const Layer* ) const; + // Modifiers. + inline void setState ( EngineState state ); + inline void setDemoMode ( bool ); + inline bool setDestroyBaseContact ( bool ); + inline bool setDestroyBaseSegment ( bool ); + inline void setWarnGCellOverload ( bool ); + inline void setGlobalThreshold ( DbU::Unit ); + inline void setSaturateRatio ( float ); + void startMeasures (); + void stopMeasures (); + void printMeasures () const; + void refresh ( bool openSession=true ); + void makePowerRails (); + virtual void createDetailedGrid (); + virtual void loadGlobalRouting ( unsigned int method, vector& ); + void layerAssign ( unsigned int method ); + // void computeNetConstraints (); + // void computeNetOptimals (); + virtual void finalizeLayout (); + // Internal Modifiers. + bool _check ( const char* message=NULL ) const; + void _check ( Net* ) const; + void _gutKatabatic (); + void _link ( AutoContact* ); + void _link ( AutoSegment* ); + void _unlink ( AutoContact* ); + void _unlink ( AutoSegment* ); + AutoContact* _lookup ( Contact* ) const; + AutoSegment* _lookup ( Segment* ) const; + void _destroyAutoSegments (); + void _destroyAutoContacts (); + void _loadGrByNet (); + void _loadNetGlobalRouting ( Net* ); + void _alignate ( Net* ); + void _canonize ( Net* ); + void _desaturate ( unsigned int depth, set& ); + void _layerAssignByLength ( unsigned long& total, unsigned long& global, set& ); + void _layerAssignByLength ( Net* , unsigned long& total, unsigned long& global, set& ); + void _layerAssignByTrunk ( unsigned long& total, unsigned long& global, set& ); + void _layerAssignByTrunk ( Net* , unsigned long& total, unsigned long& global, set& ); + void _splitContactsOfNet ( Net* ); + void _computeNetConstraints ( Net* ); + void _collapseNet ( const Name& , unsigned int depth=1 ); + void _collapseNet ( Net* , unsigned int depth=1 ); + void _collapseNets ( Nets , unsigned int depth=1 ); + void _computeNetOptimals ( Net* ); + void _computeNetTerminals ( Net* ); + void _toOptimals ( Net*, bool onlyNew=false ); + void _saveNet ( Net* ); + void _print () const; + void _print ( Net* ) const; + inline AutoContactLut& _getAutoContactLut (); + inline AutoSegmentLut& _getAutoSegmentLut (); + // Inspector Management. + virtual Record* _getRecord () const; + virtual string _getString () const; + virtual string _getTypeName () const; + + protected: + // Attributes. + static Name _toolName; + Timer _timer; + EngineState _state; + bool _destroyBaseContact; + bool _destroyBaseSegment; + bool _demoMode; + bool _warnGCellOverload; + ConfigurationConcrete _configuration; + GCellGrid* _gcellGrid; + vector _routingNets; + AutoSegmentLut _autoSegmentLut; + AutoContactLut _autoContactLut; + + protected: + // Constructors & Destructors. + KatabaticEngine ( const RoutingGauge*, Cell* ); + virtual ~KatabaticEngine (); + virtual void _postCreate (); + virtual void _preDestroy (); + private: + KatabaticEngine ( const KatabaticEngine& ); + KatabaticEngine& operator= ( const KatabaticEngine& ); + }; + + +// Inline Functions. + inline bool KatabaticEngine::doDestroyBaseContact () const { return _destroyBaseContact; } + inline bool KatabaticEngine::doDestroyBaseSegment () const { return _destroyBaseSegment; } + inline bool KatabaticEngine::doDestroyTool () const { return _state >= StateGutted; } + inline bool KatabaticEngine::setDestroyBaseContact ( bool state ) { bool p=_destroyBaseContact; _destroyBaseContact = state; return p; } + inline bool KatabaticEngine::setDestroyBaseSegment ( bool state ) { bool p=_destroyBaseSegment; _destroyBaseSegment = state; return p; } + inline Configuration* KatabaticEngine::getKatabaticConfiguration () { return &_configuration; } + inline bool KatabaticEngine::isGMetal ( const Layer* layer ) const { return _configuration.isGMetal(layer); } + inline void KatabaticEngine::setDemoMode ( bool mode ) { _demoMode = mode; } + inline void KatabaticEngine::setWarnGCellOverload ( bool mode ) { _warnGCellOverload = mode; } + inline void KatabaticEngine::setSaturateRatio ( float ratio ) { _configuration.setSaturateRatio(ratio); } + inline void KatabaticEngine::setGlobalThreshold ( DbU::Unit threshold ) { _configuration.setGlobalThreshold(threshold); } + inline bool KatabaticEngine::getDemoMode () { return _demoMode; } + inline bool KatabaticEngine::getWarnGCellOverload () { return _warnGCellOverload; } + inline EngineState KatabaticEngine::getState () const { return _state; } + inline RoutingGauge* KatabaticEngine::getRoutingGauge () const { return _configuration.getRoutingGauge(); } + inline RoutingLayerGauge* KatabaticEngine::getLayerGauge ( size_t depth ) const { return _configuration.getLayerGauge(depth); } + inline const Layer* KatabaticEngine::getRoutingLayer ( size_t depth ) const { return _configuration.getRoutingLayer(depth); } + inline Layer* KatabaticEngine::getContactLayer ( size_t depth ) const { return _configuration.getContactLayer(depth); } + inline GCellGrid* KatabaticEngine::getGCellGrid () const { return _gcellGrid; } + inline const vector& KatabaticEngine::getRoutingNets () const { return _routingNets; } + inline DbU::Unit KatabaticEngine::getGlobalThreshold () const { return _configuration.getGlobalThreshold(); } + inline float KatabaticEngine::getSaturateRatio () const { return _configuration.getSaturateRatio(); } + inline DbU::Unit KatabaticEngine::getExtensionCap () const { return _configuration.getExtensionCap(); } + inline AutoContactLut& KatabaticEngine::_getAutoContactLut () { return _autoContactLut; } + inline AutoSegmentLut& KatabaticEngine::_getAutoSegmentLut () { return _autoSegmentLut; } + inline void KatabaticEngine::setState ( EngineState state ) { _state = state; } + + + + +// ------------------------------------------------------------------- +// Global Variables. + + + extern const char* missingKTBT; + extern const char* badMethod; + + +} // End of Katabatic namespace. + + +#endif // __KATABATIC_KATABATIC_ENGINE__ diff --git a/katabatic/src/katabatic/SegmentWrapper.h b/katabatic/src/katabatic/SegmentWrapper.h new file mode 100644 index 00000000..767e492f --- /dev/null +++ b/katabatic/src/katabatic/SegmentWrapper.h @@ -0,0 +1,110 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2008, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | K a t a b a t i c - Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Header : "./SegmentWrapper.h" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#ifndef __KATABATIC_SEGMENT_WRAPPER__ +#define __KATABATIC_SEGMENT_WRAPPER__ + + +#include "hurricane/Segment.h" + + +namespace Katabatic { + + using Hurricane::Hook; + using Hurricane::Component; + using Hurricane::DbU; + using Hurricane::Point; + using Hurricane::Layer; + using Hurricane::Segment; + + +// ------------------------------------------------------------------- +// Class : "Katabatic::SegmentWrapper". + + class SegmentWrapper { + public: + // Accessors. + virtual Segment* getBase () = 0; + inline Hook* getSourceHook (); + inline Hook* getTargetHook (); + inline Hook* getOppositeHook ( const Hook* ); + inline Component* getSource () const; + inline Component* getTarget () const; + inline Component* getOppositeAnchor ( const Component* ); + inline Components getAnchors () const; + virtual DbU::Unit getX () const = 0; + virtual DbU::Unit getY () const = 0; + inline DbU::Unit getWidth () const; + inline DbU::Unit getHalfWidth () const; + inline DbU::Unit getLength () const; + virtual DbU::Unit getSourceX () const = 0; + virtual DbU::Unit getSourceY () const = 0; + virtual Point getSourcePosition () const = 0; + virtual DbU::Unit getTargetX () const = 0; + virtual DbU::Unit getTargetY () const = 0; + virtual Point getTargetPosition () const = 0; + public: + // Modifiers. + inline void setLayer ( const Layer* ); + inline void setWidth ( DbU::Unit ); + inline void invert (); + + protected: + // Constructor & Destructors. + inline SegmentWrapper ( Segment* ); + private: + SegmentWrapper& SegmentWrapper ( const SegmentWrapper& ); + SegmentWrapper& operator= ( const SegmentWrapper& ); + }; + + +// Inline Functions. + inline Hook* SegmentWrapper::getBodyHook () { return getBase()->getBodyHook(); } + inline Hook* SegmentWrapper::getAnchorHook () { return getBase()->getAnchorHook(); } + inline Component* SegmentWrapper::getAnchor () const { return getBase()->getAnchor(); } + inline DbU::Unit SegmentWrapper::getDx () const { return getBase()->getDx(); } + inline DbU::Unit SegmentWrapper::getDy () const { return getBase()->getDy(); } + inline DbU::Unit SegmentWrapper::getWidth () const { return getBase()->getWidth(); } + inline DbU::Unit SegmentWrapper::getHalfWidth () const { return getBase()->getHalfWidth(); } + inline DbU::Unit SegmentWrapper::getHeight () const { return getBase()->getHeight(); } + inline DbU::Unit SegmentWrapper::getHalfHeight () const { return getBase()->getHalfHeight(); } + inline void SegmentWrapper::setLayer ( const Layer* layer ) { return getBase()->setLayer(layer); } + inline void SegmentWrapper::setWidth ( DbU::Unit w ) { return getBase()->setWidth(w); } + inline void SegmentWrapper::setHeight ( DbU::Unit h ) { return getBase()->setHeight(h); } + inline void SegmentWrapper::setSizes ( DbU::Unit w, Dbu::Unit h ) { return getBase()->setSizes(w,h); } + inline void SegmentWrapper::setX ( DbU::Unit x ) { return getBase()->setX(x); } + inline void SegmentWrapper::setY ( DbU::Unit y ) { return getBase()->setY(y); } + inline void SegmentWrapper::setPosition ( DbU::Unit x, Dbu::Unit y ) { return getBase()->setPosition(x,y); } + inline void SegmentWrapper::setPosition ( const Point& p ) { return getBase()->setPosition(p); } + inline void SegmentWrapper::setDx ( DbU::Unit dx ) { return getBase()->setDx(dx); } + inline void SegmentWrapper::setDy ( DbU::Unit dy ) { return getBase()->setDy(dy); } + inline void SegmentWrapper::setOffset ( DbU::Unit dx, Dbu::Unit dy ) { return getBase()->setOffset(dx,dy); } + inline SegmentWrapper::SegmentWrapper ( BaseSegment* contact ) : getBase()(contact) { } + + +} // End of Katabatic namespace. + + +#endif // __KATABATIC_SEGMENT_WRAPPER__ diff --git a/katabatic/src/katabatic/Session.h b/katabatic/src/katabatic/Session.h new file mode 100644 index 00000000..3a6dd0f2 --- /dev/null +++ b/katabatic/src/katabatic/Session.h @@ -0,0 +1,227 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | K a t a b a t i c - Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Header : "./Session.h" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + + + +#ifndef __KATABATIC_SESSION__ +#define __KATABATIC_SESSION__ + +#include +#include +#include +#include +#include "hurricane/Commons.h" +#include "hurricane/DbU.h" + +namespace Hurricane { + class Layer; + class Technology; + class Net; + class Contact; + class Segment; +} + +namespace CRL { + class RoutingGauge; +} + + +namespace Katabatic { + + + using std::cerr; + using std::endl; + using std::string; + using std::vector; + using std::set; + using std::map; + using std::make_pair; + using Hurricane::tab; + using Hurricane::inltrace; + using Hurricane::_TName; + using Hurricane::Record; + using Hurricane::Layer; + using Hurricane::Technology; + using Hurricane::DbU; + using Hurricane::Net; + using Hurricane::Contact; + using Hurricane::Segment; + using CRL::RoutingGauge; + + class Configuration; + class AutoContact; + class AutoSegment; + class KatabaticEngine; + + +// ------------------------------------------------------------------- +// Class : "Katabatic::Session". + + + class Session { + + public: + enum InvalidateType { NetSplitContacts = (1<<0) + , NetCanonize = (1<<1) + , RestoreHCon = (1<<2) + , RestoreVCon = (1<<3) + }; + + public: + // Static Methods. + static inline bool doDestroyBaseContact (); + static inline bool doDestroyBaseSegment (); + static inline bool doDestroyTool (); + static Session* get ( const char* message=NULL ); + static inline Technology* getTechnology (); + static inline const Configuration* getConfiguration (); + static inline RoutingGauge* getRoutingGauge (); + static inline KatabaticEngine* getKatabatic (); + static bool getDemoMode (); + static float getSaturateRatio (); + static bool getWarnGCellOverload (); + static DbU::Unit getExtensionCap (); + static const Layer* getRoutingLayer ( size_t ); + static const Layer* getContactLayer ( size_t ); + static inline size_t getSegmentStackSize (); + static inline size_t getContactStackSize (); + static inline const vector& getInvalidateds (); + static inline const vector& getRevalidateds (); + static inline const set& getDestroyeds (); + static inline const vector& getDogLegs (); + static inline const set& getNetsModificateds (); + static Session* open ( KatabaticEngine* ); + static size_t close (); + static void setWarnGCellOverload ( bool ); + static inline void dogLeg ( AutoSegment* ); + static inline void dogLegReset (); + static inline void revalidateTopology (); + static inline void setInvalidateMask ( unsigned int ); + static inline void invalidate ( Net* ); + static inline void invalidate ( AutoContact* ); + static inline void invalidate ( AutoSegment* ); + static inline size_t revalidate (); + static void link ( AutoContact* ); + static void link ( AutoSegment* ); + static void unlink ( AutoContact* ); + static void unlink ( AutoSegment* ); + static AutoContact* lookup ( Contact* ); + static AutoSegment* lookup ( Segment* ); + static inline void destroyRequest ( AutoSegment* ); + // Methods. + bool _doDestroyBaseContact (); + bool _doDestroyBaseSegment (); + bool _doDestroyTool (); + virtual Configuration* _getConfiguration (); + inline void _dogLeg ( AutoSegment* ); + inline void _dogLegReset (); + inline void _setInvalidateMask ( unsigned int ); + inline void _invalidate ( Net* ); + inline void _invalidate ( AutoContact* ); + inline void _invalidate ( AutoSegment* ); + inline void _destroyRequest ( AutoSegment* ); + void _splitContacts (); + void _restoreHCon (); + void _restoreVCon (); + void _canonize (); + void _revalidateTopology (); + size_t _revalidate (); + Record* _getRecord () const; + string _getString () const; + inline string _getTypeName () const; + + protected: + static Session* _session; + KatabaticEngine* _katabatic; + Technology* _technology; + RoutingGauge* _routingGauge; + vector _autoContacts; + vector _autoSegments; + vector _revalidateds; + vector _dogLegs; + set _netInvalidateds; + set _netRevalidateds; + set _destroyedSegments; + unsigned int _invalidateMask; + + // Constructors. + protected: + Session ( KatabaticEngine* ); + virtual ~Session (); + virtual void _postCreate (); + virtual size_t _preDestroy (); + private: + Session ( const Session& ); + Session& operator= ( const Session& ); + }; + + +// Inline Functions. + inline Technology* Session::getTechnology () { return get("getTechnology()")->_technology; } + inline RoutingGauge* Session::getRoutingGauge () { return get("getRoutingGauge()")->_routingGauge; } + inline bool Session::doDestroyBaseContact () { return get("doDestroyBaseContact()")->_doDestroyBaseContact(); } + inline bool Session::doDestroyBaseSegment () { return get("doDestroyBaseSegment()")->_doDestroyBaseSegment(); } + inline bool Session::doDestroyTool () { return get("doDestroyTool()")->_doDestroyTool(); } + inline const Configuration* Session::getConfiguration () { return get("getConfiguration()")->_getConfiguration(); } + inline KatabaticEngine* Session::getKatabatic () { return get("getKatabatic()")->_katabatic; } + inline void Session::revalidateTopology () { return get("revalidateTopology()")->_revalidateTopology(); } + inline size_t Session::revalidate () { return get("revalidate()")->_revalidate(); } + inline size_t Session::getSegmentStackSize () { return get("getSegmentStackSize()")->_autoSegments.size(); } + inline size_t Session::getContactStackSize () { return get("getContactStackSize()")->_autoContacts.size(); } + inline const vector& Session::getInvalidateds () { return get("getInvalidateds()")->_autoSegments; } + inline const vector& Session::getRevalidateds () { return get("getRevalidateds()")->_revalidateds; } + inline const set& Session::getDestroyeds () { return get("getDestroyeds()")->_destroyedSegments; } + inline const vector& Session::getDogLegs () { return get("getDogLegs()")->_dogLegs; } + inline const set& Session::getNetsModificateds () { return get("getNetsModificateds()")->_netRevalidateds; } + inline void Session::dogLegReset () { return get("dogLegReset()")->_dogLegReset (); } + inline void Session::setInvalidateMask ( unsigned int mask ) { return get("setInvalidateMask()")->_setInvalidateMask ( mask ); } + inline void Session::invalidate ( Net* net ) { return get("invalidate(Net*)")->_invalidate ( net ); } + inline void Session::invalidate ( AutoContact* autoContact ) { return get("invalidate(AutoContact*)")->_invalidate ( autoContact ); } + inline void Session::invalidate ( AutoSegment* autoSegment ) { return get("invalidate(AutoSegment*)")->_invalidate ( autoSegment ); } + inline void Session::dogLeg ( AutoSegment* autoSegment ) { return get("dogLeg(AutoSegment*)")->_dogLeg ( autoSegment ); } + inline void Session::destroyRequest ( AutoSegment* autoSegment ) { return get("destroyRequest(AutoSegment*)")->_destroyRequest ( autoSegment ); } + + inline void Session::_dogLeg ( AutoSegment* segment ) { _dogLegs.push_back(segment); } + inline void Session::_dogLegReset () { _dogLegs.clear(); } + inline void Session::_setInvalidateMask ( unsigned int mask ) { _invalidateMask |= mask; } + inline void Session::_invalidate ( AutoContact* contact ) { _autoContacts.push_back(contact); } + inline void Session::_invalidate ( AutoSegment* segment ) { _autoSegments.push_back(segment); } + inline void Session::_destroyRequest ( AutoSegment* segment ) { _destroyedSegments.insert(segment); } + inline string Session::_getTypeName () const { return _TName("Session"); } + + inline void Session::_invalidate ( Net* net ) { + ltrace(200) << "Session::invalidate(Net*) - " << net << endl; + _netInvalidateds.insert(net); + _invalidateMask |= NetCanonize; + } + + +} // End of Katabatic namespace. + + +INSPECTOR_P_SUPPORT(Katabatic::Session); + + +#endif // __KATABATIC_SESSION__

    w@7ZfF59YvRu?FX=A%DsHy)k7FHg) zUKPFIQ-Cj%T#Vz$DeGiH~ z4->vg_q$nW_2Vr4Cwq6!W>;R|DffB4`8`o_(s)V3!msZ{C67IrSY$MLdWu0RowKQ# zHw&%W3Xr-_k>~7A6j9Jpk?s%frR*HSmRbDNPK20f zbC463mX^n@k~|ut9xf)#pYCsIo+ubS$|`u- zHtC$i88R;JR(;ytr!QIk7oWdqHeyGql{nz4{67}Arn`x{tSG2Nf zw^>P%A-Kum+Qq4tL8;R(Jl!5fN8T{I*Y6?SSPiy?DfwB1VvdeD@l+-6IM~bp5jjel(yC<1-=`#B6PmKW51pW{5ODk;X>p-$qQ9P?(HAx= z@a9B(&ynEo~w5vG;a~|M5Uwlj9a0ielG@(cfmb#PC)mPtV-)W|Oh`Wv+_X>KGUSyzlRLL0E1*1x1;yZO8w6I``JO{2}p3#?g8FN!|#vWkt|I~$lO9q%3&r#8by`B zu3oDyAf-fi?NpOiSqbWFM!8j&=p;VkK-&RrVX1VNFUL#=$nih%qS?yy5s8*RO_$bJ zi|)-qc^JD|Uf(iKuxxLKgr4!I4bAwE2UN4~-_d_No1=NrKTiWC>!b@9(Rjn1uEsM* zg_+oSHvwVb_N0%{MSWM0BY^=Ke&)-ot?`l-GHosRFBMLGW?ELRVX(%RYnj*W>A{cj4JclbGENhv`9CX?t)J|Jno;2BrG8!4+xOXamp0 z*~;r6vD&BZ0MjMsYwtHI;{uNj$&kTs;nU+8-l~~;KnSj8!-)9@lLte)Q+8anFp-Vy zlX+MXk3FkO-JZ~pDkUH0!SoIdK(|n+wb)U3T>;*cPRt;fu50E+0bER%l+{g%sIs>? zta;m-S`rnnqhQE_Pmi(^G4ac@n_8ULJbi9>@viD`#1rK;(Rvu>y3BHGoA@%|`H6ZX zllc11MR3cbW^h;6X%F#L2ei-L$*#=SGdA&me_4_!Ub!rFHOW2EQhY*rEh1P}gA$p_ yLnLD(%_n0E{b10RU)0k)!>wa`!7v}l#(xI??7{zE2Q+Ex4yojsEI9RBLjD65vuGgz literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/AutoContactG4-2.fig b/katabatic/doc/images/AutoContactG4-2.fig new file mode 100644 index 00000000..6f9fbaba --- /dev/null +++ b/katabatic/doc/images/AutoContactG4-2.fig @@ -0,0 +1,109 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +6 5535 -225 5715 3375 +2 1 3 1 0 7 45 -1 20 10.000 0 0 -1 0 0 2 + 5625 2700 5625 -225 +2 1 0 1 0 7 40 -1 15 0.000 0 0 -1 0 0 4 + 5535 3375 5535 2700 5715 2700 5715 3375 +-6 +6 7335 -225 7515 3375 +2 1 0 1 0 7 40 -1 15 0.000 0 0 -1 0 0 4 + 7515 -225 7515 450 7335 450 7335 -225 +2 1 3 1 0 7 45 -1 20 10.000 0 0 -1 0 0 2 + 7425 450 7425 3375 +-6 +6 4725 810 8325 990 +6 4725 810 5400 990 +2 1 0 1 0 7 40 -1 15 0.000 0 0 -1 0 0 4 + 4725 810 5400 810 5400 990 4725 990 +-6 +2 1 3 1 0 7 45 -1 20 10.000 0 0 -1 0 0 2 + 5400 900 8325 900 +-6 +6 -225 810 3375 990 +6 2700 810 3375 990 +2 1 0 1 0 7 40 -1 15 0.000 0 0 -1 0 0 4 + 3375 990 2700 990 2700 810 3375 810 +-6 +2 1 3 1 0 7 45 -1 20 10.000 0 0 -1 0 0 2 + 2700 900 -225 900 +-6 +6 2385 -225 2565 3375 +2 1 3 1 0 7 45 -1 20 10.000 0 0 -1 0 0 2 + 2475 2700 2475 -225 +2 1 0 1 0 7 40 -1 15 0.000 0 0 -1 0 0 4 + 2385 3375 2385 2700 2565 2700 2565 3375 +-6 +6 585 -225 765 3375 +2 1 0 1 0 7 40 -1 15 0.000 0 0 -1 0 0 4 + 765 -225 765 450 585 450 585 -225 +2 1 3 1 0 7 45 -1 20 10.000 0 0 -1 0 0 2 + 675 450 675 3375 +-6 +6 540 1215 810 1485 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 675 1260 675 1440 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 585 1350 765 1350 +-6 +6 450 1260 2700 1440 +2 2 0 1 0 7 40 -1 15 0.000 0 0 -1 0 0 5 + 1125 1260 1575 1260 1575 1440 1125 1440 1125 1260 +2 1 3 1 0 7 45 -1 20 10.000 0 0 -1 0 0 2 + 450 1350 2700 1350 +-6 +6 5490 1215 5760 1485 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 5625 1260 5625 1440 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 5535 1350 5715 1350 +-6 +6 5400 1260 7650 1440 +2 2 0 1 0 7 40 -1 15 0.000 0 0 -1 0 0 5 + 6075 1260 6525 1260 6525 1440 6075 1440 6075 1260 +2 1 3 1 0 7 45 -1 20 10.000 0 0 -1 0 0 2 + 5400 1350 7650 1350 +-6 +6 -225 1935 3375 2115 +6 -225 1935 450 2115 +2 1 0 1 0 7 40 -1 15 0.000 0 0 -1 0 0 4 + -225 1935 450 1935 450 2115 -225 2115 +-6 +2 1 3 1 0 7 45 -1 20 10.000 0 0 -1 0 0 2 + 450 2025 3375 2025 +-6 +6 4725 1935 8325 2115 +6 7650 1935 8325 2115 +2 1 0 1 0 7 40 -1 15 0.000 0 0 -1 0 0 4 + 8325 2115 7650 2115 7650 1935 8325 1935 +-6 +2 1 3 1 0 7 45 -1 20 10.000 0 0 -1 0 0 2 + 7650 2025 4725 2025 +-6 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 4950 0 8100 0 8100 3150 4950 3150 4950 0 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 6300 3600 6750 3600 6750 3825 6300 3825 6300 3600 +2 1 0 4 0 7 40 -1 -1 0.000 0 0 -1 0 0 4 + 5625 900 5625 2025 7425 2025 7425 900 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 0 0 3150 0 3150 3150 0 3150 0 0 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 1350 3600 1800 3600 1800 3825 1350 3825 1350 3600 +2 1 0 4 0 7 40 -1 -1 0.000 0 0 -1 0 0 4 + 675 2025 675 900 2475 900 2475 2025 +2 4 0 2 4 7 55 -1 -1 0.000 0 0 7 0 0 5 + 7560 2160 5490 2160 5490 765 7560 765 7560 2160 +2 4 0 2 4 7 55 -1 -1 0.000 0 0 7 0 0 5 + 2565 2160 540 2160 540 765 2565 765 2565 2160 +4 0 0 50 -1 18 12 0.0000 4 135 465 4950 -45 FCell\001 +4 1 0 50 -1 0 12 0.0000 4 135 360 6525 3780 G4.4\001 +4 0 0 50 -1 18 12 0.0000 4 135 465 0 -45 FCell\001 +4 1 0 50 -1 0 12 0.0000 4 135 360 1575 3780 G4.3\001 diff --git a/katabatic/doc/images/AutoContactG4-2.pdf b/katabatic/doc/images/AutoContactG4-2.pdf new file mode 100644 index 0000000000000000000000000000000000000000..e4e8e8cc31eaaf21eb6d61fb64610547fd32d351 GIT binary patch literal 1986 zcma)7X;c$u6ct3kaYKzgQmY-%SWsXxAt4DMr6I(yNgB|A6f`6g2nGfw14S$<-~zaT zB7zDEMvAgl>yiERxD>TWMd%T=EGh;C!CG7jt=Ml6MX*0Qe`e;s_wL;9Z9^9egx08y zEkv(>vM(QE!weV?4uc#W5l<{4gbao403tzzDm94_Fd|gTNKAmqaRuh&1ZhYDlZ8XE zNB6Ap*w@0CUe_({G8ScVV}hh6k?n1jW~(mR%sOY(`BO)|YA&ZwbRtaqxNAZ8z}?9a5Kb@Ty#YwniZBCFJmwD817ny-3o^^ESxw+V`-6W3KW-oEa7 z&_ic|Lq40>Qg@`o@K#4(R8HUDyT~(<<|Y`9ASEd$zpeRk{|iZFLTiw6pr?6fw<<1v zkj}XlyEx>Op7cq;uQO9)qX(5i@ygECG4;clmpVOzAHkcBaep`QIrusjofWKpoxEX1 z_|y~6Z=|jKJh5d{c)=l#ZkKg%X2bGTG1ZC{a!I>}c_{4mQu?CHl4-If4vUv6uFhygz7M25 z9e$&2s~9Z3GXI!u@EoP(=Js>BL&r;`N%4HOaix1y%Bh!E_deO(y52vWou0er)qQ6# zPnVaOZL>Gsp%v2d%IHEb^Nb{sHw5%9lU?&Et#x=F85hlOIH7NoVQ4^cO~EU=fPZp#)FVAXDQ@-FXZS zGzziCX54pUB!-A(AsFI?DO55(9t#IBfSJugVJ4ds2mvF3MUb#9wFMwVf@$z*LXK&` zeh?G5+y^5A5U@dD#21StfxBxgxzdLOI|4>29uOkLK{$$zynvN~xPW)SsDY_fBY^-k zDvSEW+tmZufG&7MmjA+TpM7+eO2VT*E^yb-$> zuJ~`$`_#n}m=a>ZC=+75zhFBy+m;P0;ZY1_GC}F63yye?u~AUz2^eYz)K9<|RQktb z3ifm{6k^HM->M~fe9lL z90xs1H3p2hMJREYDhC)3Hvt@Af!Y@mlcy#f%__TRX593+-|}N5kZN}gDI>^{#Davd LAv)dFTL}FNxcuVi literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/AutoContactG4-2.png b/katabatic/doc/images/AutoContactG4-2.png new file mode 100644 index 0000000000000000000000000000000000000000..472c46faf1f10ae5c1d98e9916aff2fdf8da8ebf GIT binary patch literal 3075 zcmeHJYdn{w{&srGh-f>{Xt#)< zXd*r;5Mt-%irhz^^6 zxi!;rZgDo^;a-`?&|M8H6-#R%R3w<7p5g4j$U^)Ar}PaOrklMx9#jnQ6X%L68qn^% zTMIf%zQ2X{FuL2}jFov~*>HEN90PBa-!k)aP<^I!$$FnsiK=?{X9BI{+gR-UaIWB5 ziK+LCsXZA_Z*jsOKoPr-7rA7s1OD+^Ku3tykT)h!SP+sr+HM%Cv;OfDTI_f=-!PhRTCB7DdS~a3q-azW;|RPsBc+8@8h`1^j}H7gzR;f zmV_;#aa&uW4&h)@OrJ2WJcG3o&+jIiY4?;&ShO+f$g`uP^AOFd59_Oly@xjcUlI7wYh0np7}d= zAuwfJD;&WHHoQQQ5sv)cexrZ7O0h`FFBbKoid?>tFyES1YkeTRIn3Krcp9AOpPvh@ zQpn>^B0|#47;!uESFMItDq^}>_qH1jHY}4~F$lBI!FWs5V-h``{LgI(RFQtw^N+us zvn)9}pI&KDZPv|;K|j6HvZGUzTk|aZs72>LwjT*gb+f8Gv59hxsokbhm09@X1k8O` zy4sav+rGq$g#Nd|L^`u`CMP0pk+SIt3RJUD1q5vjhp};W=|d>6I=@9yY?d6{&3pau z+@!`n1!ff~4p0Yh9!Ua@-rHAq-|A~CEgkvbbcIEB;GWEkH9fg@|E4K;-&kjvRD1)2 zH_<$R0~0wcJ@D1`pik3PEk?EcVjNKuebM40 z<~v)*{ld=7L=lO1+~C(1+7t#~Qc%?lPpRZE;+>b+zF+>MioOkn9 z2d0cx7EVr*(rXvi!NwQk7pBJV4^?UB67Lte!1{k$9+1Fs<91)3nm98RxZ_<)7ijn0 z*xiSN_$OFxpV-ZG6bRpXb%Ifzm=C9U84WA3z{}gPUO8ZgW@g`AsO5zrsk!SCEn&oi)R;x?19>*tNVG! zMxV?(y%5&;mE0t&{+?Jqd8c>4F6Ge@)wGUKNG!dTxh`rfHN8Y;{G=6SG;TWJ#)XT- z5e5~}pEL5RjNN;xa&$r|Ff{LUE$+h!VBbVr00nx)IM%Aj=rIH~xip6+_dI%=el2s z5Vd3sP@UZma*+m%4bx|!W{q|c&%Xyp7llG^<`Tfb3HP5W>Q`v{5?ji8AakFzqWqsx ziyhDJfV$eOcDt|Jnyd<7O_|0(KLzIWO_Yk2SWc4S@*sL5%cqY@ibh>lrp})0htD_A zW4dR8vLsjtfLj`s1vd2qDy3n0@;L;r#(SGNAutmXDQf|v`)B5M^k!)}=%)a6IYzBH zaFlK<1f~K&%Aj8i5*x(Jjm8kWdv`yZC*LB(ywr*T2CMjcFwj`8{fpV|NVj^dGphP^Yp$V8>!5ubuAHps)MBQ z)L!OVm?7A2mwP23Tk>_Xd;v@%UjiB=v+1voziROR#{p+8rgIHx?usVkbB6o@3@#)K literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/AutoContactG4-3.fig b/katabatic/doc/images/AutoContactG4-3.fig new file mode 100644 index 00000000..e4b2fcbc --- /dev/null +++ b/katabatic/doc/images/AutoContactG4-3.fig @@ -0,0 +1,109 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +6 5400 2160 7650 2340 +2 2 0 1 0 7 40 -1 15 0.000 0 0 -1 0 0 5 + 6075 2160 6525 2160 6525 2340 6075 2340 6075 2160 +2 1 3 1 0 7 45 -1 20 10.000 0 0 -1 0 0 2 + 5400 2250 7650 2250 +-6 +6 5490 2115 5760 2385 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 5625 2160 5625 2340 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 5535 2250 5715 2250 +-6 +6 5535 -225 5715 3375 +2 1 3 1 0 7 45 -1 20 10.000 0 0 -1 0 0 2 + 5625 2700 5625 -225 +2 1 0 1 0 7 40 -1 15 0.000 0 0 -1 0 0 4 + 5535 3375 5535 2700 5715 2700 5715 3375 +-6 +6 7335 -225 7515 3375 +2 1 0 1 0 7 40 -1 15 0.000 0 0 -1 0 0 4 + 7515 -225 7515 450 7335 450 7335 -225 +2 1 3 1 0 7 45 -1 20 10.000 0 0 -1 0 0 2 + 7425 450 7425 3375 +-6 +6 585 -225 765 3375 +2 1 0 1 0 7 40 -1 15 0.000 0 0 -1 0 0 4 + 765 -225 765 450 585 450 585 -225 +2 1 3 1 0 7 45 -1 20 10.000 0 0 -1 0 0 2 + 675 450 675 3375 +-6 +6 2385 -225 2565 3375 +2 1 3 1 0 7 45 -1 20 10.000 0 0 -1 0 0 2 + 2475 2700 2475 -225 +2 1 0 1 0 7 40 -1 15 0.000 0 0 -1 0 0 4 + 2385 3375 2385 2700 2565 2700 2565 3375 +-6 +6 450 2160 2700 2340 +2 2 0 1 0 7 40 -1 15 0.000 0 0 -1 0 0 5 + 1125 2160 1575 2160 1575 2340 1125 2340 1125 2160 +2 1 3 1 0 7 45 -1 20 10.000 0 0 -1 0 0 2 + 450 2250 2700 2250 +-6 +6 2340 2115 2610 2385 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 2475 2160 2475 2340 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 2385 2250 2565 2250 +-6 +6 -225 1260 3375 1440 +6 2700 1260 3375 1440 +2 1 0 1 0 7 40 -1 15 0.000 0 0 -1 0 0 4 + 3375 1440 2700 1440 2700 1260 3375 1260 +-6 +2 1 3 1 0 7 45 -1 20 10.000 0 0 -1 0 0 2 + 2700 1350 -225 1350 +-6 +6 -225 810 3375 990 +6 -225 810 450 990 +2 1 0 1 0 7 40 -1 15 0.000 0 0 -1 0 0 4 + -225 810 450 810 450 990 -225 990 +-6 +2 1 3 1 0 7 45 -1 20 10.000 0 0 -1 0 0 2 + 450 900 3375 900 +-6 +6 4725 585 8325 765 +6 7650 585 8325 765 +2 1 0 1 0 7 40 -1 15 0.000 0 0 -1 0 0 4 + 8325 765 7650 765 7650 585 8325 585 +-6 +2 1 3 1 0 7 45 -1 20 10.000 0 0 -1 0 0 2 + 7650 675 4725 675 +-6 +6 4725 1035 8325 1215 +6 4725 1035 5400 1215 +2 1 0 1 0 7 40 -1 15 0.000 0 0 -1 0 0 4 + 4725 1035 5400 1035 5400 1215 4725 1215 +-6 +2 1 3 1 0 7 45 -1 20 10.000 0 0 -1 0 0 2 + 5400 1125 8325 1125 +-6 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 4950 0 8100 0 8100 3150 4950 3150 4950 0 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 6300 3600 6750 3600 6750 3825 6300 3825 6300 3600 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 0 0 3150 0 3150 3150 0 3150 0 0 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 1350 3600 1800 3600 1800 3825 1350 3825 1350 3600 +2 1 0 4 0 7 40 -1 -1 0.000 0 0 -1 0 0 3 + 675 900 2475 900 2475 1350 +2 1 0 4 0 7 40 -1 -1 0.000 0 0 -1 0 0 3 + 5625 1125 5625 675 7425 675 +2 4 0 2 4 7 55 -1 -1 0.000 0 0 7 0 0 5 + 2610 1440 540 1440 540 765 2610 765 2610 1440 +2 4 0 2 4 7 55 -1 -1 0.000 0 0 7 0 0 5 + 7560 1215 5490 1215 5490 540 7560 540 7560 1215 +4 0 0 50 -1 18 12 0.0000 4 135 465 4950 -45 FCell\001 +4 1 0 50 -1 0 12 0.0000 4 135 360 6525 3780 G4.6\001 +4 0 0 50 -1 18 12 0.0000 4 135 465 0 -45 FCell\001 +4 1 0 50 -1 0 12 0.0000 4 135 360 1575 3780 G4.5\001 diff --git a/katabatic/doc/images/AutoContactG4-3.pdf b/katabatic/doc/images/AutoContactG4-3.pdf new file mode 100644 index 0000000000000000000000000000000000000000..2c4d0f44ca873835a19d671e5f4517cfccebe8b4 GIT binary patch literal 2028 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 Cek+dv literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/AutoContactG4-5.png b/katabatic/doc/images/AutoContactG4-5.png new file mode 100644 index 0000000000000000000000000000000000000000..cc00a7cc842e4ea0162d991ce39af082e7b42f8e GIT binary patch literal 10108 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 PTXYk5k47^8Yo7cM*Q%SB literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/AutoInvalidate-1.fig b/katabatic/doc/images/AutoInvalidate-1.fig new file mode 100644 index 00000000..373d2de4 --- /dev/null +++ b/katabatic/doc/images/AutoInvalidate-1.fig @@ -0,0 +1,66 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +0 32 #000000 +0 33 #ddcccc +0 34 #611616 +0 35 #ccccdd +6 4050 3195 7200 3690 +2 2 0 0 0 35 60 -1 20 0.000 0 0 -1 0 0 5 + 4050 3195 7200 3195 7200 3690 4050 3690 4050 3195 +4 0 0 50 -1 18 12 0.0000 4 180 1455 4950 3375 AutoInvalidate()\001 +4 0 0 50 -1 18 12 0.0000 4 180 2235 4950 3600 anchor->AutoInvalidate()\001 +-6 +6 4050 2700 7200 3195 +2 2 0 0 -1 33 60 -1 20 0.000 0 0 -1 0 0 5 + 4050 2700 7200 2700 7200 3195 4050 3195 4050 2700 +4 0 34 50 -1 18 12 0.0000 4 135 600 4275 2925 Router\001 +4 0 34 50 -1 18 12 0.0000 4 180 2535 4275 3150 autoSegment->SetAxis( ... )\001 +-6 +6 8325 4275 12825 7515 +6 8325 4275 12825 4545 +6 8325 4275 12825 4545 +2 2 0 1 0 7 60 -1 -1 0.000 0 0 -1 0 0 5 + 8325 4275 12825 4275 12825 4545 8325 4545 8325 4275 +4 0 0 50 -1 18 12 0.0000 4 180 2490 8550 4455 _autoContacts (invalidated)\001 +-6 +-6 +2 2 0 0 0 35 60 -1 20 0.000 0 0 -1 0 0 5 + 8325 4725 12825 4725 12825 5490 8325 5490 8325 4725 +2 1 0 2 0 7 60 -1 -1 0.000 0 0 -1 1 0 2 + 3 0 2.00 120.00 240.00 + 11205 5445 11205 6300 +2 2 0 1 0 7 60 -1 -1 0.000 0 0 -1 0 0 5 + 8325 6300 12825 6300 12825 6615 8325 6615 8325 6300 +2 2 0 0 0 35 60 -1 20 0.000 0 0 -1 0 0 5 + 8325 6750 12825 6750 12825 7515 8325 7515 8325 6750 +4 0 0 50 -1 19 12 0.0000 4 135 750 8550 4950 For each\001 +4 0 0 50 -1 18 12 0.0000 4 180 2970 9225 5175 autoContact->UpdateGeometry()\001 +4 0 0 50 -1 18 12 0.0000 4 180 2820 9900 5400 autoSegment->AutoInvalidate()\001 +4 0 0 50 -1 18 12 0.0000 4 135 1080 9360 4950 autoContact\001 +4 0 0 50 -1 19 12 0.0000 4 135 750 8505 6975 For each\001 +4 0 0 50 -1 18 12 0.0000 4 180 2745 9225 7200 autoSegment->OnRevalidate()\001 +4 0 0 50 -1 18 12 0.0000 4 180 3300 9225 7425 _revalidateCallBack ( autoSegment )\001 +4 0 0 50 -1 18 12 0.0000 4 180 1185 9360 6975 autoSegment\001 +4 0 0 50 -1 18 12 0.0000 4 180 2595 8550 6525 _autoSegments (invalidated)\001 +-6 +6 4050 4725 7200 5040 +2 2 0 0 -1 33 55 -1 20 0.000 0 0 -1 0 0 5 + 4050 4725 7200 4725 7200 5040 4050 5040 4050 4725 +4 0 34 50 -1 18 12 0.0000 4 180 1950 4275 4950 Session::Revalidate()\001 +-6 +2 1 0 2 0 7 60 -1 -1 0.000 0 0 -1 1 0 4 + 3 0 2.00 120.00 240.00 + 5670 3645 5670 5850 9225 5850 9225 6300 +2 1 0 2 0 7 60 -1 -1 0.000 0 0 -1 1 0 3 + 3 0 2.00 120.00 240.00 + 7200 3555 10530 3555 10530 4275 +2 1 0 4 33 35 50 -1 -1 0.000 0 0 -1 1 0 2 + 1 1 2.00 120.00 240.00 + 7200 4905 8325 4905 diff --git a/katabatic/doc/images/AutoInvalidate-1.pdf b/katabatic/doc/images/AutoInvalidate-1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..8765794226faa997ad23d36e3475c16b605ce50f GIT binary patch literal 2090 zcmaJ?dt6L;6lX=bL>}1{@!Q=}q3*r&Y)GhSriWpgVMV2#n%m5z=4R#&Ls&vY(nnz} z5hc(N$mp3<`qj&=j4r2-dEXcNI-Y(&Y@Vhleo`ZR%T`FU&sYQ7WyOLH$7;di z=lPslhC<5{ae{o<5R1HKzPL_VdywTRZT(|(*vUQ%+k)1tu$IWLrhFC?nA>+x&EQ(g z;m)3Ejc)Q<+g5NU!zMm0{dUe2>pbBWMiyoFZgFLj4xGx0d!BLR*3gR3HN$^e-X8F9 zM;hbtftclB)H$$DHS|OJolNeftV3)zWcFMOtmVm!-|+4Fx2xVr+q| zbavFnC)|8vHOal+;FDOkq{)6_&N~aEcIKMdMWcKU6=oTT`k<7171^Pa!sqkHZ#P8U zvvX>T&hj?|tdMMaeSTBeiM+uv*w%R@pS`qi>G6z>iGKII@9Bnb$$U|H^|0#jZ;Er7 zUpmg)XUw}~SH6)|d9y9SZptb$EOq;pFDg|d-P8N~2RbDk57PM;y&F2)>MLbpyw%FN z`SmaA%36$%>hzukW68}g>fcl!&MY77lAW5ot^QQK9^dUY|D9n-xzn>>H=WKn@L;9Q z&K8?`ht{&s?WYRgPiH0iZk=3ZIU`d#WZh$9c95}o!sTm^E=(S^r=#}dU61#8@cvis zeV&i{`>nFwu(@iag-Eo9WuJa*;)-GYu7tR88g53GmB$%E45dfUIrY0=EID;d#qs&& z#I8w;lANRm&yENTz#P7tuFx+a&RO4{-u9ZEpqEZA4L7`9Fld2mb=y-7abZlxoa)ew zWJ?cc(F={!BH_4InNI}Yx)yCuP9Bh2^LtWNe1Xeoae}jbW9w?%Ir&Uu(Zu(wdHc%4 zlAOYF9$efI=w~dnvW-P|=SltV0xQ2|>wYZvDLo=Bd0*3^95yS*P92nc$ME>kOX^Bc z;{8>MOO#i9{(9HR6*UusN1=Tia(5*h-&=gvwI;AhIQ|En|NZ78u`RhL{P(C2Z4?6A zT+b0vH}cOfZ3NfmzK&Q&?Gh|c`*U?X`%S~0X8o}a;o5AMBVi6(kM1PYa`RBafAk>J z<4gbYFfL+-Slu%|cX=#zROBn-!K(+gY~s5g9vj9Ngi z8VLd+vn=|E&ea3ipe|q%rUht#O0EUL2rXNJgaXK*qbWZMrP<9}t25GDM#-W{#RrN` z_1#BtKlSfcji7VHB7l2(nl+h{Ff&WI2puQsrZHvp!OBB;v=x=OBkrHN(YV>mOQt30 zf}p-c^iqOSMaW#e$Y{AKUsI)E1=Vo5s?-XAGfaF^T{uN|iB1d(`%o>D^`o4-;!wUS zGLnEzgI$6}W1}%DwN4w_9Z9SEe>ro)qg6|EokyBg{f7!#qL~X`2e~eS&^Y@@#XzVe zwUjnOql%?~JI;2)7%s5$@MA%#NHrf`4`==q28Ov~T#SjkGk8o6w2Mgjzni++q1Oi4}zWBgY)m^BsPsF+mHIiw$y#^(i;h-$4X1dG?b~>I2Yp~j*dQa G1js+G+6|Nd literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/AutoInvalidate-1.png b/katabatic/doc/images/AutoInvalidate-1.png new file mode 100644 index 0000000000000000000000000000000000000000..119c4da3ac6deb80c761bc70ca997a5c0c9e7fe8 GIT binary patch literal 8075 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 literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/AutoSegmentCollapse-1.fig b/katabatic/doc/images/AutoSegmentCollapse-1.fig new file mode 100644 index 00000000..7e71742d --- /dev/null +++ b/katabatic/doc/images/AutoSegmentCollapse-1.fig @@ -0,0 +1,87 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +6 3420 3195 5265 4500 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3960 3465 5040 3465 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 4050 3465 4050 3690 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 4365 3465 4365 3915 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 4950 3465 4950 4320 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 4635 3465 4635 4095 +4 1 0 40 -1 14 14 0.0000 4 195 945 4500 3375 C c g t\001 +4 2 0 40 -1 18 12 0.0000 4 135 840 4275 3825 Canonical\001 +4 2 0 40 -1 18 12 0.0000 4 180 840 4545 4050 Collapsed\001 +4 2 0 40 -1 18 12 0.0000 4 135 555 4860 4275 Global\001 +4 2 0 40 -1 18 12 0.0000 4 135 765 5265 4500 Terminal\001 +-6 +6 3555 4680 4995 4860 +2 1 0 1 12 7 40 -1 -1 0.000 0 0 -1 1 1 2 + 3 1 1.00 60.00 120.00 + 3 1 1.00 60.00 120.00 + 3555 4770 4005 4770 +4 0 0 40 -1 18 12 0.0000 4 180 735 4230 4815 Collapse\001 +-6 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 450 2700 90 90 360 2700 540 2700 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 2700 2700 90 90 2610 2700 2790 2700 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 1575 3825 90 90 1485 3825 1665 3825 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 2700 1575 90 90 2610 1575 2790 1575 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 3825 1575 90 90 3735 1575 3915 1575 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 3825 450 90 90 3735 450 3915 450 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 4950 450 90 90 4860 450 5040 450 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 1575 2700 90 90 1485 2700 1665 2700 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 0 0 5400 0 5400 4950 0 4950 0 0 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 540 2700 1485 2700 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 1665 2700 2610 2700 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 1575 2790 1575 3735 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2700 1665 2700 2610 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2790 1575 3735 1575 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3825 540 3825 1485 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3915 450 4860 450 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 3 + 5400 3150 3150 3150 3150 4950 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3150 4545 5400 4545 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 720 2385 1260 2385 1260 2655 720 2655 720 2385 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 1845 2385 2385 2385 2385 2655 1845 2655 1845 2385 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 1620 3150 2160 3150 2160 3420 1620 3420 1620 3150 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 2745 2025 3285 2025 3285 2295 2745 2295 2745 2025 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 2970 1260 3510 1260 3510 1530 2970 1530 2970 1260 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 3870 900 4410 900 4410 1170 3870 1170 3870 900 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 4095 135 4635 135 4635 405 4095 405 4095 135 +3 2 0 1 12 7 40 -1 -1 0.000 0 1 1 4 + 3 1 1.00 60.00 120.00 + 3 1 1.00 60.00 120.00 + 3735 495 3600 765 3600 1215 3780 1530 + 0.000 -1.000 -1.000 0.000 +4 1 0 40 -1 14 12 0.0000 4 165 420 990 2565 C-g-\001 +4 1 0 40 -1 14 12 0.0000 4 120 420 2115 2565 C---\001 +4 1 0 40 -1 14 12 0.0000 4 165 420 1890 3330 C-g-\001 +4 1 0 40 -1 14 12 0.0000 4 120 420 3015 2205 C---\001 +4 1 0 40 -1 14 12 0.0000 4 165 420 3240 1440 C-g-\001 +4 1 0 40 -1 14 12 0.0000 4 120 420 4140 1080 C---\001 +4 1 0 40 -1 14 12 0.0000 4 165 420 4365 315 C-g-\001 diff --git a/katabatic/doc/images/AutoSegmentCollapse-1.pdf b/katabatic/doc/images/AutoSegmentCollapse-1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..6c82fc7b5ccf294ec1a6b141ded288ae387dd5fd GIT binary patch literal 2887 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 literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/AutoSegmentCollapse-2.fig b/katabatic/doc/images/AutoSegmentCollapse-2.fig new file mode 100644 index 00000000..4362414c --- /dev/null +++ b/katabatic/doc/images/AutoSegmentCollapse-2.fig @@ -0,0 +1,87 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +6 3420 2295 5265 3600 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3960 2565 5040 2565 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 4050 2565 4050 2790 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 4365 2565 4365 3015 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 4950 2565 4950 3420 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 4635 2565 4635 3195 +4 1 0 40 -1 14 14 0.0000 4 195 945 4500 2475 C c g t\001 +4 2 0 40 -1 18 12 0.0000 4 135 840 4275 2925 Canonical\001 +4 2 0 40 -1 18 12 0.0000 4 180 840 4545 3150 Collapsed\001 +4 2 0 40 -1 18 12 0.0000 4 135 555 4860 3375 Global\001 +4 2 0 40 -1 18 12 0.0000 4 135 765 5265 3600 Terminal\001 +-6 +6 3555 3780 4995 3960 +2 1 0 1 12 7 40 -1 -1 0.000 0 0 -1 1 1 2 + 3 1 1.00 60.00 120.00 + 3 1 1.00 60.00 120.00 + 3555 3870 4005 3870 +4 0 0 40 -1 18 12 0.0000 4 180 735 4230 3915 Collapse\001 +-6 +6 4140 360 4680 630 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 4140 360 4680 360 4680 630 4140 630 4140 360 +4 1 0 40 -1 14 12 0.0000 4 135 420 4410 540 --g-\001 +-6 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 450 1800 90 90 360 1800 540 1800 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 2700 1800 90 90 2610 1800 2790 1800 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 1575 2925 90 90 1485 2925 1665 2925 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 2700 675 90 90 2610 675 2790 675 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 3825 675 90 90 3735 675 3915 675 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 1575 1800 90 90 1485 1800 1665 1800 +1 4 0 1 0 7 40 -1 -1 0.000 1 0.0000 3825 675 135 135 3690 675 3960 675 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 4950 675 90 90 4860 675 5040 675 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 540 1800 1485 1800 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 1665 1800 2610 1800 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 1575 1890 1575 2835 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2700 765 2700 1710 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 3 + 5400 2250 3150 2250 3150 4050 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3150 3645 5400 3645 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 720 1485 1260 1485 1260 1755 720 1755 720 1485 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 1845 1485 2385 1485 2385 1755 1845 1755 1845 1485 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 1620 2250 2160 2250 2160 2520 1620 2520 1620 2250 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 2745 1125 3285 1125 3285 1395 2745 1395 2745 1125 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 2970 360 3510 360 3510 630 2970 630 2970 360 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2790 675 3690 675 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 0 0 5400 0 5400 4050 0 4050 0 0 +2 1 0 2 18 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3915 675 4860 675 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 3555 855 4095 855 4095 1125 3555 1125 3555 855 +3 2 0 1 12 7 40 -1 -1 0.000 0 1 1 4 + 3 1 1.00 60.00 120.00 + 3 1 1.00 60.00 120.00 + 1620 1710 1890 1350 2430 1350 2655 1710 + 0.000 -1.000 -1.000 0.000 +4 1 0 40 -1 14 12 0.0000 4 165 420 990 1665 C-g-\001 +4 1 0 40 -1 14 12 0.0000 4 120 420 2115 1665 C---\001 +4 1 0 40 -1 14 12 0.0000 4 165 420 1890 2430 C-g-\001 +4 1 0 40 -1 14 12 0.0000 4 120 420 3015 1305 C---\001 +4 1 0 40 -1 14 12 0.0000 4 165 420 3240 540 C-g-\001 +4 1 0 40 -1 14 12 0.0000 4 90 420 3825 1035 -c--\001 diff --git a/katabatic/doc/images/AutoSegmentCollapse-2.pdf b/katabatic/doc/images/AutoSegmentCollapse-2.pdf new file mode 100644 index 0000000000000000000000000000000000000000..5c2fd3429ed02094a01d65b48afba67e6cde9fa0 GIT binary patch literal 3025 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 literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/AutoSegmentCollapse-2.png b/katabatic/doc/images/AutoSegmentCollapse-2.png new file mode 100644 index 0000000000000000000000000000000000000000..cf7fa331d761e5aade372b28e2a26f4ea24c4db8 GIT binary patch literal 4504 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 Q%O~*Z$PzYV{uK!S00KY)yZ`_I literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/AutoSegmentCollapse-3.fig b/katabatic/doc/images/AutoSegmentCollapse-3.fig new file mode 100644 index 00000000..a7d777ba --- /dev/null +++ b/katabatic/doc/images/AutoSegmentCollapse-3.fig @@ -0,0 +1,85 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +6 3420 2295 5265 3600 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3960 2565 5040 2565 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 4050 2565 4050 2790 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 4365 2565 4365 3015 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 4950 2565 4950 3420 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 4635 2565 4635 3195 +4 1 0 40 -1 14 14 0.0000 4 195 945 4500 2475 C c g t\001 +4 2 0 40 -1 18 12 0.0000 4 135 840 4275 2925 Canonical\001 +4 2 0 40 -1 18 12 0.0000 4 180 840 4545 3150 Collapsed\001 +4 2 0 40 -1 18 12 0.0000 4 135 555 4860 3375 Global\001 +4 2 0 40 -1 18 12 0.0000 4 135 765 5265 3600 Terminal\001 +-6 +6 3555 3780 4995 3960 +2 1 0 1 12 7 40 -1 -1 0.000 0 0 -1 1 1 2 + 3 1 1.00 60.00 120.00 + 3 1 1.00 60.00 120.00 + 3555 3870 4005 3870 +4 0 0 40 -1 18 12 0.0000 4 180 735 4230 3915 Collapse\001 +-6 +6 3015 360 3555 630 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 3015 360 3555 360 3555 630 3015 630 3015 360 +4 1 0 40 -1 14 12 0.0000 4 135 420 3285 540 --g-\001 +-6 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 450 1800 90 90 360 1800 540 1800 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 1575 2925 90 90 1485 2925 1665 2925 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 1575 675 90 90 1485 675 1665 675 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 1575 1800 90 90 1485 1800 1665 1800 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 1575 1800 135 135 1440 1800 1710 1800 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 2700 675 90 90 2610 675 2790 675 +1 4 0 1 0 7 40 -1 -1 0.000 1 0.0000 2700 675 135 135 2565 675 2835 675 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 3825 675 90 90 3735 675 3915 675 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 540 1800 1440 1800 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 1575 1935 1575 2835 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 3 + 5400 2250 3150 2250 3150 4050 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3150 3645 5400 3645 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 720 1485 1260 1485 1260 1755 720 1755 720 1485 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 1620 2250 2160 2250 2160 2520 1620 2520 1620 2250 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 0 0 5400 0 5400 4050 0 4050 0 0 +2 1 0 2 18 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 1575 765 1575 1665 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 1845 360 2385 360 2385 630 1845 630 1845 360 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 1665 675 2565 675 +2 1 0 2 18 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2790 675 3735 675 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 2430 855 2970 855 2970 1125 2430 1125 2430 855 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 1620 1125 2160 1125 2160 1395 1620 1395 1620 1125 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 1845 1665 2385 1665 2385 1935 1845 1935 1845 1665 +3 2 0 1 12 7 40 -1 -1 0.000 0 1 1 4 + 3 1 1.00 60.00 120.00 + 3 1 1.00 60.00 120.00 + 1485 720 1215 945 1215 1395 1485 1710 + 0.000 -1.000 -1.000 0.000 +4 1 0 40 -1 14 12 0.0000 4 165 420 990 1665 C-g-\001 +4 1 0 40 -1 14 12 0.0000 4 165 420 1890 2430 C-g-\001 +4 1 0 40 -1 14 12 0.0000 4 165 420 2115 540 C-g-\001 +4 1 0 40 -1 14 12 0.0000 4 120 420 1890 1305 C---\001 +4 1 0 40 -1 14 12 0.0000 4 90 420 2700 1035 -c--\001 +4 1 0 40 -1 14 12 0.0000 4 90 420 2115 1845 -c--\001 diff --git a/katabatic/doc/images/AutoSegmentCollapse-3.pdf b/katabatic/doc/images/AutoSegmentCollapse-3.pdf new file mode 100644 index 0000000000000000000000000000000000000000..1377bff9714234de450eeba6ee60ce9e3082f16e GIT binary patch literal 2973 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 LSXy$ny956NqWYkl literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/AutoSegmentCollapse-4.png b/katabatic/doc/images/AutoSegmentCollapse-4.png new file mode 100644 index 0000000000000000000000000000000000000000..911a2bf3e257754075d5e97ae209e2c61f575286 GIT binary patch literal 4270 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 literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/AutoSegmentCollapse-5.fig b/katabatic/doc/images/AutoSegmentCollapse-5.fig new file mode 100644 index 00000000..cd67a788 --- /dev/null +++ b/katabatic/doc/images/AutoSegmentCollapse-5.fig @@ -0,0 +1,81 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +6 4230 1710 4770 1980 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 4230 1710 4770 1710 4770 1980 4230 1980 4230 1710 +4 1 0 40 -1 14 12 0.0000 4 165 420 4500 1890 C-g-\001 +-6 +6 4905 1530 5445 1800 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 4905 1530 5445 1530 5445 1800 4905 1800 4905 1530 +4 1 0 40 -1 14 12 0.0000 4 90 420 5175 1710 -c--\001 +-6 +6 5670 1710 6210 1980 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 5670 1710 6210 1710 6210 1980 5670 1980 5670 1710 +4 1 0 40 -1 14 12 0.0000 4 135 420 5940 1890 --g-\001 +-6 +6 4950 2655 6795 3960 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 5490 2925 6570 2925 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 5580 2925 5580 3150 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 5895 2925 5895 3375 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 6480 2925 6480 3780 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 6165 2925 6165 3555 +4 1 0 40 -1 14 14 0.0000 4 195 945 6030 2835 C c g t\001 +4 2 0 40 -1 18 12 0.0000 4 135 840 5805 3285 Canonical\001 +4 2 0 40 -1 18 12 0.0000 4 180 840 6075 3510 Collapsed\001 +4 2 0 40 -1 18 12 0.0000 4 135 555 6390 3735 Global\001 +4 2 0 40 -1 18 12 0.0000 4 135 765 6795 3960 Terminal\001 +-6 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 3870 2025 90 90 3780 2025 3960 2025 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 5175 2025 135 135 5040 2025 5310 2025 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 5175 2025 90 90 5085 2025 5265 2025 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 6525 2025 90 90 6435 2025 6615 2025 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 450 2025 90 90 360 2025 540 2025 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 1800 2025 90 90 1710 2025 1890 2025 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 1800 675 90 90 1710 675 1890 675 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 3150 675 90 90 3060 675 3240 675 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3960 2025 5040 2025 +2 1 0 2 18 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 5310 2025 6435 2025 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 540 2025 1710 2025 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 1800 765 1800 1935 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 1890 675 3060 675 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 810 1710 1350 1710 1350 1980 810 1980 810 1710 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 1845 1215 2385 1215 2385 1485 1845 1485 1845 1215 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 2160 360 2700 360 2700 630 2160 630 2160 360 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 3 + 6975 2475 4725 2475 4725 4050 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 0 0 6975 0 6975 4050 0 4050 0 0 +4 1 0 40 -1 14 12 0.0000 4 165 420 1080 1890 C-g-\001 +4 1 0 40 -1 14 12 0.0000 4 120 420 2115 1395 C---\001 +4 1 0 40 -1 14 12 0.0000 4 165 420 2430 540 C-g-\001 +4 1 0 40 -1 18 12 0.0000 4 135 255 1125 2205 G1\001 +4 1 0 40 -1 18 12 0.0000 4 135 210 1665 1440 L1\001 +4 1 0 40 -1 18 12 0.0000 4 135 255 2430 855 G2\001 +4 1 0 40 -1 18 12 0.0000 4 135 255 4500 2205 G1\001 +4 1 18 40 -1 18 12 0.0000 4 135 255 5940 2205 G2\001 +4 1 0 40 -1 18 12 0.0000 4 135 210 5175 2340 L1\001 +4 1 0 40 -1 18 12 0.0000 4 135 345 1800 540 AC2\001 +4 1 0 40 -1 18 12 0.0000 4 135 345 1800 2340 AC1\001 +4 1 0 40 -1 18 12 0.0000 4 135 945 5175 1485 AC1 & AC2\001 diff --git a/katabatic/doc/images/AutoSegmentCollapse-5.pdf b/katabatic/doc/images/AutoSegmentCollapse-5.pdf new file mode 100644 index 0000000000000000000000000000000000000000..226eb66e296f1b58bf5f5a42c38e5cbb346f14a3 GIT binary patch literal 2327 zcmZ`*eLPh88dtk}uTC41W-*I1tSNWXnfDjls%4Didf6cn+UDgjqcOA1oXMceVwX*! zvMA|Iq>|)iv)I;4h0PW*>f_2JWW3zXO6o@L?m3gvviJOR&Us$Gzwh%rzu)&9dtVOM zk-VM?*f;+tBOjoHBv3Ah05)uZ{t3&%5i!U>Ej)-Tks`1Hgt$^Z0&`%YTm(Bi14={z z^CJOu-tld%vJmF`y$?#;FGS+DtvvsnvMg0vzVDNbecmDWZXD=ky*EAcX^d~p^Sh*j z_4_RpEw0vw4-c2#6!Xr$oNAj?MaQn{nytDq(vp64I*KrL*&nZ(-2KobsJ5WRbfn;7 zQqg2;{vF~4UG1YP+05R$y`ks+HEyFTj)`9y7x3Hnj54R$vdSL{Sf&Sm%Ut2~a1sfP zdvRG?D))|etUHn2wx7-(H8CT6>}Bfot4sVgjwepN@~dU)GHyuQ7%@L1D0as3-uQBJ zgMr!f{+ctxF71O`3%>dxDD(sO^TpiE7~uVHCuH#Hd(Wyed@_u6J)RS%&ZX`1E*Ye`rQhlwQB=>)^z`Nk_?hWO z!p?P;*PB~A$9o?n2A0SE-q|}j^{~uB^FL9gZI)eww$E&BzlcukcUpadY?o^Ftwr)L zpEVnFM_Wl+bl=?R9&KOY+dkC3B>BE={bw{>`f!GU=6og9CCBsY6G?$j&2Gf|JpA!x zkY$=jhj{uU2Hkvn9wYd^tHpR;rK`1S1^?fxLjI4IHn5xAw z5$~KXT2J^})uC&oVKz{o;5HsoeUh0_iciy6tuQ_|klcDcWYw_&+;s1!xA9A}nniic zL%QfOOE#1UHhT!9PWLJf-uB4usD3A->5}!TIs((ok=h6sN)&dRhOgsg98u-Tl8-X? z?%QaRyl!{O*>HwQ%#dAEAEVqH=lJuI%XVeLCRUC*i%2Ej-wG>&JAHlW! zB1Z#P=@KGzwhu4*`zdL}b?ejnGQ0kJRkuc4`x5WK7`C;(^m9Z+M1a(s-a;M8tG@U# ze!In)?>d?qr@ewWmIa(U6{h1SD(aUPt*mnh+jDF7NPM_zZ<|pS60J?Z9fSlaDCA&eeqbQy^oKpRx=4iKZgQ~kNe=MMos`2nI<`vwmk&McyjKGXo!zp#-p)`C zBP|;*hsQ{lO24>Y&}t$YUYGr==v;}%uAba!VmlcywMl~a!^Yhn@xYmG|`@~8d%pALo7 zt`R6SI3?`v&8jTE6=*&<6bt+&P0#Y&U10Wu(l&cg%Sc$5luR<>LgOOke)lCrc zht&ug?xsfE{SZ_cK{AGerf}tGI+?70L4^`>Mc+|GC5QvAR>g1fAdVy~3`R$W&IoN89g395RLao# zOpMz?GMi!P9vG1b`HSfMpXD)bb0Fw05UGT)Vy&B>FX%3oD-oqoA^8#kS!DWp62$=> zIQnHoByt%C-4$y&P81S}MPibuWEO=@VW565x#+K5Z>FGDz+nIhBvS#>n+s&n=~Oxx z2F}^YGzK~y>;h$PY%DZlp^ZjDTd*Jw-RcW%BocXXE`_=%j!gfHI3@!5Jp&ti?9w+nf;vUm}GS=#L2q`AK5XlSTz0o?MO|32e)NkcTWx4(hiL0C{l0;I&Ct q%qbRekIx(0bZ^}`ad?-*VoNA?nv@7%f#{n}X44pey}g?c7x)7q%Z6tF literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/AutoSegmentCollapse-5.png b/katabatic/doc/images/AutoSegmentCollapse-5.png new file mode 100644 index 0000000000000000000000000000000000000000..038151947c9f6a5dd86c6de61cbbe94044399e77 GIT binary patch literal 4828 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 literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/AutoSegmentCollapse-6.fig b/katabatic/doc/images/AutoSegmentCollapse-6.fig new file mode 100644 index 00000000..710d28a4 --- /dev/null +++ b/katabatic/doc/images/AutoSegmentCollapse-6.fig @@ -0,0 +1,82 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +6 4950 2655 6795 3960 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 5490 2925 6570 2925 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 5580 2925 5580 3150 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 5895 2925 5895 3375 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 6480 2925 6480 3780 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 6165 2925 6165 3555 +4 1 0 40 -1 14 14 0.0000 4 195 945 6030 2835 C c g t\001 +4 2 0 40 -1 18 12 0.0000 4 135 840 5805 3285 Canonical\001 +4 2 0 40 -1 18 12 0.0000 4 180 840 6075 3510 Collapsed\001 +4 2 0 40 -1 18 12 0.0000 4 135 555 6390 3735 Global\001 +4 2 0 40 -1 18 12 0.0000 4 135 765 6795 3960 Terminal\001 +-6 +6 810 360 1350 630 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 810 360 1350 360 1350 630 810 630 810 360 +4 1 0 40 -1 14 12 0.0000 4 165 420 1080 540 C-g-\001 +-6 +6 4185 360 4725 630 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 4185 360 4725 360 4725 630 4185 630 4185 360 +4 1 0 40 -1 14 12 0.0000 4 165 420 4455 540 C-g-\001 +-6 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 1800 2025 90 90 1710 2025 1890 2025 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 1800 675 90 90 1710 675 1890 675 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 3150 675 90 90 3060 675 3240 675 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 450 675 90 90 360 675 540 675 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 5175 2025 90 90 5085 2025 5265 2025 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 5175 675 90 90 5085 675 5265 675 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 6525 675 90 90 6435 675 6615 675 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 3825 675 90 90 3735 675 3915 675 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 3 + 6975 2475 4725 2475 4725 4050 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 0 0 6975 0 6975 4050 0 4050 0 0 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 1800 765 1800 1935 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 1890 675 3060 675 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 1845 1215 2385 1215 2385 1485 1845 1485 1845 1215 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 2160 360 2700 360 2700 630 2160 630 2160 360 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 540 675 1710 675 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 5175 765 5175 1935 +2 1 0 2 18 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 5265 675 6435 675 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 5220 1215 5760 1215 5760 1485 5220 1485 5220 1215 +2 2 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 5535 360 6075 360 6075 630 5535 630 5535 360 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3915 675 5085 675 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 5085 675 5310 675 +4 1 0 40 -1 14 12 0.0000 4 120 420 2115 1395 C---\001 +4 1 0 40 -1 14 12 0.0000 4 165 420 2430 540 C-g-\001 +4 1 0 40 -1 18 12 0.0000 4 135 210 1665 1440 L1\001 +4 1 0 40 -1 18 12 0.0000 4 135 255 2430 855 G2\001 +4 1 0 40 -1 18 12 0.0000 4 135 345 1800 540 AC1\001 +4 1 0 40 -1 18 12 0.0000 4 135 255 1080 855 G1\001 +4 1 0 40 -1 14 12 0.0000 4 120 420 5490 1395 C---\001 +4 1 0 40 -1 14 12 0.0000 4 135 420 5805 540 --g-\001 +4 1 0 40 -1 18 12 0.0000 4 135 210 5040 1440 L1\001 +4 1 18 40 -1 18 12 0.0000 4 135 255 5805 855 G2\001 +4 1 0 40 -1 18 12 0.0000 4 135 345 5175 540 AC1\001 +4 1 0 40 -1 18 12 0.0000 4 135 255 4455 855 G1\001 diff --git a/katabatic/doc/images/AutoSegmentCollapse-6.pdf b/katabatic/doc/images/AutoSegmentCollapse-6.pdf new file mode 100644 index 0000000000000000000000000000000000000000..328732cf711f29e9e923cc567dbf6745884295ef GIT binary patch literal 2299 zcmZ`*eLPh88dnl~A}Y6T$vU%)OJ2^r7&GLh#u&qpxii*Qn%rRyGc_}ZnWK=_%SYJW z=%d$*C^i)mN!_(Y7uj7aZ}&>;wh%FPLFbfVx#IT14phA_f zNDjp2e)|`qS>SC)*nBXg%yE>}rS7i!zPa(7u)#6;sLaYW*#90>n!fh;?{m)6kOr&ga(1pZ9w?4KSViQgN)a-T(D^DE+pYJ*0QRb^rncd4S> zS5?hU+C4s0^lu2}?r1?|p7_ zRCa1@M5X_jt6p+N?5@*4j9t}jkO+pTcWqlWr;O_E=?Lo8ynBYmgZ6}OCeg4$=rhrl z(Rr}FmB#iVJ1rWDx@;M}{p-Qh7{bD9th65uZ;8Hq?$|y$QF>_)&pj~AtFS&;f6!)u zHFPQ5B)4N~1Fi_@}-hO#Fux$75`%GQ)cX9)Q1s%LIUUxR0D&P*R8*(UHZXUY- z(BgdoTgRO^7YYjb!-u!@*%dDfU9=+aq{ZkGyD-AvBI|efty%YA^~neJOUF_#T835r z+eYZ>l!34hS~?7#k1j5<6zH2@XY;~zQw*#(kUja28w_qtT$h&H9(fMhH@bR$mrkdc5SgFa{mX^93{5<&PuXN4O1>QswVZ_^R?03cK<~MfH!WWsxVzb-J)bgz{ z`==;YC(L)8hul41zn;!^SFBCZ$;cniLJ*?vIsd}TdYAW?!`mDC~)+e)c3${!yLuvI3HN&P|A*N3|ri}r4 zi(7wQ-{kGY6_Z?Pab1a*)Nbjjpy~XqQcmfzq1rfo1#f@Nu}QP#JBZ`q`Y&OH zcvfq$CtRO!Rl@INGKB)n+MMRJD=01shIpb#7z%*JQV|o01w%-f+sTOxQfPD`fH{@0 z0tKnKx&aU$Rv|IUa9D-u9#4sc3t%(^!jut&g5X#b3-^vieFP|`eIOaf!BW@=mQE&X zUoa_zys&o+Q3c`>$_FshEG>MAw~~sXVZ1;sF%<}LrD7Er0^qdyfDptGVsOY0QgQTI zHGZ4vB|=3qB=Q}^TlRBH(f=4f#~OeFc>y5V!(*0{wuo6|J{`dG_;WDYs@{2B02kZ~ z@fiT)k72ldHi{`y!FWUP8kAC4>A*x}Vr{kBK4JY+V4n=BA`&E1v}l5uFchB=UKU2{ zU9Ys>4=R422eG6P5im9~Y(`kiXpmg0h*1gWGI4Gnli|R!T`(#Q7tN#dC(Gm9WqKbJz97e{tt%#Wi}v2*v)8Z?*raWu*&;%M`2&L46{l_IGOR${*%AS95+ zV<(LYLVN_ljs(7CK*(1Sfq>fW13=n-MiMg_x^L&`D3rW_WsuXzHfiu-oNknC7y?# z0gB0p0RRA?x!GxJ06<`dKjgM<;qRQgU*E-_wjspg0dy1bbENz)d&8^Fa-Tf;ZB&Sp<%^rBZ=k95&?*oVm2z9B>>oi zBmtvc48Xxe_|3cR5JR(Z*#n1`fIHKC|=ZAGvr|t$5jhXx17KMJXYyIe127(Ots)xtc!~H3& zB-ID6O9J)C_CVAtf_5`YEUuWf*{?n#@+N*FRM5i(#vS2w^lr|qk*rjc>33^CI7ks5 zjlYLWi_9xjTm+(oDfi`Snc+^x3TmFyx}%otJE6l5x>}Tw)K#24>H5Cok)`7I#wR_{ zo!fm+tdG8Y>=q*ae$J8|H*(685`^=^mYuL>gnLoi7b0*@@=wPKQ#N6dqAnnG^(3m- zi7i`xj`GN-e92d?;s}_yR$ejoMv%#S{aqsqk@6s8GnruMKM5bd5-WeUU1lNRF!ODe zbz8||j0*MnkVf6u;B!W0+4N+`nMORFM5M8u%c^K6cE}i5Q)CvzGOv@Q-XZ3=`QpLz zQPov}AP+UXR}-Cn{?n>D)y`+XNU}mjUjCVA%^psVjJQE);CQZWwmWgSc2f6X6#Z<- z0k5$q%>quZ=hB97V{e7o1+(rsbe?u3D7wY2Tb9xsz!*5m@4?8PMLBuq?uAthqesf_~b& z@!9xNzVk!&pex}z6kda7o>tBEMJanlr)s#~ml?Tk#~gOjcGhtGM4Oxe;^OUF5ME-u z&_xnaRVRo!$E)+p*|m18V(guZ!3v%BpzyIqxr6nr*tldb+i8+A^=bqaDfRJ(yb5E@ zREDms3btRq3~PXPnJUOdmC0pCeZ(t{I*4~%6<;7OPnbfPwk^wq+wWc}dl{$DAQV08 z)jD%km`*7BxjUH?_^Rw#O^wg=EnmviS}p4f$|;7`Rz}p`opWRdxNF-arR+me4DO5D zTaT^;<=qXtLAj_NSe9aa9Ai~Pfxnu~4WB(icXMF%I3a?Oc4P(z{{CXbIw|7*yg9Ul zUKuuc9Iw^=4)Fw5^}>hCC`exBT)m@fwdXv+ug_AQwEUfI*@9QaLS3+M$_N{*3+;KWR)@R`QN$@IFUofGxauM)who1_IZ8^`_rYI@Q~iP|{rD z7^8QC#PUvru=V{q?3uQ`!ez9@6z}rzO#1w%4*2H@Za`^4UzrEf?6ye7m|T^jif;CX zo>dB*ZTGZQum8KqJHcl{;W>}&j7S+oDzAh0ffKeZhG!m3##fnLwA-0b5EO@aC{)Rjn z;=otoSHzdr^Ny`@ON0WYlu5al&C)*55I4Tb{;SpCTX6okmS8c~mCf66nT<8GJkm-4 zvD5yAuGs0KIOn@@ZG~^{NY6$NO;t%4<Uqc4`rzRdOnNQL$W}WQf_Wma zl9TC$|JrmboU68_4A=h0K$Ps!?HF4V|8L@Ny zk8xO`I;R>Rg5DCWXW&Nmo<`kw32sL(fQPqS3bAmWFFhgDUYt~gr0N-(1>}e(Sp4al z_%EVRdI^sL5H46$tbh0il!Ry&GiRc8bh`gHpeg&nkIz*amEL6xOiR!?Gxog$P$^y}_n*^tQ#b5f~ zXx&l)9oIwoyU}g3RF%p>(PeU$WJ&WMVM;A(urJ6rquUJ4!WgaZ?OJ}~?Oy^CVTGOf znxR{MVID6>x1FcTDi=3;BTUhPVD*xDp6^?$7NZxI1($#K~f02MgwTk>?h@ap)Wt)xj}B4>>kg zpx}V{Ea=W?6^&q|ChBZ#Y9^GYruI%9)dNp)eK7Fq&(Lw%&fw!G%iRZ6G*OMkqptkh zT&>uZXB{5T714K0(Y?doyH8JG!_jmCA~kK<@l2xmIidK`$U#!H0$E6biqyV!(sTye z&;!+)^5V?k565eNk;jof$jRecmEHq?{NfPBaCsr4_n?&X&;0DEzbK*WO}1x8l^`x} zEqF6nUaR}(5eOprqo2*f-J^yqSwd@KwkPM3Ps5^5OXRGF*RouVJ{!Q#04y$myD?F# zs|J$F*C&DTbBocn__Yku&IEYjt@W4g5lm0Ec9j+yYL+#hgQ7&lopUa zr!&}$PW!k&l2Tt-m7A-stV( zvo1#DeYA;JR?{$N$%g*?G3aniYDOx&`{et}C|9(g1V%ZtcgjjXzr~RcfHy@Ok052w z&8Lk(T16?R?(a>2k8W#F-hU~0b%JTfUmPsUxCu8|o;x%#b5DiBAY)UCo@ilr@!CWO zo)G;~ocH)HV$w(cfl3q3z0?AJW7fG-(fxysA-u|>R3t=54t5qTh||j5vBDOZ)l?iE zmmQ5ywTaY-qI#|TaBKrP+aCqWHXa^;v?{duXH-egdQ?5k7<;H3KrEoE0z|cL^L% zSS5|U?BaZ}o#Ki74%q;J!;=P&dOMA(z3BYz1OPBMfu620y8Kh(|Gupe68f#Jp`8K( z4(x0_*4i@NCa6$XYWJvrrRylbr-uaqxDG%J(<1~A4gNL#6@tHB!T;Mw=o9YL5{AsK K0>A%z@cA1v)aobz literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-1.fig b/katabatic/doc/images/GCellConfiguration-1.fig new file mode 100644 index 00000000..2ba8ad76 --- /dev/null +++ b/katabatic/doc/images/GCellConfiguration-1.fig @@ -0,0 +1,65 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 2700 1350 90 90 2610 1350 2790 1350 +1 4 0 2 18 7 40 -1 -1 0.000 1 0.0000 2700 2025 90 90 2610 2025 2790 2025 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 1125 2025 90 90 1035 2025 1215 2025 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 3600 2025 90 90 3510 2025 3690 2025 +1 4 0 2 -1 7 40 -1 -1 0.000 1 0.0000 890 2965 90 90 800 2965 980 2965 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 2025 900 2115 900 2115 1800 2025 1800 2025 900 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 1980 1260 2160 1260 2160 1440 1980 1440 1980 1260 +2 1 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2160 1350 2610 1350 +2 1 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2700 1440 2700 1935 +2 1 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 1215 2025 2610 2025 +2 1 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2790 2025 3510 2025 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 5130 900 5220 900 5220 1800 5130 1800 5130 900 +2 2 0 2 12 7 40 -1 45 0.000 0 0 -1 0 0 5 + 5175 1305 5850 1305 5850 1395 5175 1395 5175 1305 +2 2 0 2 12 7 40 -1 45 0.000 0 0 -1 0 0 5 + 5805 1350 5895 1350 5895 2250 5805 2250 5805 1350 +2 2 0 2 12 7 40 -1 45 0.000 0 0 -1 0 0 5 + 4500 2205 5850 2205 5850 2295 4500 2295 4500 2205 +2 2 0 2 12 7 40 -1 45 0.000 0 0 -1 0 0 5 + 5850 630 6750 630 6750 720 5850 720 5850 630 +2 1 0 2 18 7 40 -1 45 0.000 0 0 -1 0 0 2 + 5850 765 5850 1260 +2 1 0 1 18 7 30 -1 -1 0.000 0 0 -1 1 0 2 + 3 0 1.00 60.00 120.00 + 6525 1125 5850 990 +2 1 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 3 + 675 2745 3375 2745 3375 3375 +2 2 3 1 0 7 30 -1 -1 8.000 0 0 -1 0 0 5 + 1575 450 3150 450 3150 2475 1575 2475 1575 450 +2 2 3 1 0 7 30 -1 -1 8.000 0 0 -1 0 0 5 + 4725 450 6300 450 6300 2475 4725 2475 4725 450 +2 4 0 1 18 7 30 -1 -1 0.000 0 0 7 0 0 5 + 6030 2430 6030 495 5670 495 5670 2430 6030 2430 +2 2 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 5 + 675 0 7200 0 7200 3375 675 3375 675 0 +4 1 12 40 -1 18 12 0.0000 4 135 210 2385 1305 L1\001 +4 1 12 40 -1 18 12 0.0000 4 135 210 6030 1845 L2\001 +4 0 18 30 -1 14 12 0.0000 4 135 315 6615 1170 gap\001 +4 0 0 30 -1 18 12 0.0000 4 180 930 2250 3285 G: "global"\001 +4 0 0 30 -1 18 12 0.0000 4 135 1095 1125 3015 AutoContact\001 +4 0 0 30 -1 18 12 0.0000 4 135 780 1125 3285 L: "local"\001 +4 1 12 40 -1 18 12 0.0000 4 135 255 6660 585 G2\001 +4 1 12 40 -1 18 12 0.0000 4 135 255 4590 2475 G1\001 +4 1 12 40 -1 18 12 0.0000 4 135 210 5445 1260 L1\001 +4 1 12 40 -1 18 12 0.0000 4 135 255 1350 2205 G1\001 +4 1 12 40 -1 18 12 0.0000 4 135 255 3375 2205 G2\001 +4 1 12 40 -1 18 12 0.0000 4 135 210 2835 1755 L2\001 +4 1 0 30 -1 14 12 0.0000 4 120 2205 2340 270 AutoContact Structure\001 +4 1 0 30 -1 14 12 0.0000 4 180 1680 5490 225 Physical Mapping\001 diff --git a/katabatic/doc/images/GCellConfiguration-1.pdf b/katabatic/doc/images/GCellConfiguration-1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..5eb69be9e6f000d4d6f820eed61370751e22e4f5 GIT binary patch literal 7042 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 K;j({jr~d-IWN^s< literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-10.fig b/katabatic/doc/images/GCellConfiguration-10.fig new file mode 100644 index 00000000..f799106a --- /dev/null +++ b/katabatic/doc/images/GCellConfiguration-10.fig @@ -0,0 +1,20 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 900 900 90 90 810 900 990 900 +2 2 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 5 + 0 225 2925 225 2925 1575 0 1575 0 225 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 2430 450 2520 450 2520 1350 2430 1350 2430 450 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 2385 810 2565 810 2565 990 2385 990 2385 810 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 2385 900 990 900 +4 1 0 40 -1 18 12 0.0000 4 180 1335 900 1170 _targetContact\001 +4 1 12 40 -1 18 12 0.0000 4 135 180 1575 855 Lt\001 diff --git a/katabatic/doc/images/GCellConfiguration-10.pdf b/katabatic/doc/images/GCellConfiguration-10.pdf new file mode 100644 index 0000000000000000000000000000000000000000..bb17b7334052f67774bb5ba9f1197bf581b18dbd GIT binary patch literal 2058 zcma)7eNYr-7zcsU1Pwk-N4xs?gh5YD_ahAJ1Sm(GscNYXJ zKN3{PU`h!a)D(4!#>pmgluT5L#E)bIZPcXHfysojX(}rRr}sUMj}x2e{gCvu0IpiFsnquJIQd&GGk5IZAzJ z&TE>qn+f0DX*Np3Dr{3Xjv_6OMwYf!5gAX?Mx< zwM~z&*-Wl7D0SUiFP%DG7yAnwNc>*Y(7ZV=@x+gddhV}X-{_uvH2UB-e_ZI^>WaF3 zwnopKshA!)p8m(v;8~lnxhnNo!TeBGTYU#uPWB&aTYs=)sr9Pc_G$ICIiDTjmYfX# z5ZG^AOy$0gaqii6^JI41b9<|%&Fvp3pbEP$v+Xl-yR2WeSM|jzJ5FuQo4IcyV0sSa z{JhZww2_55-8E0eRTuBdbv?;#_Z@Co^M1<59Y4I=caIkOC0<3Vzpwv(` zL<{(NDS&)QbSc12VAdRw4^V{?Tyj(@98L{nrtvE8kqU=O4DTM;$`Bks!kQo#*s=jM znF4|SLj?5C83>%mjWG6~YG@Tg0%9H<$*}|*9B3TbZ_qfSeKTY%hBBFk4MgWrA!%tK z3-)Mx#;uT>Q^y${8*H5+8E#+Y%%0FI?>VSmYm-BCtaF5HDUR~uOAPKi#BB_a`|nMm z9v$|7?z$pc8)L3}Msw@wTT@fl?l#Lw^;;6^TRu2o&Ri&J>sKFnOTE}mHUVQnA zZo-SjOPfA-UEQnc$cm}^=|t=G6TP>aCbdVmM}$myg-UqHAxCxI%qs#G8<`<^N(EJP z^0Up7$K_W9i5Cbmx1>PDg2(bg=N?iX?pENY{C*e=wtCT26TO81`jtnf74b6GyaJH; zA@JWXvIGTicd?NDn`HB;$Tgyfm6EJ;K&cXEfa*q9ne7;g`jt_XV#a4!>JOw_8A7M&`8>6iJaVf21b%YM>-K zqN~Iy$Qo;|4a_f+6jgD`qE7`ZWRfUdB62Vq@~S9#Ey(5?%N!j=v6O+LA*(aedbFM` zxgNeWY^yR^a1-cy7=jx906oLd3~+-XOm9TC#UJ1u!XTqV<184X^fcTe3v(*`0w-nt;2_!r9yphW-x literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-10.png b/katabatic/doc/images/GCellConfiguration-10.png new file mode 100644 index 0000000000000000000000000000000000000000..dd658a5e899e72bb22750a5b2c21f2c0ab18c15c GIT binary patch literal 1198 zcmeAS@N?(olHy`uVBq!ia0vp^yMQ>Hg9%95Y&-D_NO2Z;L>4nJ@c4o-0)pEZpkj!|Bzzj*&woHLD0VQuJgr21?@h&9}!57VMy4qL5G`_r>aHZ zpUqz08JvZU40zFj`^(K44z~!rYE3>bFDxG3Rbawg!a8+g^x@5$1jN^yYyy(gudT^A zQ?>Z*BVP{3{3?~D-P&HI0ZuV{0_Rrx#>8Blx70u8&LZXBxRND`&hApjzp%xMd5Nco zfDEXA;jvg;HdDeW=1$U`r;HC}5ADA5{%q?qgLh4FJ_!a#>UKK0-6@-Jx)647uVZu$j8rH_|fg_k}Y?4$Xql1DB8>4c*nn*sTs&! zba3{c>sx-E^{?2L-?2L`R|zTDiyD*}G4D@*!YeGHV0@OP?O|y2#zTJ=7e5O1%ehxF)%3BR z{L2%y=T2x(-^DlMorkz|_;i*`&)Q{M{2V^ccoe+v-t4Hd->b9sJv#R+cWsK^wf&p{ z;>~9#Dah_Dd4DbV+v%%cC;nWut*`3*Gt=&Mov#)wJGqbZg7Alu6QB2gzfraJX0XwH zmbST7>GA((?-5#ad3O5!BjE`zZoc?);wks{XcgzOQ`auP4xfM8ME0eMsq513W|uG5 zT>I5f6>4j}`sbRer^c7=eQLj5Vkb4#?aJTghw6;yrs!R-=Xm<4LAokJvV3P&JQFVdQ&MBd(llHlY;XO1LT{_5nKtbTZhD(3T?ZOoF zTT=WdxL-R{Q}ArR>;dmLP6^^ny9I8v9?)YcQ{2Ga7|St4g`{OqF|S^youY>v&Hx_@ B_Fe!0 literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-11.fig b/katabatic/doc/images/GCellConfiguration-11.fig new file mode 100644 index 00000000..7344480f --- /dev/null +++ b/katabatic/doc/images/GCellConfiguration-11.fig @@ -0,0 +1,24 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 900 1575 90 90 810 1575 990 1575 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 890 670 90 90 800 670 980 670 +2 2 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 5 + 0 225 2925 225 2925 2250 0 2250 0 225 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 2430 1125 2520 1125 2520 2025 2430 2025 2430 1125 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 2385 1485 2565 1485 2565 1665 2385 1665 2385 1485 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 2385 1575 990 1575 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 900 765 900 1485 +4 1 0 40 -1 18 12 0.0000 4 180 1335 900 495 _targetContact\001 +4 1 12 40 -1 18 12 0.0000 4 135 180 1710 1755 Lt\001 +4 1 12 40 -1 18 12 0.0000 4 135 180 1035 1170 Lt\001 diff --git a/katabatic/doc/images/GCellConfiguration-11.pdf b/katabatic/doc/images/GCellConfiguration-11.pdf new file mode 100644 index 0000000000000000000000000000000000000000..f93833b1840e1a4911f360576644ad538b68c4b4 GIT binary patch literal 2160 zcma)7dr(wW80V3r-Y~U*!OZcDy73b3J-h5H8N_`739&2~;VzRG_QGCW_rkpw7Ie}O zG%W{2L&Q)g3iB~#rIDh5A|j=u1rdUyV!>o&q^T4-Qs*wqW5s5=f9&4#o$v8G=llJ> zE7EIpAuv>eiO%0Hsludy08H9SEIb^KrEHnJ1;~)afa_>0Pq6^kSxKJKQ0a`Biip5C zo~6juSYBmy;u)Ja^xC+pzA-AYu_?QvX84$AwLFdt2-2l&6RlF) zu65Y&bWiEC4^ofwyOQ5+o_4rm`kid?kjH}knGbLJCisSKt@agpEyUW+)a5_Ot>xBD zdpxB2=Uz{)jg(UtF0T(>`&RS)c@2SAm9x_pdNjyOfAQQ|6ce~R?trXgwtZP)!uIlA z<&{lERWs*JPTFTJ^Ss;c8y!Ic_e6&D}p>N4qb7H<|@Apaj zzWJK6cJay2s^+VEm)|^9(iz%OwsZ+$siE=6 z#_9%+X|JfHMV~hI*^9eUqpmciG%qhWb)ed-xZl`(sA~QP{nd^6bC=o|^pw&U_iQeG zcKTJ{>xEq_EVsYryRWA`Jl_6e+_iapR3eXf2cUR3M8}|TI2?~?h^x^WW#oWBUjv3rPFRA=Fr860gbO%; zaR6URn>k>_1lR^F6`%|`LdtQWa5U5zsU~^S%4CkD7_IIsC3p27Lyh6_`Zxe1BAkwn zLpU{NkYhreVGOb3R3p0(Vo<hZ{CPeghsO`G(sZqXT88-sh?J1a~?ulAscHWirMcC7ZY376>FcqsJI3GTm(LK!;j z|E!wr6Xd5Vn;mfL#apu?-~Ld=hL-Q}FR%aPh$<$54k}-Fd_$>wdHv*FJeKu3(bH<* zBI^-v?rpWV*>iI}Sx>9=ew`0rAigxHtUi%{F7jM%u4!*5w(`AaN=$za{IIN3JoVMp zDFkzR>E6DBGg^FFCb{`8C;Xps$Z?%lksKwE4UeX*xfD;QlOZa` zYIZOJ7d9|FF(-`|7%$KZoqL3NLbseZ4Px+@UbQ6!G!Svt=s;6gGIep4NG71GwQv;agFn&o&QAt3Nr()kMUWZKMII3tF# zBQ1?bD;Y!UfHNNM2vA(Ofzd@WZChgF=+U)?&d8vUmXUak7=aTwOdZQ9Xw{h#9nqYV zPO$;nL_LVIFdWaNvvd{@6i^yUhy#&=(T9Ym8Jh;lJV5h`m>?8{oRC0;SSgXC{W!+_ z^sP}@<*`%-hOS475u*=~Nu?4g$N(cYxf01%cz|uh24!M2&s=SUT!Q-ZgiWfL5K9mc zO`IqFWD{c*VW@4ceo!Jq9C5V~O6i0ekdPrVxcWh{a$>APfo|N@k5CH3#?=O;VdHE( zOVU<~Mc;dXC(>)sh?N4|z%XbQqV^d89%IX3fY3@r%NPwX27F^;gZZiVf*18K?tT8} e(y4BNPcfwmgOuY*mUpxT$|Z74B+|y~uzvv`Mcq#T literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-11.png b/katabatic/doc/images/GCellConfiguration-11.png new file mode 100644 index 0000000000000000000000000000000000000000..0aa990d6851857e0a3c8fd2272b1911fc22716a5 GIT binary patch literal 1496 zcmeAS@N?(olHy`uVBq!ia0vp^yMVZng9%9fxM+R?NO2Z;L>4nJ@c4o-fTv*j)NCz+S&t=Pn~poquA`QQ7bZ1c$y$?`GCg8qENpDp;ouOXpr9upAkOhG{LZwmVRH9{C(B`em8TU z(wluT78So=JTSbv%Dd#xC9e&(o7QE2d1AtNv3QYx<&Tv!r{-w=?o;1gzC}<+bhUTX z#?4a`tcz~@_s138V`)i$XI@%z#k)*DdRInskm+x|iIe=Fm!0@tZ}<4cUXPQVYK4}W z<>#i#ugY&Kt^R&t!|LdwH{ad!{y(VfU*eTq_~p}=yBjluVz;eZ@#}I<)u#1a{vPI` zlNP>NeW_RZ>P~<68hb)|={DRy5q-F=x7f(B;^py2R940kc9~!JW#lC z`_jo}oB0<_Ykb`F+*efml~;D~(bk!J)&kjEp4D0^O!-~sddd4ps#c)IDt&vqnwT9) zZ#}w~zGCk?ebFlA{QFMl-n?vw@N%cOdVaDyb}796bT0A!f?YmKzpgFqIGr;~Z-PV2 zvP)HlypN35it!2;&J@|V~Tb*I znJDPxGWX7h>0RvC&t&v0JIcZqlg!FCC5e>{7y^rd-h04NIP;pmU%~;~7>lN$H3u5N z7!--0^)!xFir+cnAhlG&!}+j-l=wH-R%zzPXP7rDW%fXG2rM4aGEN6~gV{fZkWFW# z{_gBc0p?@|Pgg&ebxsLQowP3t7=xi@!KH(|2NVPjY`FBd+%8N(za_j6EMGQ|ztjj*n1ZLk0U literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-12.fig b/katabatic/doc/images/GCellConfiguration-12.fig new file mode 100644 index 00000000..855304c2 --- /dev/null +++ b/katabatic/doc/images/GCellConfiguration-12.fig @@ -0,0 +1,31 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +6 180 405 4410 1485 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 1890 1350 90 90 1800 1350 1980 1350 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 1890 675 90 90 1800 675 1980 675 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 3375 1260 3555 1260 3555 1440 3375 1440 3375 1260 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 3375 1350 1980 1350 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 1890 765 1890 1260 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 1035 585 1215 585 1215 765 1035 765 1035 585 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 1800 675 1260 675 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 225 720 225 630 1125 630 1125 720 225 720 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 3465 1395 3465 1305 4365 1305 4365 1395 3465 1395 +4 1 0 40 -1 18 12 0.0000 4 180 285 720 540 rp1\001 +4 1 0 40 -1 18 12 0.0000 4 180 285 3915 1215 rp2\001 +-6 +2 2 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 5 + 0 225 4725 225 4725 1800 0 1800 0 225 diff --git a/katabatic/doc/images/GCellConfiguration-12.pdf b/katabatic/doc/images/GCellConfiguration-12.pdf new file mode 100644 index 0000000000000000000000000000000000000000..38fefd9eab55a18c1041cdd8fd1ef7e14f4f459f GIT binary patch literal 2887 zcmdT`YfKbZ6b2EkgH+UFXz_7VAtDB5W?#$-Zg5#%0)h)tWS81ycNPYhU6>snicz7( z09qeG1S=R7Z3Qc!X{t~~v1%n&NR?DTPg1ks?KIZxK&e@Ye? ze_5e&i}lY5x!1X}70=w&G&{G}uzXT+&f0?y9(=#Rx5&Q4*==6XT*7hlxdOK|Zc*Np z8ftra<;z~l$xnlWqi$S{eD%wdC|j+j|AH!SQcggte{=iY-x4Y{wN7&oB=f3K` ze*8$^z1QD8Uhv|=?H9+ge6Kte9Dn+-HM{m+{V9c#f4#+dBRS`fdg*ekOjftW%On58 z^2P>V_1PFdtd3x7JhOs#>jZ6Xnuwypn(XcSPHx%Jf3(5T<;1!fd!{-5wXC=F)~jW` z4)vlhv=I@PJ6l3m7j?GgMoY)l6#6|&&uX*Ng5JE2AD!xCm7(sfU70U$7Rb_FotVY_ z&o^{Dt9^KJYFXXb6?NNZ?Trs;wu#e)^}iP+n@v4xb)edr8(x72CX^Ijsdftvmuxz6 zCa$wKx1qiAYvJz0GhMlyg>iS}m7(Eb3Dq0#yuKK};`UnKtL~4>S05~>!opoE?AA{| zH-Fascd8RVs}oA}2zL|UzyIzkaD(Fa$hEk{L;9I zP2XPIC?#TlUer<9TG+RQTCgNFM*(M%j@E0;Fo16eItVc6Ur2~Cvq>FW& zY@i_EFrOd*NstK`9As%d2lxng7%r!ch749s8zCa2Sc5v6<`g)@EWl&vY!12yW^=*O z97H7`5qM!pkO791Cfs5Wq<8@Qh8c}uU>usvWuYkszz(y)x`3%LBf!HLjS(m?RJI&T z05C%aN{O2~b7X*uQ|SyzgDD28ANKdL^dGJo!y}_204b3SCLX~+xetco`BTco!R}v#pZ6jlN!*dVNcqEGlX)d57k|8?tV+fmo01!@gdv=dW zXY2jPh?VQ3F4=@=)AHwar#Eezwx8XfZqM4Eek`%#ZzwMmP zo-Wc7SC9S=`rr3ow@1o)mln?{ZTzZM8oGq>EM0RfZ>w!-qx_JdX zm$EKrWoFv3b~@dY6V6;NujRRTfBnj{{%12YmAkyLlnrAyD<3^=TiU^!uqbs|RfDE; zpGRxBOUbXNPTxG$bGypvyz_Z`n`!aH9P34j-=?iX;;olx+p$AQ^aNHZ8D*~0rZ{z? z-g-_FQN_If|Gby~^Tr}no7ZSk3&dy0b3HtC7=02TO`O03l2t4c1S5dTKtk<+QIPxu zK>H$xR5j^9go4a!9;TP5cp*w4%1TP+Y1q(t}mQT>6E2BQx|ZW3*Zt3LR871xDZmP9}`VIYKZ| z7SsVegw|!!9HUlwNew!UsSMLnEGvVQ8q%myB4zd-ECG-M@-e!RX5oeHLc;N1c5?K_ z4_5jwIypl7AXqdRYMS*3jE(}q$p#~5RI^MP2PjhLP4MQzg96@WIL4rt!PCS;HlIfj z6yZbgNs1@tQ*b=Opn3Dqka}mcv=)P%6Jx~C14Ke0UkJ2d&_?lKi_ru0gEk(|2X2<7 zjqnjc7>u%skhG4n5$NC>WfO|6V=3!7ND*a~kL2^=Mp)(}1wyNQJOZ6GmVSiTdR~$w zASEsRNU`7zu?TRMeuP+HWg{seq@1N6kEBM}I9A2zXck^#0Uph)f;R&(z~u%5Ji-y8 z0UoN?8o&U$@lY91csx0ht5hcLEI+FBxVkPkb>FU;bKhi3KsNv*r(!wNM)UX-4|8`9 Ij10p52GHBpo&W#< literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-12.png b/katabatic/doc/images/GCellConfiguration-12.png new file mode 100644 index 0000000000000000000000000000000000000000..effeae92c76486e50ce6edc9ad67860b40094929 GIT binary patch literal 1374 zcmeAS@N?(olHy`uVBq!ia0y~yVAKY(Q#qJ`U+;i&`7XLGs_`74qy7kNtzkqcv(Yxlf{Cb_;hVx5VxMIw% zt?}!MX^hlRX-!|ao2TUI>xI%1UzN>P-0L%_U?^GL{rbTC-M^3jO<4L{>i@;t4_{7L zI$7k#!cU=T8+&EDCR`N0-ncaUY_j#6p1&b~S4?D_X=l4#C|G>f?fZK^fBFz-E4}-s z+zXczFWj>iZeN)8P5l0yiWle1ZClvSSN*lxFy&JPPy0KY8oP<}54Nw{6Or)QDZARC z`t!N$dz-ly70Z1&rL$%7$>+z;eTcRRe^4@WMEuWH4$^K;S74*xVA|I@-x#9Ly{`bv^w19vM zu*4C>aAB*%+d~dKUKXEu^KkhqN#>msK1R>WfBW?V>*iw)eyPf<`=? zH!ptWy~Gx-Cq>5!H?=FovKQ&bJ~h{vko`(!|3RH8#k22L&#*1ZexcyXTBNmk(YE?G zpwO3Owp`BFzI)j>=0!J8f7+Ne?~BRT6Uop0YL0nn9y`FSD=!_fuPdGNT+aO7y!kvk z#jiKIXHE;VfAvlI*-j}|xkv9D)DM|H-Tic0-J4HUq7n&WyVm;YY+sXG^Z8u$-iYgs zhHVFTdubj{uU=ZPbK{!*AAjwbTkqFs=yoXa^Ztd;Ox92N_Nq4JdF+hVON-O^Z%^D) z`FyX2!GS-;(LevaJA3og@mpOdl%>n>RO)lt9Jw3Kw`@W7G;f8|r4#)?)>TYNYk7CV zI9c_X!}=EWZ^cYbem^3go1BLYvY@SsFZ#5jc+cdV*U{xVzcvXfl}FvBr;y85}S zb4qCHq&7p{T3eO=jA3Fp`+@5+9IEV2CmREb6sC+a Tf#DFP@P+yK%V0qpYx2*{$>DuyNemZ@((<^)h z@sem;#4A;Gb9>|Gt$ah_yS`+8vbRnrdm~76l|4_a*dZlOj()BxU9x7(D(hpo+h$c&t_tF@hYlvS5no! zj@$>=cU&sB&A;N{7(kUbO1wACJWwX-yEJirrozAOLcrutT--`J9G>f(p7|yG#W9;Q zcRp8c-`5*C){!6oTB6gO2_fS-&u6Ux33lHkw6Dpz^JZxEcT-%~op`(b6g4UIhI90V zgo~G+S7+^so-{qaGr5~!B)13QkJMI-awbfMH=B}wcoO(U_@#aFNCAsH7+Ol%BKvCV9 zRy@Z&Rgnu zBEJi>!tWdWiq4;VZq=0-KAF)fO)Nl9m^qj)_*Y1Y36sfdh*VLT$qX5xh-b)fM#(Cq zx(pCQp=Ah#fQG_Y0xfckmIne%JA#xkdR;0P$LJ9uBRE}LB*Vv$h_Zl;VlsH-9+1HY zMe>N003jGd0(B@H8fi-)j*@=pKSI=l{&i$BrG>ZX=Q=_|c>!Z$dO(JQzN6zQkn6&hXq07QTGL;l|8{zF+4=Lf=|!QC(> zg*)auMk3FOXtN4dC2xGokW#$#aX}n8Lo*r1>jI+O~NtSmQaL_{i1u? zyHAxCI=OaF@1ExSeu9 zwWVK9PfN4mY&4q3r|kK4bn9=DvSXQzzKv;V^1Yr!!q%~Q@`t@wmbB9o7A7sPIIg@| z>UuG3YT?hP8-6(5b*JLhX8Y!GRt_tu*_MZtyhvGv)C(Wcx_!5t>I$fkv+{LvtAZq3 zt>vB&w~Fch|M@Qe=Y_?rHl5L^7Py~LpKH;~VYTr98he8DQ!6+u2zr2&0Rm%XkX}## z--`^jDv9I56+Fjg#Nd`d8iT)Mjdm##o_^f{5LsAG&tpJ9kzoqcBP5rxN?xsxArLwe zn#j~uJQgpUlVDg&TC}z)QBtbVGXq&8EbRiVo*n$}&#F`m5;~-8F$6_YB#a$~IZQAy z3O)%L%xKaWo{dv@NOc;eF%9EU%riqRHK69*CjPlcL?wpg=D(Jgd|CqiN#mKbNK` zG38AOpqQ2jBxpTcryPB0P`xuaMn#~?NeF8214KfhKnPS|z$T_qR`>(712&rWM$|O7 zQQjhS6(ejSd?_Pr6drsdY(j};tk`l7C=y%XL4g2K+8hsh2`%tw3iq73A0@He7eWeM zthpbQc#RT^CzrV&CGoPbL9r0cc5^=(iig>FPQhvz4!y$yGLl`5-V7vwl<9P6gkwen zGDNG=0Za`f7$N>3##JbHJFz0{a+%@VXy>y@p_&D5qnKjx{MYjejyGO2Ef7P(#U)@- GAn`Z7X51zK literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-13.png b/katabatic/doc/images/GCellConfiguration-13.png new file mode 100644 index 0000000000000000000000000000000000000000..3db5d3d1b7daf3e41bd107a79e4b605a78b0a6c2 GIT binary patch literal 1809 zcmeAS@N?(olHy`uVBq!ia0vp^#Xx+Gg9%9He$aXYq&N#aB7uTDz97ta>D*dBprCw- zYeY$Kep*R+Vo@rCYjA*qdq#e7NpW&fWK~osl z&)u1~me)Es;^^B|ThCv$Tf9%=StM7mcq`Zej%Q0xCT!-5mvuLQ1=V4<4czng+qKP_ zk~RNrP_TjZ9%X?J^w7i-zyySN;<_t#U;F$-v~#!Yi70-{Pp>Zgs0!UJUi_@+{Ow%X zcb6)4lsoLp=RZH_%)E2^)Z%UX?!Q=J_q*cY_fH!yXdjZ_W9)b1mm<({+Uq~qJ=ydA zr{A6liMqEZ_y4U-yC`n<@T>at6Pq=sFXl0}PQ3cWSS@|Vu5Hq?vw3f&?_PW7^1aUX zms%g^KDnv8Svquog!W%9ul0#67cr9wsxKBD`txS8yv!WSWb2C9aHacE*8h{GcQZm0 zSC^9VjZ+VK**8t{*W6tA*zn^szNxz%-`N_Un&rD+)YEsf@tVIYucap!@8168ZpWMC z-^I`7n6F6KR{XnY)2rIJnav!=DlM}r%i0RpM4eq`-soq#dE#9btE*@H7MXf|yLs;P+{EAg z`tqx?OmF{Oc%dE8d{Bd_~ z797lbprhneCHx}9So*S0d8n~<=d~5-W!>}dDlIX;vnfq^xA7I9*okXRUtN8p618~V z%^A)hUw{?KY0Wl0uQVfFFwKL*^z$2@#}Qj+`Q|gt%>wG;ELjEd@b05mS|{8qI6bTP z&A9;G(p+!T?K$2v=cfPYx^-7U9G;(1Bg$#>r@TL`3%-iGH0AN{29`Jsp00i_>zopr zI%!{KF+PEoSr-^N859H#IBczdZhlnYiQd5*^Jcm}*u(c@+Gf#o?Q>ys)>=dtZhMq- Y^k&znzz_?Mn3BmXE3+R}Ek#aT0A0dZH2?qr literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-14.fig b/katabatic/doc/images/GCellConfiguration-14.fig new file mode 100644 index 00000000..348653bc --- /dev/null +++ b/katabatic/doc/images/GCellConfiguration-14.fig @@ -0,0 +1,76 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +6 5220 2745 5400 2880 +4 1 18 30 -1 18 12 0.0000 4 135 150 5310 2880 G\001 +-6 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 3825 1575 90 90 3735 1575 3915 1575 +1 4 0 2 0 7 40 -1 -1 6.000 1 0.0000 1575 1800 90 90 1485 1800 1665 1800 +1 4 0 2 0 7 40 -1 -1 6.000 1 0.0000 2700 2250 90 90 2610 2250 2790 2250 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 1575 675 90 90 1485 675 1665 675 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 2700 1125 90 90 2610 1125 2790 1125 +1 4 0 2 0 7 40 -1 -1 6.000 1 0.0000 2700 1800 90 90 2610 1800 2790 1800 +1 4 0 2 0 7 40 -1 -1 6.000 1 0.0000 3825 2700 90 90 3735 2700 3915 2700 +1 4 0 2 0 7 40 -1 -1 6.000 1 0.0000 3825 2250 90 90 3735 2250 3915 2250 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 1575 1350 90 90 1485 1350 1665 1350 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 3825 1665 3825 2160 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 4185 1575 3915 1575 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 4185 1485 4365 1485 4365 1665 4185 1665 4185 1485 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 4230 1125 4320 1125 4320 2025 4230 2025 4230 1125 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 3735 2250 2790 2250 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 2700 2160 2700 1890 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 2610 1800 1665 1800 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 1575 1710 1575 1440 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 1980 225 2070 225 2070 1125 1980 1125 1980 225 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 1935 585 2115 585 2115 765 1935 765 1935 585 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 1935 675 1665 675 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 1575 765 1575 1260 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 3105 675 3195 675 3195 1575 3105 1575 3105 675 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 3060 1035 3240 1035 3240 1215 3060 1215 3060 1035 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 3060 1125 2790 1125 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 2700 1215 2700 1710 +2 2 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 5 + 0 0 5175 0 5175 3600 0 3600 0 0 +2 1 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 3 + 0 3150 2700 3150 2700 3600 +2 1 1 2 18 7 30 -1 -1 6.000 0 0 -1 0 0 2 + 1485 1350 -225 1350 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 3825 2610 3825 2340 +2 1 0 2 0 7 38 -1 -1 0.000 0 0 -1 0 0 2 + 1575 1440 1575 1440 +2 1 0 2 0 7 38 -1 -1 0.000 0 0 -1 0 0 2 + 2700 1710 2700 1890 +2 1 0 2 0 7 38 -1 -1 0.000 0 0 -1 0 0 2 + 3825 2160 3825 2385 +2 1 1 2 18 7 30 -1 -1 6.000 0 0 -1 0 0 2 + 5400 2700 3915 2700 +4 0 0 30 -1 18 12 0.0000 4 135 615 45 3555 Global:\001 +4 0 0 30 -1 18 12 0.0000 4 180 1230 45 3330 Configuration:\001 +4 0 0 30 -1 18 12 0.0000 4 135 945 1575 3555 East+West\001 +4 0 0 30 -1 18 12 0.0000 4 135 645 1575 3330 2-3-0-0\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 -135 1530 G\001 +4 1 0 40 -1 18 12 0.0000 4 180 1665 3825 3015 _northEastContact\001 +4 2 0 40 -1 18 12 0.0000 4 180 1725 1485 1215 _southWestContact\001 diff --git a/katabatic/doc/images/GCellConfiguration-14.pdf b/katabatic/doc/images/GCellConfiguration-14.pdf new file mode 100644 index 0000000000000000000000000000000000000000..14ac6032db067ed440db226a514eea337f785244 GIT binary patch literal 4434 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 JtKTet=uaAND#8E& literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-14.png b/katabatic/doc/images/GCellConfiguration-14.png new file mode 100644 index 0000000000000000000000000000000000000000..6419620f82d0a9b52cd15ebf3aa2ebd768590d3a GIT binary patch literal 4002 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 YQcUb9N}M1ChRD$Aa*&vqtJi`504F%@cK`qY literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-15.png b/katabatic/doc/images/GCellConfiguration-15.png new file mode 100644 index 0000000000000000000000000000000000000000..586b696b1cdc186eb4b62f181b89c71dda6963bd GIT binary patch literal 1378 zcmeAS@N?(olHy`uVBq!ia0vp^yMVZng9%9fxM+R?NO2Z;L>4nJ@c4o-OXU?thILy zuh#As{QOqw;U};EF)E)F`d$f5;BL&bUVJzC|C?FQ9&GNL{LyY_PXFuj`sk3b-+8O; zwt2t1J>%gw^_LH10`6aSUM>DH;DPVg)keESF2Aeym1lpL^XO8c@OSaxckMy7VGDOe z?KG&iuIPz>T=u?l>%aDw*Z#dZqo}bcOz)YV_tj^5&2t4O?k={RaYiaCj4w@nFW=r0 ziP*C4i>I`2Ct00)yGz!)ROrDTC3QwCnPrcUTgmn{lTAf>`nOx1P(i_eCwBpM@pqG&2&r6wn;N%tRnWlTVIi-Z#69~{mQ{D z-)DXomydb=p9688w2>|*aL;wH) literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-16.fig b/katabatic/doc/images/GCellConfiguration-16.fig new file mode 100644 index 00000000..f1d7de0d --- /dev/null +++ b/katabatic/doc/images/GCellConfiguration-16.fig @@ -0,0 +1,22 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 665 670 90 90 575 670 755 670 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 2250 1575 90 90 2160 1575 2340 1575 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 675 1575 90 90 585 1575 765 1575 +2 2 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 5 + 0 0 2925 0 2925 2025 0 2025 0 0 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 2160 1575 765 1575 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 675 765 675 1485 +4 1 0 40 -1 18 12 0.0000 4 180 540 675 495 target\001 +4 1 0 40 -1 18 12 0.0000 4 105 600 2250 1845 source\001 +4 1 12 40 -1 18 12 0.0000 4 135 105 1575 1530 L\001 +4 1 12 40 -1 18 12 0.0000 4 135 105 765 1170 L\001 diff --git a/katabatic/doc/images/GCellConfiguration-16.pdf b/katabatic/doc/images/GCellConfiguration-16.pdf new file mode 100644 index 00000000..aaf748a2 --- /dev/null +++ b/katabatic/doc/images/GCellConfiguration-16.pdf @@ -0,0 +1,72 @@ +%PDF-1.3 +%Çì¢ +5 0 obj +<> +stream +xœ•TÍrÔ0 ¾û)t,‡ +Ë–lùÚ†K/-y&, ;nËðú(k[)ˉÉ!Ñéûqì^ß-?B+˜‹™¹UÁ˜-Ãò%ܼ<ý:¯‡íõ‡%<ü³%ÿªÿ׎ +‹Û Iøbç~“º¸}@[ÔRK¹8¹wŒ5Ù¦³¯‡BE£¢¤œ Pªv&Î[·‡ð%†Ûúendstream +endobj +6 0 obj +455 +endobj +4 0 obj +<> +/Contents 5 0 R +>> +endobj +3 0 obj +<< /Type /Pages /Kids [ +4 0 R +] /Count 1 +>> +endobj +1 0 obj +<> +endobj +7 0 obj +<>endobj +9 0 obj +<> +endobj +10 0 obj +<> +endobj +8 0 obj +<> +endobj +2 0 obj +<>endobj +xref +0 11 +0000000000 65535 f +0000000768 00000 n +0000000985 00000 n +0000000709 00000 n +0000000559 00000 n +0000000015 00000 n +0000000540 00000 n +0000000816 00000 n +0000000916 00000 n +0000000857 00000 n +0000000886 00000 n +trailer +<< /Size 11 /Root 1 0 R /Info 2 0 R +/ID [(á]01¡”ÏÝ9­r.)(á]01¡”ÏÝ9­r.)] +>> +startxref +1096 +%%EOF diff --git a/katabatic/doc/images/GCellConfiguration-16.png b/katabatic/doc/images/GCellConfiguration-16.png new file mode 100644 index 0000000000000000000000000000000000000000..dfbe7bb82c2666603625791d0ac4b1ba95700674 GIT binary patch literal 1393 zcmeAS@N?(olHy`uVBq!ia0vp^yMVZng9%9fxM+R?NO2Z;L>4nJ@c4o--OTEcRCjDVtL}U;P$zU?>Fp^em$959drNoqUaYJjBowr$@tZBLU8A!b?1&gZ`~f2 zy(+swb6uF8h`Kn_)*{2rV0L+_p1<1WwrRhtdh~W5&3G#I>rKzIeAlhlZY|Dys<-QG z?6Lc7$N#-Q95S7_V7hW@sclrXh3?vQQ9A?XAcyRi|L!ZJPk+DkczW;zu9Z`}ExI-v zD=COG6)EB+D!YxN)DUWH_pi40ms`%gZ$)*A>FIYn7Fzv%^CM3F?M0EzMOzkb<6eJJ zar$DNW9v6o7{;EHeVgZPu$xqi!Af zc=_b#>!H(Y%a6wJ*gIdn-t$<`b?=<>WjEKx|FgdIH|^`6-E#YtYh!vkKLj1*y_%c8 z<*q=~&0D(59=E+JxbyUU?R3j+u`v^QuSUI|$^HG(Lj&3EYEWN^+OzzS_sKU>yByv7 zbW-NSPrWC;efnf|`ss#=d&_? z=BOI)EZIRDPOnT`c?*RpY z0~;>=Ew>9(&~HicpWuG&OijVF{jvwV-#8_RGwl|*(Rx6SrA%=HcVjHas1UA@ILP*| Op85ZS%^W$%aR~sCR$kcv literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-17.fig b/katabatic/doc/images/GCellConfiguration-17.fig new file mode 100644 index 00000000..b6d79a4d --- /dev/null +++ b/katabatic/doc/images/GCellConfiguration-17.fig @@ -0,0 +1,458 @@ +#FIG 3.2 +Portrait +Center +Metric +A4 +55.00 +Single +-2 +1200 2 +6 -270 22230 5490 26370 +6 4140 23355 4410 24345 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 4185 23760 4365 23760 4365 23940 4185 23940 4185 23760 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 4230 23400 4320 23400 4320 24300 4230 24300 4230 23400 +-6 +1 4 0 2 -1 7 40 -1 -1 0.000 1 0.0000 2925 24525 90 90 2835 24525 3015 24525 +2 2 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 5 + 0 22500 5175 22500 5175 26100 0 26100 0 22500 +2 1 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 3 + 0 25650 4050 25650 4050 26100 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 2250 25155 3825 25155 3825 25245 2250 25245 2250 25155 +2 2 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 2835 25110 3015 25110 3015 25290 2835 25290 2835 25110 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2925 25110 2925 24615 +2 1 0 2 -1 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 2115 23850 3510 23850 +2 1 0 2 12 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 4185 23850 3690 23850 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 3600 24615 3600 26325 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 2025 22275 2025 23085 +2 1 0 2 -1 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 3015 24525 3510 24525 +2 4 0 2 0 7 38 -1 -1 0.000 0 0 6 0 0 5 + 3690 24615 3510 24615 3510 23760 3690 23760 3690 24615 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 5400 23175 2115 23175 +2 4 0 2 0 7 38 -1 -1 0.000 0 0 6 0 0 5 + 2115 23940 1935 23940 1935 23085 2115 23085 2115 23940 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 3510 24300 -225 24300 +2 1 0 2 0 7 38 -1 -1 0.000 0 0 -1 0 0 2 + 3510 24210 3690 24210 +4 0 0 30 -1 18 12 0.0000 4 135 615 45 26055 Global:\001 +4 0 0 30 -1 18 12 0.0000 4 180 1230 45 25830 Configuration:\001 +4 0 0 30 -1 18 12 0.0000 4 135 645 1575 25830 4-1-1-0\001 +4 0 0 30 -1 18 12 0.0000 4 135 2175 1575 26055 North+South+East+West\001 +4 1 12 40 -1 18 12 0.0000 4 135 180 3915 23805 Lt\001 +4 1 0 40 -1 18 12 0.0000 4 135 180 3060 24930 Lt\001 +4 2 0 40 -1 18 12 0.0000 4 180 1665 1890 23715 _northEastContact\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 1890 22410 G\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 3510 26325 G\001 +4 0 0 40 -1 18 12 0.0000 4 180 1725 3735 24660 _southWestContact\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 5355 23130 G\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 -135 24525 G\001 +-6 +6 -270 17730 5445 21600 +6 4140 18405 4410 19395 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 4185 18810 4365 18810 4365 18990 4185 18990 4185 18810 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 4230 18450 4320 18450 4320 19350 4230 19350 4230 18450 +-6 +1 4 0 2 -1 7 40 -1 -1 0.000 1 0.0000 2925 19575 90 90 2835 19575 3015 19575 +1 4 0 2 -1 7 40 -1 -1 0.000 1 0.0000 3600 20700 90 90 3510 20700 3690 20700 +2 2 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 5 + 0 18000 5175 18000 5175 21600 0 21600 0 18000 +2 1 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 3 + 0 21150 3375 21150 3375 21600 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 3600 17775 3600 18810 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 2250 20205 3825 20205 3825 20295 2250 20295 2250 20205 +2 2 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 2835 20160 3015 20160 3015 20340 2835 20340 2835 20160 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2925 20160 2925 19665 +2 1 0 2 12 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 4185 18900 3690 18900 +2 1 0 2 -1 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 3015 19575 3510 19575 +2 4 0 2 0 7 38 -1 -1 0.000 0 0 6 0 0 5 + 3690 19665 3510 19665 3510 18810 3690 18810 3690 19665 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 5400 19575 3690 19575 +2 1 0 2 -1 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 3600 19665 3600 20610 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + -225 20700 3510 20700 +2 1 0 2 0 7 38 -1 -1 0.000 0 0 -1 0 0 2 + 3510 19260 3690 19260 +4 0 0 30 -1 18 12 0.0000 4 135 615 45 21555 Global:\001 +4 0 0 30 -1 18 12 0.0000 4 180 1230 45 21330 Configuration:\001 +4 0 0 30 -1 18 12 0.0000 4 135 645 1575 21330 3-1-1-0\001 +4 0 0 30 -1 18 12 0.0000 4 135 1545 1575 21555 North+East+West\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 3510 17910 G\001 +4 1 12 40 -1 18 12 0.0000 4 135 180 3915 18855 Lt\001 +4 1 0 40 -1 18 12 0.0000 4 135 180 3060 19980 Lt\001 +4 0 0 40 -1 18 12 0.0000 4 180 1665 3780 19800 _northEastContact\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 5310 19530 G\001 +4 2 0 40 -1 18 12 0.0000 4 180 1725 3420 20610 _southWestContact\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 -180 20655 G\001 +-6 +6 5805 18000 11565 21870 +6 10215 18855 10485 19845 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 10260 19260 10440 19260 10440 19440 10260 19440 10260 19260 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 10305 18900 10395 18900 10395 19800 10305 19800 10305 18900 +-6 +1 4 0 2 -1 7 40 -1 -1 0.000 1 0.0000 9000 20025 90 90 8910 20025 9090 20025 +2 2 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 5 + 6075 18000 11250 18000 11250 21600 6075 21600 6075 18000 +2 1 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 3 + 6075 21150 9450 21150 9450 21600 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 8325 20655 9900 20655 9900 20745 8325 20745 8325 20655 +2 2 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 8910 20610 9090 20610 9090 20790 8910 20790 8910 20610 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 9000 20610 9000 20115 +2 1 0 2 12 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 10260 19350 9765 19350 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 9675 20115 9675 21825 +2 1 0 2 -1 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 9090 20025 9585 20025 +2 4 0 2 0 7 38 -1 -1 0.000 0 0 6 0 0 5 + 9765 20115 9585 20115 9585 19260 9765 19260 9765 20115 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 9585 19800 5850 19800 +2 4 0 2 0 7 38 -1 -1 0.000 0 0 6 0 0 5 + 9765 18540 9585 18540 9585 18360 9765 18360 9765 18540 +2 1 0 2 -1 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 9675 18540 9675 19260 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 11475 18450 9765 18450 +2 1 0 2 0 7 38 -1 -1 0.000 0 0 -1 0 0 2 + 9585 19710 9765 19710 +4 0 0 30 -1 18 12 0.0000 4 135 615 6120 21555 Global:\001 +4 0 0 30 -1 18 12 0.0000 4 180 1230 6120 21330 Configuration:\001 +4 0 0 30 -1 18 12 0.0000 4 135 645 7650 21330 3-1-1-0\001 +4 0 0 30 -1 18 12 0.0000 4 135 1575 7650 21555 South+East+West\001 +4 1 12 40 -1 18 12 0.0000 4 135 180 9990 19305 Lt\001 +4 1 0 40 -1 18 12 0.0000 4 135 180 9135 20430 Lt\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 9585 21825 G\001 +4 0 0 40 -1 18 12 0.0000 4 180 1725 9810 20160 _southWestContact\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 5940 19710 G\001 +4 2 0 40 -1 18 12 0.0000 4 180 1665 9495 18495 _northEastContact\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 11385 18360 G\001 +-6 +6 -270 13230 5490 17370 +6 4140 14355 4410 15345 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 4185 14760 4365 14760 4365 14940 4185 14940 4185 14760 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 4230 14400 4320 14400 4320 15300 4230 15300 4230 14400 +-6 +1 4 0 2 -1 7 40 -1 -1 0.000 1 0.0000 2025 14850 90 90 1935 14850 2115 14850 +1 4 0 2 -1 7 40 -1 -1 0.000 1 0.0000 2925 15525 90 90 2835 15525 3015 15525 +2 2 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 5 + 0 13500 5175 13500 5175 17100 0 17100 0 13500 +2 1 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 3 + 0 16650 3375 16650 3375 17100 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 2250 16155 3825 16155 3825 16245 2250 16245 2250 16155 +2 2 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 2835 16110 3015 16110 3015 16290 2835 16290 2835 16110 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2925 16110 2925 15615 +2 1 0 2 -1 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 2115 14850 3510 14850 +2 1 0 2 12 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 4185 14850 3690 14850 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 3600 15615 3600 17325 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 2025 13275 2025 14760 +2 1 0 2 -1 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 3015 15525 3510 15525 +2 4 0 2 0 7 38 -1 -1 0.000 0 0 6 0 0 5 + 3690 15615 3510 15615 3510 14760 3690 14760 3690 15615 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 3510 15300 -225 15300 +2 1 0 2 0 7 38 -1 -1 0.000 0 0 -1 0 0 2 + 3510 15255 3690 15255 +4 0 0 30 -1 18 12 0.0000 4 135 615 45 17055 Global:\001 +4 0 0 30 -1 18 12 0.0000 4 180 1230 45 16830 Configuration:\001 +4 0 0 30 -1 18 12 0.0000 4 135 645 1575 16830 3-1-1-0\001 +4 0 0 30 -1 18 12 0.0000 4 135 1665 1575 17055 North+South+West\001 +4 1 12 40 -1 18 12 0.0000 4 135 180 3915 14805 Lt\001 +4 1 0 40 -1 18 12 0.0000 4 135 180 3060 15930 Lt\001 +4 2 0 40 -1 18 12 0.0000 4 180 1665 1890 14715 _northEastContact\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 1890 13410 G\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 3510 17325 G\001 +4 0 0 40 -1 18 12 0.0000 4 180 1725 3735 15660 _southWestContact\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 -180 15255 G\001 +-6 +6 6075 13230 11565 17370 +6 10215 14355 10485 15345 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 10260 14760 10440 14760 10440 14940 10260 14940 10260 14760 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 10305 14400 10395 14400 10395 15300 10305 15300 10305 14400 +-6 +1 4 0 2 -1 7 40 -1 -1 0.000 1 0.0000 9000 15525 90 90 8910 15525 9090 15525 +2 2 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 5 + 6075 13500 11250 13500 11250 17100 6075 17100 6075 13500 +2 1 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 3 + 6075 16650 9450 16650 9450 17100 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 8325 16155 9900 16155 9900 16245 8325 16245 8325 16155 +2 2 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 8910 16110 9090 16110 9090 16290 8910 16290 8910 16110 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 9000 16110 9000 15615 +2 1 0 2 -1 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 8190 14850 9585 14850 +2 1 0 2 12 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 10260 14850 9765 14850 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 9675 15615 9675 17325 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 8100 13275 8100 14085 +2 1 0 2 -1 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 9090 15525 9585 15525 +2 4 0 2 0 7 38 -1 -1 0.000 0 0 6 0 0 5 + 9765 15615 9585 15615 9585 14760 9765 14760 9765 15615 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 11475 14175 8190 14175 +2 4 0 2 0 7 38 -1 -1 0.000 0 0 6 0 0 5 + 8190 14940 8010 14940 8010 14085 8190 14085 8190 14940 +2 1 0 2 0 7 38 -1 -1 0.000 0 0 -1 0 0 2 + 9585 15210 9765 15210 +4 0 0 30 -1 18 12 0.0000 4 135 615 6120 17055 Global:\001 +4 0 0 30 -1 18 12 0.0000 4 180 1230 6120 16830 Configuration:\001 +4 0 0 30 -1 18 12 0.0000 4 135 645 7650 16830 3-1-1-0\001 +4 0 0 30 -1 18 12 0.0000 4 135 1635 7650 17055 North+South+East\001 +4 1 12 40 -1 18 12 0.0000 4 135 180 9990 14805 Lt\001 +4 1 0 40 -1 18 12 0.0000 4 135 180 9135 15930 Lt\001 +4 2 0 40 -1 18 12 0.0000 4 180 1665 7965 14715 _northEastContact\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 7965 13410 G\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 9585 17325 G\001 +4 0 0 40 -1 18 12 0.0000 4 180 1725 9810 15660 _southWestContact\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 11430 14130 G\001 +-6 +6 -270 9000 5490 12600 +6 4140 9855 4410 10845 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 4185 10260 4365 10260 4365 10440 4185 10440 4185 10260 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 4230 9900 4320 9900 4320 10800 4230 10800 4230 9900 +-6 +1 4 0 2 -1 7 40 -1 -1 0.000 1 0.0000 2925 9720 90 90 2835 9720 3015 9720 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 3590 10345 90 90 3500 10345 3680 10345 +2 2 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 5 + 0 9000 5175 9000 5175 12600 0 12600 0 9000 +2 1 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 3 + 0 12150 3375 12150 3375 12600 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 2835 11025 -225 11025 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 2250 11655 3825 11655 3825 11745 2250 11745 2250 11655 +2 2 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 2835 11610 3015 11610 3015 11790 2835 11790 2835 11610 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2925 11610 2925 11115 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 5445 9720 3015 9720 +2 1 0 2 -1 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 2925 9810 2925 10935 +2 1 0 2 12 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 4185 10350 3690 10350 +2 1 0 2 12 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 3600 10440 3600 10935 +2 4 0 2 0 7 38 -1 -1 0.000 0 0 6 0 0 5 + 3690 11115 2835 11115 2835 10935 3690 10935 3690 11115 +2 1 0 2 0 7 38 -1 -1 0.000 0 0 -1 0 0 2 + 3285 10935 3285 11115 +4 0 0 30 -1 18 12 0.0000 4 135 615 45 12555 Global:\001 +4 0 0 30 -1 18 12 0.0000 4 180 1230 45 12330 Configuration:\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 -135 10980 G\001 +4 0 0 30 -1 18 12 0.0000 4 135 645 1575 12330 2-1-1-0\001 +4 0 0 30 -1 18 12 0.0000 4 135 945 1575 12555 West+East\001 +4 1 12 40 -1 18 12 0.0000 4 135 180 3915 10305 Lt\001 +4 1 0 40 -1 18 12 0.0000 4 135 180 3060 11430 Lt\001 +4 2 0 40 -1 18 12 0.0000 4 180 1725 2745 10935 _southWestContact\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 5355 9675 G\001 +4 0 0 40 -1 18 12 0.0000 4 180 1665 2925 9540 _northEastContact\001 +4 0 12 40 -1 18 12 0.0000 4 135 180 3645 10755 Lt\001 +-6 +6 6075 8730 11565 12870 +6 10215 9855 10485 10845 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 10260 10260 10440 10260 10440 10440 10260 10440 10260 10260 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 10305 9900 10395 9900 10395 10800 10305 10800 10305 9900 +-6 +1 4 0 2 -1 7 40 -1 -1 0.000 1 0.0000 8100 10350 90 90 8010 10350 8190 10350 +1 4 0 2 -1 7 40 -1 -1 0.000 1 0.0000 9000 11025 90 90 8910 11025 9090 11025 +2 2 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 5 + 6075 9000 11250 9000 11250 12600 6075 12600 6075 9000 +2 1 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 3 + 6075 12150 9450 12150 9450 12600 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 8325 11655 9900 11655 9900 11745 8325 11745 8325 11655 +2 2 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 8910 11610 9090 11610 9090 11790 8910 11790 8910 11610 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 9000 11610 9000 11115 +2 1 0 2 -1 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 8190 10350 9585 10350 +2 1 0 2 12 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 10260 10350 9765 10350 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 9675 11115 9675 12825 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 8100 8775 8100 10260 +2 1 0 2 -1 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 9090 11025 9585 11025 +2 4 0 2 0 7 38 -1 -1 0.000 0 0 6 0 0 5 + 9765 11115 9585 11115 9585 10260 9765 10260 9765 11115 +2 1 0 2 0 7 38 -1 -1 0.000 0 0 -1 0 0 2 + 9585 10710 9765 10710 +4 0 0 30 -1 18 12 0.0000 4 135 615 6120 12555 Global:\001 +4 0 0 30 -1 18 12 0.0000 4 180 1230 6120 12330 Configuration:\001 +4 0 0 30 -1 18 12 0.0000 4 135 645 7650 12330 2-1-1-0\001 +4 0 0 30 -1 18 12 0.0000 4 135 1125 7650 12555 North+South\001 +4 1 12 40 -1 18 12 0.0000 4 135 180 9990 10305 Lt\001 +4 1 0 40 -1 18 12 0.0000 4 135 180 9135 11430 Lt\001 +4 2 0 40 -1 18 12 0.0000 4 180 1665 7965 10215 _northEastContact\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 7965 8910 G\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 9585 12825 G\001 +4 0 0 40 -1 18 12 0.0000 4 180 1725 9810 11160 _southWestContact\001 +-6 +6 -270 4500 5175 8100 +6 4140 5355 4410 6345 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 4185 5760 4365 5760 4365 5940 4185 5940 4185 5760 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 4230 5400 4320 5400 4320 6300 4230 6300 4230 5400 +-6 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 3600 5850 90 90 3510 5850 3690 5850 +2 2 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 5 + 0 4500 5175 4500 5175 8100 0 8100 0 4500 +2 1 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 3 + 0 7650 3375 7650 3375 8100 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 2835 6525 -225 6525 +2 1 0 2 12 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 4185 5850 3690 5850 +2 1 0 2 12 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 3600 5940 3600 6435 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 2250 7155 3825 7155 3825 7245 2250 7245 2250 7155 +2 2 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 2835 7110 3015 7110 3015 7290 2835 7290 2835 7110 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2925 7110 2925 6615 +2 4 0 2 0 7 38 -1 -1 0.000 0 0 6 0 0 5 + 3735 6615 2835 6615 2835 6435 3735 6435 3735 6615 +2 1 0 2 0 7 38 -1 -1 0.000 0 0 -1 0 0 2 + 3285 6435 3285 6615 +4 0 0 30 -1 18 12 0.0000 4 135 615 45 8055 Global:\001 +4 0 0 30 -1 18 12 0.0000 4 180 1230 45 7830 Configuration:\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 -135 6480 G\001 +4 0 0 30 -1 18 12 0.0000 4 135 645 1575 7830 1-1-1-0\001 +4 0 0 30 -1 18 12 0.0000 4 135 435 1575 8055 West\001 +4 1 12 40 -1 18 12 0.0000 4 135 180 3915 5805 Lt\001 +4 1 0 40 -1 18 12 0.0000 4 135 180 3060 6930 Lt\001 +4 0 12 40 -1 18 12 0.0000 4 135 180 3645 6255 Lt\001 +4 2 0 40 -1 18 12 0.0000 4 180 1725 2745 6435 _southWestContact\001 +-6 +6 6075 4500 11250 8370 +6 10215 5355 10485 6345 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 10260 5760 10440 5760 10440 5940 10260 5940 10260 5760 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 10305 5400 10395 5400 10395 6300 10305 6300 10305 5400 +-6 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 9675 6615 9675 8325 +2 2 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 5 + 6075 4500 11250 4500 11250 8100 6075 8100 6075 4500 +2 1 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 3 + 6075 7650 9450 7650 9450 8100 +2 1 0 2 12 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 10260 5850 9765 5850 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 8325 7155 9900 7155 9900 7245 8325 7245 8325 7155 +2 2 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 8910 7110 9090 7110 9090 7290 8910 7290 8910 7110 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 9000 7110 9000 6615 +2 4 0 2 0 7 38 -1 -1 0.000 0 0 6 0 0 5 + 9765 5760 9585 5760 9585 6615 9765 6615 9765 5760 +2 4 0 2 0 7 38 -1 -1 0.000 0 0 6 0 0 5 + 9090 6435 8910 6435 8910 6615 9090 6615 9090 6435 +2 1 0 2 -1 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 9585 6525 9090 6525 +2 1 0 2 0 7 38 -1 -1 0.000 0 0 -1 0 0 2 + 9585 6210 9765 6210 +4 0 0 30 -1 18 12 0.0000 4 135 615 6120 8055 Global:\001 +4 0 0 30 -1 18 12 0.0000 4 180 1230 6120 7830 Configuration:\001 +4 0 0 30 -1 18 12 0.0000 4 135 645 7650 7830 1-1-1-0\001 +4 0 0 30 -1 18 12 0.0000 4 135 525 7650 8055 South\001 +4 1 12 40 -1 18 12 0.0000 4 135 180 9990 5805 Lt\001 +4 1 0 40 -1 18 12 0.0000 4 135 180 9135 6930 Lt\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 9810 8280 G\001 +4 2 0 40 -1 18 12 0.0000 4 180 1725 9495 5850 _southWestContact\001 +-6 +6 -270 26730 5490 30600 +6 4140 27855 4410 28845 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 4185 28260 4365 28260 4365 28440 4185 28440 4185 28260 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 4230 27900 4320 27900 4320 28800 4230 28800 4230 27900 +-6 +1 4 0 2 -1 7 40 -1 -1 0.000 1 0.0000 2925 29025 90 90 2835 29025 3015 29025 +2 2 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 5 + 0 27000 5175 27000 5175 30600 0 30600 0 27000 +2 1 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 3 + 0 30150 4050 30150 4050 30600 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 2250 29655 3825 29655 3825 29745 2250 29745 2250 29655 +2 2 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 2835 29610 3015 29610 3015 29790 2835 29790 2835 29610 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2925 29610 2925 29115 +2 1 0 2 12 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 4185 28350 3690 28350 +2 1 0 2 -1 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 3015 29025 3510 29025 +2 4 0 2 0 7 38 -1 -1 0.000 0 0 6 0 0 5 + 3690 29115 3510 29115 3510 28260 3690 28260 3690 29115 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 3510 28800 -225 28800 +2 1 0 2 0 7 38 -1 -1 0.000 0 0 -1 0 0 2 + 3510 28710 3690 28710 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 3600 26775 3600 28260 +4 0 0 30 -1 18 12 0.0000 4 135 615 45 30555 Global:\001 +4 0 0 30 -1 18 12 0.0000 4 180 1230 45 30330 Configuration:\001 +4 0 0 30 -1 18 12 0.0000 4 135 645 1575 30330 2-1-1-0\001 +4 0 0 30 -1 18 12 0.0000 4 135 1035 1575 30555 North+West\001 +4 1 12 40 -1 18 12 0.0000 4 135 180 3915 28305 Lt\001 +4 1 0 40 -1 18 12 0.0000 4 135 180 3060 29430 Lt\001 +4 0 0 40 -1 18 12 0.0000 4 180 1725 3735 29160 _southWestContact\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 5355 27630 G\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 -135 29025 G\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 3465 26910 G\001 +-6 +2 1 0 2 0 7 38 -1 -1 0.000 0 0 -1 0 0 1 + -990 25695 diff --git a/katabatic/doc/images/GCellConfiguration-17.pdf b/katabatic/doc/images/GCellConfiguration-17.pdf new file mode 100644 index 0000000000000000000000000000000000000000..93348df5ad34ed30656e015bc6639c8129e8a17f GIT binary patch literal 19884 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 C`eBm* literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-17.png b/katabatic/doc/images/GCellConfiguration-17.png new file mode 100644 index 0000000000000000000000000000000000000000..e177753793c6d148c9caaa99ba57ca3ffc2b5d5c GIT binary patch literal 33690 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 literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-18.fig b/katabatic/doc/images/GCellConfiguration-18.fig new file mode 100644 index 00000000..f3bae363 --- /dev/null +++ b/katabatic/doc/images/GCellConfiguration-18.fig @@ -0,0 +1,123 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +6 675 3870 3375 4500 +6 675 3870 3375 4500 +1 4 0 2 -1 7 40 -1 -1 0.000 1 0.0000 890 4090 90 90 800 4090 980 4090 +2 1 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 3 + 675 3870 3375 3870 3375 4500 +4 0 0 30 -1 18 12 0.0000 4 180 930 2250 4410 G: "global"\001 +4 0 0 30 -1 18 12 0.0000 4 135 1095 1125 4140 AutoContact\001 +4 0 0 30 -1 18 12 0.0000 4 135 780 1125 4410 L: "local"\001 +-6 +-6 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 1125 2025 90 90 1035 2025 1215 2025 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 2025 2025 90 90 1935 2025 2115 2025 +1 4 0 2 18 7 40 -1 -1 0.000 1 0.0000 2025 2475 90 90 1935 2475 2115 2475 +1 4 0 2 18 7 40 -1 -1 0.000 1 0.0000 3150 2475 90 90 3060 2475 3240 2475 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 2025 1350 90 90 1935 1350 2115 1350 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 3150 1800 90 90 3060 1800 3240 1800 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 3150 3150 90 90 3060 3150 3240 3150 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 5175 3150 90 90 5085 3150 5265 3150 +2 1 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 1215 2025 1935 2025 +2 2 3 1 0 7 30 -1 -1 8.000 0 0 -1 0 0 5 + 1575 450 4950 450 4950 3600 1575 3600 1575 450 +2 1 0 2 18 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3060 2475 2115 2475 +2 1 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2025 2115 2025 2385 +2 1 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2025 1440 2025 1935 +2 1 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3150 1890 3150 2385 +2 1 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3150 2565 3150 3060 +2 1 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3240 3150 5085 3150 +2 2 3 1 0 7 30 -1 -1 8.000 0 0 -1 0 0 5 + 5850 450 9900 450 9900 3600 5850 3600 5850 450 +2 2 0 2 12 7 40 -1 45 0.000 0 0 -1 0 0 5 + 9225 3105 10125 3105 10125 3195 9225 3195 9225 3105 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 6930 900 7020 900 7020 1800 6930 1800 6930 900 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 8055 1350 8145 1350 8145 2250 8055 2250 8055 1350 +2 2 0 2 12 7 40 -1 45 0.000 0 0 -1 0 0 5 + 6975 1080 7470 1080 7470 1170 6975 1170 6975 1080 +2 2 0 2 12 7 40 -1 45 0.000 0 0 -1 0 0 5 + 6975 1980 8100 1980 8100 2070 6975 2070 6975 1980 +2 2 0 2 12 7 40 -1 45 0.000 0 0 -1 0 0 5 + 7380 1125 7470 1125 7470 2475 7380 2475 7380 1125 +2 2 0 2 12 7 40 -1 45 0.000 0 0 -1 0 0 5 + 5625 2430 7425 2430 7425 2520 5625 2520 5625 2430 +2 2 0 2 12 7 40 -1 45 0.000 0 0 -1 0 0 5 + 6930 2025 7020 2025 7020 2925 6930 2925 6930 2025 +2 2 0 2 12 7 40 -1 45 0.000 0 0 -1 0 0 5 + 7380 2475 7470 2475 7470 2925 7380 2925 7380 2475 +2 2 0 2 12 7 40 -1 45 0.000 0 0 -1 0 0 5 + 9180 2925 9270 2925 9270 3150 9180 3150 9180 2925 +2 2 0 2 18 7 40 -1 45 0.000 0 0 -1 0 0 5 + 7425 2880 9225 2880 9225 2970 7425 2970 7425 2880 +2 1 0 2 18 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 7065 2925 7335 2925 +2 4 0 1 18 7 30 -1 -1 0.000 0 0 7 0 0 5 + 7650 3060 7650 2790 6750 2790 6750 3060 7650 3060 +2 1 0 1 18 7 40 -1 -1 0.000 0 0 -1 1 0 2 + 3 0 1.00 60.00 120.00 + 7200 3240 7200 2925 +2 2 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 5 + 675 0 10350 0 10350 4500 675 4500 675 0 +2 1 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 3 + 2115 1350 2160 1350 2610 1350 +2 1 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 3 + 3240 1800 3285 1800 3735 1800 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 2655 900 2745 900 2745 1800 2655 1800 2655 900 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 2610 1260 2790 1260 2790 1440 2610 1440 2610 1260 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 3780 1350 3870 1350 3870 2250 3780 2250 3780 1350 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 3735 1710 3915 1710 3915 1890 3735 1890 3735 1710 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 7335 1035 7515 1035 7515 1215 7335 1215 7335 1035 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 6885 1935 7065 1935 7065 2115 6885 2115 6885 1935 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 7335 2835 7515 2835 7515 3015 7335 3015 7335 2835 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 9135 2835 9315 2835 9315 3015 9135 3015 9135 2835 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 9135 3060 9315 3060 9315 3240 9135 3240 9135 3060 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 7335 2385 7515 2385 7515 2565 7335 2565 7335 2385 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 6885 1035 7065 1035 7065 1215 6885 1215 6885 1035 +4 1 12 40 -1 18 12 0.0000 4 135 255 1350 2205 G1\001 +4 1 18 40 -1 18 12 0.0000 4 135 210 2610 2655 L4\001 +4 1 12 40 -1 18 12 0.0000 4 135 210 2385 1305 L1\001 +4 1 12 40 -1 18 12 0.0000 4 135 210 2160 1755 L2\001 +4 1 12 40 -1 18 12 0.0000 4 135 210 3510 1755 L5\001 +4 1 12 40 -1 18 12 0.0000 4 135 210 3285 2205 L6\001 +4 1 12 40 -1 18 12 0.0000 4 135 255 10035 3060 G2\001 +4 1 12 40 -1 18 12 0.0000 4 135 255 4680 3375 G2\001 +4 1 12 40 -1 18 12 0.0000 4 135 255 5715 2700 G1\001 +4 1 12 40 -1 18 12 0.0000 4 135 210 7245 1035 L1\001 +4 1 12 40 -1 18 12 0.0000 4 135 210 7605 1575 L2\001 +4 1 12 40 -1 18 12 0.0000 4 135 210 7740 2250 L5\001 +4 1 18 40 -1 18 12 0.0000 4 135 210 8325 3150 L4\001 +4 1 18 40 -1 18 12 0.0000 4 150 315 7200 3375 gap\001 +4 1 0 30 -1 14 12 0.0000 4 120 2205 3375 270 AutoContact Structure\001 +4 1 0 30 -1 14 12 0.0000 4 180 1680 7875 225 Physical Mapping\001 +4 1 12 40 -1 18 12 0.0000 4 135 210 2160 2340 L3\001 +4 1 12 40 -1 18 12 0.0000 4 135 210 3285 2880 L7\001 +4 1 12 40 -1 18 12 0.0000 4 135 210 7605 2745 L3\001 +4 1 12 40 -1 18 12 0.0000 4 135 210 9450 3060 L7\001 +4 1 12 40 -1 18 12 0.0000 4 135 210 6795 2340 L6\001 diff --git a/katabatic/doc/images/GCellConfiguration-18.pdf b/katabatic/doc/images/GCellConfiguration-18.pdf new file mode 100644 index 0000000000000000000000000000000000000000..2508ed72b80bdcfb1bb616dd5392fe3ecafcea2c GIT binary patch literal 12457 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 literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-18.png b/katabatic/doc/images/GCellConfiguration-18.png new file mode 100644 index 0000000000000000000000000000000000000000..1b6cbda29e2dc17c8a8cb24586a2bb765e3178f4 GIT binary patch literal 7459 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 literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-19.fig b/katabatic/doc/images/GCellConfiguration-19.fig new file mode 100644 index 00000000..769c42c0 --- /dev/null +++ b/katabatic/doc/images/GCellConfiguration-19.fig @@ -0,0 +1,119 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +6 675 3870 3375 4500 +6 675 3870 3375 4500 +1 4 0 2 -1 7 40 -1 -1 0.000 1 0.0000 890 4090 90 90 800 4090 980 4090 +2 1 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 3 + 675 3870 3375 3870 3375 4500 +4 0 0 30 -1 18 12 0.0000 4 180 930 2250 4410 G: "global"\001 +4 0 0 30 -1 18 12 0.0000 4 135 1095 1125 4140 AutoContact\001 +4 0 0 30 -1 18 12 0.0000 4 135 780 1125 4410 L: "local"\001 +-6 +-6 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 1125 2025 90 90 1035 2025 1215 2025 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 2025 2025 90 90 1935 2025 2115 2025 +1 4 0 2 18 7 40 -1 -1 0.000 1 0.0000 2025 2475 90 90 1935 2475 2115 2475 +1 4 0 2 18 7 40 -1 -1 0.000 1 0.0000 3150 2475 90 90 3060 2475 3240 2475 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 2025 1350 90 90 1935 1350 2115 1350 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 3150 1800 90 90 3060 1800 3240 1800 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 3150 3150 90 90 3060 3150 3240 3150 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 5175 3150 90 90 5085 3150 5265 3150 +2 1 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 1215 2025 1935 2025 +2 2 3 1 0 7 30 -1 -1 8.000 0 0 -1 0 0 5 + 1575 450 4950 450 4950 3600 1575 3600 1575 450 +2 1 0 2 18 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3060 2475 2115 2475 +2 1 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2025 2115 2025 2385 +2 1 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2025 1440 2025 1935 +2 1 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3150 1890 3150 2385 +2 1 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3150 2565 3150 3060 +2 1 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3240 3150 5085 3150 +2 2 3 1 0 7 30 -1 -1 8.000 0 0 -1 0 0 5 + 5850 450 9900 450 9900 3600 5850 3600 5850 450 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 6930 900 7020 900 7020 1800 6930 1800 6930 900 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 8055 1350 8145 1350 8145 2250 8055 2250 8055 1350 +2 2 0 2 12 7 40 -1 45 0.000 0 0 -1 0 0 5 + 6975 1080 7470 1080 7470 1170 6975 1170 6975 1080 +2 2 0 2 12 7 40 -1 45 0.000 0 0 -1 0 0 5 + 6975 1980 8100 1980 8100 2070 6975 2070 6975 1980 +2 2 0 2 12 7 40 -1 45 0.000 0 0 -1 0 0 5 + 7380 1125 7470 1125 7470 2475 7380 2475 7380 1125 +2 2 0 2 12 7 40 -1 45 0.000 0 0 -1 0 0 5 + 5625 2430 7425 2430 7425 2520 5625 2520 5625 2430 +2 2 0 2 12 7 40 -1 45 0.000 0 0 -1 0 0 5 + 6930 2025 7020 2025 7020 2925 6930 2925 6930 2025 +2 2 0 2 12 7 40 -1 45 0.000 0 0 -1 0 0 5 + 7380 2475 7470 2475 7470 2925 7380 2925 7380 2475 +2 4 0 1 18 7 30 -1 -1 0.000 0 0 7 0 0 5 + 7650 3060 7650 2790 6750 2790 6750 3060 7650 3060 +2 2 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 5 + 675 0 10350 0 10350 4500 675 4500 675 0 +2 1 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 3 + 2115 1350 2160 1350 2610 1350 +2 1 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 3 + 3240 1800 3285 1800 3735 1800 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 2655 900 2745 900 2745 1800 2655 1800 2655 900 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 2610 1260 2790 1260 2790 1440 2610 1440 2610 1260 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 3780 1350 3870 1350 3870 2250 3780 2250 3780 1350 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 3735 1710 3915 1710 3915 1890 3735 1890 3735 1710 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 7335 1035 7515 1035 7515 1215 7335 1215 7335 1035 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 6885 1935 7065 1935 7065 2115 6885 2115 6885 1935 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 7335 2835 7515 2835 7515 3015 7335 3015 7335 2835 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 7335 2385 7515 2385 7515 2565 7335 2565 7335 2385 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 6885 1035 7065 1035 7065 1215 6885 1215 6885 1035 +2 1 0 2 18 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3150 2385 3150 2565 +2 2 0 2 18 7 40 -1 45 0.000 0 0 -1 0 0 5 + 7425 2880 6975 2880 6975 2970 7425 2970 7425 2880 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 6885 2835 7065 2835 7065 3015 6885 3015 6885 2835 +2 2 0 2 12 7 40 -1 45 0.000 0 0 -1 0 0 5 + 6930 2925 7020 2925 7020 3150 6930 3150 6930 2925 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 6885 3060 7065 3060 7065 3240 6885 3240 6885 3060 +2 2 0 2 12 7 40 -1 45 0.000 0 0 -1 0 0 5 + 6975 3105 10125 3105 10125 3195 6975 3195 6975 3105 +4 1 12 40 -1 18 12 0.0000 4 135 255 1350 2205 G1\001 +4 1 18 40 -1 18 12 0.0000 4 135 210 2610 2655 L4\001 +4 1 12 40 -1 18 12 0.0000 4 135 210 2385 1305 L1\001 +4 1 12 40 -1 18 12 0.0000 4 135 210 2160 1755 L2\001 +4 1 12 40 -1 18 12 0.0000 4 135 210 3510 1755 L5\001 +4 1 12 40 -1 18 12 0.0000 4 135 210 3285 2205 L6\001 +4 1 12 40 -1 18 12 0.0000 4 135 210 3285 2880 L7\001 +4 1 12 40 -1 18 12 0.0000 4 135 255 10035 3060 G2\001 +4 1 12 40 -1 18 12 0.0000 4 135 255 4680 3375 G2\001 +4 1 12 40 -1 18 12 0.0000 4 135 255 5715 2700 G1\001 +4 1 12 40 -1 18 12 0.0000 4 135 210 7245 1035 L1\001 +4 1 12 40 -1 18 12 0.0000 4 135 210 7605 1575 L2\001 +4 1 12 40 -1 18 12 0.0000 4 135 210 7740 2250 L5\001 +4 1 12 40 -1 18 12 0.0000 4 135 210 6795 2250 L6\001 +4 1 0 30 -1 14 12 0.0000 4 120 2205 3375 270 AutoContact Structure\001 +4 1 0 30 -1 14 12 0.0000 4 180 1680 7875 225 Physical Mapping\001 +4 1 18 40 -1 18 12 0.0000 4 135 210 7200 2745 L4\001 +4 1 12 40 -1 18 12 0.0000 4 135 210 6615 3105 L7\001 +4 1 12 40 -1 18 12 0.0000 4 135 210 2160 2340 L3\001 +4 1 12 40 -1 18 12 0.0000 4 135 210 7605 2790 L3\001 diff --git a/katabatic/doc/images/GCellConfiguration-19.pdf b/katabatic/doc/images/GCellConfiguration-19.pdf new file mode 100644 index 0000000000000000000000000000000000000000..99e7f269cf917228eece18be886a4efdd962b234 GIT binary patch literal 12318 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 aamN!j{>4-v#mGQpFsO9E*x1&Q1N;XU1dEdZ literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-2.png b/katabatic/doc/images/GCellConfiguration-2.png new file mode 100644 index 0000000000000000000000000000000000000000..02121a5e0c40981f39dd44d654b9deb141849ea3 GIT binary patch literal 5373 zcmeHLXH*mIwjM-Lga~3m=^&uAAYw%6MVcHiKtzzx)JO?PZ$bc3Kv0@A0f|CD2qi%< zKz*Go@65aQyz8B3o@e&6cR18Q8+4ZIEC2u? zU7h2KFRN)Y3gC@{KCWA#ti{z z8bbxN?VQ~`+@HDGyLbrPm4Se7-b(UHy9@yABf9t1U_PIz<5Vwi=&mc06nuLesSE-ZKfoEM zKt!fmZZ}Yn+$-KWW^#LI+wWDYnw+iISo+j->x2|Cq&x;&MjkvG#mxs8 z{?;R|6gm$d#W;r_vj;YBU>dF$t_W0O=GR=wUMZCr45z*Ugedw`77Op1b=R>l(%G$u z>JyAVi@ra{i6RTEg;9R@yv1Ls`9VhNvLeFFUJ^f1TgT%2!*GVK`f(!D!qSj`hhc!}Cf9hF#p1k2jS@a+2;MRBe9+9ytE<(~blEK1CXP#YlzO&bnzgw(*-M|0-jc*0d^^90r zxXq0dvShXhQ3G$I6Us_3TU8GYbSx?UMGsQHPFqFanIC;fTgG0<;a^=&d>S^w%HVzF z@Cp7gc{_I!AG{o3G+aE?2lEe))>e=o-A^sxA^&c~$i^;vZN6|#B%&Ya>Qnb+!gjGb z=Tz8$MMN6}EeHH7QUH~LB)~@l$FLguH*54Lb9_nYEmirhR01(2;TM zmeVe)yDmF4365xA;=ROgbWbH%a4DQ)RVP-!ix`EXF;UQ(v zXSCUt}u79_e+r#0CZ=WI_jO_ukrTSk%ZH!Lm{ZtM`Rwe{36DH`5tHOpro zkg(cod@AfYd~ed!R*WQ`XU1S>VsD5ZG0Q3#>94TG@}B*QzY8I&4OV_Hakn4)+IBO9 z4nrVl(GEpZ7W2Hlw@n*JFQqhRc)93Np#ZOb5nn8m-WCL?GWC7+BQk5BYlaCBmYm~y zyZG+ntMw2!xETvw`+?1nsh*dnit7QhDHCYOm#zlF?C**oSejRTT%DVAo# zPe3NELf;U10{75l8~ZWU@B$OY?o*VDd$w~-?^_IGL~X=K@!}@ν+qtxvx4rmXge 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 dhPmDxeUs&{jhjAZ$!zG87w%=nBdrDoPRC zT6n0~D2jrhf(-=30{E?>)co`T2e3k7VZDd+t5=chCL(&do$m z2d62R1p}IR>G{TAAxjvAB|+iP^y!E@E)FHbU>30O5GSFC#0eO267fmg0T)PuaVslG zN)kAK5fqbkZN8gCpRFlA+HM|`q?-Oj{lO(B4bn2LEgwjr1e#hNWymcQ>}@K2#gb;16ZK1Q1 zT^fy@s6JyH(rr`dgmMILvHssN%W{%0Byxr=*pH$m;A(te7Ig#O+5J~J# z${uvp@qJs-X}h;qtzUYT-rZ@hwl!g1$EBr*Vgn6ZMwJ;4n>+qYCbSRs@gEWHVp0=c z@M34j&A-Ox{`=>gmc;jGWDn-vYb{A?^tINjsOfm1UXdE$`TTLZ{`$*)JLVf^*-gq8 zTbB*X;%k6fj6~~_`f=Asdek{B7ysZR4NJY|B8+I5WqEaP zhim@AnM0=Veu=6LFqryYcJlC{%Fv9wyx6I=GeTEZE=^dkceAKyU0909DN5r=zG<`O zq$9!4iVI_ZyXvGD$jw^1+Wg+xwW7KlmySIFA0ur_v(2A94UF2sFx|V}J-pO-biV7T zlj>UI$F?lX$?M43^d_dhV#WrWgVjd2T830uCpDn zgu6IF)yO76f+-xT4~1cjeQ<^4BRkrf%)yXxlfPZyI%+r*2eKHRgED zN84GCn=h0%UrxpoMC(RwxwxWm6lOoqI?l^)`ZZjf_BK{ef7xxrDM9TYmalJJ7;Z7{ z@et>VLC4f&Lx*fQfUJm{T5^_^MtZq#aL}vp(B%h1*gx_# z;$5n3hq=*i6!_R|Txe>aY^zPvN-FiG=}c=gWYn1K3x8U)>c#5KGYsG|Z~7*#!+j(5 z#8%bB*rbfyIO*=h28T^Xf9#Aum#v2z`t3BSTJa%nzt#+c^YDDr0h6U>%e2%p)49PH zMf+&wliB8PuDvbrxi)?Du|VF5b*ks$40W`M$Hx1Yt4tg3-d0ik)VlV#u2$XcpqO3E z+&4368)t8W(+<45I-_V>tZkYUuR|Q6C;7BtzdqOXFjbpy0UKF0e@Vga_L37P>I*dk z2fb=It-b3{!tWvtdok13^#kwX(Ho)2k9F50k}O)Yjy>EPeaO08zii90%SEi`@r~6+ zQ(Z1PwvCZ|3_laJ>r--2gY&>kwdGcq)-*U*)qCv`uTj-Y_Dat4S@3bk#9N`yJ~kGF zRc>xb*GRr1TyHQ;^LUO8d3jdWxk>j^?zhKo(XaB>etp};)wlRjo_EJ^kB*kHsim)~ zJ_I^NNmp*=f6uysW+*-6DJ07P}&PWxMU?M%r;a62D^@Itw93%_OI0KHP6{p#R*)fhq6n0tP3jk;a~P1q#_Sh|~E%#~?ZtCa_^l z2$L@cJYo_qD{upt3Pu07cHr%6V-+^+w9Z*uakOEg=5fW088WBbjcfR5gL*@yC$uOxuMD>9X@5msM zQe#T`7(H?zk4KU0a<%S?6tUw=@$Q#-Lb0t_D(rrD5Qc={K)Hcb`$H&#B3NLrF?$^# zY7}ZEhzl-?!bzckKgCWW3YLc?)(aRX+A2iLZsDyaf7h z7Zmi>S!#Z}TW8tIAj$gn zV_2d9^u9JalMC3SpN)kA0`F^MqFm*eIVeb)zWp#RRlxVPF*pn*UvQODwsDzC>tJAP zrSa&P^4jQh79f&-^D-Gqz6>@?89x?BsUODv%sM`^ZwwYkX~1szzM^F`>q7LU^l@3tO9Q c`WaIob)A!ve1epxCX>lxLK7!C&US+S25{r~^~ literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-20.png b/katabatic/doc/images/GCellConfiguration-20.png new file mode 100644 index 0000000000000000000000000000000000000000..af8117ee0593a820b4853c8b6ba5fede1df7d837 GIT binary patch literal 4960 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 literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-21.fig b/katabatic/doc/images/GCellConfiguration-21.fig new file mode 100644 index 00000000..4510ae6b --- /dev/null +++ b/katabatic/doc/images/GCellConfiguration-21.fig @@ -0,0 +1,92 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +6 0 -270 5175 3870 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 3825 1125 90 90 3735 1125 3915 1125 +2 2 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 5 + 0 0 5175 0 5175 3600 0 3600 0 0 +2 1 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 3 + 0 3150 2925 3150 2925 3600 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 2610 2385 2790 2385 2790 2565 2610 2565 2610 2385 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 2655 2025 2745 2025 2745 2925 2655 2925 2655 2025 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 405 675 495 675 495 1575 405 1575 405 675 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 360 1035 540 1035 540 1215 360 1215 360 1035 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 1530 1350 1620 1350 1620 2250 1530 2250 1530 1350 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 1485 1710 1665 1710 1665 1890 1485 1890 1485 1710 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 3060 1125 540 1125 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 3060 1800 1665 1800 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 3060 2475 2790 2475 +2 4 0 2 0 7 38 -1 -1 0.000 0 0 7 0 0 5 + 3240 2565 3240 1035 3060 1035 3060 2565 3240 2565 +2 1 1 2 18 7 30 -1 -1 6.000 0 0 -1 0 0 2 + 3150 3825 3150 2565 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 3735 1125 3240 1125 +2 1 1 2 18 7 30 -1 -1 6.000 0 0 -1 0 0 2 + 3825 1035 3825 -225 +4 0 0 30 -1 18 12 0.0000 4 135 615 45 3555 Global:\001 +4 0 0 30 -1 18 12 0.0000 4 180 1230 45 3330 Configuration:\001 +4 0 0 30 -1 18 12 0.0000 4 135 1125 1575 3555 North+South\001 +4 0 0 30 -1 18 12 0.0000 4 135 645 1575 3330 2-3-0-0\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 3960 -90 G\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 3285 3825 G\001 +4 0 0 40 -1 18 12 0.0000 4 180 1725 3285 2610 _southWestContact\001 +4 2 0 40 -1 18 12 0.0000 4 180 1665 3735 945 _northEastContact\001 +-6 +6 5805 -270 11250 3870 +6 7515 630 9180 1620 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 7605 675 7695 675 7695 1575 7605 1575 7605 675 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 7560 1035 7740 1035 7740 1215 7560 1215 7560 1035 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 9135 1125 7740 1125 +-6 +6 8640 1305 9180 2295 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 8685 1710 8865 1710 8865 1890 8685 1890 8685 1710 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 8730 1350 8820 1350 8820 2250 8730 2250 8730 1350 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 9135 1800 8865 1800 +-6 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 9900 1125 90 90 9810 1125 9990 1125 +2 2 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 5 + 6075 0 11250 0 11250 3600 6075 3600 6075 0 +2 1 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 3 + 6075 3150 9675 3150 9675 3600 +2 4 0 2 0 7 38 -1 -1 0.000 0 0 7 0 0 5 + 9315 2565 9315 1035 9135 1035 9135 2565 9315 2565 +2 1 1 2 18 7 30 -1 -1 6.000 0 0 -1 0 0 2 + 9225 3825 9225 2565 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 9810 1125 9315 1125 +2 1 1 2 18 7 30 -1 -1 6.000 0 0 -1 0 0 2 + 9900 1035 9900 -225 +2 1 1 2 18 7 30 -1 -1 6.000 0 0 -1 0 0 2 + 9135 2475 5850 2475 +4 0 0 30 -1 18 12 0.0000 4 135 615 6120 3555 Global:\001 +4 0 0 30 -1 18 12 0.0000 4 180 1230 6120 3330 Configuration:\001 +4 0 0 30 -1 18 12 0.0000 4 135 1665 7650 3555 North+South+West\001 +4 0 0 30 -1 18 12 0.0000 4 135 645 7650 3330 3-2-0-0\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 10035 -90 G\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 9360 3825 G\001 +4 0 0 40 -1 18 12 0.0000 4 180 1725 9360 2610 _southWestContact\001 +4 2 0 40 -1 18 12 0.0000 4 180 1665 9810 945 _northEastContact\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 5895 2700 G\001 +-6 diff --git a/katabatic/doc/images/GCellConfiguration-21.pdf b/katabatic/doc/images/GCellConfiguration-21.pdf new file mode 100644 index 0000000000000000000000000000000000000000..4cd1519e237ec5ca65fe53e89e0c178d66478578 GIT binary patch literal 5770 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 literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-22.png b/katabatic/doc/images/GCellConfiguration-22.png new file mode 100644 index 0000000000000000000000000000000000000000..1370d722fc96c58f7b51e976bac87c7154ccbf63 GIT binary patch literal 5871 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 HxIzB{6%-qo literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-23.png b/katabatic/doc/images/GCellConfiguration-23.png new file mode 100644 index 0000000000000000000000000000000000000000..be407d03a4069fc80e8db52a3dc50d17620dba0d GIT binary patch literal 6440 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 RDW4{K&{c-_4*w~C{{?$HBB=lX literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-24.fig b/katabatic/doc/images/GCellConfiguration-24.fig new file mode 100644 index 00000000..a3d425f9 --- /dev/null +++ b/katabatic/doc/images/GCellConfiguration-24.fig @@ -0,0 +1,45 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +6 -270 -270 5175 3600 +6 1440 630 3105 1620 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 1530 675 1620 675 1620 1575 1530 1575 1530 675 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 1485 1035 1665 1035 1665 1215 1485 1215 1485 1035 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 3060 1125 1665 1125 +-6 +6 2565 1305 3105 2295 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 2610 1710 2790 1710 2790 1890 2610 1890 2610 1710 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 2655 1350 2745 1350 2745 2250 2655 2250 2655 1350 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 3060 1800 2790 1800 +-6 +2 2 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 5 + 0 0 5175 0 5175 3600 0 3600 0 0 +2 1 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 3 + 0 3150 3600 3150 3600 3600 +2 1 1 2 18 7 30 -1 -1 6.000 0 0 -1 0 0 2 + 3060 2475 -225 2475 +2 4 0 2 0 7 38 -1 -1 0.000 0 0 7 0 0 5 + 3240 2565 3240 1035 3060 1035 3060 2565 3240 2565 +2 1 1 2 18 7 30 -1 -1 6.000 0 0 -1 0 0 2 + 3150 -225 3150 1035 +4 0 0 30 -1 18 12 0.0000 4 135 615 45 3555 Global:\001 +4 0 0 30 -1 18 12 0.0000 4 180 1230 45 3330 Configuration:\001 +4 0 0 30 -1 18 12 0.0000 4 135 1035 1575 3555 North+West\001 +4 0 0 30 -1 18 12 0.0000 4 135 645 1575 3330 2-2-0-0\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 -135 2700 G\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 3285 -90 G\001 +4 0 0 40 -1 18 12 0.0000 4 180 1725 3285 2925 _southWestContact\001 +4 0 0 40 -1 18 12 0.0000 4 180 1665 3285 2700 _northEastContact\001 +-6 diff --git a/katabatic/doc/images/GCellConfiguration-24.pdf b/katabatic/doc/images/GCellConfiguration-24.pdf new file mode 100644 index 0000000000000000000000000000000000000000..7d5c44ddd719fefc5ef96c063be95b6762a455ab GIT binary patch literal 3111 zcmdT`c~BEq7zed#SF2QugQEDrQYa#OBq52F2q9b&6oT5?B-M~CxNXRW-31~Y@v672 zrKqT-+FEH1qV}#>OV#lxU@sIbo=gp`Xz@U$gAUraOMsBr8K-}Aru#>-`@Qe`-go_e z?**r-;wRw|A|&|4pX+xZ5`Y0Z<5gtJ6jV)Gvbgym5=t~^JZ0uc2B7g~14pVzBW)rT z3WVht(vXeVN{`J-p~v7p+4~;&D%xY!QI~H7XyeX@1;^9`mIqB6k@)4}eyYy<@7>y} z-*m^PZd!f7x=Uy2i&Y&>Y5vjK4*NB;U7=S+T`EslzH0Q2Gn;iQR0Y+ELz{Ff#Zk)D zz!-CN&#*bWb`LKoORZ(`y;CFEC(|;n9XPq^UhNx~L*CqWSABif#5LOoh8zECS+7sxxl~do{#n#7Xk*({$o88_XTDQABuCcP_PfOdq7tyv~=Zyy@?%=>i z%k|S`S7vND^w}#Xjw~&9lsOI`9Y#%lwqtNnM$B1l6vMRnY=8ZzviOq`o9DGIs=YX* zth4scIRASeo09(On0Iikbl_9l zkC=w~eMD4mJf(d4es1FOVcx~5WZ{inv0G<5lJ&pa1~*I--H9Lhv@NJL{O$ZbzevyB zJ!Q$s{rbW}{l2_YjeEzmczrl&_Qi^ZcQ5>Ao-9kN2}bZ0&Ee!=RYl3GjYk->R;zQH*QOfrf$aV@D=#TRk15WO$dMkO)*t6AS^Wq)3_2+AU3}^gQ4LL~XCpV|> zma3b=AL4Uv7A2H!IJbY!!_AS~hp$=ZuPI;m+O-FU2VZQt9?-D6O_3b6|NVrOC#sSr z6>eY_PLG)|W=m1a%DSSF%Q{?I>fi^(~R@Qoi}er$z*u?TUB#J#gUbAgpaQw>=pnnIc=gOauZEe4lGVi6$3Vm$&E z8PdW55kLJ1sv%iAmobto#6>DY8`DWni$df8bS7!zpn9B*OGxJ+HUQ2;2%5yx&>R=g zgFvXDvG5yuWI@+D6gk77Mn^CH zK*>au6o-^leY{VZltzV>6z*SI;%-|wIB8uc<3;+drUamp&e9y>+v#w|LmInJ)5bW3zz#o0qGo_pdvRGj_)=U)EL z3o8t@Gf9CictAs-Tj1G8S+W2wfC7!3Z(w*vU;(5C90)T9(T@R~A9xJ}tH1;)29BX@ zS{^8HiT~9LawVi5fq9@Qlu!)I@g4z&stwLp9DR{8ar0R%!s{StdTs{C(-$9<$OV)h z;C4oeDh({z9X9l3iLtO$&$o)o%p@VzL2lC`7>c2|-o>X2W%6G55}=8sIgjKhqhXSg zHk*Vngj8H>BY?k8q!461ti`XoR`$`sh$Uz?Wyxh-;&C^0ZwU_ujYmuPk_#;nmjAbD?4O%VD)z9&F#ZU2*CRY^aSZd&BM1V5tFJ9CmcpvJ$s{sQe=;7@ZhH75 z_9fsY!A+0Aq@K2z7@q!a{xGShOfL8IhevwKL~@sWImSSlNd{ij0h&$~kg!Jp)zCD& zAn@Z3&?HMH4Z1i8O;Q1EXz>LvQPj(~3QNOoSkJU{tb5*5qUY}xEN5Uiq49)7jv>Lp JaWmqPzX2mOI2Hf^ literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-24.png b/katabatic/doc/images/GCellConfiguration-24.png new file mode 100644 index 0000000000000000000000000000000000000000..5ab40997713afa68e283ff6321b3bf80b179036f GIT binary patch literal 3471 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 literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-3.fig b/katabatic/doc/images/GCellConfiguration-3.fig new file mode 100644 index 00000000..b4e5958a --- /dev/null +++ b/katabatic/doc/images/GCellConfiguration-3.fig @@ -0,0 +1,171 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 9450 2475 90 90 9360 2475 9540 2475 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 9450 1800 90 90 9360 1800 9540 1800 +1 4 0 2 0 7 40 -1 -1 6.000 1 0.0000 7200 2025 90 90 7110 2025 7290 2025 +1 4 0 2 0 7 40 -1 -1 6.000 1 0.0000 8325 2475 90 90 8235 2475 8415 2475 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 9450 3150 90 90 9360 3150 9540 3150 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 7200 900 90 90 7110 900 7290 900 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 8325 1350 90 90 8235 1350 8415 1350 +1 4 0 2 0 7 40 -1 -1 6.000 1 0.0000 8325 2025 90 90 8235 2025 8415 2025 +1 4 0 2 0 7 40 -1 -1 6.000 1 0.0000 7200 1575 90 90 7110 1575 7290 1575 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 3825 1800 90 90 3735 1800 3915 1800 +1 4 0 2 0 7 40 -1 -1 6.000 1 0.0000 1575 2025 90 90 1485 2025 1665 2025 +1 4 0 2 0 7 40 -1 -1 6.000 1 0.0000 2700 2475 90 90 2610 2475 2790 2475 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 3825 3150 90 90 3735 3150 3915 3150 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 1575 900 90 90 1485 900 1665 900 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 2700 1350 90 90 2610 1350 2790 1350 +1 4 0 2 0 7 40 -1 -1 6.000 1 0.0000 2700 2025 90 90 2610 2025 2790 2025 +1 4 0 2 0 7 40 -1 -1 6.000 1 0.0000 1575 1575 90 90 1485 1575 1665 1575 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 3825 2475 90 90 3735 2475 3915 2475 +1 4 0 2 0 7 40 -1 -1 6.000 1 0.0000 6525 1575 90 90 6435 1575 6615 1575 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 10305 2700 10395 2700 10395 3600 10305 3600 10305 2700 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 10260 3060 10440 3060 10440 3240 10260 3240 10260 3060 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 10260 3150 9540 3150 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 9450 2565 9450 3060 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 9450 1890 9450 2385 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 9810 1800 9540 1800 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 9810 1710 9990 1710 9990 1890 9810 1890 9810 1710 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 9855 1350 9945 1350 9945 2250 9855 2250 9855 1350 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 9360 2475 8415 2475 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 8325 2385 8325 2115 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 8235 2025 7290 2025 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 7200 1935 7200 1665 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 7605 450 7695 450 7695 1350 7605 1350 7605 450 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 7560 810 7740 810 7740 990 7560 990 7560 810 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 7560 900 7290 900 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 7200 990 7200 1485 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 8730 900 8820 900 8820 1800 8730 1800 8730 900 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 8685 1260 8865 1260 8865 1440 8685 1440 8685 1260 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 8685 1350 8415 1350 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 8325 1440 8325 1935 +2 2 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 5 + 5625 225 10800 225 10800 3825 5625 3825 5625 225 +2 1 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 3 + 5625 3375 8100 3375 8100 3825 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 3 0 1.00 60.00 120.00 + 6525 2925 6525 1710 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 6525 1485 6525 0 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 4680 2700 4770 2700 4770 3600 4680 3600 4680 2700 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 4635 3060 4815 3060 4815 3240 4635 3240 4635 3060 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 4635 3150 3915 3150 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 3825 2565 3825 3060 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 3825 1890 3825 2385 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 4185 1800 3915 1800 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 4185 1710 4365 1710 4365 1890 4185 1890 4185 1710 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 4230 1350 4320 1350 4320 2250 4230 2250 4230 1350 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 3735 2475 2790 2475 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 2700 2385 2700 2115 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 2610 2025 1665 2025 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 1575 1935 1575 1665 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 1980 450 2070 450 2070 1350 1980 1350 1980 450 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 1935 810 2115 810 2115 990 1935 990 1935 810 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 1935 900 1665 900 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 1575 990 1575 1485 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 3105 900 3195 900 3195 1800 3105 1800 3105 900 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 3060 1260 3240 1260 3240 1440 3060 1440 3060 1260 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 3060 1350 2790 1350 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 2700 1440 2700 1935 +2 2 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 5 + 0 225 5175 225 5175 3825 0 3825 0 225 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 3 0 1.00 60.00 120.00 + 1575 2925 1575 2160 +2 1 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 3 + 0 3375 2475 3375 2475 3825 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2700 1935 2700 2115 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 1575 1485 1575 1665 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 1485 1575 -225 1575 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 3825 2385 3825 2565 +2 1 0 2 0 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 6615 1575 7110 1575 +4 0 0 30 -1 18 12 0.0000 4 135 615 5670 3780 Global:\001 +4 0 0 30 -1 18 12 0.0000 4 180 1230 5670 3555 Configuration:\001 +4 0 0 30 -1 18 12 0.0000 4 135 495 7200 3780 North\001 +4 0 0 30 -1 18 12 0.0000 4 135 645 7200 3555 1-4-0-0\001 +4 1 0 40 -1 18 12 0.0000 4 180 1725 6525 3150 _southWestContact\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 6615 135 G\001 +4 1 0 40 -1 18 12 0.0000 4 180 1725 1620 3150 _southWestContact\001 +4 0 0 30 -1 18 12 0.0000 4 135 615 45 3780 Global:\001 +4 0 0 30 -1 18 12 0.0000 4 180 1230 45 3555 Configuration:\001 +4 0 0 30 -1 18 12 0.0000 4 135 435 1575 3780 West\001 +4 0 0 30 -1 18 12 0.0000 4 135 645 1575 3555 1-4-0-0\001 +4 1 12 40 -1 18 12 0.0000 4 135 180 4275 3105 Lt\001 +4 1 12 40 -1 18 12 0.0000 4 135 285 4050 1665 Lct\001 +4 1 12 40 -1 18 12 0.0000 4 135 285 2925 1215 Lct\001 +4 1 12 40 -1 18 12 0.0000 4 135 285 1755 765 Lct\001 +4 1 0 40 -1 18 12 0.0000 4 135 105 3240 2655 L\001 +4 1 12 40 -1 18 12 0.0000 4 135 105 3915 2205 L\001 +4 1 12 40 -1 18 12 0.0000 4 135 105 3915 2880 L\001 +4 1 0 40 -1 18 12 0.0000 4 135 210 2835 2340 Lc\001 +4 1 0 40 -1 18 12 0.0000 4 135 105 2115 2205 L\001 +4 1 0 40 -1 18 12 0.0000 4 135 210 1710 1890 Lc\001 +4 1 12 40 -1 18 12 0.0000 4 135 180 9945 3105 Lt\001 +4 1 12 40 -1 18 12 0.0000 4 135 285 9675 1710 Lct\001 +4 1 12 40 -1 18 12 0.0000 4 135 285 8550 1260 Lct\001 +4 1 12 40 -1 18 12 0.0000 4 135 285 7425 810 Lct\001 +4 1 12 40 -1 18 12 0.0000 4 135 105 9540 2880 L\001 +4 1 12 40 -1 18 12 0.0000 4 135 105 9540 2205 L\001 +4 1 0 40 -1 18 12 0.0000 4 135 105 8865 2655 L\001 +4 1 0 40 -1 18 12 0.0000 4 135 105 7740 2205 L\001 +4 1 0 40 -1 18 12 0.0000 4 135 105 6840 2205 L\001 +4 1 0 40 -1 18 12 0.0000 4 135 210 8460 2340 Lc\001 +4 1 0 40 -1 18 12 0.0000 4 135 210 7335 1890 Lc\001 +4 1 12 40 -1 18 12 0.0000 4 135 105 2790 1755 L\001 +4 1 12 40 -1 18 12 0.0000 4 135 105 1665 1305 L\001 +4 1 12 40 -1 18 12 0.0000 4 135 105 8415 1755 L\001 +4 1 12 40 -1 18 12 0.0000 4 135 105 7290 1305 L\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 -135 1800 G\001 diff --git a/katabatic/doc/images/GCellConfiguration-3.pdf b/katabatic/doc/images/GCellConfiguration-3.pdf new file mode 100644 index 0000000000000000000000000000000000000000..55a7f4d147f0e038e004b1fc643946a984b85612 GIT binary patch literal 9296 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 literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-30.fig b/katabatic/doc/images/GCellConfiguration-30.fig new file mode 100644 index 00000000..79c79d7c --- /dev/null +++ b/katabatic/doc/images/GCellConfiguration-30.fig @@ -0,0 +1,128 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +6 -270 0 6570 3600 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 2160 1575 90 90 2070 1575 2250 1575 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 2160 900 90 90 2070 900 2250 900 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 3520 895 90 90 3430 895 3610 895 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 3510 1350 90 90 3420 1350 3600 1350 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 1353 1578 183 183 1170 1578 1536 1578 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 4953 1350 183 183 4770 1350 5136 1350 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 4950 450 90 90 4860 450 5040 450 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 1350 450 90 90 1260 450 1440 450 +2 1 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 3 + 0 3150 2700 3150 2700 3600 +2 2 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 5 + 0 0 6300 0 6300 3600 0 3600 0 0 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + -225 450 1260 450 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 5040 450 6525 450 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 900 1620 900 1530 1800 1530 1800 1620 900 1620 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 2475 945 2475 855 3150 855 3150 945 2475 945 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 1710 1485 1890 1485 1890 1665 1710 1665 1710 1485 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 2385 810 2565 810 2565 990 2385 990 2385 810 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 3060 810 3240 810 3240 990 3060 990 3060 810 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 4275 1395 4275 1305 5400 1305 5400 1395 4275 1395 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 4185 1260 4365 1260 4365 1440 4185 1440 4185 1260 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 1890 1575 2070 1575 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 2160 990 2160 1485 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 2250 900 2385 900 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 3240 900 3420 900 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 3510 990 3510 1260 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 3600 1350 4185 1350 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 1350 1395 1350 540 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 4950 1170 4950 540 +4 0 0 30 -1 18 12 0.0000 4 135 615 45 3555 Global:\001 +4 0 0 30 -1 18 12 0.0000 4 180 1230 45 3330 Configuration:\001 +4 0 0 30 -1 18 12 0.0000 4 135 945 1575 3555 East+West\001 +4 0 0 30 -1 18 12 0.0000 4 135 645 1575 3330 2-0-3-0\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 -135 675 G\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 6435 675 G\001 +4 1 0 40 -1 18 12 0.0000 4 180 765 4860 1755 _rightRP\001 +4 1 -1 30 -1 18 12 0.0000 4 135 210 1485 1035 L1\001 +4 1 -1 30 -1 18 12 0.0000 4 135 210 5085 945 L2\001 +4 1 0 40 -1 18 12 0.0000 4 180 660 1350 1935 _leftRP\001 +4 1 0 40 -1 18 12 0.0000 4 180 1725 1350 270 _southWestContact\001 +4 1 0 40 -1 18 12 0.0000 4 180 1665 4950 270 _northEastContact\001 +-6 +6 7200 -270 13500 3870 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 9360 1575 90 90 9270 1575 9450 1575 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 9360 900 90 90 9270 900 9450 900 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 10720 895 90 90 10630 895 10810 895 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 10710 1350 90 90 10620 1350 10800 1350 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 10350 1800 90 90 10260 1800 10440 1800 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 12825 900 90 90 12735 900 12915 900 +2 1 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 3 + 7200 3150 10125 3150 10125 3600 +2 2 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 5 + 7200 0 13500 0 13500 3600 7200 3600 7200 0 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 12825 810 12825 -225 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 10350 3825 10350 1890 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 8100 1620 8100 1530 9000 1530 9000 1620 8100 1620 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 9675 945 9675 855 10350 855 10350 945 9675 945 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 8910 1485 9090 1485 9090 1665 8910 1665 8910 1485 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 9585 810 9765 810 9765 990 9585 990 9585 810 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 10260 810 10440 810 10440 990 10260 990 10260 810 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 11475 1395 11475 1305 12600 1305 12600 1395 11475 1395 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 11385 1260 11565 1260 11565 1440 11385 1440 11385 1260 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 9090 1575 9270 1575 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 9360 990 9360 1485 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 9450 900 9585 900 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 10440 900 10620 900 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 10710 990 10710 1260 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 10800 1350 11385 1350 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 12735 900 12105 900 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 11925 1800 10440 1800 +2 4 0 2 0 7 40 -1 -1 0.000 0 0 6 0 0 5 + 12105 1890 11925 1890 11925 810 12105 810 12105 1890 +4 0 0 30 -1 18 12 0.0000 4 135 615 7245 3555 Global:\001 +4 0 0 30 -1 18 12 0.0000 4 180 1230 7245 3330 Configuration:\001 +4 0 0 30 -1 18 12 0.0000 4 135 1125 8775 3555 North+South\001 +4 0 0 30 -1 18 12 0.0000 4 135 645 8775 3330 2-0-3-0\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 12960 -45 G\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 10485 3825 G\001 +4 1 -1 30 -1 18 12 0.0000 4 135 210 12465 1080 L2\001 +4 1 -1 30 -1 18 12 0.0000 4 135 210 11160 1980 L1\001 +4 2 0 40 -1 18 12 0.0000 4 180 1665 12735 675 _northEastContact\001 +4 0 0 40 -1 18 12 0.0000 4 180 900 12240 1845 biggestRP\001 +4 2 0 40 -1 18 12 0.0000 4 180 1725 10170 1890 _southWestContact\001 +-6 diff --git a/katabatic/doc/images/GCellConfiguration-30.pdf b/katabatic/doc/images/GCellConfiguration-30.pdf new file mode 100644 index 0000000000000000000000000000000000000000..24064df461b7efd0c6e8ccfc42f0d3c3a768cf25 GIT binary patch literal 7433 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 t(vUTnrWx{ki0q7trW8r8C{0H2gtY`oL literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-30.png b/katabatic/doc/images/GCellConfiguration-30.png new file mode 100644 index 0000000000000000000000000000000000000000..0ac65c097494ed0448297f7b8262922ba944b0bb GIT binary patch literal 6285 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 ZA98Od60?M2bm34)6cS)&=Cool@Nf5WcrO3| literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-31.png b/katabatic/doc/images/GCellConfiguration-31.png new file mode 100644 index 0000000000000000000000000000000000000000..c42d755f37d9b39463c01c8d7b764240a54792e6 GIT binary patch literal 5662 zcmeHLc|4T++kPx#-{&9QF_SHljGYYg8>e%A?|GNs=kxya{_%c3zdz=g?|h%{bI%LR%Y|I7u zWcUC85VZK!#2x@RL|Ef#9(LBz>Tq%)>x&opt8+L22w3lZ*amv5Y*>?u5vCU+9725~ zqCLZW08&>tT064teSpPEsysKk=q_6=cnvDsD z2|JTEj^s$+9Dp`CGu=Psx4+F^eQQwoSTiTU=nJLV63*c6sq(1;N}hSH_9r4kI@kb< zK{x%A5OE+LVJEpG(5zE?iEXe&Qy)+&bL3l9K=1;0K4;4T@p&C($0e))0K&RD3H>6C z6t@y-bRNU643T=WL=|>FJdX)lc(6#SHITb7DpyAmg+5FXoH}u|FiRo5vy9E3liE};U7GqdlfkJIO%4YzmSD>% zT&?ecV#omV#Uqe-UH|v230qXc7oWl zg!mjaSawn>L0pVqcsS6w4HerXXtSRCLXwGsGz&cJS>ki7l2 z`-DO3H`-12v0!1m7ghqJ;ctR0GzU#ek8!*RxKZA3&vir6~_}X*D$bqfKMXQ2b+?0MkZRs`m z;0Afy7pWN>U!aHMbV_y&v)*6*nzk%^H92!)a$iS$Y`cD&sP-xQX}lH)fy*K&8aCR_ zvb=Z!h{NEpd*+V&QuZX){MEAD*zbyWQWfB{{NP$dF3nzB^DK-~Jv{V{ZcASnXsfDk zy>Vetevs^%J2KNs5<$TH1P3`T=Ov|@b0q|-yEmZbLsB_T#XjJvn3o6Fz`F{T5>~=@ z8oV;4wsg8=NTEKI=cI)C>23YRr?b}gw632Z)<8tec7w z2th|?3`&9M_N;kjZP%AYUG@z!O<)&~)BHPju>)v2O`?B@zj%FqGi6L%DSRoE5 z_YqZy4U_4E*|GeV)o#?$JW7%o z4}Oh1fej*Vtrthk?tY;ziZ0%VnH;BF%!Jb;(DM%9bheyseNe2!@)tK5$A$5QAq=}a zlo(RxF~JwD>3AqFTbaw9vr=L*9VA=ULuAvcszw$bQw8JQREggbplP(a>*&<91Ertw z?^2zhLUGeS?z#!W>10Y~wtab?oI2mqKRBcv&gO+qyNgb>q^w{3m|esUF-W652)7gh zO8gg=*LF?$DSdX+P_fX0HJ{qQLAfA;C{`hw<@XM0z6unA8yj9U{V>{|3M@j29_8&+ z?EIL>#-%amGG*LI?F0umMar0rL+nu3BSNZyu#8#HfRizU5?e zz`#Q|c_xpN0mBHos}gCVE!rqwUn!`6BdJ8586R@1h@ zN#e;&tN3o&kPel5T3S_p1_8Bm^C7WMUbgI9-7I;?EfwE0$&b4)h_ZcLP{=0NFrax< zGA-`;!r^^fap*LsEAil}koULlQa{G|Ss2P>!8r1`#3jAo+OUoQziE3IOdtzEET*P$nF+eSWp64AMxS4zILg_pt%Dm5A8~b7&Hl#?YiBUl!TcPW@$s z{xyl9?#_AogMRKC35Lx6fsi1VBA1+6Lg`(XICf#lvNQD3G3b0lVTTEHxt z$8AW;jhv!5{@ZsNAACOgUUTYPL*mD<4eH@zz< zVXs`N3=z+7^|5waB5LY4bt)zlA-HeD4OfSUli~^so!kPsu9$N_HqUN&+$*E{Qd&yQ zMwe2VVji|6G?=5FxQa;waBUh|4#2lCvx|}CZ}SwtwY|kUz0dXZ%171cC<+og2A6v%xBEEM>|^V{#(WYmZ!wj5wp2t(nPTzu|X{a+#GVF|ak3ll<`V!5oGU605s&WPzYa z8aoWOT8v8|o_GrWmERuCny+4MIZolE7niO#!yFN}^p8i5u=mZa-V<{Ac>g@K=?XfC zG4U0Fb!!+XLI-qaEX`LrZ4+0dr3SL@XIj*4wUxWuWSJ$caXQ`WDF`wB>KMSO5ZLDp zIYu^uJ>_W&Un%AiR`(MYvFXrmEEA$`0>U<9uccI%qEbHu)qUF1nav zUa)rInl*P3smOi3gLgp>fyFsNI$`&A%gP9! zLD3^{|I7Q619CnvB^MiNnsH_^oQkAv9(1KR;%Wb`DYaJM$oHX-YikL!yBYWiPcJ%_ zVV{(h4si40t!7%HIHejsu%1lLwZ)+YOy9Dug2-y;KGzZB!+-L!jWYktSk2UYqJQPb zGs44%BTCLd>2^Q+4rR%kSW79ERJa3cr?Ic(7&Td z3Oda46=y0cdJ;`opo}u|{W7hYDaWZQwYLrRXedsp`1IRmY}*qT-A(a-!*OBO;L zmMwf-srL2W#Zh15?8a)Co$hZl)ZR=pC1>P64CSuX8xuIm5b*s%rxs|sy?*3-(YXCK z7|pl($QGve3njZ2uFo}Yj%;-=zV9`OPBR-~&?)dWoiW;3l`TzBs;85|)pi8yr^5`0 z|BmYFD4j~oMCBVpEl*j%gS4n&rVGq8hoKq62eiC;R@!lkA!-5!4JYom^R*;CLJ8xl zF`BuC-`1I&nc&%5GoKdQgMID2#S~Sx;=0VwJ?|-B<#qWmbj$!v%OfrH^5V7l4uY-x zaxSZ<8U7f*=4%MY6E93I?|MmLd>37B4|8PGu4`Cs zW9v_G?y-lM+M2Zn7@5^XIB$Xed850htQxrrBOc>+ zVTysK7z3ghP~y?-4e9;HNB0*LnubW-sr9^Tg^}h4-bvI>m8i1n@)(u>EUU;_!c@|O zt;aaU#b-c_s1XW72UL=7B`2NTH>U(wu3ttaDKhJchJfRJ z5446=^fVB|5{-gczx_C8l|f6OZ`v&kd9qxrY0!DEexfs94|WqG!o|+8x-Ni)sf`K# zvpuSS5;|<(?40$27-Ly0MNTT#s&b@+N{nA$ZC9W lvKlcW0xU{`{d?ly@8jRw;r~@OoOo@^*lYbz>d-gg#5ju^X0jVM`;!3?7@lbNx!NS2~flx$@=p+qH0 zC5aT3(_$-2ld@H|bc#4fi|>7hYH-f^y1uKc>pI{3!MykLJooZ@?)Scb&odfpP0h7I z9V|-Yc7JRp3J+iamWMCOzyNJSWqNac00Jx_qs{3IE|m?S%^4If)s*VV@}e3VqBvYO zmEwmAPQB*j%=*b}{+^~kWd@6PJ>iW=#$F|ro~d0@ctkvMEpg`3(;SaO@^3~)P7mbw zrt67!5|cO975nD(H99={B{tOcB6Rv>#wUZ+#85-KzWY(nn>5tV?K^n-&10>_O%0WM zH%d2ldc^21wmaD|-p{d4?QYsVV?7HA?W$$*X!hg77TL|o z7m_KC70mFgf_m(Z^frsG5#w7rv>@w&C00*Kn(sqY{pw2^-F^@LC2n=Q>4Cg^mI;F; zwT>=rLk_W4IjiwX7SNt%zwZN|V`9Q3>Gj$LrBo?*OQ0$oRUbi-b zZDJckWS6d3zB)0(9c57aB;$TqNXaMnh3b8(kJ4;JXqLR3j%(JR=D&OsalPaMK-p+E z=*4NH$S#J&0=2FZMQ3S6o{F%$|FcQYWgq$1ai;pEkzpwvxt`YRQqm^r47q>Nq>CS0s*1|aT)eA>=$;8D(c&;Aiatrnt z>ni>3K&-~4xkiNfdBSSq4-D+KEJ!*-QHo-81jhKL_T4(55X}tCE%FZZ8_tvk&0}KX zKQWivyPR4uut-74|K6cOH(ruVN;nPQ;Qs7jyIM6v{3*S~=4q`LVaBP4eNs_%M0G0O zSN)}x^<#QshpfkTUix|0=#pDCt>`y|2mTFaA-A31QF}5qQ$5e#^7BiJY!G|xxNmDx zc5!C1+A!Vy>RtwA@dIUpHK~o+ndfy2Jf#xosa&Y_%p%$LJ9}oY320nYJ zl#Si14N->EN;sRnUXY7IF>LWM{sKmQ=0Kfl~|E zomabHD zD~Jqkfio(uyW36wekrU~V~H|`0xuMyMIV!%yW>J$v&y`>)&R360GBndom;A^sGmMh zDLlARGSMCFbW`WxPaV~#97ppoy__wZ!l)5L>bW&%gx7pnpP}$E-$wa0-8W`b8Q1in zt*Cdt=(W+x@P|3Y*XMV5G!;l@RwZX%i1g~|rS)0}y)a!i>mk-!W1Z{mSrN4vq*7OYMI+s`gZJOU|Rg*|#4b^wSM#Lt15oV*L+d5PclY9ta^(DQ6xw#$9TcImNeeV?L^L)CUyB{qEDk1?q=Fx(d;#x zGzV)h9;4{DG2)Tg+0ybQOW$_IXF-Z3NBl34%YF7Md0r{yKvx4+LX)0sD~y|Vadc3GD8 zr(V%l_cs(Zc>6v{D7!HxY#o%#t6eOW?^lIRRx!dK`9raG=B}RQT^4df-)=VLT(Ir=Gc{}pP)~GEVdbKDZyRhX^=zG&o@u0~w@ALKY`OahIuS2l<>w6o; z-6dA)u2?LdMY$~uDke64)bQ)mdOuU5_t3M0VT8gId+$myO^5zQJr3_T>4bR&QF_P9 zLb|B+;x=XG5u2`uN37@lEe*`vZ+iifJJBw3QeYRSOIKL zDhDPwYuPMMdn(r%4O1Why`CD(g{PYZb1m$-Fv$TR-SH*nEO!SD}eO1Gc>hmZFqCmtCGMWq# zP|!Hl(!0G%9Xkb(sAGsDCY z4Gq6AN$h%zkckOk19mOz67gqWF%r>p*|WA@$da~Y_wp|PiX*Zo*eCo&*}_7e!jgFi z^po=i{G2fG2LHWDkN`vUtu|$r$&(V4G`khM6^wQrC$V*s;+H0s<(wl~t)nkX+F2Za zNI0oXJeiBy;)v<0586xUf})?-2Q>r*2F_s5U@(TR$#BD<2Y>3FxU#j%s46hfC0z&Q zyMJb^%iH0H4lR&`wVzXNiPz(7%^Dl|gr4g++O9wE&6U0*b4OH2b`xgl^dKRDeEItz zzbmc~^fl%F-sHa=SMZyH{I0lyU#rIdZ@z*^;h3m1f1f2^DoNXH?@&}`CfuZ@BFXt$iF>EfyTurE(p1T zNf#5oP@*%v0SHMiGTOw4!baE`2Y|ac2=HqpOx`d6zd$3L3ymzarEuBwU}r=pJcRsp z<;zJh4dk;xcquHQvpHNuBY;8MP$s^D=nZr)t`El!@8KpOb-3avnicMqr$Wk=9$hY3>t$5T?KRsFcd@!5((Op$_S)# z>7EpA5{u!*cY_~_05(`YxtioDOk%!}Pl5EA?CB(DaCo#Iof*Ip@P|+D1Y?}CCs+j8 z>3hQ8DgK^(rp7;LPx$@_`uhd;|9wvc`V$|#sSqH%U^)c+4M89n$Kr=&C02l@Oy2AN z9RWU}7esX`1mlE%%9{y|pMhWq_^s#%zL{77-t@gN;Gbmv34`&I&J+yzCyw#z^!Y^i zquvC8_W!*w;2+`s2?KtNQ!6z8bil`ee>C}#c_6?Iz8ePc+dcsS+=aXXJgIC=GyAoG zg%69v<#@8`Tetub#Oq)nE%-VB{t1LjXE9CTI|EHqeF%dgVstTBkO=AF_26+^me*eo zeL15Cv#B%`2EYgOhQJ3`d;i3r-g~3rwDe#p2)=Gew5O zPq(WFM?YmAM8Ly^VDef>moUu+9z;@f@;oeoI1K|Vak>oxNSJO{PY=EonW7Iw=*eUm zo`9RS7KcG-#pHQ7Xu1uYp6;|bAUtxTGkGn9$4`^N&`;YBJcck`2I)<+fye&^_C%!2 zO}0zG=uVemu>vwKn?h$$+3>H40NS3ujSA;DfF`q8@Z}fMPyw_Rlg0v&ZU)y5D^tK( vQ`{r&uF*w7>CLgb3voN>4mHkbeEz$pNtG&IcY%u)XVtM;8+ literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-32.png b/katabatic/doc/images/GCellConfiguration-32.png new file mode 100644 index 0000000000000000000000000000000000000000..d8edc01e685dedd6169e04259124da1244a2c09a GIT binary patch literal 6092 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 literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-33.fig b/katabatic/doc/images/GCellConfiguration-33.fig new file mode 100644 index 00000000..37ea4802 --- /dev/null +++ b/katabatic/doc/images/GCellConfiguration-33.fig @@ -0,0 +1,74 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +6 -270 13230 6570 17370 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 2160 15075 90 90 2070 15075 2250 15075 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 2160 14400 90 90 2070 14400 2250 14400 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 3520 14395 90 90 3430 14395 3610 14395 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 3510 14850 90 90 3420 14850 3600 14850 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 4815 16200 90 90 4725 16200 4905 16200 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 4815 13950 90 90 4725 13950 4905 13950 +2 1 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 3 + 0 16650 3780 16650 3780 17100 +2 2 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 5 + 0 13500 6300 13500 6300 17100 0 17100 0 13500 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 900 15120 900 15030 1800 15030 1800 15120 900 15120 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 2475 14445 2475 14355 3150 14355 3150 14445 2475 14445 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 1710 14985 1890 14985 1890 15165 1710 15165 1710 14985 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 2385 14310 2565 14310 2565 14490 2385 14490 2385 14310 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 3060 14310 3240 14310 3240 14490 3060 14490 3060 14310 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 4275 14895 4275 14805 5400 14805 5400 14895 4275 14895 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 4185 14760 4365 14760 4365 14940 4185 14940 4185 14760 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 1890 15075 2070 15075 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 2160 14490 2160 14985 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 2250 14400 2385 14400 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 3240 14400 3420 14400 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 3510 14490 3510 14760 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 3600 14850 4185 14850 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 4815 15390 4815 16110 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 4815 17325 4815 16290 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + -225 16200 4725 16200 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 4905 13950 6525 13950 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 4815 13860 4815 13275 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 4815 14040 4815 14310 +2 4 0 2 0 7 40 -1 -1 0.000 0 0 6 0 0 5 + 4905 15390 4725 15390 4725 14310 4905 14310 4905 15390 +4 0 0 30 -1 18 12 0.0000 4 135 615 45 17055 Global:\001 +4 0 0 30 -1 18 12 0.0000 4 180 1230 45 16830 Configuration:\001 +4 0 0 30 -1 18 12 0.0000 4 135 2175 1575 17055 North+South+East+West\001 +4 0 0 30 -1 18 12 0.0000 4 135 645 1575 16830 4-0-3-0\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 -135 16425 G\001 +4 0 0 40 -1 18 12 0.0000 4 180 900 5040 15345 biggestRP\001 +4 1 -1 30 -1 18 12 0.0000 4 135 210 4680 15840 L1\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 4725 17325 G\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 6435 14175 G\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 4950 13410 G\001 +4 2 0 40 -1 18 12 0.0000 4 180 1665 4635 13995 _northEastContact\001 +4 1 -1 30 -1 18 12 0.0000 4 135 210 4995 14265 L2\001 +4 2 0 40 -1 18 12 0.0000 4 180 1725 4680 16110 _southWestContact\001 +-6 diff --git a/katabatic/doc/images/GCellConfiguration-33.pdf b/katabatic/doc/images/GCellConfiguration-33.pdf new file mode 100644 index 0000000000000000000000000000000000000000..0d08c952f4ae4144d44326eea3457ed795d48d3d GIT binary patch literal 4457 zcmds5c~leU7RRLDYhvq9}+^K>-)4Agv<$zKKDW=z0C4r{}zvKa!dI-Fv@#fA`Ms zev|3$j(ls(h7L`?_;~99hzX;xVtEK;Ym2zy@*px8W&w#1;S(|vSHcKiCMI!5T%riX z?d%{Gsl>&hP;~kkUsr{hvyuEn_w25ko0Vk!R&&44^2a(!%*v)%Le7ygtDi!M^qx%)ezil4TV|Iov>@JFFm022E zZ79AzB!F-DJ4V-^3!(!2)SDK2JcqQ(^ zlk$G^s5vuS%qXo>@2z^jiFt3ucJ`sLqOK{rI zUzb0;xi|GfT5QTN`|R&pn{VtUc2xe5`DtF=Zf4?6v0>hU$_hokbCu;M-`9@t>io*B znZD=LsvS`tCe^-%^F=230anij50|;c;Sywvo?pWj{VB|+UDY${nPB%g=`)8AGejSPMBg!49uta?0Nb>ZRWb%j%>wcsPOWd$L* zaxYfy5)<#cSk4_EZ%_3JnT%Z)AJu+kRc_>Te)az3;!!@(iiNc^EuxOcq%D5xb5Fv` z-!ISpj+l9knI4;T`>gftt!9t!onURWkD`kN3AIT@=`NRV4a>Tm@vQjCix<`R8#~$O zewDQdc-~X*#^teFk9J(V+f&^5;6=&(#)sYN;*zdy)>THcVwj4t%R@pFTkrQgEG}2) z#1jQm8t)|SJ&^eG`PEC^PFtnA2Cdz8j)+`zFn!E|q2_w`0#j_4PBwGswzuAs{iMez zd$n<6dqWKO_2!n?<+l&lqF=FGdxx=q@eBFQ%;LE)hlL9iR08Y5VuofZx|{>2%pu7nHO*xy5to!LvVp zZCd0SmnYzJTvJ9pJ8hJ>f8I;eitkIt`G`kJvsNkG#u#(8JLR{(R2tGNNJjW~dN;86ur zY%hd>NE;Tl#XI%~-auTiCNLF@xDtUX*bkz@7DE0o@DM?{>}QI-H`Q7?h)JHtZBkQarWR!9@&q1)RchSXwcCfJ78vXzp)en`=~~n#RugSw^R=k!QIV0KDnFIU zI)5HVuAx=D7|4k$v;p_ijDs3rvK{=JBYs!iZcP1%E3vOkO#pu3IrkI5G+HRKLVfrL=1NXjFOB5q>sC5HGCfn>1C z52AD+#4}t|H#wI}%bU4yFkhAAS&u zpa|yQ=Tk$NTA!2`3IfChmqp?vArV{i6tX}~7&_RzuV{vuzz}O$ijmy=+ln#ss?@MQ( zfOrPRLT9o1$w;M`kl{-3R|kxE5-V{~a~KgS6yRJ7h(`z`0=ZNHYe)t{1dgzur7P#! r&Gp~z-Iu*_#;Eznf7vxlSK?0{iB+UnNopF2&SA2k>C>GS^P&F$Bi?OI literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-33.png b/katabatic/doc/images/GCellConfiguration-33.png new file mode 100644 index 0000000000000000000000000000000000000000..256e3b5ceca83aebc83c860ef442a876279c2dbb GIT binary patch literal 4107 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 V|1V&OV5QmqgTPqS&HpRI{s}U_h8h3> literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-34.fig b/katabatic/doc/images/GCellConfiguration-34.fig new file mode 100644 index 00000000..5b2aac4b --- /dev/null +++ b/katabatic/doc/images/GCellConfiguration-34.fig @@ -0,0 +1,67 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +6 -270 18000 6300 21870 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 2160 19575 90 90 2070 19575 2250 19575 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 2160 18900 90 90 2070 18900 2250 18900 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 3520 18895 90 90 3430 18895 3610 18895 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 3510 19350 90 90 3420 19350 3600 19350 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 4815 20250 90 90 4725 20250 4905 20250 +2 2 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 5 + 0 18000 6300 18000 6300 21600 0 21600 0 18000 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 900 19620 900 19530 1800 19530 1800 19620 900 19620 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 2475 18945 2475 18855 3150 18855 3150 18945 2475 18945 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 1710 19485 1890 19485 1890 19665 1710 19665 1710 19485 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 2385 18810 2565 18810 2565 18990 2385 18990 2385 18810 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 3060 18810 3240 18810 3240 18990 3060 18990 3060 18810 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 4275 19395 4275 19305 5400 19305 5400 19395 4275 19395 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 4185 19260 4365 19260 4365 19440 4185 19440 4185 19260 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 1890 19575 2070 19575 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 2160 18990 2160 19485 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 2250 18900 2385 18900 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 3240 18900 3420 18900 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 3510 18990 3510 19260 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 3600 19350 4185 19350 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + -225 20700 5535 20700 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 4815 19530 4815 20160 +2 4 0 2 0 7 40 -1 -1 0.000 0 0 6 0 0 5 + 4905 19530 4725 19530 4725 19170 4905 19170 4905 19530 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 4905 20250 5535 20250 +2 4 0 2 0 7 40 -1 -1 0.000 0 0 6 0 0 5 + 5715 20790 5535 20790 5535 20160 5715 20160 5715 20790 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 5625 21825 5625 20790 +2 1 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 3 + 0 21150 3780 21150 3780 21600 +4 0 0 30 -1 18 12 0.0000 4 135 615 45 21555 Global:\001 +4 0 0 30 -1 18 12 0.0000 4 180 1230 45 21330 Configuration:\001 +4 0 0 30 -1 18 12 0.0000 4 135 1065 1575 21555 South+West\001 +4 0 0 30 -1 18 12 0.0000 4 135 645 1575 21330 2-0-3-0\001 +4 0 0 40 -1 18 12 0.0000 4 180 900 5040 19620 biggestRP\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 5535 21825 G\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 -180 20880 G\001 +4 1 -1 30 -1 18 12 0.0000 4 135 465 4545 19890 L1-tc\001 +4 2 0 40 -1 18 12 0.0000 4 180 1725 5490 20565 _southWestContact\001 +-6 diff --git a/katabatic/doc/images/GCellConfiguration-34.pdf b/katabatic/doc/images/GCellConfiguration-34.pdf new file mode 100644 index 0000000000000000000000000000000000000000..997e84a225244791122b83084ffbe22a5debf655 GIT binary patch literal 4406 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 literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-34.png b/katabatic/doc/images/GCellConfiguration-34.png new file mode 100644 index 0000000000000000000000000000000000000000..d7a178b98a8644a34a2493d8f223f09d1a343391 GIT binary patch literal 3617 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 DXVMcD literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-35.fig b/katabatic/doc/images/GCellConfiguration-35.fig new file mode 100644 index 00000000..c30ff532 --- /dev/null +++ b/katabatic/doc/images/GCellConfiguration-35.fig @@ -0,0 +1,111 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +6 0 22500 6570 26100 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 2160 24075 90 90 2070 24075 2250 24075 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 2160 23400 90 90 2070 23400 2250 23400 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 3520 23395 90 90 3430 23395 3610 23395 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 3510 23850 90 90 3420 23850 3600 23850 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 4815 24750 90 90 4725 24750 4905 24750 +2 2 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 5 + 0 22500 6300 22500 6300 26100 0 26100 0 22500 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 900 24120 900 24030 1800 24030 1800 24120 900 24120 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 2475 23445 2475 23355 3150 23355 3150 23445 2475 23445 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 1710 23985 1890 23985 1890 24165 1710 24165 1710 23985 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 2385 23310 2565 23310 2565 23490 2385 23490 2385 23310 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 3060 23310 3240 23310 3240 23490 3060 23490 3060 23310 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 4275 23895 4275 23805 5400 23805 5400 23895 4275 23895 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 4185 23760 4365 23760 4365 23940 4185 23940 4185 23760 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 1890 24075 2070 24075 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 2160 23490 2160 23985 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 2250 23400 2385 23400 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 3240 23400 3420 23400 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 3510 23490 3510 23760 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 3600 23850 4185 23850 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 4815 24030 4815 24660 +2 4 0 2 0 7 40 -1 -1 0.000 0 0 6 0 0 5 + 4905 24030 4725 24030 4725 23670 4905 23670 4905 24030 +2 1 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 3 + 0 25650 3780 25650 3780 26100 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 4905 24750 6525 24750 +4 0 0 30 -1 18 12 0.0000 4 135 615 45 26055 Global:\001 +4 0 0 30 -1 18 12 0.0000 4 180 1230 45 25830 Configuration:\001 +4 0 0 30 -1 18 12 0.0000 4 135 405 1575 26055 East\001 +4 0 0 30 -1 18 12 0.0000 4 135 645 1575 25830 1-0-3-0\001 +4 0 0 40 -1 18 12 0.0000 4 180 660 5040 24120 rightRP\001 +4 1 -1 30 -1 18 12 0.0000 4 135 210 4680 24390 L1\001 +4 2 0 40 -1 18 12 0.0000 4 180 1725 4635 24660 _southWestContact\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 6480 24930 G\001 +-6 +6 6930 22500 13500 26100 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 9360 24075 90 90 9270 24075 9450 24075 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 9360 23400 90 90 9270 23400 9450 23400 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 10720 23395 90 90 10630 23395 10810 23395 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 10710 23850 90 90 10620 23850 10800 23850 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 8550 24750 90 90 8460 24750 8640 24750 +2 2 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 5 + 7200 22500 13500 22500 13500 26100 7200 26100 7200 22500 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 8100 24120 8100 24030 9000 24030 9000 24120 8100 24120 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 9675 23445 9675 23355 10350 23355 10350 23445 9675 23445 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 8910 23985 9090 23985 9090 24165 8910 24165 8910 23985 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 9585 23310 9765 23310 9765 23490 9585 23490 9585 23310 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 10260 23310 10440 23310 10440 23490 10260 23490 10260 23310 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 11475 23895 11475 23805 12600 23805 12600 23895 11475 23895 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 11385 23760 11565 23760 11565 23940 11385 23940 11385 23760 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 9090 24075 9270 24075 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 9360 23490 9360 23985 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 9450 23400 9585 23400 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 10440 23400 10620 23400 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 10710 23490 10710 23760 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 10800 23850 11385 23850 +2 1 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 3 + 7200 25650 10980 25650 10980 26100 +2 4 0 2 0 7 40 -1 -1 0.000 0 0 6 0 0 5 + 8640 24255 8460 24255 8460 23895 8640 23895 8640 24255 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 8550 24255 8550 24660 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 6975 24750 8460 24750 +4 0 0 30 -1 18 12 0.0000 4 135 615 7245 26055 Global:\001 +4 0 0 30 -1 18 12 0.0000 4 180 1230 7245 25830 Configuration:\001 +4 0 0 30 -1 18 12 0.0000 4 135 435 8775 26055 West\001 +4 0 0 30 -1 18 12 0.0000 4 135 645 8775 25830 1-0-3-0\001 +4 1 -1 30 -1 18 12 0.0000 4 135 210 8415 24525 L1\001 +4 2 0 40 -1 18 12 0.0000 4 135 555 8325 23940 leftRP\001 +4 0 0 40 -1 18 12 0.0000 4 180 1725 8685 24795 _southWestContact\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 7020 24930 G\001 +-6 diff --git a/katabatic/doc/images/GCellConfiguration-35.pdf b/katabatic/doc/images/GCellConfiguration-35.pdf new file mode 100644 index 0000000000000000000000000000000000000000..779c3f696d66ec547666aaf9cdfba6cfc7174dd1 GIT binary patch literal 7051 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 literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-36.fig b/katabatic/doc/images/GCellConfiguration-36.fig new file mode 100644 index 00000000..43e883bc --- /dev/null +++ b/katabatic/doc/images/GCellConfiguration-36.fig @@ -0,0 +1,64 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +6 0 26775 6300 30645 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 2160 28350 90 90 2070 28350 2250 28350 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 2160 27675 90 90 2070 27675 2250 27675 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 3520 27670 90 90 3430 27670 3610 27670 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 3510 28125 90 90 3420 28125 3600 28125 +1 4 0 2 0 7 40 -1 -1 0.000 1 0.0000 4815 29025 90 90 4725 29025 4905 29025 +2 2 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 5 + 0 26775 6300 26775 6300 30375 0 30375 0 26775 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 900 28395 900 28305 1800 28305 1800 28395 900 28395 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 2475 27720 2475 27630 3150 27630 3150 27720 2475 27720 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 1710 28260 1890 28260 1890 28440 1710 28440 1710 28260 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 2385 27585 2565 27585 2565 27765 2385 27765 2385 27585 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 3060 27585 3240 27585 3240 27765 3060 27765 3060 27585 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 4275 28170 4275 28080 5400 28080 5400 28170 4275 28170 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 4185 28035 4365 28035 4365 28215 4185 28215 4185 28035 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 1890 28350 2070 28350 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 2160 27765 2160 28260 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 2250 27675 2385 27675 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 3240 27675 3420 27675 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 3510 27765 3510 28035 +2 1 0 2 12 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 3600 28125 4185 28125 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 4815 28305 4815 28935 +2 4 0 2 0 7 40 -1 -1 0.000 0 0 6 0 0 5 + 4905 28305 4725 28305 4725 27945 4905 27945 4905 28305 +2 1 0 2 0 7 40 -1 -1 6.000 0 0 -1 0 0 2 + 4905 29025 5535 29025 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 5625 30600 5625 29115 +2 1 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 3 + 0 29925 3780 29925 3780 30375 +2 4 0 2 0 7 40 -1 -1 0.000 0 0 6 0 0 5 + 5715 29115 5535 29115 5535 28935 5715 28935 5715 29115 +4 0 0 30 -1 18 12 0.0000 4 135 615 45 30330 Global:\001 +4 0 0 30 -1 18 12 0.0000 4 180 1230 45 30105 Configuration:\001 +4 0 0 30 -1 18 12 0.0000 4 135 525 1575 30330 South\001 +4 0 0 30 -1 18 12 0.0000 4 135 645 1575 30105 1-0-3-0\001 +4 0 0 40 -1 18 12 0.0000 4 180 900 5040 28395 biggestRP\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 5535 30600 G\001 +4 1 -1 30 -1 18 12 0.0000 4 135 465 4545 28665 L1-tc\001 +4 2 0 40 -1 18 12 0.0000 4 180 1725 5490 29340 _southWestContact\001 +-6 diff --git a/katabatic/doc/images/GCellConfiguration-36.pdf b/katabatic/doc/images/GCellConfiguration-36.pdf new file mode 100644 index 0000000000000000000000000000000000000000..6b21257b557dc85d70c1e5d41fe8c7c995314a34 GIT binary patch literal 4374 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 ls|*Ak55=q9e6n#QLp4ebj zT&NWVj0#q0p`uu=BC@;|ML|WhE>t$FxS(JwXgd=?f!IF3@AdQh`sR;h?z#7zd$xOi z=gvGo7qzyx7XvLY6+vxB^a;+0qoXoFLDkQ*w(gi;W46A3V(i!f3W zC3J8AWSCSahyxP8tO@q`IMQAFqmqZgCn9N1yC3{w|GC#0_~^PivZ?bF6U9-mHDvpL zZZ!sz3-qJuecI7X74ko&xDAs*-gIXSaO% zgtu|8k?=BAciZP?{#k(s_*w@{Yj-&*1|L2-&|B9zbADi%{q{W_$%8$b{nZDp204|6 zWdX72ytdFHJzF;;-z(Mc-FlJO+Xzm(*J6;jC~vwuw_-+PuW4!j{efJi!S1aq-MPB8 znhRfE-~FZeRok`#+OMnU%qi`vMhtw(7E?Ct-sjE%`mw9c7R?}MB{xNdaV(5|zW9ol>=jfL%%IrinrnuU zR=ju+(eKi7vuw$ebQ5d+&>m8*N5E!<(ThcQi#^eZz>K9Am#l?M{VeTrzW*fL{@jtH zR+p{zWLnk?G}xkw(hmYAwN)KDF@?4rz3x+!<1$vnlfttP^KM&`Tr3?;mKiyw z)VPx#Bb2qv$k7L@p@%-kKBBSW|_U^Fq zPE6^-jkgvk;g_7Rw6D(9&`fR)&c3e!R!uFvRh}7fBCnjJe=tX*G4*gU=vk-LVwEGC z;33bKG7L7Z57k~!yL){FpF9<<(Kb)NMs2zyPbZ0u?VJ)k+&C>Bmg4nN{){E}z{KW2 zGVoDIv)&~cLfYVIhH8Qr7}{y+hc3HtocBKWqZDrnsZZn`Q1DQ~UJF?X+ z)p-8Bvd5ox^8^`1H>n!_Kk*Y? z`@F)Hfv!bmSL{o6QjRx;Wt4o&+wVE>VZl-VJc@9!fMVFM320Rm+bGJeQIPLu748bw zKj}!(Ot@_xIoF}w&_rJ&;`a~M{2Z=LF7U2kVtz(H-qdDgHH8FaUo86aS<;#nb$501 zy80S$AVv4SoG?x?TtFeQy6!a)xT`{eX>)AS*Nb`%w!;_FeOh%zf|W=zkC|= z2TMxB_WlRU`eHA4ey%uHl7D!>xXk*|Rj2AYMo_R_lT)sC_JC`NPk!-1-~9cH$#bvy z=rYeNjqRs7+wA*p3(eDTeYBTjzTM>R5Z$v}qeC^T;y9u*bKoi2TKW8`;kRlrROg4zXTKfzR)AdeUot4sTOR`SPI~Aavf$3gvAXcrA+u7< zP8T;Aq#i0CxN|-8T<_r1WZBDm@+YfaDx51$E7Q6A9`|l4$volL&8GNK6fg9Dw(2fy zTSVUJE)j~OhO0ULMj!xD_lbXm!Lk8{X^hwC5SX+|2>A(C3Lzh16e@6*B!b~EK5fHc zfiwmq0>CGwLNNx?3H$&co=_%PEsYe)aAfh5N+JVg!C_b@l@Y^|c`Sh7 z$Q$GQ^|70FCe>58@##08w#4JT|}{rZMnvjFp6pLhK=s9*xl>AkJVr zIJ^RDdLXR9<$~TwyJh=?cxk2M1P*__Uz5h-=v5gXw#QfH=qshl_(@WdMkHxkG2!H~ znSqR?1|G^k-x9IGo$RB2(Z<|f+HtME0uFH3pTJP9uzT^7?rOqDysO65e$I>>F zc6>j1CkCuq0=G9MY_Msk{kx+np*cY=pD3Lu5f(>5gBDwCnZiCu!)1!RBu;lE}N^2>rQ{ zf3II(=kfosUx`$H$A0C!&6fZ0e0?h$neba5Nm6SrAMS81;-majzQ)$L>Ebt>5u#N6 z*I53;9jhwM!$zt=kANi{uEh8q2oM%7W3$nj}8bZ;M@mP8;`E*SE~yYs-Pp5gEE zfT|Vxt1K95pT@gDFRsX=rsJ?jpfB}J8HHuXlyka!eQeDZyYbo zQPY{uvQg8SX2VkR6^+Hl6KbqHx(#vf7)wLgZ2Z)Zqj3;58l6d3m&bzDX&i>y9t=d? z4hDlc$~H_YKt)0+{$UY>0?=gqmd6GmoyLLTC12{?q6kcSHxPUTa*Zn!+I nb;=HFn)sajuXwV>8%PnvT~3Axq?jr-88%D?FmIl#uN&|O0{L?h literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-4.png b/katabatic/doc/images/GCellConfiguration-4.png new file mode 100644 index 0000000000000000000000000000000000000000..56f654613ac9ee87a83d8005a96419e25742e0d3 GIT binary patch literal 6126 zcmeHL`9IX(_kWp8%#avljj<0CB}H#0gX~*lYcR&7lCotFZ+m1Z$riE=S>MBurI@VQ zcVQ??wn3J%RhH0adVl(UAMbzQ`@{F~c>i!8_dd?O=iGD8ecp4=InfwnofA-gC;$K_ z^mH{%0RU7>A8#{*eo?NcHPJhWo35270I(YUY79gDrN(rku$Pvlm)X7BUia-h>;Ww^ z3|!~VJx?#sn;v)Fyx^DQFUp-epW>5w3II4c^fcAYeKS5!;Sw^GVE`tzhUJS@mv2We zlOhib`_)jPrSO(_MrK@Kt%SVrPmy+?06_6zX_Xrw!W#FFRxRMs!40+yfa57~c67`K zuqhURC(E1c@;%%n6n@7@dV_(4R9M8_m|TsV5pKZup*iu|3KXcba}0cH%B6#62vO4I z=$60&Gkm1is879?47DJj*l_vn?$x_Fn0+Mh6!TPAmq$O33;?ZPvzQnF%_1ZK$a{bR z_@d2p`^VC=n3N8jh*tEo!?M+*AK#QWYV3H8rTDar*!;ynh$^&&BQ7A}X3t2E;A@Xjr8< zq{l4vtT~v>ynSP1S!%?w2XH&B)3(eLKBBxTkn8r_sT@c;!VZz>X5|yUw z9VHNV$2-FDbgf)=f5-OEX%4@$4*Ve{o!l~9cU_}Yf)W}$+k*YR0lVQ1u~cOb(d_J3 zOPup~cA>lcQFQ^eAT^Fj1uLX?1k@<-@ScW`TIASR8-i6YyfW313dkGmB^%Y-mYBCb?S(@>koidpsgi7*GKYS-nf~&p};!d*ql7`)w6@{jJ1WpPV}AonZ<2(Xrj1U6Xdcd7piY@OUd2=8x< z0XHTUx=g+Y1x_kJT5BC(z*yV(Ao&8$Y=r=ODv>7vd?k20@0KSva~ zEC+vMN(`CzOc1FB4eV2Q(BFgb9(?nDHgS7a2kK_M&}S&)M)r3?gcjCJ<-?QcmWpCf z$aC>7?tOF^p+mZvAZ6BGP6=N)*|Sh~q)Z4p=U!V?I@Z6GJ-|n(hjBh)@dhn})TR<> z&}J)i>iI+Edo0We(X(-#%RV0~&K(L~P|mPkT5$T&2&P7rRFVNxz^z4ncg+Ek-Mzb3gi;x-C**Y*{%G7dxQKXn!=|^6I-KtD*HEr;4>g9Ek`8lh8 z!75E>SwAO}?J;uJ@{elQkLnk1c%KG{nge6pVT%X$eCV1PTiLDke$QKr3oHgYsu9J~(YAxlKO~G7=Vv&7~p}yUjg8i?< z+wdpr)+WRohh;}gtKIZWGe9#W15FAS)JA01CV0Q%%jX%0?!n*CyqpozXy%~L zU$I3~nf=kqiqCYXwc%f;8)9GB-zF9fhAot1fw7vCx!3lQ7aYHZTBZmy>Kici$Btp0Nv#ATFyLXr3lthU5Bxkp4h+ zYPzcr=G1XhvludU%E2_T)TugL`>PX2-z$)0Zfk~3jz&eeSlH)Eex8tL(J;jcu`dpD{2{?Ran@~Qg{`wBD6;1cm3myuzKt;HX59%1ge^SxphBy`xcV?DD zmLS?>Z3c*>L>kLvO!T;Gre ztxc4uQ_JUIqfDD@j`yG&^K&;5IVVJ&tOacceVId)@N%-O=$6P*-rR5-5i_%~@G@*3 zq;PLp=v20~8i*qiWjr#!Ce@uh&ZRQ6gmImr?l+0$MCtSSu zi|L*$tvBFvC2g-c`|wO!>bO|KZPwgYnoTm!0u|5N7_T$*eSjq)MOMi-efl$3HlE;Zgmddz6yaw7@Oo=-Z5ZF>A0b+I?*yEr3I;dt8xqCHw0s3iYV;LHejjshoaMM zQI>R0?Jo~>dtBH)IPSq_rEeZF7e8Qf?xV{A0H#uCREGnyN& z7`2p~CDB@X?fcdmfBnjR&&9a_MWely*$Y~`e8)5S(zyjMcB~%6wMO z_+_NH;x`%Pq)D%wO?EeRj5+3J(GZH*)-sN|X=yyrk;xWE2f-{u>@7${0Z8XUkP;W8 z+=$LJgiWbT?+X_%e;mvs0>|G4bF|-4Cq_J&GY`#)IN?EO5hV~Uz}|Z=nM5#}_ena> zRXQTp+L0zVM6s9pUQ3B?YsYL{yQ;!LAv>KfIbA1JSL_0#yAV%nAxr7yO2YKmqH(xd z^n6?WsYlRp$>L&U#yqJqe=aKyLlWgb-5E*&NjYEKO3p%5P1dI=8ZFQ^%E85=Rf zTAn(-$oKW2tT{tH_p&kMd^c4>n2=bi6l*AQQ6R$yA!Q?`Zzx08T!yt*xV1sqVPmXx zZ)sU80MbMC99(R&CHhNzg!$>O3~7{3d@k`{fljSy9_@XM6-Q>535cnLt<;{W?HWxt zH^nknET%`iP^o9y>cUs_$C#JV{0%DEXFItWpNkQv~0-&H(l4* zWX$frXpz#4*7t~54rmNm+~1l+WmhOW407cBe4+C6N=d`==vG(wWsTF%Wu$uRG1hn7 zNd44df}OXH(DWOeXFJcE@%qh~=Zt3jKShIbqefgvKR*9((pVhtg-OPtf<5$-c&UlV zCTXqkkarIP-HS}s35yk6Rdx@O15gA1a784m=@A zHxuc6nBjT?*U#-3T!&Pcn|pZpoGIvS5Yw*C3YT28j%A!*yJ$~Wl~+Y;v+8uY+E%j+t7Bq^H5C@Gjg z%eZ`U5XT)>iq-O2a16EE^Vt@Z*s^t)uJ@m}z)UgpT~5ra_GY%2mMUVF9gD3zk7m+g z4CG*ISmD5}=SMoTOe*MEZ`$A}PmhHj;hOFDr8_zx4T%<$RxLi}!hQ7kQFf~?q(pF% zgH-t0UWomICCc>jxc^>yb!@LinwS{(XEsX=zopmw-lpbaL^;A8H?Z)6X_}?sf#7Gb>W&w$a*4jBZcaf zQ*f<5cX^h1O`i_=6Jf!JLZG#Qn%L%n00S+C_sIy1uMp$vEy(m1iW&Z;Z%MtA8}8JD z%Mn7cEy#1s)JNnuT1X@Ums~sxp%NS znzU(^q2BY8BO(L)bwq$&=m+_pj5GbOsjOTOZ&0tih=&EiXXH2Ff}l5hLqxxUH+ zzo67op;@Ns`$uo7*Q=^s)!{h&7MO`3*FBg-HFKuv(%oAW%uT&vUXd)+?#_2=IBc$? z??Xt_2Q?A>CUD#Wbb55|RrllRn5u*lCcPm@ocylQg8N%6h6Jl66vabxZE z#@ptMB|CO5^u7L98NwCS+z26*MK<0%i|GkMeUUuIU4S@uNKvj=;pBf-Huc<>7NK+d zk)VMRC($pvr1Q_y87@vvg!B`(mHU|}Z}Bg33gIq=|jP2unB@LT&M zaq9cIfu0mWXQwli$nAiI2PZxLBDn>KO$s{Yf08wnPBdrywAHw4;D~8KQia;t64l9kYmcT zKI|N8FSk~%hyb&h{;7a5=aZlu6PWD}t)nc=vs{QWONV{OM%i4|l=N|$9`Ptky&svL z5lq`VwW=8Nlyq$1n*xc2AXn>Ilo(kE(keB{oltppQajo;-m=v|6*o~i7~5+!@VIP4 zx8Os+{THuRauAJ0V7s$=yjr5=0b|VkGc1Sa6MNh5hWOdVo$Ar`Ls#{CsmrIL1H{#w z@k)%9Mg|l3^L1)OOJ&pV!lw$*nX#}d#sly3;5?oYV$C(mW+oBEMFE1FcM1#%Hfl-!-TP9Z;RZiplKG zLk|pWU!5nr?#Z0(>6~;5%^gL&lLfW)-Siu;BjJv=o}0Z6$X3vET|3;*dtcZfC0n_( zs_?~ZUJ>-WhU66t4!ncAz3v&luGh16D03)$wTPsoImAn^wgG^ima!&T<9b;1|9vIy z*y`^}+^9T56P&%N$@FKIF!)x)tg(7~N!lI&upLb>08PVnAOQ1k`_~5lV&MNT1{D1j O8RwN?>AC;(G5-Om(0gA1 literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-40.fig b/katabatic/doc/images/GCellConfiguration-40.fig new file mode 100644 index 00000000..bf5e41fa --- /dev/null +++ b/katabatic/doc/images/GCellConfiguration-40.fig @@ -0,0 +1,81 @@ +#FIG 3.2 +Portrait +Center +Metric +A4 +55.00 +Single +-2 +1200 2 +6 4140 5355 4410 6345 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 4185 5760 4365 5760 4365 5940 4185 5940 4185 5760 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 4230 5400 4320 5400 4320 6300 4230 6300 4230 5400 +-6 +6 10215 5355 10485 6345 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 10260 5760 10440 5760 10440 5940 10260 5940 10260 5760 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 10305 5400 10395 5400 10395 6300 10305 6300 10305 5400 +-6 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 3600 5850 90 90 3510 5850 3690 5850 +2 2 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 5 + 0 4500 5175 4500 5175 8100 0 8100 0 4500 +2 1 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 3 + 0 7650 3375 7650 3375 8100 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 2835 6525 -225 6525 +2 1 0 2 12 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 4185 5850 3690 5850 +2 1 0 2 12 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 3600 5940 3600 6435 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 2250 7155 3825 7155 3825 7245 2250 7245 2250 7155 +2 2 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 2835 7110 3015 7110 3015 7290 2835 7290 2835 7110 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2925 7110 2925 6615 +2 4 0 2 0 7 38 -1 -1 0.000 0 0 6 0 0 5 + 3735 6615 2835 6615 2835 6435 3735 6435 3735 6615 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 9675 6615 9675 8325 +2 2 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 5 + 6075 4500 11250 4500 11250 8100 6075 8100 6075 4500 +2 1 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 3 + 6075 7650 9450 7650 9450 8100 +2 1 0 2 12 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 10260 5850 9765 5850 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 8325 7155 9900 7155 9900 7245 8325 7245 8325 7155 +2 2 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 8910 7110 9090 7110 9090 7290 8910 7290 8910 7110 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 9000 7110 9000 6615 +2 4 0 2 0 7 38 -1 -1 0.000 0 0 6 0 0 5 + 9765 5760 9585 5760 9585 6615 9765 6615 9765 5760 +2 4 0 2 0 7 38 -1 -1 0.000 0 0 6 0 0 5 + 9090 6435 8910 6435 8910 6615 9090 6615 9090 6435 +2 1 0 2 -1 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 9585 6525 9090 6525 +2 1 0 2 0 7 38 -1 -1 0.000 0 0 -1 0 0 2 + 3285 6435 3285 6615 +2 1 0 2 0 7 38 -1 -1 0.000 0 0 -1 0 0 2 + 9585 6210 9765 6210 +4 0 0 30 -1 18 12 0.0000 4 135 615 45 8055 Global:\001 +4 0 0 30 -1 18 12 0.0000 4 180 1230 45 7830 Configuration:\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 -135 6480 G\001 +4 0 0 30 -1 18 12 0.0000 4 135 645 1575 7830 1-1-1-0\001 +4 0 0 30 -1 18 12 0.0000 4 135 435 1575 8055 West\001 +4 1 12 40 -1 18 12 0.0000 4 135 180 3915 5805 Lt\001 +4 1 0 40 -1 18 12 0.0000 4 135 180 3060 6930 Lt\001 +4 0 12 40 -1 18 12 0.0000 4 135 180 3645 6255 Lt\001 +4 2 0 40 -1 18 12 0.0000 4 180 1725 2745 6435 _southWestContact\001 +4 0 0 30 -1 18 12 0.0000 4 135 615 6120 8055 Global:\001 +4 0 0 30 -1 18 12 0.0000 4 180 1230 6120 7830 Configuration:\001 +4 0 0 30 -1 18 12 0.0000 4 135 645 7650 7830 1-1-1-0\001 +4 0 0 30 -1 18 12 0.0000 4 135 525 7650 8055 South\001 +4 1 12 40 -1 18 12 0.0000 4 135 180 9990 5805 Lt\001 +4 1 0 40 -1 18 12 0.0000 4 135 180 9135 6930 Lt\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 9810 8280 G\001 +4 2 0 40 -1 18 12 0.0000 4 180 1725 9495 5850 _southWestContact\001 diff --git a/katabatic/doc/images/GCellConfiguration-40.pdf b/katabatic/doc/images/GCellConfiguration-40.pdf new file mode 100644 index 0000000000000000000000000000000000000000..2de1c32d2e9a7bbd0365e18c7c28a1e6df699fac GIT binary patch literal 5061 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 Rq+652<_jQ8OW_=M=vVFg1xx?{ literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-40.png b/katabatic/doc/images/GCellConfiguration-40.png new file mode 100644 index 0000000000000000000000000000000000000000..ed77e55baf67ade0d892f8f6f8f1f3e73516edfe GIT binary patch literal 4425 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 AYybcN literal 0 HcmV?d00001 diff --git a/katabatic/doc/images/GCellConfiguration-41.fig b/katabatic/doc/images/GCellConfiguration-41.fig new file mode 100644 index 00000000..c3a293ba --- /dev/null +++ b/katabatic/doc/images/GCellConfiguration-41.fig @@ -0,0 +1,98 @@ +#FIG 3.2 +Portrait +Center +Metric +A4 +55.00 +Single +-2 +1200 2 +6 -270 9000 5490 12600 +6 4140 9855 4410 10845 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 4185 10260 4365 10260 4365 10440 4185 10440 4185 10260 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 4230 9900 4320 9900 4320 10800 4230 10800 4230 9900 +-6 +1 4 0 2 -1 7 40 -1 -1 0.000 1 0.0000 2925 9720 90 90 2835 9720 3015 9720 +1 4 0 2 12 7 40 -1 -1 0.000 1 0.0000 3590 10345 90 90 3500 10345 3680 10345 +2 2 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 5 + 0 9000 5175 9000 5175 12600 0 12600 0 9000 +2 1 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 3 + 0 12150 3375 12150 3375 12600 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 2835 11025 -225 11025 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 2250 11655 3825 11655 3825 11745 2250 11745 2250 11655 +2 2 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 2835 11610 3015 11610 3015 11790 2835 11790 2835 11610 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2925 11610 2925 11115 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 5445 9720 3015 9720 +2 1 0 2 -1 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 2925 9810 2925 10935 +2 1 0 2 12 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 4185 10350 3690 10350 +2 1 0 2 12 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 3600 10440 3600 10935 +2 4 0 2 0 7 38 -1 -1 0.000 0 0 6 0 0 5 + 3690 11115 2835 11115 2835 10935 3690 10935 3690 11115 +2 1 0 2 0 7 38 -1 -1 0.000 0 0 -1 0 0 2 + 3285 10935 3285 11115 +4 0 0 30 -1 18 12 0.0000 4 135 615 45 12555 Global:\001 +4 0 0 30 -1 18 12 0.0000 4 180 1230 45 12330 Configuration:\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 -135 10980 G\001 +4 0 0 30 -1 18 12 0.0000 4 135 645 1575 12330 2-1-1-0\001 +4 0 0 30 -1 18 12 0.0000 4 135 945 1575 12555 West+East\001 +4 1 12 40 -1 18 12 0.0000 4 135 180 3915 10305 Lt\001 +4 1 0 40 -1 18 12 0.0000 4 135 180 3060 11430 Lt\001 +4 2 0 40 -1 18 12 0.0000 4 180 1725 2745 10935 _southWestContact\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 5355 9675 G\001 +4 0 0 40 -1 18 12 0.0000 4 180 1665 2925 9540 _northEastContact\001 +4 0 12 40 -1 18 12 0.0000 4 135 180 3645 10755 Lt\001 +-6 +6 6075 8730 11565 12870 +6 10215 9855 10485 10845 +2 2 0 2 12 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 10260 10260 10440 10260 10440 10440 10260 10440 10260 10260 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 10305 9900 10395 9900 10395 10800 10305 10800 10305 9900 +-6 +1 4 0 2 -1 7 40 -1 -1 0.000 1 0.0000 8100 10350 90 90 8010 10350 8190 10350 +1 4 0 2 -1 7 40 -1 -1 0.000 1 0.0000 9000 11025 90 90 8910 11025 9090 11025 +2 2 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 5 + 6075 9000 11250 9000 11250 12600 6075 12600 6075 9000 +2 1 0 1 0 7 30 -1 -1 0.000 0 0 -1 0 0 3 + 6075 12150 9450 12150 9450 12600 +2 2 0 2 0 7 50 -1 45 0.000 0 0 -1 0 0 5 + 8325 11655 9900 11655 9900 11745 8325 11745 8325 11655 +2 2 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 8910 11610 9090 11610 9090 11790 8910 11790 8910 11610 +2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 9000 11610 9000 11115 +2 1 0 2 -1 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 8190 10350 9585 10350 +2 1 0 2 12 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 10260 10350 9765 10350 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 9675 11115 9675 12825 +2 1 1 2 18 7 30 -1 -1 4.000 0 0 -1 0 0 2 + 8100 8775 8100 10260 +2 1 0 2 -1 7 30 -1 -1 0.000 0 0 -1 0 0 2 + 9090 11025 9585 11025 +2 4 0 2 0 7 38 -1 -1 0.000 0 0 6 0 0 5 + 9765 11115 9585 11115 9585 10260 9765 10260 9765 11115 +2 1 0 2 0 7 38 -1 -1 0.000 0 0 -1 0 0 2 + 9585 10710 9765 10710 +4 0 0 30 -1 18 12 0.0000 4 135 615 6120 12555 Global:\001 +4 0 0 30 -1 18 12 0.0000 4 180 1230 6120 12330 Configuration:\001 +4 0 0 30 -1 18 12 0.0000 4 135 645 7650 12330 2-1-1-0\001 +4 0 0 30 -1 18 12 0.0000 4 135 1125 7650 12555 North+South\001 +4 1 12 40 -1 18 12 0.0000 4 135 180 9990 10305 Lt\001 +4 1 0 40 -1 18 12 0.0000 4 135 180 9135 11430 Lt\001 +4 2 0 40 -1 18 12 0.0000 4 180 1665 7965 10215 _northEastContact\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 7965 8910 G\001 +4 1 18 30 -1 18 12 0.0000 4 135 150 9585 12825 G\001 +4 0 0 40 -1 18 12 0.0000 4 180 1725 9810 11160 _southWestContact\001 +-6 diff --git a/katabatic/doc/images/GCellConfiguration-41.pdf b/katabatic/doc/images/GCellConfiguration-41.pdf new file mode 100644 index 0000000000000000000000000000000000000000..e13e946132824d53609a66605028e095e8ddce0d GIT binary patch literal 5322 zcmds5dpwkR7k5e4qm`0UYWL})Tzf7vV}@PUbub8nCAXT)gAp^#j7yeCvI&c5g%w#u zN*8Nh+ePw5l&+Mpl_Jw_#Jkw7w{3f$XHb}S-#(vrKYc#?&L7Nke!p{m=X}q3&iDLA z%h`%1WLd**D=dm$U zQ$Qf(W2{gh`kN-tR_=1DYWlI4>T#({c0Z_pw!Z;Z)sPKQ8aWTkVIlS^0c$+>X5GK0 zx7Rw-)qah=1^LUxTU)w4huz0x3(A~pN}b}kk?qiMW313Lt{_Lict+N%EF0n8GhbM{ z`-GjyaUpw=%VB+;L#O(qV_wCY=5;s}MIC$cS)dJjRnLJZ{xt>hCJ8TTHmrf2kn6vc zP8X^H#wKntn&O>z$Hoo?D#kmV9Q{(Hm~f}I(@GAmgR#j4t*5u>pHz_JLD9abuzqtixafY z4m|IOb5?B*F{{ih9b4cMruXeXtj_OGN=&Sy%Z@9H%W8JCwnmdPgB&(gcNXUs_tYFX zZ;F+I#a63J*YdZ>2G7l8*6rPVd`_ozY9OPrQgjcL4Wb$wL>6C4;{e?!HHzikOG+2z ztGFpJHXb~^>*R&)kq5VLdfC^$^%Ye+Q*STpQ+}DbwV&q_ZN}Gk){r%*t|KJHN1wK6n9eR=RhXTT6;U!&vEgK5#3F;+ z%h*?|u5O-xPh6!^?7w|LPdw%f