Import image (in padded cell..!)
-
Yes I did mean to combine them.
TheUI.openpanel
call gets the 1st argument toEntities#add_image
.
You'd either already have the insert point, or call a get point tool (there is an example in the Examples package.)
You could also expand the tool to draw the rectangle, or just insert the image, and then push it into the selection and call the scale tool.The other option is to insert the image (at the origin,) then delete it, but because images are components, you might be able to use
Model#place_compoment()
. -
mmmh, will play some more... as mentioned, i already traveled the component route but the behaviour is not what i want. strange you cannot specify the import option.
Thanks
-
get_image = UI.openpanel("Open Image File", "~/Desktop/", "Image Files|*.jpg;*.png;||") model = Sketchup.active_model image = model.active_entities.add_image(get_image, ORIGIN, 400, 400)
you may want to 'get' the image height, width first...
-
Thanks Driven, i've tried this already but what i'm going mad about is i cannot simply replicate the way it works when you import 'as image' (floats on the cursor, place and scale....).
the nearest i got was to turn it into a comp, but not the simple action that i want.
m = Sketchup.active_models = m.selection;e = m.entities;d = m.definitions x = e.add_image(path, ORIGIN, 800, ) s.add x g = e.add_group(s) c = g.to_component cd = c.definition cd.behavior.is2d = true cd.behavior.snapto = 0 c.erase! m.place_component cd, true
problem is the registry setting stores the last option used, and it seems one cannot bypass this during the session from ruby.
i can get round it with 'sendaction' but of course, only on pc.
ocd, but seems crazy that in ruby one just can't select 'as image'.
-
Like a Group, an Image already has a "component-definition".
This code places a tiny hidden chosen Image at the ORIGIN.
Then it uses its definition to let the user decide where it's actually going...
It deletes the original tiny hidden one once the user has placed the second one.
It uses a timer to wait until the user has inserted the second instance, because if the original Image is deleted before the second one is added then its definition just disappears - just like a Group might...imagefile = UI.openpanel("Choose Image File", "~/Desktop", "Image Files|*.jpg;*.png;||") model = Sketchup.active_model sel = model.selection images1 = model.definitions.select{|d| d.image? } ### existing images model.start_operation("!", true) image = model.active_entities.add_image(imagefile, ORIGIN, 0.1) image.hidden = true model.commit_operation images2 = model.definitions.select{|d| d.image? } ### all images including the new one defn = (images2 - images1)[0] ### the new image's definition img = model.place_component(defn, false) tid = UI.start_timer(0.1, true){ if inst = defn.instances[1] ### user has added the second instance begin; image.erase! ;rescue;end puts UI.stop_timer(tid) end } puts
-
Thanks TIG, though i think that is like the one i did already.
with this workaround, you don't get the type of 'import as image' interaction (which allows you to position/align AND scale the image in one comfortable action).
in other words, i'm trying to get exactly the same behaviour as 'sendaction 21200' - which works on a pc but not on a mac. i spent the whole of bank holiday monday on this, and concluded there is not a way to replicate it...(that's why the padded cell!).
-
To mimic the Image tool completely you need to do what I did in terms of getting the defn, then have a Tool class set up to allow you to place/scale etc...
-
maybe I should tell you that your original code works on a mac...
It is unaffected by last import method, i.e. it comes in as a placable/scalable image...
Also it has no impact on the 'File' >> 'Import' setting...
so for mac you can use your simple code...
john -
(Which is what I alluded to above.)
This timer code:
tid = UI.start_timer(0.1, true){ if inst = defn.instances[1] ### user has added the second instance begin; image.erase! ;rescue;end puts UI.stop_timer(tid) end }
... would be better like:
@tid = UI.start_timer(0.1, true){ ### use persistent var reference if defn.instances[1] ### not nil, user has added the second instance UI.stop_timer(@tid) ### always immediately stop the timer image.erase! rescue nil ### use rescue in modifier position puts "Image has been inserted." end }
.. and at the end of the method,
return img
-
ok, thanks... that's some food for thought... let's see what i can cook.
-
I assumed that if you stop a timer it's the same as '
break
' in a block, so then it'd never get toimage.erase!
, but having tested it I see that it complete the entire iteration after the timer is stopped !I don't immediately see the advantage of using
@tid
overtid
- the block of code executed by the timer is referring back to itself, it's not like we are stopping it in another def method ? -
@driven said:
maybe I should tell you that your original code works on a mac...
It is unaffected by last import method, i.e. it comes in as a placable/scalable image...
Also it has no impact on the 'File' >> 'Import' setting...
so for mac you can use your simple code...
johnThanks Driven, i had missed your post... if it works on mac it's great news. i can use sendaction for pc and the code posted originally for mac.
-
@tig said:
I assumed that if you stop a timer it's the same as '
break
' in a block, so then it'd never get toimage.erase!
, but having tested it I see that it complete the entire iteration after the timer is stopped !Of course it does. A timer just loops and calls the block on the set interval. (The setInterval timers in Javascript work the same way.)
This why you should always stop the timer immediately when the condition is met. Otherwise the block gets queued up to be executed again, perhaps even before the first time is done doing it's work.
@tig said:
I don't immediately see the advantage of using
@tid
overtid
- the block of code executed by the timer is referring back to itself, ...Sometimes it works. But I have experienced that in some situations, the ID reference becomes invalid (perhaps gets garbage collected.) And then the call to stop the timer does not work.
[I remember having a discussion with Jim Foltz about timer IDs being invalid, or garbage collected.]The Ruby docs say a proc is supposed to have access to it's environment (like a snapshot,) when it is defined. But the API
UI
timer is implemented on the C++ side.@tig said:
... it's not like we are stopping it in another
def
method ?I always assume code samples are going to run in a method.
It is rare that code is something that runs once at startup, (although we sometimes do post code like that.)
THIS feature we are discussing, is something that will be used "on demand" (by a end user,) in a
Tool
class or aUI::Command
, which means it'll likely be wrapped in a method.Bottom line, ... the above is my best advice on best practice. Believe or not, as you will.
It is not arbitrary. I have had timer use fail in the past when using local var for the id. Perhaps under Ruby 2.0, things have changed with regard to the timer IDs, .. but I still always use a persistent reference for timer IDs on the Ruby side, until I know it is no longer needed.
As far as using
rescue
in modifier position goes, that is a no brainer. (And is not a best practice rule I made up. I got it from one of the Style Guides or maybe the "Pick-Axe" book.)begin; statement; rescue; end
is just plain uglier, and doesn't read as nice as:
statement rescue nil
Advertisement