Ruby, Excel, Dynamic Components, and JPEG output

I want to be able to produce a large quantity of images based upon different dynamic component values. Those values are stored in a spread sheet; one line per image.

For the sake of this discussion, let’s assume the dynamic component is a box with Xlen, Ylen, Zlen, Color, and Output File Name. The spread sheet will have 100’s of lines, each with different Xlen, Ylen, Zlen, Color, and File Name values.

I would like to find someone who can develop the Ruby plugin code to do this or at least get the framework build in such a way I can easily modify it for my particulars.

Open Excel spread sheet
Begin Loop
Read one line of data from spread sheet
Change Dynamic Component Values from the spread sheet data
Apply those changes to the model
Export a JPEG image of the result
Exit Loop at end of spread sheet
End Loop

Any help would be appreciated.

Joe

It’ll be a lot easier if you save a comma delimiter file out of Excel…rather than trying to deal with a .xls file.

Is that OK?

Do you know any ruby or do any scripting?

If you get given the “bare bones” Can you finish/edit the script and customise it for yourself?

Regards,
AS

i got bored…and wanted to see if I could do it.

below is the “bare bones”…this is not a plugin, you’ll need to work out how to run it…

(oh by the way, this is by no means my own knowledge or skill…I am standing on the shoulders of giants…I had to look up details and posts from the regulars to these forums…)

you have to have the dynamic component selected when you run the script…(selection[0])

class String
def numeric?
Float(self) != nil rescue false
end
end

def dcloop
thedc = Sketchup.active_model.selection[0]
afile = File.open(‘D:\Users\whereever\Documents\acsvfile.csv’)
thecontents = afile.read.split(/\n/)
allsets = []
headings = thecontents[0].split(",")
thecontents[1…-1].each do |l|
eachset = {}
l.split(",").each_with_index do |v, i|
if v.numeric? then
eachset[headings[i]] = v
else
eachset[headings[i]] = ‘"’ + v + '"'
end
end
allsets.push eachset
end
thedcdef = thedc.definition
allsets.each_with_index do |s, i|
s.each do |k,v|
thedcdef.set_attribute ‘dynamic_attributes’, k, v
thedcdef.set_attribute ‘dynamic_attributes’, “_” + k + “_formula”, v
end
dcs = $dc_observers.get_latest_class
dcs.redraw_with_undo(thedc)
keys = {
:filename => “D:/Users/whereever/Documents/” + i.to_s + “.jpg”,
:width => 640,
:height => 480,
:antialias => false,
:compression => 0.9,
:transparent => false
}
model = Sketchup.active_model
view = model.active_view
#model.active_view.refresh || Sketchup.active_model.active_view.invalidate
view.write_image keys
end
end

i tested it on a windows 10 machine with sketchup 2014.

here is the sample csv file i used:

size1,size2,colour
520,100,red
200,600,green

have fun!

Regards,
AS

[anthonysmithemail] anthonysmithemail
http://forums.sketchup.com/users/anthonysmithemail
August 24

It’ll be a lot easier if you save a comma delimiter file out of
Excel…rather than trying to deal with a .xls file.

Is that OK?

I can build whatever excel format I need. No problem.

Do you know any ruby or do any scripting?

I don’t really know Ruby but have a solid old school computer
science background so I can understand code and can make little tweaks

If you get given the “bare bones” Can you finish/edit the script and
customise it for yourself?

If I had a simple Sketchup Box model with a working plugin I could
probably edit and tune to plug it into my big model.

I am more than happy to pay for coding and support.

Thank you so much. I’ll study this and try to learn up on Ruby.

If you, or anyone can complete this as a plugin, that would be
fantastic. Again, More than will into to pay for coding and support.

Many thanks,
Joe

(Moved to the Ruby API category.)

@anthonysmithemail, regarding your monkey patch example:

class String
  def numeric?
    Float(self) != nil rescue false
  end
end

… is an absolute NO NO.

DO NOT modify Ruby nor API base classes !
SketchUp Ruby is a shared environment.

Instead use refinements:
http://ruby-doc.org/core-2.0.0/doc/syntax/refinements_rdoc.html

ie:


module Smith::Refinements
  refine String do
    def numeric?
      Float(self) != nil rescue false
    end
  end
end


using Smith::Refinements

module Smith

  # Write a method / class here that uses 
  # the file-local String class refinement.

end

I’ve attached a simple Sketchup model and Excel spread sheet that
basically represents what I want to do.

I hope this helps to explain better.

Thanks,
Joe

box.skp (163 KB)

Dan - thank you for the advice… I am still a novice Ruby person, these are the shoulders I stand upon to get better. I’ve incorporated the improvement for Joe.

Joe: didn’t get a chance to look at your files… I gotta catch a plane in a few hours…I’m away from the internet for 4-5 days…I’ll check back in then.

I did notice that the forum swallowed some underscores…and also my indents…

I’ll post it as an upload this time

jg.rb (1.3 KB)

Code blocks need to be wrapped in lines of triple backticks (the character above the tilde “~”). If you add the language to the first triple backtick line (ie, “```ruby”), it will be color lexed. (Other langs can be “javascript”, “html”, etc.)

The code blocks also get scollbars if needed.

here is the code

module Smith
end
module Smith::Refinements
	refine String do
		def numeric?
			Float(self) != nil rescue false
		end
	end
end
using Smith::Refinements
module Smith
	#using Smith::Refinements
	def self.dcloop
		thedc = Sketchup.active_model.selection[0]
		afile = File.open('c:\acsvfile.csv')
		thecontents = afile.read.split(/\n/)
		allsets = []
		headings = thecontents[0].split(",")
		puts "345".numeric?
		thecontents[1..-1].each do |l|
			eachset = {}
			l.split(",").each_with_index do |v, i|
				if v.numeric? then
					eachset[headings[i]] = v
				else
					eachset[headings[i]] = '"' + v + '"'
				end
			end
			allsets.push eachset
		end
		#puts allsets
		thedcdef = thedc.definition	
		allsets.each_with_index do |s, i|
		s.each do |k,v|
			thedcdef.set_attribute 'dynamic_attributes', k, v
			thedcdef.set_attribute 'dynamic_attributes', "_" + k + "_formula", v
		end
		dcs = $dc_observers.get_latest_class
		dcs.redraw_with_undo(thedc)
		keys = {
			:filename => "c:/" + i.to_s + ".jpg",
			:width => 640,
			:height => 480,
			:antialias => false,
			:compression => 0.9,
			:transparent => false
		}
		model = Sketchup.active_model
		view = model.active_view
		#model.active_view.refresh || Sketchup.active_model.active_view.invalidate
		view.write_image keys	
		end
	end
	puts
end

Joe,
did you work out how to use it without it being wrapped in a plugin?

Regards,
AS

No. Not yet. My wife had foot surgery and I’ve been tending to that situation plus pulling double duty in our business.

I’ll try to understand the code first, then try to test it out. A learning experience for sure.

Thanks to all for the help.

Joe