Perhaps I'm not using 'touches()' correctly? #video & code#

366
5
Jump to solution
07-19-2012 05:12 AM
DavidOConnor
New Contributor
Hi Folks

Here is something that has been puzzling me for ages.

I've been trying to (roughly) emulate the terrific-looking NYC2259 recursive vertical splits.  However, due to my shortfall in skill, I'm using a much simpler approach. 

It goes like this:

  • The core has a given height, and the sections have a given (potential) height. For this example, the potential section height is twice the height of the core.

  • Using the touches() instruction as a limitation, the randomized recursive vertical split and gaps should keep looping upwards while they touch the core.

  • --If the sections and gaps loop too high ,to where the sections are not touching the core (i.e. be floating in the air and unsupported) so they will stop (give NIL).

  • --If the sections and gaps reach the maximum specified section height, they will also stop.

What puzzles me is that seems to work great, but not all the time.  I've embedded the script below, and here you can see it on this 2-minute video: http://youtu.be/j8phESvleRM
 
If I split, translate or rescale the core geometry, the core geometry is always generated but, often, the section geometry is not generated at all*. 
But if I turn off the touches() limitation, both the sections and core are generated of course.  Yet, the generated section geometry is visibly touching one or more elements of the core.

As I understand it, the touches() should pick up contact with any shape tree.  Perhaps there is there something that I am missing?

Thanks for your help!
David
* yes, I'm working with watertight volumes, not polygons


#################################################################################################################################### ## VARIABLES #################################################################################################################################### ## Level of Detail  attr LOD      = 1 ############################ ## Height and floors  numberOfFloors     = rint((scope.sx * scope.sz)/floorHeight/10 * popDensityFactor )  popDensityFactor    = 1  coreHeight      = numberOfFloors * floorHeight   // actual height of the core  sectionHeight      = numberOfFloors * floorHeight * 2  // potential maximum height of the recursive sections and building   floorHeight      = 3  tileWidth      = 3  ############################ ## Sections  sectionRandomizer    = (rint(randomSectionDistribution * sectionHeight *.75/floorHeight)) * floorHeight  randomSectionDistribution    = 15%:.4 20%:.2  20%:.1  20%:.5  else: .3  gapRandomizer     = (rint(randomGapDistribution * sectionHeight *.75/floorHeight)) * floorHeight  randomGapDistribution     = 50%:.05  20%:.1  20%:.2  else: .3     #################################################################################################################################### ## RULES ####################################################################################################################################  Lot-->         // make a rectangle from the initial shape, rescale it and align it  innerRect  s('0.7,'1,'0.7) center(xz) alignScopeToAxes(y) s('1,0,'1) Squareize  Squareize -->       //  make the new rectangle shape into square, lenght of side is the shortest scope length  case scope.sx  == scope.sz:   s('1,0,'1)   center(xz)   Footprint  case scope.sx > scope.sz:   s(scope.sz,0,scope.sz)   center(xz)   Footprint  case scope.sz > scope.sx:   s(scope.sx,0,scope.sx)   center(xz)   Footprint  else:   NIL   Footprint-->       // extrude the core  case scope.sx * scope.sz > 500:   extrude(coreHeight )      Tower   else:            NIL   ################################ ################################ ## CORE AND SECTIONS ################################  Tower-->        // insert the model    i(fileRandom("assets/volumes/Rule5/*.obj")) //CORE    split(z){ '0.1:       NIL      | '0.3 :      s('.5, '1, '.5)              center(xz)              t(0,0,2)               Mass       | '0.2 :       NIL         | '0.3:        s('.5, '1, '.5)              center(xz)              t(0,0,-10)              Mass       |'0.1:       NIL      } //SECTIONS    split(z){ '0.1:       NIL                       | '0.7:       center(xz)               s('1, sectionHeight, '1)              RecursiveSections      |~1: NIL      }         ############################### ############################### ## RECURSIVE SECTIONS ###############################  RecursiveSections -->     // ALTERNATIVE 1: DESIRED  repeat the section and gap, while it touches the core    case touches(intra) :      split(y){ sectionRandomizer: Mass        | gapRandomizer :   NIL        | ~1:      RecursiveSections         }    else:     NIL           // ALTERNATIVE 2: CHECK  turn off touches() to see if some of the sections touch the core  /*     split(y){ sectionRandomizer: Mass        | gapRandomizer :   NIL        | ~1:      RecursiveSections         }        */           ################################   ################################ ## MASS ################################  Mass-->         //  split up the mass into roof, base and sides   alignScopeToAxes(y)   center(xyz)    comp(f) {horizontal: BasicRoof      |all : WallAlignCheck      }  ################################   ################################ ## WALL ################################  WallAlignCheck-->       // check the alignment (not sure how this part works, but it seems to work)   alignScopeToGeometry(zUp, auto)   alignScopeToAxes(y)          split(y){0.01 :  TinySplit  // Workaround split to get a tiny horizontal edge, for vertical alignment     | ~1 :   Wall1     } Wall1-->        // split odd shapes into more usual shapes (not sure how this part works, but it seems to work)   convexify()     comp(f){all: Wall2}      Wall2-->        // give it a nice color   color("#ff0000")    ################################   ################################ ## FRAME ################################  Frame-->        // give it a nice color    color("#ff0000")    Done.          ################################   ################################ ## TINY SPLIT ################################  TinySplit-->       // give it a nice color    color("#ff0000")    Done.      ################################   ################################ ## BASIC ROOF ################################  BasicRoof -->       // leave it white    Roof.   
0 Kudos
1 Solution

Accepted Solutions
MatthiasBuehler1
Frequent Contributor II
hey !

I guess you're having the following currently unsolvable issue.

Once the 'occlusion ghosts' have been created, they exist during the full period of the model generation phase. the tricky part of this is that all possible ghosts (also the ones created in recursions) are checked for occlusions. Thus in many cases, the user would only like to be able to check the occlusion on the 'current state' of the model during the generation phase and not all of them which have ever existed. But sadly, this is not possible with the current implementation of the occlusion functionality.

I personally almost never use occlusions since they have great limitations and make the code insanely complex and slow sometimes.

Also, there is no way to visualize the ghosts, which makes 'debugging' hard.

View solution in original post

0 Kudos
5 Replies
DavidOConnor
New Contributor
Hooray, I think I've solved it :D

It seems the rule file is working fine.  The problem seems to occur only with some specific volume shapes that I'm using (OBJ format), that I made made initially in 3ds Max.

The volumes giving trouble aren't complex shapes (even a cube!) but they have something that conflicts with the touches() instruction, causing it to be ignored.  Interesting, I'll look at the volumes in more detail later today.
0 Kudos
DavidOConnor
New Contributor
Wow, this is really puzzling.  I made a new generic 3ds Max cube, converted it to editable polygons, and exported it as an FBX and OBJ.

The FBX and OBJ files seem to consistently work differently with the 'touches()' rule.  Unfortunately, neither are giving the results I'm hoping for.  For the sake of completeness: MAX, ASE and 3DS formats give the same (regrettably, incorrect) results as FBX.

Here is a 1-minute video of what I mean:
[video=youtube_share;Reo5w2Pqalo]http://youtu.be/Reo5w2Pqalo[/video]

As far as I can tell, all the blocks on screen should get recursive sections.  But only a (consistent) few seem to get them.
0 Kudos
MatthiasBuehler1
Frequent Contributor II
hey !

I guess you're having the following currently unsolvable issue.

Once the 'occlusion ghosts' have been created, they exist during the full period of the model generation phase. the tricky part of this is that all possible ghosts (also the ones created in recursions) are checked for occlusions. Thus in many cases, the user would only like to be able to check the occlusion on the 'current state' of the model during the generation phase and not all of them which have ever existed. But sadly, this is not possible with the current implementation of the occlusion functionality.

I personally almost never use occlusions since they have great limitations and make the code insanely complex and slow sometimes.

Also, there is no way to visualize the ghosts, which makes 'debugging' hard.
0 Kudos
DavidOConnor
New Contributor
unsolvable issue


Thanks for the insight Matthias, appreciated :D

It is ok, I found another way to do it that serves the same purpose.  Once the core height is exceeded, the recursive sections stop.  To get that nice section protruding above the core, which is a characteristic of your futuristic-NYC example, instead I randomly add a building cap (split and textured to match the recursive sections) to the top of the core height.
0 Kudos
MatthiasBuehler1
Frequent Contributor II
glad you found a solution .. !
0 Kudos