I want to test how python attr. and para. api work and adjust "height" by python.
so I wrote cga :
attr height = 10
Lot --> extrude(height) Mass.
and python script:
objects= ce.getObjectsFrom(ce.selection, ce.isModel)
for o in objects:
h= ce.getAttribute(o, 'height')
ce.setAttribute(o, 'height', addh)
I hope it can add 10 on height of each building but it returns None. Through debugging, I found "o" is ok (when I choose 5 shapes, 2 shapes without rules, it can report those 3 shapes assigned with rule)
However, it shows [ ] no attribute in "o" (by getAtrributeSource).
so How CAN I get the Attribute defined in the rule by myself and use it in Python Script ????
If Possible, Could anyone help me finish this simple python script??? (just get "height" and add 10 then return the value back to adjust building)????
Thanks a lot!!!!
First, attributes should be set on shape objects (instead of models):
objects = ce.getObjectsFrom(ce.selection, ce.isShape)
Second, the rule attribute name should be preceded by "/ce/rule/":
h = ce.getAttribute(o, '/ce/rule/height')
Lastly, rule attributes only appear in the list returned by ce.getAttributeList() if they are user set. This means we can only set them in Python if we first make them user-set attributes. There are two options for this. The first option (a simple workaround) is good if this is just a one time operation that you'd like to do because it involves manually setting the attribute. The second option is more complicated but will work if you'd like everything to work within the python script without having to set anything manually. In this case, we make the attributes user-set by way of an extra python script that is run from your first python script.
1) Select your shapes.
2) Set the height attribute in the Inspector to 10. This is the value it already was set to by the rules, but by resetting it through the Inspector we are making a user-set attribute instead of a rule-set attribute. The number now appears bold indicating that it is a user set attribute.
3) Now you can run the python script (with the two changes above).
1) Create an export python script. Right click on the scripts folder -> New -> Python Module -> Select Module:Export (Reporting) and choose a name (e.g. coexport.py).
2) In the finishModel() function, add the following code to make the attribute a user set attribute:
ce.setAttributeSource(shape, "/ce/rule/height", "USER")
3) In your first python script, add some lines (after you get the objects but before the for loop) to run the export script you just created:
expSettings = ScriptExportModelSettings()
4) Now you can run the first python script (with the two changes above).
Actually, there might be an easier way than Option 2. It might be possible to just set the source to user in the first python script in which case the second python script is unnecessary.
1) In the first python script, do this to set the source to user before setting the value of the attribute:
ce.setAttributeSource(o, "/ce/rule/height", "USER")
ce.setAttribute(o, "/ce/rule/height", addh)
2) Now you can run the python script.
Thanks for your kind reply!! I will try it and sorry late reponse(these days too busy)
hope I can succeed.
Dear Cheryl Lau,
Sorry to disturb you again, recently I tried what you suggested. It work well by Option 1. But when I adopted Option3, I met a problem and I can't fix it. Now code became :
objects = ce.getObjectsFrom( ce.selection, ce.isShape)
for o in objects:
h= ce.getAttribute(o, '/ce/rule/height')
addh = h+5
ce.setAttribute(o, '/ce/rule/height', addh)
If I had reset the height attribute once( became user-set once), it will suceed running python script to adjust it but it adjusted user-set value not rule-set value( for ex., I reset it before as 10, then return the value source to rule-set as 6.123456, but after running the script, which use the previous value 10 + 5 = 15 not 6.123456+5 = 11.123456 ). Is it possible for script to read the current value not only the user-set value we set before?
and if I never reset it or just assign one new shape with this rule, I ran the script and the value showed 'NaH'-- none.
So for that I consider the problem comes from getAttribute(). The user-set value and rule-set value are independent, which means if I assign one new shape with this rule, the rule-set is 6.123456 but user-set remain empty, so when running script it showed NaH. getAttribute() can only read user-set value, right?
I want everything work within python script and is it possible to read current value without problems above? And for option2, I don't know why need to export objects??
Your guess is correct. Unfortunately, it is not possible to get rule-set attribute values this way.
However, there is a workaround (which is not so easy) if you need to access the rule-set attribute values. This involves reporting the attribute's value in the cga code and reading that reported value in python. Use option 2, and in step 2, add the following code to the finishModel() method:
h = model.getReports()["height"] # get value of height from reports
ce.setAttribute(shape, "/ce/rule/height", h+5) # add 5 to height
ce.setAttributeSource(shape, "/ce/rule/height", "USER") # set source to USER (since value doesn't come from rules anymore)
And, report the value of the rule-set attribute height in your cga code:
Why do we need to export objects? No reason really, but this is just the workaround that I found works. Perhaps there is another way.
I will try it now!
该文档由下列讨论生成：adjust attr of CGA rule by python script