Module: TT::Edges
- Defined in:
- TT_Lib2/edges.rb
Overview
Collection of methods to manipulate sets of edges.
Defined Under Namespace
Modules: Gaps
Class Method Summary collapse
- .common_vertex(edge1, edge2) ⇒ Sketchup::Vertex|Nil
-
.find_curves(entities, progress_in_ui = false) ⇒ Array<Array<Sketchup::Edge>>
Find continous sets of edges not part of faces.
-
.find_isolated_curves(entities) ⇒ Array<Array<Sketchup::Edge>>
Finds all sets of edges forming a curve not connected to any other geometry.
-
.repair_splits(entities, progress_in_ui = false) ⇒ Integer
Attempts to merge colinear edges into one edge.
-
.sort(edges) ⇒ Array<Sketchup::Edge>
Sorts the given set of edges from start to end.
-
.sort_from_hash(edges) ⇒ Array<Sketchup::Edge>
Sorts the given set of edges from start to end.
-
.sort_vertices(curve) ⇒ Array<Sketchup::Vertex>
Takes a sorted set of edges and returns a sorted set of vertices.
Class Method Details
.common_vertex(edge1, edge2) ⇒ Sketchup::Vertex|Nil
54 55 56 57 58 59 60 61 |
# File 'TT_Lib2/edges.rb', line 54 def self.common_vertex(edge1, edge2) for v1 in edge1.vertices for v2 in edge2.vertices return v1 if v1 == v2 end end nil end |
.find_curves(entities, progress_in_ui = false) ⇒ Array<Array<Sketchup::Edge>>
Find continous sets of edges not part of faces. The result is an array of more arrays. Each sub-array contains a set of sorted edges.
Sub-arrays may contains arrays of only one edge.
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'TT_Lib2/edges.rb', line 73 def self.find_curves( entities, progress_in_ui=false ) cache = {} # Use Hash for quick lookups entities.each { |e| next unless e.is_a?( Sketchup::Edge ) && e.faces.empty? cache[e] = e } if progress_in_ui && progress_in_ui.is_a?( TT::Progressbar ) progress = progress_in_ui else progress = TT::Progressbar.new( cache, 'Finding curves' ) end curves = [] until cache.empty? curve = {} # Use Hash for quick lookups stack = [ cache.keys.first ] until stack.empty? # Fetch the next edges in the stack and add to the curve edge = stack.shift curve[edge] = edge cache.delete(edge) progress.next if progress_in_ui # Find next edges for v in edge.vertices vert_edges = v.edges next if vert_edges.size != 2 for e in vert_edges stack << e unless curve.key?(e) end end end # until stack.empty? curves << self.sort( curve ) end # until cache.empty? curves end |
.find_isolated_curves(entities) ⇒ Array<Array<Sketchup::Edge>>
Finds all sets of edges forming a curve not connected to any other geometry. Returns an array of sorted curves. (Curve = array of edges)
116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'TT_Lib2/edges.rb', line 116 def self.find_isolated_curves(entities) source = entities.to_a curves = [] until source.empty? entity = source.shift next unless entity.is_a?( Sketchup::Edge ) connected = entity.all_connected source -= connected next unless connected.all? { |e| e.is_a?(Sketchup::Edge) } sorted_edges = self.sort( connected ) curves << sorted_edges unless sorted_edges.nil? end return curves end |
.repair_splits(entities, progress_in_ui = false) ⇒ Integer
Attempts to merge colinear edges into one edge. Makes use of SketchUp's own healing feature. Based on repair_broken_lines.rb by Carlo Roosen 2004
If progress_in_ui
is true then a TT::Progressbar
object is used to give UI feedback to the user about the process.
If progress_in_ui
is a TT::Progressbar
object
then that is used instead and .next
is called for each entity.
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'TT_Lib2/edges.rb', line 147 def self.repair_splits( entities, progress_in_ui=false ) temp_edges = [] return 0 if entities.length == 0 parent = entities[0].parent.entities if progress_in_ui && progress_in_ui.is_a?( TT::Progressbar ) progress = progress_in_ui else progress = TT::Progressbar.new( entities, 'Repairing split edges' ) end for e in entities.to_a next unless e.is_a?(Sketchup::Edge) progress.next if progress_in_ui for vertex in e.vertices next unless vertex.edges.length == 2 # (?) Like coplanar faces - can one compare vectors like this? Or do one # have to check if all vertices lie on the same line? v1 = vertex.edges[0].line[1] v2 = vertex.edges[1].line[1] next unless v1.parallel?(v2) # To repair a broken edge a temporary edge is placed at their shared vertex. # This temporary edge is then later erased which causes the two edges to # merge. pt1 = vertex.position pt2 = pt1.clone pt2.x += rand(1000) / 100.0 pt2.y += rand(1000) / 100.0 pt2.z += rand(1000) / 100.0 temp_edge = parent.add_line( pt1, pt2 ) temp_edges << temp_edge unless temp_edge.nil? end end parent.erase_entities(temp_edges) unless temp_edges.empty? temp_edges.size end |
.sort(edges) ⇒ Array<Sketchup::Edge>
Comment source
Sorts the given set of edges from start to end. If the edges form a loop an arbitrary start is picked.
198 199 200 201 202 203 204 205 206 207 208 209 210 |
# File 'TT_Lib2/edges.rb', line 198 def self.sort( edges ) if edges.is_a?( Hash ) self.sort_from_hash( edges ) elsif edges.is_a?( Enumerable ) lookup = {} for edge in edges lookup[edge] = edge end self.sort_from_hash( lookup ) else raise ArgumentError, '"edges" argument must be a collection of edges.' end end |
.sort_from_hash(edges) ⇒ Array<Sketchup::Edge>
Sorts the given set of edges from start to end. If the edges form a loop an arbitrary start is picked.
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 |
# File 'TT_Lib2/edges.rb', line 220 def self.sort_from_hash( edges ) # Get starting edge - then trace the connected edges from either end. start_edge = edges.keys.first # Find the next left and right edge vertices = start_edge.vertices left = [] for e in vertices.first.edges left << e if e != start_edge && edges[e] end right = [] for e in vertices.last.edges right << e if e != start_edge && edges[e] end return nil if left.size > 1 || right.size > 1 # Check for forks left = left.first right = right.first # Sort edges from start to end sorted = [start_edge] # Right edge = right until edge.nil? sorted << edge connected = [] for v in edge.vertices for e in v.edges connected << e if edges[e] && !sorted.include?(e) end end return nil if connected.size > 1 # Check for forks edge = connected.first end # Left unless sorted.include?( left ) # Fix: 2.6.0 edge = left until edge.nil? sorted.unshift( edge ) connected = [] for v in edge.vertices for e in v.edges connected << e if edges[e] && !sorted.include?(e) end end return nil if connected.size > 1 # Check for forks edge = connected.first end end sorted end |
.sort_vertices(curve) ⇒ Array<Sketchup::Vertex>
The first vertex will also appear last if the curve forms a loop.
Takes a sorted set of edges and returns a sorted set of vertices. Use
TT::Edges.sort
to sort a set of edges.
287 288 289 290 291 292 293 294 295 296 297 298 |
# File 'TT_Lib2/edges.rb', line 287 def self.sort_vertices(curve) return curve[0].vertices if curve.size <= 1 vertices = [] # Find the first vertex. common = self.common_vertex( curve[0], curve[1] ) # (?) Errorcheck? vertices << curve[0].other_vertex( common ) # Now the rest can be added. curve.each { |edge| vertices << edge.other_vertex(vertices.last) # (?) Errorcheck? } return vertices end |