Hej Thom,
Then it sounds like I have to switch to Sketchup 2014
Hej Thom,
Then it sounds like I have to switch to Sketchup 2014
Hi!
This one might be though, since most of you are US-Guys. But if you come from an ancient country like mine you have special characters like æøå.
And that appears to be a problem if you want to save a file with a name containing letters like æ, ø or å.
Do you have any ideas how to fix that?
-Rasmus
@sdmitch said:
Interesting! In the Ruby Console, type ENV and press Enter. Does that show anything? How about ENV['HOME'].
When I type ENV in Ruby Console:
"PUBLIC"=>"C:\\Users\\Public", "SESSIONNAME"=>"Console", "SystemDrive"=>"C:", "SystemRoot"=>"C:\\windows", "TEMP"=>"C:\\Users\\RASMUS~1\\AppData\\Local\\Temp", "TMP"=>"C:\\Users\\RASMUS~1\\AppData\\Local\\Temp", "USERDOMAIN"=>"RasmusVS-pc-Pc", "USERNAME"=>"RasmusVS-pc", "USERPROFILE"=>"C:\\Users\\RasmusVS-pc", "windir"=>"C:\\windows", "windows_tracing_flags"=>"3", "windows_tracing_logfile"=>"C:\\BVTBin\\Tests\\installpackage\\csilogfile.log"}
As you can see there is no ENV['Home'] variable.
I would use ENV['USERPROFILE']
instead.
I use Sketchup 8.0.15158 - Maybe thats why...?
@sdmitch said:
ENV['Home'] is your user account, ie C:/Users/Rasmus. In this case filename would equal 'C:/Users/Rasmus/Desktop/mysketchup.skp'
Great, thanks! I figured it out with your help
model = Sketchup.active_model status = model.save('d:/rs_model.skp')
But ENV['Home'] dont seems to work.
I have tried:
test = ENV['Home'] puts(test.to_s)
and nothing shows...
Hi!
How do I save the model to a file?
I have tried the following but it don't seems to work.
` model = Sketchup.active_model
filename = File.join(ENV['Home'], 'Desktop', 'mysketchup.skp')
status = model.save(filename)`
And can anyone tell me what ENV['Home'] is?
And if I want to save to a diffenrent location than desktop will it then be, eg:
'c:\my\project\folder'?
Thanks in advance
-Rasmus
Great, this solved my problem! Thank you very much Dan!
@dan rathbun said:
Problem is you are already within the
EntitiesObserver
instance attached to the Group'sEntities
collection !
You must be careful not to set up an infinite loop !Changing the model from within observer callbacks can crash SketchUp !
Ok, for now I will abandon this approach.
Please consider this example:
mod = Sketchup.active_model
ent = mod.entities
i = 0
h= {}
ent.each do |o|
attr = o.get_attribute "rsdict","area"
if attr
h[i] = {'structid' => 201, 'area' => attr}
i += 1;
end
end
Here it scans the entire model for groups with the attribute_dictionary "rsdict", "area".
Lets say it finds a group with the "rsdict" attribute. Inside the group there are a face
with an attribute attached to it.
Is it possible to scan that group for all its entities? Something like this:
mod = Sketchup.active_model
ent = mod.entities
i = 0
h= {}
ent.each do |o|
attr = o.get_attribute "rsdict","area"
if attr
o.entites.each do |u|
yv_face_area = u.get_attribute "rsdict", "yv_face_area"
if yv_face_area
h[i] = {'structid' => 201, 'area' => yv_face_area} i += 1;
end
end
end
Thank you Dan, but I try to explain it again:
My goal is to set an attribute to the group when a face has been modified. As you can see in the code below Im able to set an attribute to the face inside the group, but not the group containing the face. Do you have any ideas how to work around this problem?
If the group is called rsgroup:
yv_face_height = rsgroup.entities.add_face pts[0..3]
rsgroup.set_attribute "rsdict","area", yv_area
yv_face_height.set_attribute "rsdict", "yv_face_area", yv_area
class MyEntitiesObserver < Sketchup;;EntitiesObserver
def onElementModified(entities, entity)
attr_area = entity.get_attribute "rsdict", "yv_face_area"
if attr_area
yv_area_new = i.area.to_m.to_m
entity.set_attribute "rsdict", "yv_face_area", yv_area_new
#(HERE I WOULD LIKE TO SET THE ATTRIBUTE OF THE GROUP-something like;)
entity.parent.set_attribute "rsdict","area", yv_area_new
end #attr_area
end #onElementModified_end
end #class
Hi,
Im working with EntitiesObserver
, and having trouble understanding the method
def onElementModified(entities, entity)
.
For instance, if you add an EntitiesObserver
to a group consisting of a face, the EntitiesObserver
will fire when you doubleclick the group and alter the face.
(Eg. moving one of the edges so that the area of the face will increase.) In that case it will fire 3 times because 2 edges will get longer, and the face itself will increase in size.
If you have set an attribute to the face it is then possible to retrieve the value by saying
myFaceAttr = entity.get_attribute "rsdict", "face_attr"
, and you can set a new value with set_attribute "rsdict", "face_attr", "new value"
.
But now my question is: what if I have an attribute set to the group, and I want to alter that when the EntitiesObserver
fires. Is it possible to see name of the parent of the entity? (The face is a child of the group)
Hope the question is understandable...
-Rasmus
Ok. hopefully there is a solution. If I find one I will return...
I'm not sure how to do these tests.
Are you saying if I pushpull one red face, it triggers events for every instance?? (If there is 200 boxes it triggers 200 times?) (box=instance)
Or will it trigger the number of times, you have runned the script which adds observers? (instance = observer added)
(Because in my case it only shows the UI.messagebox once)
@thomthom said:
Got a sample model with "Boxes"?
What do you do to trigger the events?
In post number 7 in this thread there are two pieces of codes attached...
The 1. piece of code draw boxes without observers, the 2. piece of code add observers to the boxes.
When you have deleted a box, try to undo, and it attaches new observers in a way that it solves the problem with lost observers.
It triggers when the red face is modified (push/pulled) using the def onElementModified(entities, entity) in the "MyEntitesObserver", and it messure the area of the green face.
@thomthom said:
Not correct. For each new instance of your observer class you attach you add an observer
Ok, maybe you are right, but to me it seems like it only triggers once, even though I have attached it many times in a row.
Could it be that it is overwritten each time its attached?! As far as I can see its not possible to see which observers is added in the model.
If you try the code I have attached above you can what I mean...
(Run the first code a couple of times to get some boxes without observers, then run the second code as many times you want, and the observers only triggers once)
@rvs1977 said:
and its not possible to add more than one observer to each entity, so you dont have to take care if the entity allready has got one.
@thomthom said:
Yes you can add more than one observer.
What I meant was, if you do like this:
(adding 3 identical observers to one entity)
Code:
[....]
mygroup.entities.add_observer(myEntitiesObserver.new)
mygroup.entities.add_observer(myEntitiesObserver.new)
mygroup.entities.add_observer(myEntitiesObserver.new)
[....]
it will only have one myEntitesObserver attached to mygroup. - not three. That means its easier to handle... You dont need to check if its allready added, its faster just to add new one to every entities.
Yes you can add more observers to one entity eg. MyEntitiesObserverWatchFaces and MyEntitiesObserverWatchEdges
@thomthom said:
There is still the problem that you modify the model on observer events. When you do that you interfer with any operation that is going on - which might be in the middle of a start/commit operation of another plugin or native tool. You'll be adding to the Undo stack - causing unexpected behaviour when the user expects to undo their last operation but instead the undo is your injected attribute change.
Model change at observer events may cause bug splats.
Im not sure how to do it yet, but I think a solution could be to remove the observers, when editing the group, and adding the observer again when finished.
It seems to be very quick to add observers to ALL the entities in the model, and its not possible to add more than one observer to each entity, so you dont have to take care if the entity allready has got one.
Think I found a usable solution to this problem:
(It only works in SU8+)
The solution seems to be simple: - Every time something happens (like undo or change, etc.) the executed observer iterates through each entity and, in my case, when it finds an entity with the attributes ("rsdict", "area") it simply add_observer(MyEntitiesObserver.new).
It can be testet with the two pieces of codes below.
In this example it messures the area of the green face, when you pushpull the red face at the top.
In the first codepiece it draws some boxes and adds some attributes, but dont add any observers. Try to run the code a few times so it will produce a number of boxes.
mod = Sketchup.active_model # Open model
ent = mod.entities # All entities in model
sel = mod.selection # Current selection
pts = []
pts[0] = [ 0, 0, 0]
pts[1] = [ 1000.mm, 0, 0]
pts[2] = [ 1000.mm, 1000.mm, 0]
pts[3] = [ 0, 1000.mm, 0]
pts[4] = [ 0, 0, 1000.mm]
pts[5] = [ 1000.mm, 0, 1000.mm]
pts[6] = [ 1000.mm, 1000.mm, 1000.mm]
pts[7] = [ 0, 1000.mm, 1000.mm]
10.times do |i|
rsgroup = ent.add_group
rsgroup.entities.add_face pts[0..3]
yv_face_height = rsgroup.entities.add_face pts[4..7]
rsgroup.entities.add_face pts[0], pts[3], pts[7], pts[4]
rsgroup.entities.add_face pts[3], pts[2], pts[6], pts[7]
yv_face_length = rsgroup.entities.add_face pts[1], pts[2], pts[6], pts[5]
yv_face_area = rsgroup.entities.add_face pts[0], pts[1], pts[5], pts[4]
yv_face_height.pushpull rand(1000.mm)
yv_area = yv_face_area.area.to_m.to_m
yv_face_area.material = (0xAADEAA) #green
yv_face_height.material =(0x8811FF) #red
rsgroup.set_attribute "rsdict","area", yv_area
yv_face_area.set_attribute "rsdict", "yv_face_area", yv_area
yv_face_length.set_attribute "rsdict", "yv_face_length" , 0
yv_face_height.set_attribute "rsdict", "yv_face_height", 0
point = Geom;;Point3d.new (1100.mm * i, 0, 0)
t = Geom;;Transformation.new point
rsgroup.transform! t
end #times_do
ent.each do |o|
point = Geom;;Point3d.new (0, 1100.mm, 0)
t = Geom;;Transformation.new point
o.transform! t
end #each_do
Second piece of code: - Here it add the observers. Every time the code is executed it will asign the observers. And it seems like it doesnt matter how many times you do it.There will only be one observer for each entity.
mod = Sketchup.active_model # Open model
ent = mod.entities # All entities in model
sel = mod.selection # Current selection
class MyModelObserver < Sketchup;;ModelObserver
def onTransactionUndo(model)
#UI.messagebox("onTransactionUndo; " + model.to_s)
Sketchup.active_model.entities.each do |o|
attr = o.get_attribute "rsdict","area"
if attr
o.add_observer(MyEntityObserver.new)
o.entities.add_observer(MyEntitiesObserver.new)
end
end
end
end #MyModelObserver
#Adding ModelObserver - Undo
Sketchup.active_model.add_observer(MyModelObserver.new)
class MyEntityObserver < Sketchup;;EntityObserver
#def onEraseEntity(entity) #this work
#UI.messagebox("onEraseEntity; " + entity.to_s)
#end
#def onChangeEntity(entity)
#UI.messagebox("onChangeEntity; " + entity.to_s)
#end
end #class
class MyEntitiesObserver < Sketchup;;EntitiesObserver
def onElementModified(entities, entity)
attr_length = entity.get_attribute "rsdict", "yv_face_length"
attr_height = entity.get_attribute "rsdict", "yv_face_height"
if attr_length
entities.each do |i|
attr_area = i.get_attribute "rsdict", "yv_face_area"
if attr_area
yv_area_new = i.area.to_m.to_m
#UI.messagebox "Length changed - area before; " + attr_area.to_s + " m² - area after; " + yv_area_new.to_s + " m²"
i.set_attribute "rsdict", "yv_face_area", yv_area_new
end #attr_area
end #each do
end #if attr_length
if attr_height
entities.each do |i|
attr_area = i.get_attribute "rsdict", "yv_face_area"
if attr_area
yv_area_new = i.area.to_m.to_m
UI.messagebox "Height changed - green face - area before; " + attr_area.to_s + " m² - area after; " + yv_area_new.to_s + " m²"
i.set_attribute "rsdict", "yv_face_area", yv_area_new
end #attr_area
end #each do
end #if attr_height
end #onElementModified_end
end #class
i = 0
ent.each do |o|
attr = o.get_attribute "rsdict","area"
if attr
o.add_observer(MyEntityObserver.new)
o.entities.add_observer(MyEntitiesObserver.new)
i += 1
end
end
UI.messagebox "number of boxes; " + i.to_s
I think Im calmed a little down for now...
Ok, sounds great...
But it had something special to it, that it was under Google...
OMG Trimble SketchUp?
Now they want to earn quick money, and sold Google Sketchup?
Guess I have to pull my self together and accept it...
[edit] Luckily it stills says Google Sketchup 8 when installing... (Its all in the name)
Next problem:
When deleting a group, and undoing - it looses all the observers.
Well, have to look at that tomorrow.
Luckily it keeps the attributes as far as I can see...
Dan, ok I stay away from win32api for a while