Select to view content in your preferred language

Python code: Selecting all objects with one attribute

2085
4
Jump to solution
05-03-2023 08:18 PM
AlexWierzbicki
Emerging Contributor

Hoping that someone can help me out. I am a python newbie and I am trying to create a script that will select all objects that have the Object Attribute "amenity" equal to "school". Could some please help me identify what is wrong with the below code? 

from scripting import *

# get a CityEngine instance
ce = CE()

def selectByAttribute(attr, value):
    objects = ce.getObjectsFrom(ce.scene)
    selection = []
    
    for item in objects:
        attribute = ce.getAttribute(item, attr)
        if attribute == value:
                selection.append(item)
        
    ce.setSelection(selection)

if __name__ == '__main__':
    selectByAttribute("/ce/geometry/amenity", "school")
0 Kudos
1 Solution

Accepted Solutions
JonasObertuefer
Esri Contributor

hi again,

  • @noUIupdate needs to be directly above the function you want to trigger no UI updates
  • change the filter in your getObjectsFrom() from ce.isGraphSegment to ce.isShape. Amenity is isuallay a object attribute assigned to shapes.

I tested the the code below, and it works for me:

# get a CityEngine instance
ce = CE()

@noUIupdate
def selectByAttribute(attr, value):
    objects = ce.getObjectsFrom(ce.scene, ce.isShape)
    selection = []
    for item in objects:
        attribute = ce.getAttribute(item, attr)
        if attribute == value:
                selection.append(item)
    ce.setSelection(selection)

if __name__ == '__main__':
    selectByAttribute("amenity", "school")

 

View solution in original post

0 Kudos
4 Replies
MJF
by
Emerging Contributor

Remove /ce/geometry/ and it should work

selectByAttribute("amenity", "school")

 

JonasObertuefer
Esri Contributor

Hi @AlexWierzbicki,

For a python newbie you got already quite far 😉

For object attributes you don't need any prefix just write selectByAttribute("amenity", "school") and your script should work.

I suggest two other small improvements to your script:

  • Add @noUIupdate before your function. This makes sure the UI will be refreshed only after the function is run through. Depending on the size of the scene and what your function does this can speed up the run significantly
  • In your case you don't need to query all objects from the scene, you can limit it to shapes only if you write objects = ce.getObjectsFrom(ce.scene, ce.isShape)

Cheers,
Jonas

0 Kudos
AlexWierzbicki
Emerging Contributor

I've made the suggested changes but unfortunately it is still not working, receiving either the following error or nothing at all happening, depending on where I put the @noUIupdate

AlexWierzbicki_0-1684463010311.png
Below is the code. Any other advice? 

from scripting import *

@noUIupdate

# get a CityEngine instance
ce = CE()

def selectByAttribute(attr, value):
    objects = ce.getObjectsFrom(ce.scene, ce.isGraphSegment)
    selection = []
    
    for item in objects:
        attribute = ce.getAttribute(item, attr)
        if attribute == value:
                selection.append(item)
        
    ce.setSelection(selection)

if __name__ == '__main__':
    selectByAttribute("amenity", "school")

 

 

0 Kudos
JonasObertuefer
Esri Contributor

hi again,

  • @noUIupdate needs to be directly above the function you want to trigger no UI updates
  • change the filter in your getObjectsFrom() from ce.isGraphSegment to ce.isShape. Amenity is isuallay a object attribute assigned to shapes.

I tested the the code below, and it works for me:

# get a CityEngine instance
ce = CE()

@noUIupdate
def selectByAttribute(attr, value):
    objects = ce.getObjectsFrom(ce.scene, ce.isShape)
    selection = []
    for item in objects:
        attribute = ce.getAttribute(item, attr)
        if attribute == value:
                selection.append(item)
    ce.setSelection(selection)

if __name__ == '__main__':
    selectByAttribute("amenity", "school")

 

0 Kudos