Combining Edges
-
I wanted a routine that I can use in my stair maker that will convert individual connected edges into a polyline.
I looked at weld.rb and I thought there is another way to weld things together more efficiently.
I have a small benchmark file that I can upload if requested. It has 308 edges.
running my combine.rb against it took this time.
0.036
0.037running weld.rb against it took this time.
0.187
0.197Please do note that I am currently not interested in a closed polyline. Nor am I interested in filling in faces.
require 'sketchup.rb'
def combine_edges()
model = Sketchup.active_model
entities = model.active_entities
selection = model.selectionedges = [] # array of user selected edges right = [] # right hand chain left = [] # left hand chain t = Time.now selection.each { |val| edges << val if ( val.typename == "Edge" ) }
check to make sure user has selected at least 2 edges
return UI.messagebox( "Please select at least 2 edges" ) if ( edges.length < 2 )
remove first edge and split into both chains
edge = edges.shift right << edge.end left << edge.start found = false
loop through the edges and add to right or left chain
while ( edges.length > 0 ) found = false edges.each_with_index do |edge, idx| if ( right.last == edge.start ) right << edge.end elsif ( right.last == edge.end ) right << edge.start elsif ( left.last == edge.start ) left << edge.end elsif ( left.last == edge.end ) left << edge.start else next end found = true edges[idx] = nil break end edges.compact! if ( found ) return UI.messagebox( "Polyline requires all edges to connect. Please try again!" ) if ( ! found ) end
concatenate chains - since we pushed vertices on the left chain they are in reverse and need to be fixed
left.reverse! left += right puts Time.now - t
create the new polyline "curve", explode the container group and clear the selection
model.start_operation "polyline" group = ( container = entities.add_group ).entities group.add_curve( left ) container.explode model.commit_operation selection.clear
end
#-----------------------------------------------------------------------------
if ( not file_loaded?( "combine.rb" ) )
add_separator_to_menu( "Plugins" )
UI.menu( "Plugins" ).add_item( "Combine Edges" ) { combine_edges() }
file_loaded( "combine.rb" )
end
#----------------------------------------------------------------------------- -
Because your sets of edges are already 'in order' then it seems likely that the full weld code that sorts a potential list of randomly drawn edges, which is initially unordered, into an ordered list... will take somewhat longer.
-
I've benchmarked with ordered and unordered edges.
With unordered I'm getting NN with combine.rb and 2N*N with weld.rb.
Most of what I want to do will be with mostly ordered edges.I wanted to test some of the underlying array operations and see if what I am familiar with in C/C++ has any similarity.
I've worked with TList objects in C++ containing millions of pointers. Dropping an element from the middle of the list is fairly efficient. The array pointers are in contiguous memory so all that is needed is to perfrom a single memcpy and to decrement the count.
Anyway - this works for me - I just wanted to share an alternative solution.
-
Good point about the 'from middle sorting'...
-
The next thing I need to do is take a handrail profile such as the image on the left which is a cross section of a handrail for level handrail.
Then I want to create a sorted array of the edges used to describe the level handrail profile. - I'm thinking the outer_loop should work.
Then I stretch the profile based on the slope of the handrail - just store the vertices in an array. After that I rotate the vertices the appropriate amount for the next section of handrail. Create edges that go from the first adjusted profile to the next section of profile.
The catch is that these handrails may not have a consistent slope. There may be a small section of handrail that transitions from one slope to another. For instance there could be a tight radius for the inside stringer that has a steep slope and then over a couple of feet at the top of the stair the handrail levels out for level balcony handrail. This means that I have to adjust the profile for the handrail for each small section.
I'm thinking of using the top center of the handrail for registration purposes. This makes sense to me as building codes talk about the height of the handrail for level rail and for stair rail. Residential codes are usually 36" for level handrail and 32" for stair rail - measured vertically up from the edge of the tread nosing. Commercial codes are usually 42" and 36" respectively. The top center is consistent regardless of the height of the rail profile.
Advertisement