Texturign results in mottles effect and roof texture missing, why?

2855
4
05-02-2013 01:21 PM
LoringTupper
New Contributor
I'm using one of the sample cga file that does texturing and I've added some code for reporting purposes and edited the settings for the attribute values. Wehn I run this against a parcel polygon the resulting building has a mottles effect on it that changes as I rotate the view around the building. I've ried all of the light settings and nothing helps this problem.

The code includes a random roof texture selection but what I find is that no roof texture is applied to the actual top of the building. When I accidentally went into the interior of a building I saw that the floor had the roof texture on it. The actual roof is just white, no texture at all.

Below is a screen capture that shows both phenomenon, the mottl;e colors and the non-textured roof:
[ATTACH=CONFIG]23981[/ATTACH]

The code I'm using is as follows:

version "2012.1"

/* Attributes *************************************/

@Group("SETBACKS",0) 
attr FSetback = 3
@Group("SETBACKS")
attr BSetback = 3
@Group("SETBACKS")
attr LSetback = 3
@Group("SETBACKS")
attr RSetback = 3

@Group("HEIGHTS",1)
attr GroundFloorHeight = 5
@Group("HEIGHTS")
attr UpperFloorHeight = 4

@Group("COLORS",2)
attr LUColor = "#FFFFE0"

@Hidden
attr height    = 50

@Hidden
attr tile_width   = 4

@Hidden 
attr wallColor          = "#FFFFE0"
#attr wallColor          = "#fefefe"

@Hidden
attr parcelArea = 0

@Range ("transparent", "as is")
@Group("VISIBILITY MODE",3)
attr vizMode = "transparent"


attr LOD     = 1
/* Assets *************************************/

// geometries
window_asset = "facades/window.obj"

// textures
frontdoor_tex    = "facades/textures/shopdoor.tif"
wall_tex     = "facades/textures/brickwall2_bright.tif"
dirt_tex    = "facades/textures/dirtmap.15.tif"
roof_tex     = "roof/F_roof5.tif"


# this function will get one of the 9 window textures in the assets folder
randomWindowTexture = fileRandom("*/facades/textures/window.*.tif") 

# this function will get one of the 6 roof textures in the assets folder
randomRoofTexture = fileRandom("*/roof/F_roof*.tif")

/* Initial Shape starting rule *************/

# scale the lit to leave a small border and extrude the lot to building height

Lot --> 
 set ( parcelArea, geometry.area )
 report ( "Parcel Area", parcelArea )
 setback(FSetback) { street.front : NIL | remainder :
  setback(BSetback) { street.back : NIL | remainder :
   setback(LSetback) { street.left : NIL | remainder :
    setback(RSetback) { street.right : NIL | remainder :
     FootprintReach
    }
   } 
  }
 }

@StartRule
Footprint --> 
 extrude(height) Building
 NIL
 comp(f) { front : Frontfacade | side : Sidefacade | top: Roof}

Reporting -->
 report("GFA", geometry.area(bottom))
 report("FAR", geometry.area(bottom) / parcelArea )
 NIL  #NIL the geometry

Visualization -->
 case vizMode == "as is" :
  Done.
 case vizMode == "transparent" :
  set (material.opacity, 0.8)
  Done.
 else :
  comp(f) { front : Frontfacade | side : Sidefacade | top: Roof}

# inner lots are dropped
LotInner --> NIL

# split the building geometry into its facade components
Building -->
 comp(f) { front : Frontfacade | side : Sidefacade | top: Roof}

# the front facade is subdivided into one front groundfloor 
# and upper floors
Frontfacade --> 
 setupProjection(0, scope.xy, 1.5, 1, 1) # setup 1.5m x 1m texture tiles along scopes xy plane (and distortion in z)
 setupProjection(2, scope.xy, scope.sx, scope.sy)
 split(y){ GroundFloorHeight    : Groundfloor 
   | {~UpperFloorHeight : Floor}* }


# a side facade is subdivided into one bottom floor 
# and upper floors. 
Sidefacade --> 
 setupProjection(0, scope.xy, 1.5, 1, 1) # setup 1.5m x 1m texture tiles along scopes xy plane (and distortion in z)
 setupProjection(2, scope.xy, scope.sx, scope.sy)
 split(y){ GroundFloorHeight    : Floor 
   | {~UpperFloorHeight : Floor}* }
 

# a roof texture is applied to the roof face
Roof --> 
 setupProjection(0, scope.xy, scope.sx, scope.sy, 0, 1)
 texture(randomRoofTexture) 
 #texture(roof_tex)
 projectUV(0) 


# each floor is horizontally split into two narrow corner areas on 
# each side of the floor, and into a set of window tiles in between
Floor -->
 split(x){ 1 : Wall 
   | { ~tile_width : Tile }* 
   | 1 : Wall }
   Visualization
 
 
# similarily, the front groundfloor is horizontally split into 
# two narrow corner areas on each side of the floor, 
# a special entrance tile on the right 
# and into a set of window tiles in between
Groundfloor -->
 split(x){ 1    : Wall 
   | { ~tile_width : Tile }* 
   | ~tile_width  : EntranceTile 
   | 1    : Wall }
   Visualization


# a tile consists of a centered window element and 
# wall elements above, below, left and right  
Tile -->
 split(x){ ~1 : Wall 
   |  2 : split(y){ 1: Wall | 1.5: Window | ~1: Wall }
   | ~1 : Wall }   
 
 
# similarily, the EntranceTile contains a centered Door element,
# but with no wall on spacing below
EntranceTile -->
 split(x){ ~1 : SolidWall 
   | 2  : split(y){ 2.5: Door | ~2: SolidWall } 
   | ~1 : SolidWall }
 
 
# firstly, the depth and the depth position of the future window is set
# secondly, one of nine window textures is randomly selected   
# finally, the window geometry asset is inserted
Window -->
  case LOD > 0 :
 s('1,'1,0.5)
 t(0,0,-0.15)
 texture(randomWindowTexture) 
 i(window_asset)  
  else : 
 setupProjection(0,scope.xy,scope.sx,scope.sy) 
 texture(randomWindowTexture) 
 projectUV(0)    
 
# same for the door asset. Scaling, positioning, texture selection
# and geometry insert
# TODO: fix door uv bug (problem with uv handling on split?)
Door -->
  case LOD > 0 :
 s('1,'1,0.1)
 t(0,0,-0.5)
 texture(frontdoor_tex)    
 i("builtin:cube")   
  else :
   setupProjection(0,scope.xy,scope.sx,scope.sy) 
 texture(frontdoor_tex) 
 projectUV(0)   
 
# for the wall asset, setting the texture scale params u and v 
# guarantees a texture mapping that nicely fits over the whole facade
Wall -->
 color(wallColor)
 texture(wall_tex)  
 set(material.dirtmap, dirt_tex)
 projectUV(0) projectUV(2)

SolidWall -->
  case LOD > 0 :
 color(wallColor)
 s('1,'1,0.4) 
 t(0,0,-0.4) 
 texture(wall_tex)  
 set(material.dirtmap, dirt_tex)
 i("builtin:cube:notex") 
 projectUV(0) projectUV(2)
  else :
   Wall   
#
@Group("FAR",4)
attr targetFAR = 5

@Hidden
attr currentFloorIndex = 1

@Hidden
attr CalculatedHeight = 0

floorHeightFunction =
 case currentFloorIndex == 1 :
  GroundFloorHeight
 else :
  UpperFloorHeight

FootprintReach -->
 #always use the 2D flat shape for the floor footprint!!
 Reachrecursion( targetFAR * parcelArea )

Reachrecursion( restArea ) -->
 case restArea < geometry.area(bottom) :
  Done.
 else :
  extrude(world.y, floorHeightFunction)
  VisualizationReach ( currentFloorIndex )
  set (currentFloorIndex, currentFloorIndex + 1)
  Reporting
  comp(f){top : Reachrecursion( restArea - geometry.area ) | all : NIL}

VisualizationReach(volumeType) -->
 case volumeType == 1 :
  set (CalculatedHeight, CalculatedHeight + 5)
  report("Calc Height", CalculatedHeight)
  Building
  #Volume("GF")
 else :
  set (CalculatedHeight, CalculatedHeight + 4)
  report("Calc Height", CalculatedHeight)
  Building
  #Volume("UF")


I've checked the path for the various textures and it they are correct. I've no idea why the rule behaves the way it does when applied to a polygon, it looked pretty straight forward but I'm obviously missing something.
0 Kudos
4 Replies
LoringTupper
New Contributor
I've solved the rpoblem with the mottles appearance of the texture, I needed to remove those first references to "Visualization", it appears I was duplicating things.

I still have the rpoblem with the roof texture displaying though. I assume this is again a case where I am adding the roof at the wrong time, but I can't quite see where I should place it i the code to make it appear on the actual top of the building vs. on each of the floors.
0 Kudos
MatthiasBuehler1
Frequent Contributor
from what I see you have 2 structures how to derive volumes.

1]
extrude (buildingHeight) --> 1 volume > thus 1 roof shape after comp(f)

2]
extrude (buildingHeight) --> 1 volume > split (y) in ground floor and upper floor volumes > thus many volumes with many roof shapes after comp(f)


in 2] you see that only the top most makes sense to get a roof.

check out the docs on 'split.index' and 'split.total'. I usually use this to distinguish the 'top floor'.

e.g. in 2], I'd code :
[ check the code, indices may be off, did not test this]
building volume > split(y) { groundFloorHeight : Volume(0) : ~1 : UpperFloors }

UpperFloors --> split(y) { ~upperFloorHeight : Volume(split.index + 1) }* # split indices are 0-based, thus +1 because GF is 0.

Volume(floorIndex) -->
    case floorIndex == 0 :
        GroundFloorVolume.
    case floorIndex == split.total :
        TopFloorVolume.
    else :
        UpperFloorVolume.



then only on the TopFloorVolume, you trigger the roof.

ok ?
0 Kudos
LoringTupper
New Contributor
Thanks for the feedback Mattias.
I tried several iterations of plugging in the code you supplied but I get some strange results. The roof doesn't appear, there ar some lines that run acros the roof but the actual texture is not there. I also noticed that the tiles on the ground floor and upper flors are handles differnetly depending on the side of the building you are looking at. The window textures are sometime missing altogether so there appears to be a hole in the building. The same for the entranceTile, there will be a hole where the door should be. I also noticed that when using my original code there was anothe mistake in that the entranceTile is used on all floor, the groundfloor get that tile on the front of building burt the upper florrs, which shouldn't have them at all, has them on a differnet side. With the new code, the inserted code below, the same thing happens only now on the opposite side of the building where the entranceTile is, there is a hole in the building. It's sort of hard to explain so I'll load a couple of images to clarify. I think I'm close but I've obviously got something in the wrong place or perhaps I've left code in there that should no longer be there.

[ATTACH=CONFIG]24144[/ATTACH]

[ATTACH=CONFIG]24145[/ATTACH]


The Code:

version "2012.1"

/* Attributes *************************************/

@Group("SETBACKS",0) 
attr FSetback = 3
@Group("SETBACKS")
attr BSetback = 3
@Group("SETBACKS")
attr LSetback = 3
@Group("SETBACKS")
attr RSetback = 3

@Group("HEIGHTS",1)
attr GroundFloorHeight = 5
@Group("HEIGHTS")
attr UpperFloorHeight = 4

@Group("COLORS",2)
attr LUColor = "#FFFFE0"

@Hidden
attr height    = 50

@Hidden
attr tile_width   = 4

@Hidden 
attr wallColor          = "#FFFFE0"
#attr wallColor          = "#fefefe"

@Hidden
attr parcelArea = 0

@Range ("transparent", "as is")
@Group("VISIBILITY MODE",3)
attr vizMode = "transparent"


attr LOD     = 1
/* Assets *************************************/

// geometries
window_asset = "facades/window.obj"

// textures
frontdoor_tex    = "facades/textures/shopdoor.tif"
wall_tex     = "facades/textures/brickwall2_bright.tif"
dirt_tex    = "facades/textures/dirtmap.15.tif"
roof_tex     = "roof/F_roof5.tif"


# this function will get one of the 9 window textures in the assets folder
randomWindowTexture = fileRandom("*/facades/textures/window.*.tif") 

# this function will get one of the 6 roof textures in the assets folder
randomRoofTexture = fileRandom("*/roof/F_roof*.tif")

/* Initial Shape starting rule *************/

# scale the lit to leave a small border and extrude the lot to building height

Lot --> 
 set ( parcelArea, geometry.area )
 report ( "Parcel Area", parcelArea )
 setback(FSetback) { street.front : NIL | remainder :
  setback(BSetback) { street.back : NIL | remainder :
   setback(LSetback) { street.left : NIL | remainder :
    setback(RSetback) { street.right : NIL | remainder :
     FootprintReach
    }
   } 
  }
 }

@StartRule
Footprint --> 
 extrude(height) Building
 NIL
 #comp(f) { front : Frontfacade | side : Sidefacade | top: Roof}

Reporting -->
 report("GFA", geometry.area(bottom))
 report("FAR", geometry.area(bottom) / parcelArea )
 NIL  #NIL the geometry

#Visualization -->
# case vizMode == "as is" :
#  Done.
# case vizMode == "transparent" :
#  set (material.opacity, 0.8)
#  Done.
# else :
#  comp(f) { front : Frontfacade | side : Sidefacade | top: Roof}

# inner lots are dropped
LotInner --> NIL

# split the building geometry into its facade components
Building -->
 #comp(f) { front : Frontfacade | side : Sidefacade | top: Roof}
 split(y) { GroundFloorHeight : Volume(0) | ~1 : UpperFloors }
 
 UpperFloors -->
  split(y) { ~UpperFloorHeight : Volume(split.index + 1) }*
 
 Volume(floorIndex) -->
  case floorIndex == 0 :
   Groundfloor
  case floorIndex == split.total :
   TopFloor
  else :
   Floor
 
 
# the front facade is subdivided into one front groundfloor 
# and upper floors
#Frontfacade --> 
# setupProjection(0, scope.xy, 1.5, 1, 1) # setup 1.5m x 1m texture tiles along scopes xy plane (and distortion in z)
# setupProjection(2, scope.xy, scope.sx, scope.sy)
# split(y){ GroundFloorHeight    : Groundfloor 
#   | {~UpperFloorHeight : Floor}* }


# a side facade is subdivided into one bottom floor 
# and upper floors. 
#Sidefacade --> 
# setupProjection(0, scope.xy, 1.5, 1, 1) # setup 1.5m x 1m texture tiles along scopes xy plane (and distortion in z)
# setupProjection(2, scope.xy, scope.sx, scope.sy)
# split(y){ GroundFloorHeight    : Floor 
#   | {~UpperFloorHeight : Floor}* }
 

# a roof texture is applied to the roof face
Roof --> 
 setupProjection(0, scope.xy, scope.sx, scope.sy, 0, 1)
 #texture(randomRoofTexture) 
 texture(roof_tex)
 projectUV(0) 


# each floor is horizontally split into two narrow corner areas on 
# each side of the floor, and into a set of window tiles in between
Floor -->
 #extrude(height) comp(f) { side :  Facade | top(0):  Roof }
 split(x){ 1 : Wall | { ~tile_width : Tile }* | 1 : Wall }
 
TopFloor -->
 split(x){ 1 : Wall 
   | { ~tile_width : Tile }* 
   | 1 : Wall }
 split(y) { 1 : Roof }
 
# similarily, the front groundfloor is horizontally split into 
# two narrow corner areas on each side of the floor, 
# a special entrance tile on the right 
# and into a set of window tiles in between
Groundfloor -->
 split(x){ 1    : Wall 
   | { ~tile_width : Tile }* 
   | ~tile_width  : EntranceTile 
   | 1    : Wall }


# a tile consists of a centered window element and 
# wall elements above, below, left and right  
Tile -->
 split(x){ ~1 : Wall 
   |  2 : split(y){ 1: Wall | 1.5: Window | ~1: Wall }
   | ~1 : Wall }   
 
 
# similarily, the EntranceTile contains a centered Door element,
# but with no wall on spacing below
EntranceTile -->
 split(x){ ~1 : SolidWall 
   | 2  : split(y){ 2.5: Door | ~2: SolidWall } 
   | ~1 : SolidWall }
 
 
# firstly, the depth and the depth position of the future window is set
# secondly, one of nine window textures is randomly selected   
# finally, the window geometry asset is inserted
Window -->
  case LOD > 0 :
 s('1,'1,0.5)
 t(0,0,-0.15)
 texture(randomWindowTexture) 
 i(window_asset)  
  else : 
 setupProjection(0,scope.xy,scope.sx,scope.sy) 
 texture(randomWindowTexture) 
 projectUV(0)    
 
# same for the door asset. Scaling, positioning, texture selection
# and geometry insert
# TODO: fix door uv bug (problem with uv handling on split?)
Door -->
  case LOD > 0 :
 s('1,'1,0.1)
 t(0,0,-0.5)
 texture(frontdoor_tex)    
 i("builtin:cube")   
  else :
   setupProjection(0,scope.xy,scope.sx,scope.sy) 
 texture(frontdoor_tex) 
 projectUV(0)   
 
# for the wall asset, setting the texture scale params u and v 
# guarantees a texture mapping that nicely fits over the whole facade
Wall -->
 color(wallColor)
 texture(wall_tex)  
 #set(material.dirtmap, dirt_tex)
 projectUV(0) projectUV(2)

SolidWall -->
  case LOD > 0 :
 color(wallColor)
 s('1,'1,0.4) 
 t(0,0,-0.4) 
 texture(wall_tex)  
 #set(material.dirtmap, dirt_tex)
 i("builtin:cube:notex") 
 projectUV(0) projectUV(2)
  else :
   Wall   
#
@Group("FAR",4)
attr targetFAR = 5

@Hidden
attr currentFloorIndex = 1

@Hidden
attr CalculatedHeight = 0

floorHeightFunction =
 case currentFloorIndex == 1 :
  GroundFloorHeight
 else :
  UpperFloorHeight

FootprintReach -->
 #always use the 2D flat shape for the floor footprint!!
 Reachrecursion( targetFAR * parcelArea )

Reachrecursion( restArea ) -->
 case restArea < geometry.area(bottom) :
  Done.
 else :
  extrude(world.y, floorHeightFunction)
  VisualizationReach ( currentFloorIndex )
  set (currentFloorIndex, currentFloorIndex + 1)
  Reporting
  comp(f){top : Reachrecursion( restArea - geometry.area ) | all : NIL}

VisualizationReach(volumeType) -->
 case volumeType == 1 :
  set (CalculatedHeight, CalculatedHeight + 5)
  report("Calc Height", CalculatedHeight)
  Building
  #Volume("GF")
 else :
  set (CalculatedHeight, CalculatedHeight + 4)
  report("Calc Height", CalculatedHeight)
  Building
  #Volume("UF")


Any idea what I have done wrong here?
0 Kudos
MatthiasBuehler1
Frequent Contributor
Hi !


You're mixing 2 things in your code.

You're calling a facade rule ( which works only on 2d faces ) on a 3d volume, thus you cut the volume only in 1 direction.

You're missing the comp(f).

Note there's a big difference between the following 2 strategies, which you're mixing :

1]
- Extrude to full height ( Create 1 extruded, simple 3d Volume )
- comp(f) Facades / Roof

2]
Recursively add single floor volumes on top of each other until a certain goal ( FAR ) is reached.
Note : In this 2nd approach, you only create 1 roof on top of the top most volume.
Note : Each floor volume's facade created that way is logically only 1 floor high.


Also, try to structure the code flow nicely.

But most importantly, make VERY sure on what you work : 3d volumes or 2d faces ( comp(f) ).

Check out that thread too :
http://forums.arcgis.com/threads/44417-CGA-Understanding-the-concept-of-the-scope

Ok ?

Matt
0 Kudos