Intra Occlusion issues

1071
3
03-15-2019 12:28 PM
AbeleGiandoso
Occasional Contributor

Hi all!

I am having a lot of troubles in making Occlusion queries work correctly.

I guess I am doing something wrong, but the help guide is a bit cryptic at times. 

An example:

I have the top plane of a building.

On this I want to create both a Roof AND a chimney stack.

The type of roof is decided by a stochastic attribute used into a Conditional rule.

attr RoofHeight = rand (3,7)

attr RoofType = 50%: "CustomRoof"
                           20%: "PyramidRoof"
                           else: "HipRoof"
#--------------------------------------------------------------------------------

BuildingTop-->

   set(BuildingLenght,scope.sx)

   set(BuildingDepth,scope.sz)

   RoofCreation

  ChimneyStackCreation

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

RoofCreation-->
   case RoofType== "CustomRoof": roofGable (byHeight, RoofHeight)
                                                            i (CustomRoof)                                                             
                                                            label ("roofVolume")                                                           
                                                            RoofComp
   case RoofType== "PyramidRoof": roofPyramid (byHeight, RoofHeight)
                                                             label ("roofVolume")         
                                                             RoofComp
   else: roofHip (byHeight, RoofHeight)
            label ("roofVolume")         
            RoofComp

RoofComp-->

      comp (f){bottom: NIL| all: RoofExtrude}

RoofExtrude -->

      extrude (vertex.normal,0.1)

      label ("roofVolume")        

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

The Chimneystack is basically a box create at random on the top surface of the building.

The problem is that this cube does not know how tall it should be to poke out from the roof.

Therefore I want this Chimneystack to be pushed upward until it intersects the roof shape with a conditional parametrized rule. Then i can continue building on this base knowing it is tall enough for the rest.

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

ChimneyStackCreation-->

   primitiveCube(1,2,0.3)

   t(rand(0,BuildingLenght-scope.sx),0, rand(0,BuildingDepth-scope.sz))

   ChimneyYPlacement (0)

ChimneyYPlacement(n)-->

   case !inside (intra, "roofVolume") || n==20: ChimneyTexture

   else: t(0,0.5,0) 

            ChimneyYPlacement (n+1)

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

Problem is.. lt does not work 

The ChimneyStack does not see the roof volume and it is pushed up until n=20, so up to 10 m where it is floating in the air. 

Can anybody help me understand what am I doing wrong. I have many of these procedures in my rules and I can not seem to understand what make occlusion queries tick.

Is it because I comp the Roof shape and remove its bottom faces? I do create a "RoofVolume" label right before though. And even after, when I am extruding the roof planes.. Isn't this enough?

Any help will be greatly appreciated

Thanks

A

0 Kudos
3 Replies
CherylLau
Esri Regular Contributor

There is an easier way to create a chimney on top of a roof.  Occlusion is not necessary.  Instead, you could comp the top of the roof, split out a section for the chimney footprint, insert a cube, and resize it.

Roof -->
	roofGable(45) Roof.
	comp(f) { top= CreateChimney }
	
CreateChimney -->
	alignScopeToAxes(y)
	split(x) { ~1: NIL
			 | w: split(z) { ~1: NIL | w: Chimney | ~1: NIL }
			 | ~1: NIL }
			 
Chimney -->
	primitiveCube
	s('1, h, '1)‍‍‍‍‍‍‍‍‍‍‍‍‍
AbeleGiandoso
Occasional Contributor

Thanks Cheryl, I did not think about this method  I am surely going to implement it in all the similar cases. 

I was wondering though, since I have several other cases of occlusion queries not working as they should when they are "intersecting" with geometries derived from other conditional rules, if you could help me to understand why the query is not working. 

Is it because of the "2 passes generation process"?

Many thanks

A

0 Kudos
CherylLau
Esri Regular Contributor

Occlusion queries are performed with a two pass generation which means we run through the code twice.  In general, on the first pass, the code is evaluated such that the occlusion query functions inside, overlaps, and touches return false.  This generates a shape tree.  The geometries in this shape tree become possible occluders for the next pass.  Then, on the second pass, the occlusion query functions are tested against the shapes that were generated in the first pass.  When evaluating the occlusion query touches, we ask if the current shape touches closed shapes that were generated in the first pass.  The geometry generated in the second pass is the final result.

https://doc.arcgis.com/en/cityengine/latest/cga/cga-context-queries.htm

0 Kudos