sketchucation logo sketchucation
    • Login
    1. Home
    2. hank
    3. Posts
    ℹ️ Licensed Extensions | FredoBatch, ElevationProfile, FredoSketch, LayOps, MatSim and Pic2Shape will require license from Sept 1st More Info
    H
    Offline
    • Profile
    • Following 0
    • Followers 0
    • Topics 9
    • Posts 40
    • Groups 1

    Posts

    Recent Best Controversial
    • RE: [Plugin] Material Tools

      OK, figured out what is up with "List Textures in Console" I think...

      I changed puts to print in the following def from Plugins/tt_material_tools/core.rb and it works in SU2018 (sorry ThomThom - I'm probably not supposed to be messing around in there!?). So general question... is puts no longer valid in 2018?

      def self.list_textures
          Sketchup.send_action('showRubyPanel;')
          # Collect textures and sort by size
          mats = Sketchup.active_model.materials.select { |m|
            !m.texture.nil?
          }
          mats.sort! { |a,b|
            size_a = a.texture.image_width * a.texture.image_height
            size_b = b.texture.image_width * b.texture.image_height
            size_b <=> size_a
          }
          # Print textures
          print "=== TEXTURE MATERIALS BY SIZE ==="
          buffer = ''
          mats.each { |m|
            next if m.texture.nil?
            t = m.texture
            size = t.image_width * t.image_height
            file = File.basename( t.filename )
            path = File.dirname( t.filename )
            #puts "#{m.display_name} - #{t.image_width}x#{t.image_height} - #{t.filename}"
            buffer << "#{m.display_name}\n"
            buffer << "  Size; #{t.image_width}x#{t.image_height} pixels\n"
            buffer << "  Size; #{self.readable_file_size(size*3, 2)} estimated uncompressed RGB\n"
            buffer << "  Size; #{self.readable_file_size(size*4, 2)} estimated uncompressed RGBA\n"
            if File.exist?( t.filename )
              disksize = File.size( t.filename )
              buffer << "  Size; #{self.readable_file_size(disksize, 2)} on disk\n"
            end
            buffer << "  File; #{file}\n"
            buffer << "  Path; #{path}\n"
          }
          print buffer
          print "---"
        end
      
      posted in Plugins
      H
      hank
    • RE: [Plugin] Material Tools

      Thanks for a great plugin thomthom. As is mentioned on Extension Warehouse, "List Textures in Console" generates a blank console window. Is this just a SU2018 thing or are other folks experiencing that issue?

      posted in Plugins
      H
      hank
    • RE: Search a DC attribute string value

      YES! I see now. That is some pretty sweet re-engineering of the pretty remedial string functions! I do wish FIND would just return FALSE if the string is not found but oh well. Thanks Again pcmoor!

      posted in Dynamic Components
      H
      hank
    • RE: Search a DC attribute string value

      Thanks pcmoor.

      So... trying to understand this. You have:

      =if((find("hello",Astring&"hello",1)-len(Astring))<0,"true","false")
      

      where Astrin is set to

      hellggggheloxxhell
      

      So in other words

      =if((find("hello","hellggggheloxxhell"&"hello",1)-len("hellggggheloxxhell"))<0,"true","false")
      

      Which I think means:
      If FIND returns a number that is greater than the length of the search string, return true.

      So you are sort of forcing FIND to return something if the search string is not found by a certain position by adding the search string onto the end of the search haysatck,right?

      I'm not sure I understand completely but this seems like some ninja stuff!

      posted in Dynamic Components
      H
      hank
    • Search a DC attribute string value

      If you wanted to see if the string "Hello" was in the following attribute string value...

      qwertyHello12345

      How would you do it?

      The trick is, can you return one value (like "TRUE" or "1") if found and another (like "FALSE" or "0") if not?

      I would be interested in a Ruby solution too if necessary!

      posted in Dynamic Components sketchup
      H
      hank
    • RE: Ruby Group Copy - Regardless of Context?

      Thank you Dan!

      posted in Developers' Forum
      H
      hank
    • RE: How to use FIND() in an IF() statement

      Thank You Jim!

      So how about if I wanted to find out if the string "SINGLE" exists anywhere in the string?

      posted in Dynamic Components
      H
      hank
    • RE: Ruby Group Copy - Regardless of Context?

      Thanks Dan.

      So it sounds like really what I am doing is saying

      give me entities whose layer property is 'X'
      Right?

      And regarding...

      @unknownuser said:

      And yes, transformations of nested objects are a PITB.

      I am glad I'm not alone in that sentiment!

      posted in Developers' Forum
      H
      hank
    • RE: Importing Bulk Attribute Values from CSV

      BTW, the answer to the original question was that

      
      input = UI.inputbox(@prompts, @defaults, @list, "Select Attribute Target")
      
      

      returns an array of values because typically the inputbox would present more than 1 option. In my case there was only one input or prompt so when I put input into

      
      set_result = Sketchup.active_model.set_attribute("dynamic_attributes", input, att_string.to_s )
      
      

      I was actually sending in an array and thus setting a new key in the format ["whatever user put into inputbox"]. Even .to_s did not seem to help...

      
      set_result = Sketchup.active_model.set_attribute("dynamic_attributes", input.to_s, att_string.to_s )
      
      

      The answer was to get the first item in the array like so:

      
      set_result = Sketchup.active_model.set_attribute("dynamic_attributes", input[0], att_string.to_s )
      
      
      posted in Developers' Forum
      H
      hank
    • RE: Importing Bulk Attribute Values from CSV

      Alright @TIG, I re-wrote this script trying to comply with your suggestions and it worked! Thank you for your help!

      Here is the updated script for your entertainment:

      
      require 'sketchup.rb'
      module AttModuleTop
      	module AttModuleBottom
      		class<<self
      			def list_att()
      				model = Sketchup.active_model
      				attrdicts = model.attribute_dictionaries
      				attrdict = attrdicts["dynamic_attributes"]
      				if(!attrdict)
      					UI.messagebox("AttTools is intended for use within Dynamic Component Files only")
      				else
      					@prompts = ["What attribute to overwrite"]
      					@defaults = [""]
      					@list = []
      					@option_pairs = ""
      					option_string = "select attribute to overwrite"
      					attrdict.each{|key,value|
      						@option_pairs += "key; #{key} | value; #{value}\n"
      						option_string += "|#{key}"
      					}
      					@list << option_string
      				end
      			end
      			def replace_att()
      				list_att()
      				new_prompt = "What should it be set to?"
      				@prompts << new_prompt
      				input = UI.inputbox(@prompts, @defaults, @list, "Select Attribute Target")
      				set_result = Sketchup.active_model.set_attribute("dynamic_attributes", input[0], input[1] )
      				UI.messagebox('succesfully set ' + input[0] + ' to ' + set_result + '!')
      			end
      			def load_att()
      				list_att()
      				input = UI.inputbox(@prompts, @defaults, @list, "Select Attribute Target")
      				att_string = ""
      				csv=UI.openpanel("Choose CSV File...")
      				lines=IO.readlines(csv)
      				lines.each{|line|
      					line.chomp!
      					next if line.empty?
      					new_line = line.gsub(",", " ") #replace commas
      					new_line = new_line.gsub("  ", "") #replace double spaces
      					new_line = new_line.gsub("   ", "") #replace double spaces (again)
      					new_line = new_line.gsub("& ", "&") #replace double spaces (again)
      					new_line = new_line.gsub("= ", "=") #replace double spaces (again)
      					att_string += new_line.to_s 
      				}
      				set_result = Sketchup.active_model.set_attribute("dynamic_attributes", input[0], att_string.to_s )
      				UI.messagebox('succesfully set ' + input[0] + ' to ' + set_result + '!', MB_MULTILINE)
      			end
      			def report_att()
      				list_att()
      				if(@option_pairs)
      					UI.messagebox(@option_pairs, MB_MULTILINE)
      					#puts @option_pairs
      				end
      			end
      		end # end of class
      	end # end of module AttModuleBottom
      end # end of module AttModuleTop
      
      # menus ##############################################################
      
      if( not file_loaded?("att_tools.rb") )
      	main_menu = UI.menu("Plugins").add_submenu("Att Tools")
      	main_menu.add_item("Load Attributes") {(AttModuleTop;;AttModuleBottom;;load_att)}
      	main_menu.add_item("Replace Attribute") {(AttModuleTop;;AttModuleBottom;;replace_att)}
      	main_menu.add_item("Report Attributes") {(AttModuleTop;;AttModuleBottom;;report_att)}
      end
      file_loaded("att_tools.rb")
      
      
      posted in Developers' Forum
      H
      hank
    • RE: [Layout] Transparent background in LO and extracting image

      @Jennyarchitect, you can do it on a Mac if in Sketchup the background color is set to a transparency other than 0 (zero) and in Layout, the reference is set to vector.

      Interestingly, you can still seem to have sky and ground on!

      posted in SketchUp Tutorials
      H
      hank
    • RE: Importing Bulk Attribute Values from CSV

      Thanks TIG. I'll give that a try.

      Of course you do... that info is for anyone else reading this thread and having a similar struggle as I did.

      posted in Developers' Forum
      H
      hank
    • RE: Importing Bulk Attribute Values from CSV

      That key is actually EXACTLY what I want. I just had to do it by hard coding the $input argument in set_attribute($input,$att_string) to read "_leny_options" (a string) in order to get it to work. When I feed in $input from UI.inputbox it comes creates a separate new key called ["_leny_options"] with brackets and quotes around it. That is the problem - somehow I need to format $input so this does not happen.

      The reason I want that key to be so long is because this is what I want the drop-down to look like:

      screenshot

      peripheral information...

      drop-down attributes are stored in a &key1=value1&key2=value2&key3=value3... format in the dictionary

      and

      UI.inputbox will present a drop-down if given 4 arguments and the 3rd argument is a bar separated list.

      posted in Developers' Forum
      H
      hank
    • RE: Importing Bulk Attribute Values from CSV

      Thanks TIG... will do. Any idea about the problem I mentioned?

      posted in Developers' Forum
      H
      hank
    • RE: Importing Bulk Attribute Values from CSV

      Sure! Here is a simple wall DC that I wanted to bring in a large list of wall assemblies:

      A basic wall dynamic component

      and here is the list of assemblies I put together in a spreadsheet - you will see that I added the "&" separator and "=" value indicator right in the spreadsheet because I was being lazy about the string cleanup...

      A list of assemblies for commercial construction

      And for convenience, here is the ruby file too!

      ruby CSV attribute importer

      posted in Developers' Forum
      H
      hank
    • Importing Bulk Attribute Values from CSV

      Hello All,

      I have worked up the script below in an attempt to allow myself to input a large number of annoyingly long attributes from a CSV file into a Dynamic Component's attribute dictionary. Yes, yes, I read several places that this has been covered extensively and that TIG had written a few scripts to accomplish this. That was not really my experience and I had trouble finding this exact function. I used TIG's script as a starting point but the documentation on dictionaries seemed thin and not all that helpful.

      I also understand that there are a number of extensions out there but I wanted to try and understand what was going on under the hood with dictionaries so I could possibly take advantage of them and hopefully help others do the same.

      Here it is:

      
      require 'sketchup.rb'
      def set_attribute(key_in, value_in)
      	model = Sketchup.active_model
      	target_dictionary = model.attribute_dictionaries['dynamic_attributes']
      	new_key = target_dictionary[key_in] = value_in
      	#puts key_in
      end
      
      def load_attributes()
      
      	list = []
      	$option_string = "please select an attribute"
      	model = Sketchup.active_model
      	attrdicts = model.attribute_dictionaries
      	attrdict = attrdicts["dynamic_attributes"]
      	attrdict.each{|key,value|
      		#puts "key; #{key} | value; #{value}"
      		$option_string += "|#{key}"
      	}
      	list << $option_string
      
      	prompts = ["What attribute would you like to input values for?"]
      	defaults = ["_leny_options"]
      	$input = UI.inputbox(prompts, defaults, list, "Select Attribute Target")
      	#puts $input
      
      	$att_string = ""
      	csv=UI.openpanel("Choose CSV File...")
      	lines=IO.readlines(csv)
      	lines.each{|line|
      		line.chomp!
      		next if line.empty?
      		new_line = line.gsub(",", " ") #replace commas
      		new_line = new_line.gsub("  ", "") #replace double spaces
      		new_line = new_line.gsub("   ", "") #replace double spaces (again)
      		new_line = new_line.gsub("& ", "&") #replace double spaces (again)
      		new_line = new_line.gsub("= ", "=") #replace double spaces (again)
      		$att_string += new_line.to_s 
      	}
      	#puts $att_string
      	set_attribute('_wall_thickness_options',$att_string)
      	#set_attribute($input,$att_string)
      end
      
      def report_attributes()
      	model = Sketchup.active_model
      	attrdicts = model.attribute_dictionaries
      	attrdict = attrdicts["dynamic_attributes"]
      	attrdict.each{|key,value|
      		puts "key; #{key} | value; #{value}"
      	}
      end
      
      

      Now for my dilemma...

      You can see that I added a drop-down prompt for a user to select a particular key that is already in the model (I'm only focusing on the 'dynamic_attributes' library though there are others). Well, the input I get from the user prompt ends up adding a key to the dictionary like so...

      If I wanted to overwrite the key _lenx_options for example, it comes in as a NEW key called ["_lenx_options"] which is not in fact setting the existing key but creating a new one.

      How can I pass the input argument correctly to the set_attribute def?

      Thanks for any help!

      posted in Developers' Forum
      H
      hank
    • RE: Ruby Group Copy - Regardless of Context?

      OK folks, I figured it out... how long has it been? A week or so. Jeez! Anyway, I found this thread where Thomas answered a similar question:

      Redirecting to Google Groups

      favicon

      (groups.google.com)

      I could not get it to work for my purposes as written so modified it as shown in my reply. I've tested it to 4 levels and seems to be working. Hopefully this is helpful to someone.

      posted in Developers' Forum
      H
      hank
    • Ruby Group Copy - Regardless of Context?

      Hello All,

      I have created a script the copies groups on a certain layer, call them target groups to a new temporary group I am planning to use for later shenanigans. The trouble I'm having is that the add_instance method needs the transformation of both the target group I am copying AND the parent. HOWEVER, sometimes the target groups will be nested in other groups and sometimes they won't. Sometimes they could be nested many times over.

      How would I create a transform argument that somehow "senses" the nesting level of the entities being copied in in order to preserve their original position?

      Here is what I have so far, which seems to work at only one nesting level.

      
      Sketchup.active_model.definitions.each{|defn|
      	#puts "definition name; #{defn.name} | layer; #{defn.layer.name}"
      	defn.instances.each{|inst|
      		inst.definition.entities.each{ |defn_inst|
      			if(defn_inst.layer.name == "OPENING_PRIMITIVES")
      				puts "defn_inst; #{defn_inst} name; #{defn_inst.name} | layer; #{defn_inst.layer.name}"
      				@@temp_opening_primitives.entities.add_instance(defn_inst.entities.parent, inst.transformation*defn_inst.transformation)
      			end
      		}
      	}	
      }
      
      

      Honestly, this seems like an overly complicated way to do this. I wish there was a way to quickly say "give me everything on this layer and copy it to a temporary group." Having to loop, then loop again, going back and forth between the instance and the definition bends my head in knots. As best I can tell from this forum though, this is the way I guess.

      posted in Developers' Forum
      H
      hank
    • RE: Ruby Sketchup Programmatic Union of Multiple items

      Thanks Dan. Feelin' the power of grep!

      posted in Developers' Forum
      H
      hank
    • RE: Label and annotations text to change SketchUp model info

      I agree TommyK... basically its a good system. Could be better but has a lot of power built in. I am using Sketchup for space programming (bubble diagrams) and have found I can add custom properties to a component, then get Layout to report them. So, like when you have <ComponentDescription> you can change it to:

      %(#FF0000)[<DynamicComponent(role)>
      <DynamicComponent(staff)>]

      Where role and staff are custom attributes I created for my "bubble" component. Pretty cool! I just figured this out yesterday so there are probably way cooler things we can do.

      BTW, attached is the bubble component if you are interested. You can change the area you want to change the size of the circle.


      BUBBLE.skp

      posted in LayOut Feature Requests
      H
      hank
    • 1
    • 2
    • 1 / 2