Attaching arbitrary data to a model
-
Is there a way to attach what was once called a blob to a model? Perhaps I'm blind, but I'm just not seeing it. If not, is there some other magic method to accomplish something similar?
Cheers
-
model.set_attribute('MyLovelyBlob', 'some_key', value)
To read that key use:
val = model.get_attribute('MyLovelyBlob', 'some_key', nil)
Returnsnilif not set.The
valuecan be integer/float/length/string/boolean/array [array of any of the other types]Attributes can be set/got for most kinds of things in SketchUp - from the model itself down through collections and entities...
-
I interpret "blob" to mean "binary large object", that is, a sizeable chunk of otherwise opaque binary data. You might need to pack your blob into a Ruby type that set/get_attribute handles correctly. Test with specific examples to see whether what you have survives the round trip or needs to be packed.
-
If the 'blob' is actually binary data you can convert it with ruby into a string for the set_..., then convert it back to binary after the string is returned by the get...
There is a length limit for a single string attribute [~20000]...
Before the API introduced the ability to download a SKP [binary-file] from a URL, in the oldie system I invented a temporary fix using the then API, to allow you to do it by downloading/inserting a remote almost empty [binary] SKP and then extracting its special string attribute[s] and reworking them back into binary data - concatenating multiple strings into one if the max length was exceeded.
You then had an RBZ to install...RBZ2SKP [note: some references etc need setting initially !]
defn = model.definitions.add(File.basename(path)) ### make defn [if needed] defn.entities.add_cpoint([0,0,1]) ### so NOT empty data = File.open(path, "rb"){|io| io.read}.unpack('H*')[0] ### tidy up in case observers have added stuff ? defn.attribute_dictionaries.each{|attd| attd.keys.each{|k| attd.delete_key(k) } defn.attribute_dictionaries.delete(attd) } if defn.attribute_dictionaries ### divide up key = 'x0001' chunk = 20000 ### size limit start = 0 parts = data.length / chunk (parts + 1).times{ part = data[start..(start+chunk)] defn.set_attribute("RBZdata", key, part) start = start + chunk + 1 key.next! } ### save as SKP nname = File.basename(path).gsub(/^[^A-Za-z0-9._-]/, '').gsub(/[^A-Za-z0-9._-]/, '_') + '.skp' ### strip out leading # and all non A0Z etc as '_' skp = File.join(File.dirname(path), nname) defn.save_as(skp) defn.entities.clear!SKP2RBZ [note again: you'll need to define some references and decide on the exact code !]
### after the SKP is added... defn = model.definitions[-1] return false unless defn ### reassemble attd = defn.attribute_dictionaries['RBZdata'] return unless attd data = '' attd.keys.sort.each{|key| data << defn.get_attribute('RBZdata', key, '') } datax = [data].pack('H*') ### fi = File.open(path,'wb') fi.write(datax) fi.close @model.start_operation('SKP2RBZ') defn.entities.clear! Sketchup.send_action("editUndo;") @model.commit_operationYou might be able to extract a 'blob' set/get from this...
-
Please forgive me. I was convinced that I'd already replied. This is exactly what I needed (and I'm further at a loss wrt how I didn't see that in the the API reference). Thanks very much
Hello! It looks like you're interested in this conversation, but you don't have an account yet.
Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.
With your input, this post could be even better π
Register LoginAdvertisement