Ability to use conditional command (case and else) in @Range annotaion

2283
10
03-14-2021 08:13 PM
maziaryousefi
New Contributor

Hi, is there a way to do this when i select an option from the Scenario_Type attribute then only its subset appears in the SubScenario_Type attribute.In other words when i select A in Scenario_Type attribute Only appear A1 ,A2,A3 in SubScenario_Type attribute . also for B and C

 

@Range("A","B","C")
attr Scenario_Type ="A"


@Range("A1","A2","A3","B1","B2","B3","C1","C2","C3")
attr SubScenario_Type =""

 

Parcel-->
extrude(rand(5,25))
Building

 

Building -->
case Scenario_Type =="A" :
case SubScenario_Type =="A1" :
color(1,0,0)
case SubScenario_Type =="A2" :
color(0.5,0,0)
else :
color(0.3,0,0)

case Scenario_Type =="B" :
case SubScenario_Type =="B1" :
color(1,1,0)
case SubScenario_Type =="B2" :
color(1,0.4,0)
else :
color(1,0.6,1)


else :

case SubScenario_Type =="C1" :
color(0,1,0)
case SubScenario_Type =="C2" :
color(0,0.5,0)
else :
color(0,0.3,0)

 

#-----------------------------------------------------------

for example :
#---


@Range("A","B","C")
attr Scenario_Type ="A"


@Range(case Scenario_Type =="A" :"A1;A2;A3" case Scenario_Type =="B" :"B1;B2;B3" else :"C1;C2;C3" )
attr SubScenario_Type =""

 

Parcel-->
extrude(rand(5,25))
Building

 

Building -->
case Scenario_Type =="A" :
case SubScenario_Type =="A1" :
color(1,0,0)
case SubScenario_Type =="A2" :
color(0.5,0,0)
else :
color(0.3,0,0)

case Scenario_Type =="B" :
case SubScenario_Type =="B1" :
color(1,1,0)
case SubScenario_Type =="B2" :
color(1,0.4,0)
else :
color(1,0.6,1)


else :

case SubScenario_Type =="C1" :
color(0,1,0)
case SubScenario_Type =="C2" :
color(0,0.5,0)
else :
color(0,0.3,0)

















 

 

0 Kudos
10 Replies
BrianWamsley
Occasional Contributor III

I wonder if you could use an table lookup/array initialization on your "subtypes" to do something like this?

Tutorial 21: CSV import—ArcGIS CityEngine Resources | Documentation

Maybe it could do a first row lookup [A,B,C] from your types, and report back rows [2,3,4] (first row is A, second row 2 is A1, etc.) for values?     

I couldn't figure out a way to use conditional statements with attributes either.

 

0 Kudos
BrianWamsley
Occasional Contributor III

@maziaryousefi 

Turns out you can use arrays to limit what is shown in the attribute function.  Look at this code to see how it is done.  I would be glad to answer further questions.   But that doesn't preclude that maybe there is a way that you can use  conditional statements.

 

 

 

version "2020.1"

const Types_filename = "data/TypesAttr.csv"
const Types_data = readStringTable(Types_filename)
const rowLookup = nRows(Types_data)
const colLookup = nColumns(Types_data)

## Hidden Attributes

@Hidden
attr ScenarioType = Types_data[0,0:colLookup-1]
@Hidden
attr ColumnIndex = float(findFirst(ScenarioType,TypeAssign))
@Hidden
attr getSubType = Types_data[1:rowLookup-1,ColumnIndex]  //You could unhide this to expose the array for modification

## Exposed Attributes

@Order(1) @Enum(valuesAttr=ScenarioType)
attr TypeAssign = "unassigned"	

@Order(2) @Enum(valuesAttr=getSubType)
attr SubType = ""	


###########################################################

@StartRule
Start-->
	extrude(3)
	Building
	
Building-->
	case SubType == "R1": 	color(1,0,0,1) 
	case SubType == "R2":  color(1,0,0,.5) 
	case SubType == "R3":  color(1,0,0,.1) 
	case SubType == "MU1" :	color(0.5,0,1,1)
	case SubType == "MU2" :	color(0.5,0,1,.5)
	case SubType == "MU3" :	color(0.5,0,1,.1)
	case SubType == "H1" :	color(1,1,0,1)
	case SubType == "H2" :	color(1,1,0,.5)
	case SubType == "H3" :	color(1,1,0,.1)
	else :	NIL	

 

 

 

Here is how my table was designed to make this work.

Table DesignTable Design

   You'll have to save your table as .csv and localize your filepath to the code.   Note that my headers go across the top, and trying to transpose your table would require a different CGA code.

 

0 Kudos
maziaryousefi
New Contributor

Hello Brian Wamsley .thanks for your replay 

. It's a good idea- can you send me the excel file? I save the excel file in csv format but when using the excel file in the rule file, the options inside the excel file do not appear in the attribute in the inspector

0 Kudos
BrianWamsley
Occasional Contributor III

The .csv file is pretty simple, what you see in that image is all.  So if your not seeing the options you will need to make sure that the filepath is localized to your folder structure.   A simple drag and drop of the csv should do the trick.  I saved my csv in the project/data folder, yours might be different.

0 Kudos
CherylLau
Esri Regular Contributor

Brian is right, using valuesAttr in an Enum is the way to do this.  You don't necessarily need a csv file if you want to hard code it, but maybe the csv file makes it easier for you to extend.  It depends on your needs.

Here's a simple version with hard coded values in a case statement.

@Enum("A", "B", "C")
attr type = "A"

@Enum(valuesAttr=subtypeValues)
attr subtype = subtypeValues[0]

@Hidden
attr subtypeValues =
	case type=="A":		["A1", "A2", "A3"]
	case type=="B":		["B1", "B2", "B3"]
	else:				["C1", "C2", "C3"]

 

Instead of a case statement, you could also make it more extendable for the future, for example, by putting all the possible subtype values in an array and then creating the subtypeValues array by only choosing those values from the big list that begin with type.  Again, not sure this strategy would work for you; it depends what values you have and what your needs are.

hadiyousefi
New Contributor II

hi  CherylLau  . very thanks for your answer . very good . Is this method applicable to numeric attributes as well? For example, a numeric attribute to control three other attributes, such as building window width, window length, and window depth.That is, when we select the window width option in the building window attribute, we control the window width through a numeric attribute, and then select the window height option and change the window height value without changing the window width and depth numbers. 

0 Kudos
CherylLau
Esri Regular Contributor

Sorry, I don't understand what you mean.

It is possible to have separate attributes for window width, height, and depth, and changing one of them will not affect the others.

attr window_width = 1
attr window_height = 2
attr window_depth = 0.5

 

But, I don't think this answers your question.  I don't understand what attributes you want and what behavior you want (i.e. what you want to appear in the drop down box for each attribute).

0 Kudos
hadiyousefi
New Contributor II

Hello dear CheryILau . very thanks for your answer. In order to be able to control the dimensions of width, depth, height separately through the dimension_control attribute, so that by changing the dimensions of each option in dimension_control attribute, the value of other options in dimension_control attribute does not change .Instead of using three attributes of width, depth and height in inspector separately, use only one attribute to control them.Is this possible? If this method can be done, the inspector will no longer be crowded due to too many attributes5664.png

 

010.png020.png

0 Kudos
BrianWamsley
Occasional Contributor III

If your goal is to manage the attribute space, consider using the @Group and @Order function to make it more visual intuitive.   You can also create a new code and call that it into an existing code and that code will have an "accordion" drop-down, which can be a strategy to save space.  If your trying to have one attribute control width, depth, height, your going to overwrite the other two attributes each time.  You could use a table for this but it would be more complicated than its worth, in my opinion.