extract_curves 0.0.1-i586-linux

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. data/CVS/Entries +4 -0
  2. data/CVS/Repository +1 -0
  3. data/CVS/Root +1 -0
  4. data/bin/CVS/Entries +5 -0
  5. data/bin/CVS/Repository +1 -0
  6. data/bin/CVS/Root +1 -0
  7. data/bin/ec_rect2polar.rb +22 -0
  8. data/bin/ec_rev_lines.rb +5 -0
  9. data/bin/ec_sph_area.rb +30 -0
  10. data/bin/extract_curves.rb +2145 -0
  11. data/ruby_ext/CVS/Entries +1 -0
  12. data/ruby_ext/CVS/Repository +1 -0
  13. data/ruby_ext/CVS/Root +1 -0
  14. data/ruby_ext/pav/CVS/Entries +14 -0
  15. data/ruby_ext/pav/CVS/Repository +1 -0
  16. data/ruby_ext/pav/CVS/Root +1 -0
  17. data/ruby_ext/pav/extconf.rb +22 -0
  18. data/ruby_ext/pav/pav.so +0 -0
  19. data/ruby_libs/CVS/Entries +1 -0
  20. data/ruby_libs/CVS/Repository +1 -0
  21. data/ruby_libs/CVS/Root +1 -0
  22. data/ruby_libs/pav/CVS/Entries +20 -0
  23. data/ruby_libs/pav/CVS/Repository +1 -0
  24. data/ruby_libs/pav/CVS/Root +1 -0
  25. data/ruby_libs/pav/attr_cache.rb +211 -0
  26. data/ruby_libs/pav/attr_cache.t1.rb +32 -0
  27. data/ruby_libs/pav/cache.rb +31 -0
  28. data/ruby_libs/pav/dbg_log.rb +458 -0
  29. data/ruby_libs/pav/floatsio.rb +53 -0
  30. data/ruby_libs/pav/generator_cache.rb +165 -0
  31. data/ruby_libs/pav/gtk/CVS/Entries +4 -0
  32. data/ruby_libs/pav/gtk/CVS/Repository +1 -0
  33. data/ruby_libs/pav/gtk/CVS/Root +1 -0
  34. data/ruby_libs/pav/gtk/button.rb +130 -0
  35. data/ruby_libs/pav/gtk/icons.rb +87 -0
  36. data/ruby_libs/pav/gtk/toolbar.rb +192 -0
  37. data/ruby_libs/pav/heap.rb +54 -0
  38. data/ruby_libs/pav/icons/CVS/Entries +17 -0
  39. data/ruby_libs/pav/icons/CVS/Repository +1 -0
  40. data/ruby_libs/pav/icons/CVS/Root +1 -0
  41. data/ruby_libs/pav/icons/alt_handle.xpm +3832 -0
  42. data/ruby_libs/pav/icons/alt_handle_hover.xpm +3368 -0
  43. data/ruby_libs/pav/icons/alt_handle_pressed.xpm +3828 -0
  44. data/ruby_libs/pav/icons/extract_curves/CVS/Entries +6 -0
  45. data/ruby_libs/pav/icons/extract_curves/CVS/Repository +1 -0
  46. data/ruby_libs/pav/icons/extract_curves/CVS/Root +1 -0
  47. data/ruby_libs/pav/icons/extract_curves/extract_curves-icon-rgb.ppm +14 -0
  48. data/ruby_libs/pav/icons/extract_curves/extract_curves-logo-rgb.gif +0 -0
  49. data/ruby_libs/pav/icons/extract_curves/trace_mark.xpm +38 -0
  50. data/ruby_libs/pav/icons/handle.xpm +213 -0
  51. data/ruby_libs/pav/icons/next.xpm +29 -0
  52. data/ruby_libs/pav/icons/next_hover.xpm +315 -0
  53. data/ruby_libs/pav/icons/next_pressed.xpm +144 -0
  54. data/ruby_libs/pav/icons/prev.xpm +29 -0
  55. data/ruby_libs/pav/icons/prev_hover.xpm +315 -0
  56. data/ruby_libs/pav/icons/prev_pressed.xpm +144 -0
  57. data/ruby_libs/pav/icons/vnext.xpm +29 -0
  58. data/ruby_libs/pav/icons/vprev.xpm +29 -0
  59. data/ruby_libs/pav/numeric/CVS/Entries +2 -0
  60. data/ruby_libs/pav/numeric/CVS/Repository +1 -0
  61. data/ruby_libs/pav/numeric/CVS/Root +1 -0
  62. data/ruby_libs/pav/numeric/ext.rb +13 -0
  63. data/ruby_libs/pav/pav_find.rb +90 -0
  64. data/ruby_libs/pav/pix/CVS/Entries +11 -0
  65. data/ruby_libs/pav/pix/CVS/Repository +1 -0
  66. data/ruby_libs/pav/pix/CVS/Root +1 -0
  67. data/ruby_libs/pav/pix/aapix.rb +378 -0
  68. data/ruby_libs/pav/pix/blob.rb +543 -0
  69. data/ruby_libs/pav/pix/circle.rb +73 -0
  70. data/ruby_libs/pav/pix/contour/CVS/Entries +5 -0
  71. data/ruby_libs/pav/pix/contour/CVS/Repository +1 -0
  72. data/ruby_libs/pav/pix/contour/CVS/Root +1 -0
  73. data/ruby_libs/pav/pix/contour/calc_situations.rb +9 -0
  74. data/ruby_libs/pav/pix/contour/carp_calc.rb +212 -0
  75. data/ruby_libs/pav/pix/contour/situations.dmp +0 -0
  76. data/ruby_libs/pav/pix/contour/situations.rb +21 -0
  77. data/ruby_libs/pav/pix/contour.rb +644 -0
  78. data/ruby_libs/pav/pix/curve.rb +1508 -0
  79. data/ruby_libs/pav/pix/img_obj.rb +751 -0
  80. data/ruby_libs/pav/pix/node.rb +712 -0
  81. data/ruby_libs/pav/pix/node_grp.rb +853 -0
  82. data/ruby_libs/pav/pix/shaved_core.rb +534 -0
  83. data/ruby_libs/pav/pix/subpix.rb +212 -0
  84. data/ruby_libs/pav/pix.rb +402 -0
  85. data/ruby_libs/pav/rand_accessible.rb +16 -0
  86. data/ruby_libs/pav/rangeset.rb +63 -0
  87. data/ruby_libs/pav/search.rb +210 -0
  88. data/ruby_libs/pav/set.rb +20 -0
  89. data/ruby_libs/pav/string/CVS/Entries +6 -0
  90. data/ruby_libs/pav/string/CVS/Repository +1 -0
  91. data/ruby_libs/pav/string/CVS/Root +1 -0
  92. data/ruby_libs/pav/string/bits.rb +523 -0
  93. data/ruby_libs/pav/string/ext.rb +58 -0
  94. data/ruby_libs/pav/string/observable.rb +155 -0
  95. data/ruby_libs/pav/string/text.rb +79 -0
  96. data/ruby_libs/pav/string/words.rb +42 -0
  97. data/ruby_libs/pav/sub_arr.rb +55 -0
  98. data/ruby_libs/pav/traced_obj.rb +79 -0
  99. metadata +147 -0
@@ -0,0 +1,534 @@
1
+ require 'set'
2
+ require 'pav/pix'
3
+ require 'pav/pix/node'
4
+ require 'pav/pix/curve'
5
+ require 'pav/attr_cache'
6
+ require 'pav/pix/contour'
7
+ require 'pav/pix/node_grp'
8
+
9
+ module PPix
10
+
11
+ class ShavedCoreCalc
12
+ attr_accessor :shaved_core, :curve, :min_branch_len, :min_lp_len_min,
13
+ :visited, :node_map
14
+
15
+ def initialize(shaved_core)
16
+ @shaved_core = shaved_core
17
+ @curve = @shaved_core.curve
18
+ @min_branch_len = @shaved_core.min_branch_len
19
+ @min_lp_len_min = @shaved_core.min_lp_len_min
20
+ @visited = {}
21
+ @use_progr = false
22
+ @dup_grps = []
23
+ @orig_grps = []
24
+ @node2gid = {}
25
+ @node_conn_depths = {}
26
+ @node_map = {}
27
+ end
28
+
29
+ def node_dir_max_depth(node, to_parent_conn_is, visited={})
30
+ #$PDbgLog.sig_call(self)
31
+ #$PDbgLog.print_msg "node#{node}, to_parent_conn_is: #{
32
+ # to_parent_conn_is.inspect}: "
33
+ if visited.include?(node)
34
+ #$PDbgLog.sig_return(1.0/0.0)
35
+ return 1.0/0.0
36
+ end
37
+ visited[node] = true
38
+ max_depth = 0
39
+ node.conns.each_with_index { |conn, conn_i|
40
+ next if to_parent_conn_is.include?(conn_i)
41
+ depth = self.node_conn_max_depth(node, conn_i, visited)
42
+ max_depth = depth if depth > max_depth
43
+ }
44
+ visited.delete(node)
45
+ #$PDbgLog.sig_return#("#{node}: #{max_depth}")
46
+ max_depth
47
+ end
48
+
49
+ def node_conn_max_depth(node, conn_i, visited={})
50
+ #$PDbgLog.sig_call(self)
51
+ if (conn_depths = @node_conn_depths[node])
52
+ if (tmp = conn_depths[conn_i])
53
+ #$PDbgLog.sig_return
54
+ return tmp
55
+ end
56
+ else
57
+ conn_depths = @node_conn_depths[node] = []
58
+ end
59
+ exit = (conn = node.conns[conn_i]).exit
60
+ #$PDbgLog.print_msg "node#{node}, conn[#{conn_i}]: #{conn}: "
61
+ if (nd_gid = @node2gid[node]) && nd_gid == @node2gid[exit] &&
62
+ (path = conn.path).kind_of?(NodePath) &&
63
+ (nd_grp = @orig_grps[nd_gid]).include?(path.first)
64
+ rev_conn_is = []
65
+ exit.conns.each_with_index { |r_conn, r_conn_i|
66
+ rev_conn_is << r_conn_i if
67
+ (r_path = r_conn.path).kind_of?(NodePath) &&
68
+ nd_grp.include?(r_path.first)
69
+ }
70
+ else
71
+ rev_conn_is = [node.to_parent_conn_idx(conn_i)]
72
+ end
73
+ res =
74
+ conn_depths[conn_i] = conn.length +
75
+ self.node_dir_max_depth(exit, rev_conn_is, visited)
76
+ #$PDbgLog.sig_return("#{node},conn[#{conn_i}]: #{conn}: #{res}")
77
+ res
78
+ end
79
+
80
+ def min_lp_get_grp(min_lp_path)
81
+ #$PDbgLog.sig_call(self)
82
+ #$PDbgLog.print_msg "min_lp_path: #{min_lp_path}: "
83
+ res = min_lp_path.undir_to_link_grp
84
+ tail = res.nodes_to_a
85
+ while !tail.empty?
86
+ node = tail.pop
87
+ node.conns.each_with_index { |conn, conn_i|
88
+ if conn.length <= @min_lp_len_min &&
89
+ !res.include?(link = NodeLink.new(node, conn_i))
90
+ begin
91
+ excl_link = link.reverse
92
+ rescue NoReverseLinkError
93
+ res << link
94
+ next
95
+ end
96
+ #$PDbgLog.puts_msg "link(#{link.length}): #{link.
97
+ # to_s(1)}"
98
+ node_calc = NodeCalc.new(conn.exit)
99
+ node_calc.link_filter = proc {|lk| lk != excl_link }
100
+ if (path =node_calc.find_shortest_path_to_node(node,
101
+ @min_lp_len_min - conn.length))
102
+ #$PDbgLog.puts_msg "+=(#{path.get_length}) " +
103
+ # path.to_s
104
+ res << link; res << excl_link
105
+ res.add_undir_path!(path)
106
+ path.each { |lk| tail.push(lk.node) }
107
+ end
108
+ end
109
+ }
110
+ end
111
+ #$PDbgLog.sig_return('= ' + res.to_s)
112
+ res
113
+ end
114
+
115
+ def dup_node(node)
116
+ #$PDbgLog.sig_call(self)
117
+ if (tmp = @node_map[node])
118
+ #$PDbgLog.sig_return#(tmp.to_s + ' (cached).')
119
+ return tmp
120
+ end
121
+ #$PDbgLog.print_msg node.coords_to_s + ": "
122
+ #$PDbgLog.puts_msg "map: #{@node_map.to_s}, tmp=#{tmp.inspect}"
123
+ lp, len = *node.get_min_lp_n_len(@min_lp_len_min)
124
+ #$PDbgLog.print_msg "lp(#{len.inspect}): #{lp}: "
125
+ if lp
126
+ #$PDbgLog.puts_msg 'condensing group.'
127
+ grp = self.min_lp_get_grp(lp)
128
+ grp.each { |m|
129
+ if @node_map.include?(m)
130
+ raise "BUG: Group member #{m} already in " +
131
+ "visited: #{grp.node_cnt < 100 ?
132
+ "m's grp.: " + grp.to_s + '. ' : ''}#{
133
+ @node2gid.include?(m) ? (
134
+ @dup_grps[@node2gid[m]].length<100 ?
135
+ @dup_grps[@node2gid[m]].to_s : 'large') :
136
+ ''}!" #'
137
+ end
138
+ }
139
+ if (entries = grp.get_entries_grp).empty?
140
+ #$PDbgLog.puts_msg 'Whole graph is one group.'
141
+ entries = grp
142
+ l_len = @min_lp_len_min#Don't neglect grp.extent
143
+ else
144
+ #$PDbgLog.puts_msg 'Entries: ' + Xy.path_to_s(
145
+ # entries.to_a.sort)
146
+ end
147
+ if (l_path = grp.get_a_longest_path)
148
+ l_len = l_path.get_length
149
+ else
150
+ #$PDbgLog.puts_msg 'A one-node loop group.'
151
+ l_len = -1 # Neglect group's extent.
152
+ end
153
+ # $PDbgLog.print_msg "longest_path(#{l_len}): #{l_path}: "
154
+ if l_len < @min_lp_len_min
155
+ #$PDbgLog.puts_msg 'group extent negligible.'
156
+ gid = @dup_grps.length
157
+ @dup_grps << (new_grp = NodeGrp.new)
158
+ @orig_grps << grp
159
+ entries.each_node { |m|
160
+ raise "BUG: Group entry already duplicated: #{m
161
+ }!" if @node_map[m]
162
+ new_grp <<(@node_map[m]=AaXyNode.new(m.ax,m.ay,[]))}
163
+ new_grp.each { |m| @node2gid[m] = gid }
164
+ entries.each_node { |m| nd_conns = @node_map[m].conns
165
+ grp.get_node_paths_to_entries(m).each { |path|
166
+ raise "BUG: Group entry not duplicated: #{
167
+ path.exit}!" unless @node_map[path.exit]
168
+ cn = NodeConn.new(@node_map[path.exit],
169
+ path.get_length)
170
+ cn.path = path
171
+ #$PDbgLog.puts_msg "path_to_exterior: #{
172
+ # path.to_s(2)}, conn.: #{cn}"
173
+ nd_conns << cn
174
+ }
175
+ m.conns.each_with_index { |conn, conn_i|
176
+ if !grp.include?(NodeLink.new(m, conn_i))
177
+ #$PDbgLog.puts_msg "link to exterior: #{
178
+ # NodeLink.new(m, conn_i).to_s(1)}"
179
+ cn = NodeConn.new(self.dup_node(
180
+ conn.exit), conn.length)
181
+ cn.path = conn.path
182
+ nd_conns << cn
183
+ end
184
+ }
185
+ }
186
+ #dbg_nodes = entries.nodes_to_a
187
+ else
188
+ #$PDbgLog.puts_msg "group's extent non-negligible."
189
+ paths = [l_path]
190
+ dyke = l_path.to_node_grp.get_vicinity_grp_in_set(
191
+ @min_lp_len_min/2, grp.as_node_set)
192
+ #$PDbgLog.puts_msg "Dyke: #{Xy.path_to_s(dyke.to_a.
193
+ # sort)}"
194
+ grps = grp.get_link_islands(dyke)
195
+ #$PDbgLog.puts_msg "grps: #{grps.join("\n --:")}"
196
+ grps_left_idxs = (0...grps.length).to_a
197
+ while !grps_left_idxs.empty?
198
+ i = 0
199
+ while i < grps_left_idxs.length
200
+ t_grp = grps[grps_left_idxs.at(i)]
201
+ l_path = t_grp.get_a_longest_path
202
+ l_len = l_path.get_length
203
+ #$PDbgLog.puts_msg "l_path(#{l_len}): #{l_path}"
204
+ if l_len < @min_lp_len_min
205
+ grps_left_idxs.delete_at(i)
206
+ else
207
+ paths << l_path
208
+ dk = l_path.to_node_grp.get_vicinity(
209
+ @min_lp_len_min/2)
210
+ dk.each { |m| dyke << m }
211
+ islands = t_grp.get_link_islands(dyke)
212
+ if islands.empty?
213
+ grps_left_idxs.delete_at(i)
214
+ else
215
+ grps[grps_left_idxs.at(i)] = islands.first
216
+ 1.upto(islands.length-1).each { |j|
217
+ grps_left_idxs << grps.length
218
+ grps << islands[j]
219
+ }
220
+ end
221
+ end
222
+ end
223
+ end
224
+ #$PDbgLog.puts_msg "grps: #{grps.join("\n --:")}"
225
+ paths.concat(grp.get_islands_min_span_paths(grps))
226
+ paths_grp = NodeGrp.new
227
+ paths.each { |path|
228
+ path.each { |link| paths_grp << link.node }
229
+ paths_grp << path.exit
230
+ }
231
+ entries.each { |m|
232
+ unless paths_grp.include?(m)
233
+ node_calc = NodeCalc.new(m)
234
+ path =node_calc.find_first_path_to(proc{|nd,lev|
235
+ paths_grp.include?(nd) })
236
+ paths << path
237
+ #$PDbgLog.puts_msg "Path to an entry: path: #{
238
+ # path}"
239
+ path.each { |link| paths_grp << link.node }
240
+ paths_grp << path.exit
241
+ end
242
+ }
243
+ entries.each { |m| @node_map[m] =
244
+ AaXyNode.new(m.ax,m.ay,[]) }
245
+ #dbg_nodes = entries.to_a
246
+ paths.each { |path| path.each { |link| nd=link.node
247
+ @node_map[nd] = AaXyNode.new(nd.ax,nd.ay,[]
248
+ ) unless @node_map.include?(nd)
249
+ #dbg_nodes << nd unless @node_map.include?(nd)
250
+ }
251
+ nd = path.exit
252
+ @node_map[nd] = AaXyNode.new(nd.ax, nd.ay, []
253
+ ) unless @node_map.include?(nd)
254
+ #dbg_nodes << nd unless @node_map.include?(nd)
255
+ }
256
+ #$PDbgLog.print_msg "Adding links: "
257
+ paths.each { |path| path.each { |link|
258
+ #$PDbgLog.print_msg "#{link.to_s(1)} "
259
+ conn = link.conn
260
+ cn = NodeConn.new(@node_map[conn.exit],
261
+ conn.length)
262
+ cn.path = conn.path
263
+ @node_map[link.node].conns << cn
264
+ conn = (link=link.reverse).conn #<-- reverse --
265
+ cn = NodeConn.new(@node_map[conn.exit],
266
+ conn.length)
267
+ cn.path = conn.path
268
+ @node_map[link.node].conns << cn
269
+ } }
270
+ #$PDbgLog.puts_msg '.'
271
+ #$PDbgLog.puts_msg 'Adding conns.: '
272
+ entries.each { |m| nd_conns = @node_map[m].conns
273
+ m.conns.each_with_index { |conn, conn_i|
274
+ #$PDbgLog.print_msg "conn:#{conn.to_s(1)} "
275
+ unless grp.include?(NodeLink.new(m, conn_i))
276
+ nd_conns << (cn=NodeConn.new(
277
+ self.dup_node(conn.exit),conn.length))
278
+ cn.path = conn.path
279
+ end
280
+ }
281
+ }
282
+ #$PDbgLog.puts_msg '.'
283
+ end
284
+ # $PDbgLog.sig_return("#{node.to_s} done: "+dbg_nodes.
285
+ # sort.collect{|nd| @node_map[nd].to_s(1) }.join('. ') +
286
+ # ": #{@node_map[node]}")
287
+ @node_map[node]
288
+ else
289
+ #$PDbgLog.print_msg 'copying node: '
290
+ res = @node_map[node] =
291
+ AaXyNode.new(node.ax, node.ay, conns=[])
292
+ node.conns.each { |conn|
293
+ cn = NodeConn.new(self.dup_node(conn.exit),
294
+ conn.length)
295
+ cn.path = conn.path
296
+ conns << cn
297
+ }
298
+ #$PDbgLog.sig_return(res.to_s(1))
299
+ res
300
+ end
301
+ end
302
+
303
+ def dup_graph(node)
304
+ self.dup_node(node)
305
+ end
306
+
307
+ def expand_path(path)
308
+ (node = path.first.node).clear_rev_conns_cache
309
+ path.each { |link|
310
+ unless @node_map.include?(l_nd = link.node)
311
+ @node_map[l_nd] = AaXyNode.new(l_nd.ax, l_nd.ay, [])
312
+ end
313
+ }
314
+ for link in path
315
+ l_exit = link.exit; l_len = link.length
316
+ unless (l_cns = @node_map[link.node].conns).detect { |cn|
317
+ l_exit.node_eql?(cn.exit) && cn.length == l_len }
318
+ l_cns << (new_conn = NodeConn.new(@node_map[l_exit], l_len))
319
+ new_conn.path = link.path
320
+ end
321
+ end
322
+ end
323
+
324
+ def expand_proxy_paths
325
+ #$PDbgLog.sig_call(self)
326
+ @dup_grps.each { |grp|
327
+ #$PDbgLog.print_msg "Group: #{grp}: "
328
+ grp.each_node { |node|
329
+ #$PDbgLog.print_msg "node#{node}: "
330
+ conn_i = 0
331
+ while conn_i < (conns = node.conns).length
332
+ conn = conns.at(conn_i)
333
+ #$PDbgLog.print_msg "conn: #{conn.to_s(1)} "
334
+ if (path = conn.path).kind_of?(NodePath) &&
335
+ grp.includes_node?(conn.exit)
336
+ #$PDbgLog.print_msg " => expanding path: "
337
+ conns.delete_at(conn_i)
338
+ self.expand_path(path)
339
+ else
340
+ conn_i += 1
341
+ end
342
+ end
343
+ }
344
+ #$PDbgLog.puts_msg '.'
345
+ }
346
+ #$PDbgLog.sig_return
347
+ end
348
+
349
+ def shave_node!(node)
350
+ #$PDbgLog.sig_call(self)
351
+ conns = node.conns
352
+ i1 = i2 = nil
353
+ i1_depth = i2_depth = 0
354
+ i = -1
355
+ while (i += 1) < conns.length
356
+ depth = self.node_conn_max_depth(node, i)
357
+ #$PDbgLog.print_msg node.to_s + ": --" +
358
+ # conns[used_conn_is[i]].last.coords_to_s +
359
+ # ",#{used_conn_is[i]}:#{depth}: "
360
+ if i2
361
+ if depth > i1_depth
362
+ i_min = i2; min_depth = i2_depth
363
+ i2 = i1; i2_depth = i1_depth
364
+ i1 = i; i1_depth = depth
365
+ elsif depth > i2_depth
366
+ i_min = i2; min_depth = i2_depth
367
+ i2 = i; i2_depth = depth
368
+ else
369
+ i_min = i; min_depth = depth
370
+ end
371
+ if min_depth < @min_branch_len
372
+ #$PDbgLog.print_msg "deleting at #{i_min
373
+ # }"
374
+ node.delete_conn(i_min)
375
+ if (c_depths = @node_conn_depths[node])
376
+ c_depths.delete_at(i_min)
377
+ end
378
+ i1 -= 1 if i1 > i_min
379
+ i2 -= 1 if i2 > i_min
380
+ i -= 1
381
+ end
382
+ elsif i1
383
+ if depth > i1_depth
384
+ i2 = i1; i2_depth = i1_depth
385
+ i1 = i; i1_depth = depth
386
+ else
387
+ i2 = i; i2_depth = depth
388
+ end
389
+ else
390
+ i1 = i; i1_depth = depth
391
+ end
392
+ #$PDbgLog.puts_msg "."
393
+ end
394
+ #$PDbgLog.sig_return
395
+ end
396
+
397
+ def shave!(node)
398
+ #$PDbgLog.sig_call(self)
399
+ #$PDbgLog.print_msg node.coords_to_s + ", conns: #{node.conns.
400
+ # join('; ')}: "
401
+ node.conns.each { |conn|
402
+ next if @visited.include?(conn.exit.a_yx)
403
+ self.shave_node!(conn.exit)
404
+ @visited[conn.exit.a_yx] = true
405
+ unless conn.exit.conns.detect { |cn|
406
+ cn.exit.node_eql?(node) }
407
+ #$PDbgLog.sig_return(node.coords_to_s + ": " +
408
+ # (res = self.shave!(conn.last)).coords_to_s)
409
+ return self.shave!(conn.exit) #res
410
+ end
411
+ if !(tmp = self.shave!(conn.exit)).node_eql?(conn.exit)
412
+ #$PDbgLog.sig_return(node.coords_to_s + ": " +
413
+ # tmp.coords_to_s)
414
+ return tmp
415
+ end
416
+ }
417
+ $PDbgLog.progr.progr_units = @visited.length if @use_progr
418
+ #$PDbgLog.sig_return(node.coords_to_s + ": " + node.coords_to_s)
419
+ node
420
+ end
421
+
422
+ def shave_graph(node)
423
+ $PDbgLog.sig_call(self)
424
+ #$PDbgLog.print_msg "node#{node}: "
425
+ @node_map = {}
426
+ unless (wrk_node = self.dup_graph(node))
427
+ # node could have been a non-visitable node in a group.
428
+ @node_map.each_value { |wrk_node| break }
429
+ end
430
+ #$PDbgLog.print_msg "wrk_node#{wrk_node} "
431
+ $PDbgLog.new_progr
432
+ $PDbgLog.progr.total_progr_units = @node_map.length
433
+ $PDbgLog.progr.show_as = "/ node" + (@node_map.length == 1 ?
434
+ '' : 's')
435
+ @use_progr = true
436
+ #$PDbgLog.puts_msg "Duplicated graph: #{wrk_node.graph_to_s}"
437
+ res = self.shave!(wrk_node)
438
+ #$PDbgLog.puts_msg "Shaved graph: #{res.graph_to_s}"
439
+ self.expand_proxy_paths
440
+ #$PDbgLog.print_msg "res#{res} "
441
+ @use_progr = false
442
+ $PDbgLog.sig_return
443
+ res
444
+ end
445
+ end
446
+
447
+ class Curve
448
+ def get_shaved_core(min_branch_len, min_lp_len_min)
449
+ ShavedCore.new(self, min_branch_len, min_lp_len_min)
450
+ end
451
+
452
+ def c_shaved_core(min_hair_len, min_lp_len)
453
+ return @c_shaved_core if @c_shaved_core
454
+ #$PDbgLog.sig_call(self)
455
+ #$PDbgLog.print_msg @shaved_core.inspect
456
+ @c_shaved_core = self.get_shaved_core(min_hair_len, min_lp_len)
457
+ #$PDbgLog.sig_return(@shaved_core.object_id)
458
+ #@c_shaved_core
459
+ end
460
+
461
+ def c_delete_shaved_core
462
+ @c_shaved_core = nil
463
+ end
464
+ end
465
+
466
+ class ShavedCore < ImageObject
467
+ attr_reader :curve, :branches, :min_branch_len, :min_lp_len_min
468
+
469
+ self.img_obj_add_sub_obj :branches
470
+
471
+ def initialize(curve, min_branch_len, min_lp_len_min)
472
+ @curve = curve
473
+ @branches = []
474
+ @min_branch_len = min_branch_len
475
+ @min_lp_len_min = min_lp_len_min
476
+ super()
477
+ self.rebuild
478
+ end
479
+
480
+ def rebuild
481
+ self.clear
482
+ if @curve.length < 2
483
+ self.replace(@curve)
484
+ return
485
+ end
486
+ $PDbgLog.sig_call(self)
487
+ $PDbgLog.print_msg "@min_branch_len=#{@min_branch_len
488
+ }, @min_lp_len_min=#{@min_lp_len_min}; Shaving: "
489
+ calc = ShavedCoreCalc.new(self)
490
+ node = @curve.pix_node(@curve.first)
491
+ node = node.conns.first.exit unless node.conns.empty?
492
+ #$PDbgLog.puts_msg "Graph: #{node.graph_to_s}"
493
+ node = calc.shave_graph(node)
494
+ $PDbgLog.print_msg "done. Traversing: "
495
+ @branches.clear
496
+ branch_start_i = 0
497
+ if node.conns.length < 2
498
+ self << AaPix.new(@curve.pixbuf, node.ax, node.ay)
499
+ else
500
+ node.graph_each_node { |nd|
501
+ if nd.conns.length < 2
502
+ node = nd
503
+ self << AaPix.new(@curve.pixbuf,node.ax,node.ay)
504
+ break
505
+ end
506
+ }
507
+ end
508
+ next_node = node
509
+ #$PDbgLog.puts_msg "node#{node}"
510
+ #$PDbgLog.puts_msg "Final graph: #{node.graph_to_s}"
511
+ node.graph_each_conn_i { |node, conn_i|
512
+ #$PDbgLog.puts_msg "node#{node},conn_i[#{conn_i}]: #{
513
+ # node.conns[conn_i].to_s(2)}: #{node.
514
+ # conns[conn_i].path.expand_to_xy_path.xy_nodes}"
515
+ if !next_node.node_eql?(node) || node.conns.length > 2
516
+ @branches << ImageObject.new(self,
517
+ branch_start_i, self.length)
518
+ #$PDbgLog.puts_msg "Branch: #{Xy.path_to_s(
519
+ # @branches.last)}"
520
+ branch_start_i = self.length
521
+ end
522
+ conn = node.conns[conn_i]
523
+ self.concat(conn.path.expand_to_xy_path.xy_nodes)
524
+ next_node = conn.exit
525
+ }
526
+ @branches << ImageObject.new(self, branch_start_i,
527
+ self.length) unless branch_start_i >= self.length
528
+ #$PDbgLog.print_msg "@branches.length=#{@branches.length
529
+ # }; @branches: #{@branches.inspect} "
530
+ $PDbgLog.sig_return("done all.")
531
+ end
532
+ end
533
+
534
+ end