I am currently working on 3D zoning, specifically with planning law and regulation in Bulgaria. I prepared the regulations in ArcMap for the different zones in the fields for setbacks, max heights, max GFA etc with the respective values. I assigned these fields to attributes in Cityengine and they work well. I also adapted the CGA rule from Tutorial 16: Urban Planning for highlighting the building stories which are over the specified 3D volume.
I face 3 issues for which I looked all over the forum, the help documentation and the tutorials and I can't figure out how to solve them. This is the question for the first one. Here is a link to the second and a link to the third one.
FYI - I am an urbanist and GIS user with some basic coding understanding but not Python experience and new to Cityengine and CGA rule grammar. Your help will be highly appreciated.
@Order(1)
attr floorHeight = 3.5
@Order(2)
attr floorCount = 0
@Order(3)
attr buildingHeight = floorHeight*floorCount
@Order(4) @Hidden
attr testerH = floorHeight*floorCount
@Order(5)@Hidden
attr testerF = buildingHeight/floorHeight
@StartRule
Building -->
alignScopeToAxes(y)
extrude(buildingHeight)
split(y){~floorHeight: Legal}*
Legal -->
case inside: color("#000fff")
else: color("#ffff11")
Input
Input -->
case testerH == testerF : set(buildingHeight, testerH)
else: set (floorCount, testerF)
Sorry, it is not possible to have attribute A depend on attribute B and at the same time have attribute B depend on attribute A. The dependency can go only one way.
If you create another attribute to choose whether you use buildingHeight or floorCount to calculate the other, then the user can decide whether the building height should be used or the floor count should be used. Then, you can have another function (not an attribute) that calculates the desired amount to extrude the building. However, the values shown in the Inspector won't necessarily be the desired values. If the user changes the value of an attribute, then the user's value is shown in bold. The inspector shows only initial values for attributes. Also, if you set an attribute later in the code, this will not be shown in the inspector. If you want to see calculated values for buildingHeight and floorCount, then you'll have to report these.
I found an old test rule where I tried to get that to work, looks like I made two sets of variables with two sets of display fields and a switch. Needless to say, a rather convoluted solution..
If you want to try to solve it with Python, look up setAttributeSource.
@Group("0 Switcher")
@Range("SubMulti","Total")
attr Mode = "SubMulti"
#------------------------
@Group("1-1 SubMulti")
attr UA_sub = 5
attr UA_multi = 5
@Group("1-2")
attr A_total = UA_sub*UA_multi
attr A_sub = UA_sub
attr A_multi = UA_multi
#------------------------
@Group("2-1 Total")
attr UB_total = 10
attr UB_multi = 2
@Group("2-2")
attr B_total = UB_total
attr B_sub = UB_total/UB_multi
attr B_multi = UB_multi
@StartRule
Lot -->
case Mode == "SubMulti": extrude(A_total) split(y){A_multi: X.}*
else: extrude(B_total) split(y){B_total/B_multi: X.}*
Thank you both for the answers.
I modified the rule that L R showed. It can be used as a workaround but not as an entire solution for situations like that.
version "2017.1"
@Group("0 Switch Mode")
@Range("A_Floor_to_Height","B_Height_to_Floor")
attr Mode = "A_Floor_to_Height"
#------------------------
@Group("A_Floor_to_Height")
@Order (1)
attr A_floorCount_change = 5
@Order (2)
attr A_floorHeight_change = 5
@Order (3)
attr A_totalHeight = A_floorCount_change*A_floorHeight_change
#------------------------
@Group("B_Height_to_Floor")
@Order (1)
attr B_floorCount = rint(B_totalHeight_change/B_floorHeight)
@Order (2)
attr B_floorHeight = 5
@Order (3)#@Range(min=1, max=30, stepsize=1)
attr B_totalHeight_change = 10
@StartRule
Lot -->
case Mode == "A_Floor_to_Height": extrude(A_totalHeight) split(y){A_floorHeight_change: X.}*
else: extrude(B_totalHeight_change) split(y){B_totalHeight_change/B_floorCount: X.}*