comp(f) ignored after rule call

437
4
02-10-2020 05:15 AM
DaveLajoie
New Contributor

Hello Guys, 

I facing an issue where calling comp(f) after calling a rule call, the comp operation would not be executed

colorRed -->

    set(material.color.r, 1.0)

    set(material.color.g, 0.0)

    set(material.color.b, 0.0)

colorGreen -->

    set(material.color.r, 0.0)

    set(material.color.g, 1.0)

    set(material.color.b, 0.0)

colorBlue -->

    set(material.color.r, 0.0)

    set(material.color.g, 0.0)

    set(material.color.b, 1.0)

colorWhite -->

    set(material.color.r, 1.0)

    set(material.color.g, 1.0)

    set(material.color.b, 1.0)

makeARoof -->

    roofHip( "byHeight" ,

             5.0        ,

             1.0        ,

             true       )

TestWorks -->

    extrude( 20.0 )

    comp(f) { top : roofHip( "byHeight" ,

                             5.0        ,

                             1.0        ,

                             true       )

                    comp(f) { street.front : colorRed  |

                              all          : colorBlue } |

              all : colorGreen                           }

TestDoesntWork -->

    extrude( 20.0 )

    comp(f) { top : makeARoof comp(f) { street.front : colorRed  | all : colorBlue } | all : colorGreen }Works!

works

Does not work...

does not work

somehow calling a rule ( with and without arguments ) doesn't appear to call the next statement (comp in this case). I am sure I am missing something stupid.

0 Kudos
4 Replies
CherylLau
Esri Regular Contributor

In your rule TestWorks, the hip roof is created, and then the comp is performed on the hip roof geometry.  However, in your rule TestDoesntWork, the generation process creates a child shape in the derivation shape tree for makeARoof, and the hip roof is created in this child shape.  The comp that follows makeARoof is applied to the geometry that results from the first comp (the top face of your extrude).  The comp is not applied to the hip roof geometry because the hip roof geometry is not created before it in the derivation tree but rather in a different path in the tree.

See the section called "Rule application" in the help doc:

CGA essentials—Help | Documentation 

0 Kudos
DaveLajoie
New Contributor

Tx a lot I was looking for that piece of documentation, despite few hours of search.

Even reading the section, I am still unsure how to go about fixing the problem

So here is what I am trying to do. I want to build library of functions ( I guess those are called rules, right ), that can can re-use in my master rule

for example

makeRoof

makeFacadeWall

makeLeftWall

etc.

The encapsulation of the code, is important to make easy to maintain, and allow other people to take over the code without scratching their heads too much. I hope you get me pointer on how to solve this. I have attached a copy of my current cga, still very preliminary. If you could show me how you would  get function + comp() to work, it would be lovely.

Tx

Dave.

/**

 * File:    roof.cga

 * Created: 7 Feb 2020 21:13:10 GMT

 * Author:  dave.lajoie

 */

version "2019.1"

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

# TODO

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

# Integrate LOD concepts

// ************************************************

// * Constants

// ************************************************

const roofTypeGableMode   = "Gable"

const roofTypeHipMode     = "Hip"

const roofTypePyramidMode = "Pyramid"

const wall1Mode = "Wall Type 1"

const wall2Mode = "Wall Type 2"

const wall3Mode = "Wall Type 3"

const wall4Mode = "Wall Type 4"

//const facadeWallMode    = "Facade"

//const leftSideWallMode  = "LeftSideWall"

//const rightSideWallMode = "RightSideWall"

//const backWallMode      = "BackSideWall"

const roofModeByHeight = "byHeight"

const roofModeByAngle  = "byAngle"

const wallHeightAbsoluteMode = "Absolute"

const wallHeightStoreyMode   = "Storey"

// ************************************************

// * Roof Attributes

// ************************************************

@Group("Roof") @Enum( "Gable", "Hip", "Pyramid")

attr roofMode = "Gable"

@Group("Roof", "Gable") @Enum( "byHeight", "byAngle" ) @Order(0)

attr roofGableMode = "byHeight"

@Group("Roof", "Gable") @Order(1)

attr roofGableHeight    = 2.0

@Group("Roof", "Gable") @Order(2)

attr roofGableAngle     = 45.0

@Group("Roof", "Gable") @Order(3)

attr roofGableOverHangX = 1.0

@Group("Roof", "Gable") @Order(4)

attr roofGableOverHangY = 1.0

@Group("Roof", "Gable") @Order(5)

attr roofGableEven = false

const roofGableValue =

    case roofGableMode == roofModeByHeight : roofGableHeight

    case roofGableMode == roofModeByAngle  : roofGableAngle

    else: roofGableHeight

// ************************************************

@Group("Roof", "Hip") @Enum( "byHeight", "byAngle") @Order(0)

attr roofHipMode = "byHeight"

@Group("Roof", "Hip") @Order(1)

attr roofHipHeight    = 2.0

@Group("Roof", "Hip") @Order(2)

attr roofHipAngle     = 45.0

@Group("Roof", "Hip") @Order(3)

attr roofHipOverHang = 1.0

@Group("Roof", "Hip") @Order(5)

attr roofHipEven = false

const roofHipValue =

    case roofHipMode == roofModeByHeight : roofHipHeight

    case roofHipMode == roofModeByAngle  : roofHipAngle

    else: roofHipHeight

// ************************************************

@Group("Roof", "Pyramid") @Enum( "byHeight", "byAngle") @Order(0)

attr roofPyramidMode = "byHeight"

@Group("Roof", "Pyramid") @Order(1)

attr roofPyramidHeight    = 2.0

@Group("Roof", "Pyramid") @Order(2)

attr roofPyramidAngle     = 45.0

const roofPyramidValue =

    case roofPyramidMode == roofModeByHeight : roofPyramidHeight

    case roofPyramidMode == roofModeByAngle  : roofPyramidAngle

    else: roofPyramidHeight

// ************************************************

// * Wall Attributes

// ************************************************

@Group("Walls")

@Group("Walls", "Height") @Order(0) @Enum("Absolute", "Storey")

attr wallHeightMode = wallHeightAbsoluteMode

@Group("Walls", "Height", "Absolute" ) @Order(1) @Range(min = 1.0, max = 500.0)

attr wallHeight = 3.5

@Group("Walls", "Height", "Storey" ) @Order(2) @Range(min = 1, max = 100)

attr numberOfStorey = 1

@Group("Walls", "Height", "Storey" ) @Order(3) @Range(min = 3.0, max = 5.0)

attr storeyHeight   = 3.5

@Group("Walls") @Order(10) @Enum( "Wall Type 1", "Wall Type 2", "Wall Type 3", "Wall Type 4" )

attr streetFrontWallType = wall1Mode

@Group("Walls") @Order(20) @Enum( "Wall Type 1", "Wall Type 2", "Wall Type 3", "Wall Type 4" )

attr streetLeftWallType = wall2Mode

@Group("Walls") @Order(30) @Enum( "Wall Type 1", "Wall Type 2", "Wall Type 3", "Wall Type 4" )

attr streetRightWallType = wall3Mode

@Group("Walls") @Order(40) @Enum( "Wall Type 1", "Wall Type 2", "Wall Type 3", "Wall Type 4" )

attr streetBackWallType = wall4Mode

const totalWallHeight =

    case wallHeightMode == wallHeightAbsoluteMode: wallHeight

    case wallHeightMode == wallHeightStoreyMode: numberOfStorey * storeyHeight

    else: 3.5

// ************************************************

// * Functions

// ************************************************

@Hidden

colorRed -->

    #set(material.color.r, 1.0)

    #set(material.color.g, 0.0)

    #set(material.color.b, 0.0)

    color(1,0,0)

@Hidden

colorGreen -->

    #set(material.color.r, 0.0)

    #set(material.color.g, 1.0)

    #set(material.color.b, 0.0)

    color(0,1,0)

@Hidden

colorBlue -->

    #set(material.color.r, 0.0)

    #set(material.color.g, 0.0)

    #set(material.color.b, 1.0)

    color(0,0,1)

@Hidden

colorWhite -->

    #set(material.color.r, 1.0)

    #set(material.color.g, 1.0)

    #set(material.color.b, 1.0)

    color(1,1,1)

#CreateRoofShed -->

#    roofShed( "byAngle", 45.0, 3 )

#CreateRoofEnvelop -->

#    envelope(normal, 50, 15, 30) 

// ************************************************

CreateRoof -->

    case roofMode == roofTypeGableMode:

    

        roofGable( roofGableMode      ,

                   roofGableValue     ,

                   roofGableOverHangX ,

                   roofGableOverHangY ,

                   roofGableEven      )

    

    case roofMode == roofTypeHipMode:

    

        roofHip( roofHipMode     ,

                 roofHipValue    ,

                 roofHipOverHang ,

                 roofHipEven     )

    

    case roofMode == roofTypePyramidMode:

    

        roofPyramid( roofPyramidMode  ,

                     roofPyramidValue )

    

    else:

        colorRed

// ************************************************

CreateWall1-->

    colorRed

CreateWall2-->

    colorGreen

CreateWall3-->

    colorBlue

CreateWall4-->

    colorWhite

// ************************************************

CreateWall( wallMode ) -->

    case wallMode == wall1Mode:

        CreateWall1

    case wallMode == wall2Mode:

        CreateWall2

    case wallMode == wall3Mode:

        CreateWall3

    case wallMode == wall4Mode:

        CreateWall4

    else:

        CreateWall4

// ************************************************

// * Rules

// ************************************************

@StartRule

Footprint -->

    extrude( totalWallHeight )

    comp(f) { top : CreateRoof comp(f){ street.front : color(1,0,0) X. |

                                        all          : color(1,1,1) X. } |

              all : comp(f){ street.front : CreateWall( streetFrontWallType ) |

                             street.back  : CreateWall( streetBackWallType  ) |

                             street.left  : CreateWall( streetLeftWallType  ) |

                             street.right : CreateWall( streetRightWallType ) |

                             all          : colorWhite                        } }

0 Kudos
CherylLau
Esri Regular Contributor

Sorry, cga doesn't work like that.  You can't create the roof in CreateRoof and then come back to the original rule and do the comp on the geometry created in CreateRoof.

It's not what you want, but if you want to separate out the roof creation code, then you should also move the roof coloring code so that it is called by the roof creation code:

Footprint -->
     ...
     comp(f) { top : CreateRoof }

CreateRoof -->
     case ...
          roofGable(...)
          ColorRoof
     case ...
          roofHip(...)
          ColorRoof
     else:
          ...

ColorRoof -->
     comp(f){ street.front : color(1,0,0) X.
            | all          : color(1,1,1) X. }‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos
DaveLajoie
New Contributor

Excellent, tx. This is what I ended up doing to make it work. It increases the code complexity, but yeah, that is CGA

Tx. 

0 Kudos