CGA pass a rule as argument

670
4
08-03-2017 07:32 AM
Status: Open
deleted-user-F36TjxlqdCoV
New Contributor II

Currently it is not possible to pass rule as an Argument

this is quite needed for materials and uvs, since the rule being executed is for the geometry, and the material and texture are being executed after. It allows to generate window with different materials, and make the code quite clean as well.

4 Comments
ThomasFuchs

Hello Dave

Thank you for your feature request. Currently it is not possible to pass a rule as an argument.

But there is a way to accomplish the task you are describing:

In the CityEngine Example Sternwarte 2016.0, that showcases detailed building modeling, the material properties of the window glass can either be set with a global attribute glass_material or a rule argument isTransparent. This is done with a case statement.

To keep the rule that generates the geometry window.cga clean, the material properties should be defined in an imported rule file material.cga. This material rule can be reused in other geometry rules and constantly extended/modified without the need to modify the parent rules.

/**
 * File:    window.cga
 */

version "2017.0"

import material:"rules/material.cga"

// assets
windowFrame_asset     = "/Example_Sternwarte__2016_0/assets/window_frame.obj"
windowGlass_asset     = "/Example_Sternwarte__2016_0/assets/window_glass.obj"

@Range("CE Blue","CE Dark Blue","CE Green","CE Brown","CE Black","iRay Glass")
attr glass_material = "CE Black"

@StartRule
// window
Window -->
     s(1, 2, 0.3)
     WindowFrame
     WindowGlass
          
// frame and inner grid of window
WindowFrame -->
     t(0, 0, '-0.8)
     i(windowFrame_asset)
     color("#929280")
     
// window glass
WindowGlass -->
     t(0, 0, '-0.15)
     i(windowGlass_asset)
     material.Glass(false)  // not transparent‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

/**
 * File:    material.cga
 */

version "2017.0"

@hidden 
@Range("CE Blue","CE Dark Blue","CE Green","CE Brown","CE Black","iRay Glass")
attr glass_material = "CE Black"

@StartRule
MyMaterials -->
     primitiveCube()
     Glass(false)  // not transparent

// glass material for windows
// isTransparent      [true, false] true: use default opacity, false: opacity=1
Glass(isTransparent) -->   
     case glass_material == "CE Blue":
          case isTransparent :
               color(0.7,0.75,1)
            set(material.ambient.r,0) set(material.ambient.g,0) set(material.ambient.b,1)
            set(material.specular.r,0.8) set(material.specular.g,0.8) set(material.specular.b,0.8)
            set(material.reflectivity,0.8) set(material.shininess,50) set(material.opacity,0.6)
          else :
                color(0.7,0.75,1)
            set(material.ambient.r,0) set(material.ambient.g,0) set(material.ambient.b,1)
            set(material.specular.r,0.8) set(material.specular.g,0.8) set(material.specular.b,0.8)
            set(material.reflectivity,0.8) set(material.shininess,50)
               set(material.opacity,1)
     case glass_material == "CE Dark Blue":
          case isTransparent :
            color(0.2,0.2,0.25)
            set(material.ambient.r,0) set(material.ambient.g,0) set(material.ambient.b,0.1)
            set(material.specular.r,0.8) set(material.specular.g,0.8) set(material.specular.b,0.8)
            set(material.reflectivity,0.6) set(material.shininess,50) set(material.opacity,0.8)     
          else :
            color(0.2,0.2,0.25)
            set(material.ambient.r,0) set(material.ambient.g,0) set(material.ambient.b,0.1)
            set(material.specular.r,0.8) set(material.specular.g,0.8) set(material.specular.b,0.8)
            set(material.reflectivity,0.6) set(material.shininess,50)     
              set(material.opacity,1)
     case glass_material == "CE Green":
          case isTransparent :
            color(0.4,0.5,0.4)
            set(material.ambient.r,0) set(material.ambient.g,0.2) set(material.ambient.b,0.05)
            set(material.specular.r,0.8) set(material.specular.g,0.8) set(material.specular.b,0.8)
            set(material.reflectivity,0.8) set(material.shininess,50) set(material.opacity,0.6)     
          else :
            color(0.4,0.5,0.4)
            set(material.ambient.r,0) set(material.ambient.g,0.2) set(material.ambient.b,0.05)
            set(material.specular.r,0.8) set(material.specular.g,0.8) set(material.specular.b,0.8)
            set(material.reflectivity,0.8) set(material.shininess,50)
              set(material.opacity,1)
     case glass_material == "CE Brown":
          case isTransparent :
            color(0.3,0.25,0.2)
            set(material.ambient.r,0.2) set(material.ambient.g,0.1) set(material.ambient.b,0)
            set(material.specular.r,0.8) set(material.specular.g,0.8) set(material.specular.b,0.8)
            set(material.reflectivity,0.8) set(material.shininess,50) set(material.opacity,0.6)     
          else :
            color(0.3,0.25,0.2)
            set(material.ambient.r,0.2) set(material.ambient.g,0.1) set(material.ambient.b,0)
            set(material.specular.r,0.8) set(material.specular.g,0.8) set(material.specular.b,0.8)
            set(material.reflectivity,0.8) set(material.shininess,50)     
              set(material.opacity,1)
     case glass_material == "CE Black":
           case isTransparent :
            color(0.1,0.1,0.1)
            set(material.specular.r,0.8) set(material.specular.g,0.8) set(material.specular.b,0.8)
            set(material.reflectivity,0.7) set(material.shininess,50) set(material.opacity,0.8)     
          else :
            color(0.1,0.1,0.1)
            set(material.specular.r,0.8) set(material.specular.g,0.8) set(material.specular.b,0.8)
            set(material.reflectivity,0.7) set(material.shininess,50)     
              set(material.opacity,1)
     case glass_material == "iRay Glass":
           case isTransparent :
            color(0.35,0.37,0.5)
               set(material.specular.r,0.8) set(material.specular.g,0.8) set(material.specular.b,0.8)
            set(material.reflectivity,0.8) set(material.shininess,128) set(material.opacity,0.8) 
          else :
            color(0.35,0.37,0.5)
               set(material.specular.r,0.8) set(material.specular.g,0.8) set(material.specular.b,0.8)
            set(material.reflectivity,0.8) set(material.shininess,128) 
              set(material.opacity,1)
     else:
           case isTransparent :
            color(1,1,1)
            set(material.opacity,0.8) 
          else :
               color(1,1,1)
              set(material.opacity,1)‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
deleted-user-F36TjxlqdCoV

Thanks Thomas, I see how it can be achieved.

I guess my explanation weren't really detailed enough.

I want to isolate material, texture, geometry generation into rule libraries, and be able to re-use it, by passing it as an argument to another rule.

I hope it make sense with the code example below.

generateWindowLayout( param1, param2 ) -->
    ...

generateWindowFrame ( param3, param4 ) -->
    ...

setMaterialAsGlass -->
    ...

generateModel( windowLayerRule ,
               windowFrameRule ,
               materialRule    ) -->
    windowLayerRule( 1,2 )
    windowFrameRule( 3,4 )
    materialRule

generateModel( generateWindowLayout,
               generateWindowFrame ,
               setMaterialAsGlass  )



ThomasFuchs

Hello Dave

The feature you are requesting has been formulated in a paper called CGA++ Advanced Procedural Modeling of Architecture in section "4.1 Event handling". At this point it is unclear, when it will be implemented. 

CGA++ Integration Timeframes 

deleted-user-F36TjxlqdCoV

Much appreciated, Thanks Thomas!