Advertisement
Crashguard303

CG303 Structure Changes V3.100

May 2nd, 2013
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 10.85 KB | None | 0 0
  1. --[[
  2. Structure Changes V3.100 by Crashguard303
  3.  
  4. part of my "cardinal segment detection" used in GA+EO Remix
  5. finds changes in secondary structures and
  6. creates a segment list, where changes do occur.
  7.  
  8. can also:
  9. -- freeze complete puzzle,
  10.    then unfreeze detected segments to use them as "ankles" or
  11. -- band detected segments to use them as scaffolding nodes
  12.  
  13. you can use this script:
  14. -- just for detection, or
  15. -> to protect the puzzle from breaking apart
  16.    while wiggling and turning the CI to low values ;)
  17. ]]--
  18.  
  19. function structure_changes_append(structure_changes,seg_count)
  20. -- scan secondary structures of all puzzle segments (1 to seg_count)
  21. -- append segment indices with ss changes to table structure_changes
  22.  local structure_changes= structure_changes
  23.  
  24.  local seg_count2= seg_count-1
  25.  
  26.  local i=1
  27.  -- initialize segment iterator
  28.  -- (position 1 -> first segment of puzzle)
  29.  while i<seg_count2 do
  30.  -- with iterator i,
  31.  -- cycle through all puzzle segments (but not last)
  32.        local ss1=structure.GetSecondaryStructure(i)
  33.        -- check ss of segment with index i
  34.        local ss2=structure.GetSecondaryStructure(i+1)
  35.        -- check ss of segment behind index i
  36.        if ss1~=ss2
  37.        -- are ss different?
  38.        -- primary, we want to find segments with loop-ss at the end of helix or sheet sections
  39.        -- but sometimes helices are directly near (adjacent to) sheets
  40.           then if     ss1=="L"
  41.                       -- loop found at i? (-> other ss: behind i)
  42.                       then table.insert(structure_changes,i)
  43.                elseif ss2=="L"
  44.                       -- loop found directly after i? (-> other ss: at i)
  45.                       then table.insert(structure_changes,(i+1))
  46.                            i=i+1
  47.                elseif ss1=="H"
  48.                       -- helix found at i? (-> other ss (but no loop): behind i)
  49.                       then table.insert(structure_changes,i)
  50.                elseif ss2=="H"
  51.                       -- helix found directly after i? (-> other ss (but no loop): at i)
  52.                       then table.insert(structure_changes,(i+1))
  53.                            i=i+1
  54.                end -- if ss1,ss2
  55.        end -- if ss1~=ss2
  56.        i=i+1
  57.        -- increase iterator
  58.        -- (next position -> next segment)
  59.  end -- while i<seg_count2
  60.  
  61.  return structure_changes
  62. end -- structure_changes_append()
  63.  
  64. function structure_changes_filter(structure_changes)
  65. -- remove duplicate entries from table structure_changes
  66.  local structure_changes= structure_changes
  67.  
  68.  local i=1
  69.  -- initialize element iterator
  70.  -- (position 1 -> first element of list)
  71.  while i<=(#structure_changes-1) do
  72.  -- with iterator i,
  73.  -- cycle through all (but not last) elements in list
  74.        if structure_changes[i]==structure_changes[i+1]
  75.        -- element at current position identical with direct next one?
  76.           then table.remove(structure_changes,(i+1))
  77.                -- remove next one
  78.                i=i-1
  79.                -- as element was removed,
  80.                -- we need to shift iterator
  81.        end -- if structure_changes[i]==structure_changes[i+1]
  82.        i=i+1
  83.        -- increase iterator
  84.        -- (next position -> next element)
  85.  end
  86.  
  87.  return structure_changes
  88. end -- structure_changes_filter()
  89.  
  90. function structure_changes_find(option)
  91. -- detect structure changes
  92. -- option.first=true: generally add first segment
  93. -- option.last= true: generally add last  segment
  94.  print("Detecting changes...")
  95.  
  96.  local seg_count=structure.GetCount()
  97.  -- get number of segments
  98.  
  99.  local structure_changes={}
  100.  -- initialize found list table
  101.  
  102.  if option.first -- activated?
  103.      then table.insert(structure_changes,1)
  104.           -- add first segment to list
  105.  end -- if option.first
  106.  
  107.  structure_changes= structure_changes_append(structure_changes,seg_count)
  108.  -- get segment numbers, where structure changes do occur
  109.  
  110.  if option.last -- activated?
  111.     then table.insert(structure_changes,seg_count)
  112.          -- add last segment to list
  113.  end -- if option.last
  114.  
  115.  structure_changes= structure_changes_filter(structure_changes)
  116.  -- remove duplicate entries
  117.  
  118.  return structure_changes
  119. end -- structure_changes_find()
  120.  
  121. function structure_changes_show(structure_changes,option)
  122. -- show detected structure changes
  123. -- if set, do some freezing or banding
  124.  
  125. -- option.freeze= true:        freeze complete puzzle and unfreeze detected segments
  126. -- option.sbands= true:        band detected segments with each other (scaffolding)
  127.  
  128. -- option.freeze_invert= true: invert freezing
  129.  
  130. -- option.sbands_mode= "grid": scaffold all detected segments with each other
  131. -- option.sbands_mode= "ring": scaffold all detected segments with next only
  132.  
  133. -- option.sbands_pitch =0:     use scaffolding - fix    seg's distances, how they are
  134. -- option.sbands_pitch >0:     use scaffolding - change seg's distances (expand   puzzle)
  135. -- option.sbands_pitch <0:     use scaffolding - change seg's distances (compress puzzle)
  136.  
  137. -- option.sbands_strength:     strength of scaffolding
  138.  print("\nFound changes:")
  139.  
  140.  if option.freeze -- activated?
  141.     then if option.freeze_invert -- activated?
  142.             then freeze.UnfreezeAll()
  143.                  -- unfreeze all segments
  144.             else freeze.FreezeAll()
  145.                  -- freeze all segments
  146.          end -- if option.freeze_invert
  147.  end -- if option.freeze
  148.  
  149.  local i
  150.  -- initialize element iterator
  151.  for i=1,#structure_changes do
  152.  -- by variable i, cycle through all elements in list
  153.  -- giving segments which have been found
  154.  
  155.      print('#'..i..': idx'..structure_changes[i])
  156.      -- show segment number
  157.  
  158.      if option.freeze -- activated?
  159.         then if option.freeze_invert -- activated?
  160.                 then freeze.Freeze(structure_changes[i],true,true)
  161.                      -- freeze segment number
  162.                 else freeze.Unfreeze(structure_changes[i],true,true)
  163.                      -- unfreeze segment number
  164.              end -- if option.freeze_invert
  165.      end -- if option.freeze
  166.  end -- for i
  167.  
  168.  if option.sbands -- activated?
  169.     then print("\nAdding bands:")
  170.     if   option.sbands_mode=="ring"
  171.          then sbands_apply_ring(structure_changes,option.sbands_pitch,option.sbands_strength)
  172.     else -- if option.sbands_mode~="ring" -> =="grid"
  173.               sbands_apply_grid(structure_changes,option.sbands_pitch,option.sbands_strength)
  174.     end -- if option.sbands_mode
  175.  end -- if option.bands
  176. end -- structure_changes_show()
  177.  
  178. function sbands_apply_ring(structure_changes,sbands_pitch,sbands_strength)
  179. -- using list structure_changes
  180.  local i
  181.  for i=1,#structure_changes do
  182.  -- by variable i (origin segment),
  183.  -- cycle through all elements in list structure_changes
  184.  -- giving segments which have been found
  185.      local j= i+1
  186.      -- target segment: next element to i in list
  187.      if j>#structure_changes
  188.      -- element index out of list range?
  189.         then j= 1
  190.         -- take first element
  191.      end -- if j
  192.      band.AddBetweenSegments2(structure_changes[i],structure_changes[j],sbands_pitch,sbands_strength)
  193.      -- band segment stored in element i to segment stored in element j
  194.  end -- for i
  195. end -- function sbands_apply_ring
  196.  
  197. function sbands_apply_grid(structure_changes,sbands_pitch,sbands_strength)
  198. -- using list structure_changes
  199.   local i
  200.   for i=1,(#structure_changes-1) do
  201.   -- by variable i (origin segment),
  202.   -- cycle from "first element" to "second last element" in list structure_changes
  203.   -- giving segments which have been found
  204.       local j
  205.       for j=(i+1),#structure_changes do
  206.       -- by variable j (target segment),
  207.       -- cycle from "element behind i" to "last element" in list structure_changes
  208.       -- giving other segments which have been found
  209.           band.AddBetweenSegments2(structure_changes[i],structure_changes[j],sbands_pitch,sbands_strength)
  210.           -- band segment stored in element i to segment stored in element j
  211.       end -- for j
  212.   end -- for i
  213. end -- function sbands_apply_grid
  214.  
  215. function band.AddBetweenSegments2(i,j,sbands_pitch,sbands_strength)
  216. -- i:               origin segment index
  217. -- j:               target segment index
  218. -- sbands_pitch:    add this to measured distance, giving band length
  219. -- sbands_strength: strength of bands
  220.  
  221.  if (math.abs(j-i))>1
  222.  -- bands not directly near each other?
  223.     then local band_GetCount1= band.GetCount()
  224.          band.AddBetweenSegments(i,j)
  225.          -- band segment i to segment j
  226.          local band_GetCount2= band.GetCount()
  227.  
  228.          if band_GetCount2>band_GetCount1
  229.          -- has band been added?
  230.             then local length= structure.GetDistance(i,j)+sbands_pitch
  231.                  if length<0
  232.                     then length= 0
  233.                          -- to prevent errors
  234.                  end -- if length
  235.                  band.SetGoalLength(band_GetCount2,length)
  236.                  -- set length of applied band to measured distance (scaffolding)
  237.                  -- +/- sbands_pitch
  238.                  band.SetStrength(band_GetCount2,sbands_strength)
  239.                  -- set strength of applied band to sbands_strength
  240.                  print('#'..band_GetCount2..': idx'..i..':idx'..j..' l:'..length..' s:'..sbands_strength)
  241.          end -- if band_GetCount2>
  242.  end -- if >1
  243. end -- function band.AddBetweenSegments2
  244.  
  245. -- get list containing those segments where ss changes occur
  246. -- and remove duplicate entries:
  247. structure_changes= structure_changes_find({first=true;last=true})
  248. -- first=true: generally add first segment
  249. -- last= true: generally add last  segment
  250.  
  251. -- show results:
  252. structure_changes_show(structure_changes,
  253.                        {freeze=true;
  254.                         -- activate freezing?
  255.                         freeze_invert=false;
  256.                         -- invert freezing?
  257.                         sbands=false;
  258.                         -- activate bands?
  259.                         sbands_mode="ring";
  260.                         -- band mode?
  261.                         sbands_pitch=0;
  262.                         -- change segment distance by?
  263.                         sbands_strength=1}
  264.                         -- band strength?
  265.                       )
  266.  
  267. -- you should activate either freeze or bands:
  268. -- freeze= true:        freeze complete puzzle and unfreeze detected segments (detected segments serve as "ankles")
  269. -- freeze_invert= true: invert freezing
  270.  
  271. -- sbands= true:        band detected segments with each other                (detected segments serve as scaffolding nodes)
  272. -- sbands_mode= "grid": scaffold all detected segments with each other
  273. -- sbands_mode= "ring": scaffold all detected segments with next only
  274.  
  275. -- sbands_pitch:        add this value to measured segment distance, giving band length
  276. -- sbands_pitch =0:     fix    seg's distances, how they are
  277. -- sbands_pitch >0:     change seg's distances (expand   puzzle)
  278. -- sbands_pitch <0:     change seg's distances (compress puzzle)
  279.  
  280. -- sbands_strength:     strength of scaffolding
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement