# Copyright 2004, D. Bur, # Permission to use, copy, modify, and distribute this software for # any purpose and without fee is hereby granted, provided that the above # copyright notice appear in all copies. # THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR # IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. #----------------------------------------------------------------------------- # Name : contour_lines # Description : A tool to create contour lines with a set of faces # Menu Item : Plugins -> contour lines # Context Menu: NONE # Author : Didier Bur # Usage : Select faces, select menu Plugins/contour lines # : Enter start altitude and increment value # Date : 9/22/2004 # Type : Tool #----------------------------------------------------------------------------- def in_face( p, f ) v = f.vertices i = 0 sum_angles = 0 two_pi = 6.28318530717959 0.upto (v.length - 1) do |a| if(i != (v.length - 1)) vec1 = p.vector_to v[i] vec2 = p.vector_to v[i + 1] else vec1 = p.vector_to v[i] vec2 = p.vector_to v[0] end sum_angles = sum_angles + vec1.angle_between(vec2) i = i + 1 end #puts sum_angles.to_s + "\n" if( (two_pi - 0.5) < sum_angles) and ( sum_angles < (two_pi + 0.5)) #puts "vrai\n" return true else return false #puts "faux\n" end end def create_contour_lines model = Sketchup.active_model entities = model.active_entities model.start_operation "create contour lines" ss = model.selection if ss.empty? UI.messagebox("No selection !") return nil end # Selection error checking: eliminates the non-face objects ss_remove = [] i = 0 j = 0 0.upto( ss.length - 1) do |look| if( not ss[i].kind_of? Sketchup::Face ) or (ss[i].normal.z.to_f == 1.0) or (ss[i].normal.z.to_f == -1.0) ss_remove[j] = ss[i] j = j + 1 end i = i + 1 end #of upto if(j != 0) UI.messagebox( ss_remove.length.to_s + " object(s) of the selection aren't faces and will be ignored.") Sketchup.set_status_text("Removing ignored objects from selection, please wait..." ) ss.remove( ss_remove ) Sketchup.set_status_text("Removing ignored objects from selection, please wait...Done." ) end #----------------------------------------------------------------------------- Layer settings set_layer_code = UI.messagebox("Put contour lines on specified layer ?", MB_YESNO) if set_layer_code == 6 prompts1 = ["Layer name"] values1 = ["Contour lines"] results1 = inputbox prompts1, values1, "Layer name" if results1.to_s.empty? == true results1 = model.layers.unique_name("Contour lines") elsif results1 == false results1 = saved_layer.name end model.layers.add(results1.to_s) model.active_layer = (results1.to_s) end # ------------------------------------------------------------------------------ Search for Z min and Z max y = 0 zmin = 0.0 zmax = 0.0 $all_z = [] k = 0 0.upto( ss.length - 1) do |that| current_face = ss[y] # Verbose Sketchup.set_status_text("Z search for face: " + (y + 1).to_s + " / " + ss.length.to_s ) vert = current_face.vertices 0.upto( vert.length - 1) do |m| #pt = vert[k].position #all_z[k] = pt[2] $all_z[k] = vert[m].position.z k = k + 1 end #of upto y = y + 1 end z_max = $all_z.max z_min = $all_z.min UI.messagebox( "\nSelection MIN altitude: " + z_min.to_s + "\nSelection MAX altitude: " + z_max.to_s) # ------------------------------------------------------------------------------ Dialog box # User input values prompts = ["Start at altitude ", "Create a contour line each "] # default values in the input box #values = [0.feet, 15.feet] values = [0.cm, 200.cm] results = inputbox prompts, values, "Contour lines settings" return if not results start_alt, increment = results start_alt = results[0] increment = results[1] # --------------------------------------------- Iterate through selection, face by face i = 0 line_inters = [] inf = 0 current_alt = 0.0 0.upto( ss.length - 1) do |cut| current_face = ss[i] # Verbose Sketchup.set_status_text("Processing triangle: " + (i + 1).to_s + " / " + ss.length.to_s ) edges = current_face.edges vert = current_face.vertices current_plane = current_face.plane # --------------------------------------------- At what altitudes this triangle must be cut ? face_z = [] k = 0 0.upto( vert.length - 1) do |k| pt = vert[k].position face_z[k] = vert[k].position.z #all_z[k] = pt[2] k = k + 1 end #of upto z_max = face_z.max z_min = face_z.min first_alt = 0.0 last_alt = 0.0 current_alt = 0.0 # First and last intersection altitudes first_alt = ((z_min - start_alt) / increment).ceil last_alt = ((z_max - start_alt) / increment).ceil first_alt = (first_alt * increment) last_alt = (last_alt * increment) current_alt = first_alt # Computes intersection of each edge of the face from first_alt plane to last_alt plane if ((first_alt == last_alt) or (first_alt < last_alt)) a = 1 upstairs = true while upstairs # intersect with all edges of current face m = 0 if (current_alt != z_max) or (current_alt != z_min) 0.upto( edges.length - 1) do |that| edge = edges[m] inters = Geom.intersect_line_plane(edge.line, [0, 0, 1.0, (0 - current_alt)]) if inters and in_face(inters, current_face) line_inters[inf] = inters inf = inf + 1 end #of if m = m + 1 end #of upto if ((current_alt.to_f - 1) < last_alt.to_f ) and ((current_alt.to_f + 1) > last_alt.to_f ) upstairs = false end current_alt = current_alt + increment end #of if end #of while # Next face i = i + 1 end #of upto end #of if #Draw all intersection lines group = entities.add_group entities = group.entities nlines = line_inters.length.to_s #print line_inters y = 0 0.upto( (line_inters.length / 2) - 1) do |that| Sketchup.set_status_text("Creating line: " + (y + 1).to_s + " / " + nlines ) #Sketchup.active_model.active_entities.add_line(line_inters[y], line_inters[(y+1)]) entities.add_line(line_inters[y], line_inters[(y+1)]) y = y + 2 end #of upto # Close/commit group model.commit_operation end #of def if( not file_loaded?("contour_lines.rb") ) add_separator_to_menu("Plugins") UI.menu("Plugins").add_item("Contour lines") { create_contour_lines } end file_loaded("contour_lines.rb")