POV-Ray Object Collection
Block Wall Macros


Overview
Examples
Macros
Variables

A simple scene (see Example 7 below)

Overview


A spiral staircase (see Example 21 below)
These macros enable you to add a wall to a POV-Ray scene with just a few lines of SDL (Scene Description Language). By invoking one of the Blockwall macros from the include file 'blockwall.inc' you can generate POV-Ray wall objects composed of individual blocks that can be cut using CSG operations. The main macros provide different ways of specifying the shape of a wall. These then call a macro that generates a randomised blockwork pattern and a macro to build individual blocks that fit into the spaces available in the pattern. There are also a couple of handy utility macros, such as a macro that drops a spline onto a surface so that you can build a curved country wall that follows the lay of the land.

The sample scene file 'blockwall.pov' contains plenty of examples showing the use of the various options and settings available with these macros. These examples are described and illustrated below. There are lots of optional settings that you can use to control the operation of the macros but it's likely that you'll only ever need a few of them, so it's easiest to cut and paste an example that's close to what you want to do and then use the Variables section of this page to swot up on just the specific settings that you need.

The position and alignment of the generated object depends on which macro you use to generate it, but the default settings generally create a wall with it's bottom left corner at the origin using a scale of 1 POV-Ray unit to represent 1 metre. The ScaleConvert macro on the object collection can be used to convert between different units. Some of the macros set values that can be useful to you after calling the macro when positioning/aligning things with the wall segments, as demonstrated in a number of the examples below.

The randomised blockwork pattern is controlled through a number of variables that allow you to define the proportion of large to small blocks, the maximum size of blocks and the relationship between the number of short, wide blocks and tall ones. Various standard block types and colors are incorporated and can be specified by name. Alternatively you can specify color limits and contrast settings to suit your own needs.

You can suggest changes to these macros or provide other feedback on the Object Collection newsgroup at http://news.povray.org/groups/povray.object-collection or (for registered users) using the feedback option available from the Object Collection Search page. The Object Collection is covered by an open license (CC-LGPL), encouraging reuse, modification and redistribution. If you make changes that you wish to contribute back to the collection you can register on the Object Collection website and then upload a new version through the contributions page (self registration usually takes just a few minutes).

Return to Table of Contents


Examples

The blockwall.pov scene file contains a series of examples demonstrating the use of the various Blockwall macros. You can render any of these examples simply by setting the 'Example' variable at the top of the scene file. You can also use POV-Ray command-line animation options to generate a sequence of example images by setting the 'Example' variable to 'frame_number'. With command-line options +KFI0 +KFF23 you can therefore regenerate all of the examples in one go, which provides a useful means of regression testing changes if you ever need to change the macros.

Each of the examples is explained and illustrated here. The code snippets illustrate the use of the various Blockwall macros, but doesn't always show additional props used in the image. You can see the full source, including props and full texture definitions in the 'blockwall.pov' scene file.
Example=0; Default settings
Example 0 illustrates the Blockwall macro using the default settings to generate a simple square slab of walling.

The default settings for the Blockwall macro produce a section of wall 0.1 units thick and 1 unit square. The section sits on the XZ plane with the bottom left corner at the origin. You can alter the defaults by setting control variables before calling the Blockwall macro to adjust the height, width and thickness dimensions along with the color and other texture settings (see Variables).

 camera {orthographic
   location 0.5-1.2*z
   look_at 0.5
 }
 light_source {<-10,20,-50>, rgb 1}
 #include "blockwall.inc"
 Blockwall("")

You can also wrap the macro call in an object statement and perform translations, rotations and scaling on the result. For example:

 object {Blockwall("")
   scale 0.5
   rotate <3,0,4>
   translate x*1.3
 }

Example=1; Three copies with wrapping to interleave the ends.
The panels from Example 0 can be tiled, but the seams between adjacent panels would be readily apparent.

Example 1 uses the Blockwall_Wrap setting to tell the Blockwall macro to wrap some blocks around from the left hand side of a panel to the right hand side of the panel so that adjacent copies of the same blockwork segment can be joined together without generating vertical joints that run from the bottom to the top of the wall. This example shows 4 identical panels, one in the default position and the others displaced on either side. In this example a default value for the Blockwall_WallLength variable is set by the Blockwall macro because none has been specified prior to the macro call. You can use variables such as this after the macro has been run to generated the wall. In this example we use it to position wall segments.

This example passes a parameter into the macro to use one of the standard block styles "BuffBrick". This to select non-default color settings for the blocks.

The macro doesn't add Mortar to the blockwork, but you can readily add some using a simple POV-Ray primitive (in this case a box) at a depth of your choosing. This example uses the same normal and finish settings that were used to generate the blockwork (the defaults set by the macro) to texture the mortar. As with the Blockwall_WallLength variable, the default normal and finish identifiers are also set by the Blockwall macro because neither was specified prior to the macro call.

  #declare Blockwall_Wrap = 1;
  #declare Section = Blockwall("BuffBrick")
  // Show 3 copies of the same section side by side
  object {Section translate  -Blockwall_WallLength*x}
  object {Section}
  object {Section translate   Blockwall_WallLength*x}
  object {Section translate 2*Blockwall_WallLength*x}
  // Add some mortar
  box {
    <-0.994,0,0.006><3,0.994,0.074> 
    texture {
      pigment {rgb <1,0.6,0.4>*0.6}
      normal {Blockwall_Normal scale 0.3}
      finish {Blockwall_Finish}
    }
  }

Example=2; Using Blockwall_Fill to create a wall.
Example 2 uses the Blockwall_Fill macro to define a box filled with blockwork. At times this can be more convenient than specifying the height, width and depth of the wall for the Blockwall macro using control variables.

This example illustrates the use of a superellipsoid to add mortar, removing the overspill of mortar that can be seen on the nearest corner in the image generated from Example 2. The superellipsoid is generated straddling the origin, so needs a bit more transformation to correctly scale it and move it to align with the centre of the wall.


  object {Blockwall_Fill(<0,0,0>,<0.3,1,10>,"GreyBrick")}
  // Add some mortar
  superellipsoid {
    <0.1,0.05>
    rotate x*90
    scale 0.5
    translate 0.5
    scale <0.3,1,10>-0.0160
    translate 0.008
    texture {
      pigment {rgb 0.68}
      normal {Blockwall_Normal scale 0.3}
      finish {Blockwall_Finish}
    }
  }

Example=3; Following a spline (a hump-back bridge).
Example 3 illustrates the Blockwall_FollowSpline macro using its default settings. This macro generates a wall that follows a spline assigned to the control variable Blockwall_Spline. This example calls the macro without explicitly setting the spline, so it uses the default setting which generates a short section of wall with a little hump in the middle. This default spline stretches out along the +Z axis.

Calling the macro a second time uses the same spline, but generates a different randomised pattern of blockwork. This is because the first call initialises a randomisation seed and subsequent calls just continue to call off random numbers from the same random number stream.

  object {Blockwall_FollowSpline("")}
  // Add a second wall following the same spline and translate it to the left.  
  object {Blockwall_FollowSpline("") translate x*1.8} 

Example=4; Dropping a spline onto an object
Example 4 shows how the Blockwall_DropSplineToSurface macro can be used in conjunction with the Blockwall_FollowSpline macro. The Blockwall_DropSplineToSurface macro drops the spline assigned to the Blockwall_Spline variable onto an arbitrary object that has been assigned to the Blockwall_Target identifier. In this instance a torus is used as the target object, so the Blockwall_DropSplineToSurface macro adjusts the spline so that it can subsequently be used to draw a wall that sits neatly on the surface of that torus.

The "RoughStone" block style specified as a parameter generates randomised stone shapes. The Blockwall_ClipBlock setting tells the macro to trim the edges of each block to give a smoothed appearance to the dressed surfaces of the wall.

  #declare Blockwall_ClipBlock  = 1;  

  // Define a surface to drop a spline onto.
  #declare Blockwall_Target = torus {8,12 
    translate -y*12 
    scale <1,0.4,1>
    translate <3,0,6>
  }  

  // Create a spline above the target surface.
  #declare Blockwall_Spline = spline {
    cubic_spline
    -.25, < 0  ,1,-1>
    0.00, < 0  ,1, 0>
    0.20, < 1  ,1, 5>
    0.40, < 2  ,1,10>
    0.60, < 1  ,1,15>
    0.80, < 0  ,1,20>
    1.00, < 1  ,1,25>
    1.25, < 2  ,1,30>
  } 

  // Drop the spline onto the surface
  Blockwall_DropSplineToSurface()  

  // Call the macro to generate a wall that follows the new spline
  object {Blockwall_FollowSpline("RoughStone")}             

Example=5; Following an array of corner points.
Example 5 uses the Blockwall_FollowArray macro which draws a sequence of straight wall segments based upon corner points defined in the Blockwall_CornerArray array. The default points define a 1 metre cube with its bottom left corner at the origin.

This macro adjusts the corners so that the blocks are interwoven and don't overrun. This macro works best with wall segments that meet at right angles. It still works with non-perpendicular wall segments, but you may get some artifacts at the joints (see Example 8). If the first and last corner points are the same, the macro generates a closed shape and the blocks on the final corner are also interwoven. Otherwise it switches wrapping off for the ends so you get neat start and end sections.

  // Call the macro to fill a box with a stone wall
  object {Blockwall_FollowArray("GreenBrick")}  

Example=6; Creating a shell with holes in it.
Example 6 uses the Blockwall_Shell macro to create a rectangular shell, filling the perimeter of the box with walls. This example declares the Blockwall_Holes object before calling the Blockwall_Shell macro. This object is used by the macro to cut each individual block, giving the cut surfaces the correct texture. Alternatively you could use CSG to poke door and window holes into that shell once it's been generated, but this doesn't give you the blockwork texture on the cut surfaces and is often considerably slower.

  // Create a CSG object that defines where the holes in the wall go
  #declare Blockwall_Holes = union {
    box {<0,0.1,-0.01><1,1.9,0.11>}     // Front Door
    box {<1.2,1.2,-0.01><1.6,1.9,0.11>} // Side Window
    box {<-3.5,1,-0.01><-1.5,1.9,0.11>} // Front Window
    box {<0,0.1,9.8><1,1.9,10.01>}      // Back Door
    box {<-4.01,1,1><-3.9,1.9,3>}       // Window 1 in Left Side Wall
    box {<-4.01,1,6><-3.9,1.9,8>}       // Window 2 in Left Side Wall
    box {< 4.01,1,1>< 3.9,1.9,3>}       // Window 1 in Right Side Wall
    box {< 4.01,1,6>< 3.9,1.9,8>}       // Window 2 in Right Side Wall
  }

  // Call the macro to fill a box with the outline of a stone wall
  #declare OuterShell = object {Blockwall_Shell(<-4,0,0>,<4,2.4,10>,"ColorBrick")}  
  #declare Mortar = difference {
    box {<-3.994,0.001,0.006>,<3.994,2.394,9.994>}
    box {<-3.924,0,0.076>,<3.924,2.4,9.924>}
  }

  // Draw the Block Wall 
  object {OuterShell}

  // Add Mortar
  difference {
    object {Mortar}
    object {Blockwall_Holes}
    texture {
      pigment {rgb 0.68}
      normal {Blockwall_Normal scale 0.3}
      finish {Blockwall_Finish}
    }
  }

Example=7; A more complete scene (a walkers refuge under construction)
Example 7 provides a more complete sample scene showing a walkers refuge under construction out in the countryside. It uses the Blockwall_FollowSpline macro to generate a country wall and calls the Blockwall_Shell twice, once for the main shell of the building and a second time to generate a chimney.

This example also demonstrates the use of the Blockwall_DropSplineToSurface macro which drops the spline declared as Blockwall_Spline onto the surface of the target object declared as Blockwall_Target. The results are written back into the Blockwall_Spline identifier and subsequently used by the Blockwall_FollowSpline macro to generate a country wall that follows the contours of the surface of the target object.

This example declares the Blockwall_Holes object before calling the Blockwall_Shell macro to generate the main shell of the building. This object is used by the macro to cut each individual block, giving the cut surfaces the correct texture. Alternatively you could use CSG to poke door and window holes into the shell once it's been generated, but this doesn't give you the blockwork texture on the cut surfaces and is often considerably slower. The #undef directive is used to undeclare the Blockwall_Holes identifier before calling the Blockwall_Shell macro a second time to generate a chimney so that the top of chimney is not cut off at the roofline.

  // Define a surface to drop a spline onto.
  #declare Blockwall_Target = torus {8,12 
    translate -y*12 
    scale <1,0.4,1>
    translate <3,0,6>
  }
    
  // Add a grassy surface using a textured copy of the target object
  object {Blockwall_Target texture {GrassTexture}}

  // Create a spline some distance above the target surface.
  #declare Blockwall_Spline = spline {
    cubic_spline
    -.25, <0, 1, -1>
    0.00, <0, 1,  0>
    0.20, <1, 1,  5>
    0.40, <2, 1, 10>
    0.60, <1, 1, 15>
    0.80, <0, 1, 20>
    1.00, <1, 1, 25>
    1.25, <2, 1, 30>
  }
   
  // Drop the spline onto the surface
  Blockwall_DropSplineToSurface()  

  // Call the macro to generate a wall that follows the new spline
  #declare Blockwall_ClipBlock       = 1;
  #declare Blockwall_MatrixSpacing   = 0.03;
  #declare Blockwall_BlockThickness  = 0.35;
  #declare Blockwall_HBias           = 1;
  #declare Blockwall_VBias           = 3;  
  #declare Blockwall_MaxHU           = 10;  
  #declare Blockwall_MaxVU           = 5;  
  object {Blockwall_FollowSpline("BuffStone")}  
  
  // Now for the refuge itself
  #declare Blockwall_MatrixSpacing   = 0.1;
  #declare Blockwall_HBias           = 2.5;
  #declare Blockwall_VBias           = 3;  
  #declare Blockwall_MaxHU           = 5;  
  #declare Blockwall_MaxVU           = 3;  
  #declare Blockwall_BlockThickness  = 0.15;
  // Create a CSG object that defines where the holes in the wall go
  #declare Blockwall_Holes = union {
    // Roofline
    box {0,<3,2,4.2> rotate z*35 translate <-4+Blockwall_BlockThickness,1.78,0.9>}
    box {0,<3,2,4.2> rotate z*35 scale <-1,1,1> translate <-1-Blockwall_BlockThickness,1.78,0.9>}
    // Level off tops of walls
    box {0, translate <-1-Blockwall_BlockThickness,1.78,0.9>}
    box {0, scale <-1,1,1>  translate <-4+Blockwall_BlockThickness,1.78,0.9>}
    // Doorway
    box {0,<0.9,1.8,Blockwall_BlockThickness+0.1> translate <-3,0  ,0.95>}
    // Lintel
    box {0,<1.2,0.2,Blockwall_BlockThickness+0.1> translate <-3.1 ,1.8,0.95> }
  }
  // Call a macro to fill a box with the outline of a building then use CSG to cut away the bits we don't want.
  object {Blockwall_Shell(<-4,0,1><-1,3,5>,"ColorBrick")}
  // Add a chimney.
  // We need to #undef the Blockwall_Holes object first or we'll slice bits off the chimney at the roofline.
  #undef Blockwall_Holes
  Blockwall_Shell(<-4,0,4.5><-3,2.8,5.1>,"ColorBrick")
  
  // Add Mortar
  difference {
    box {<-3.994,0,1.006>,<-1.006,3,4.994>}
    box {<-3.926,-0.01,1.074>,<-1.074,3.01,4.926>}
    // Roofline
    box {0,<3,2,4.2> rotate z*35 translate <-4+Blockwall_BlockThickness,1.75,0.9> }
    box {0,<3,2,4.2> rotate z*35 scale <-1,1,1> translate <-1-Blockwall_BlockThickness,1.75,0.9>}
    // Level off tops of walls
    box {0, translate <-1-Blockwall_BlockThickness,1.8,0.9> texture {Blockwall_ThisBlockTexture}}
    box {0, scale <-1,1,1>  translate <-4+Blockwall_BlockThickness,1.8,0.9> texture {Blockwall_ThisBlockTexture}}
    // Doorway
    box {0,<0.9,1.8,Blockwall_BlockThickness+0.1> translate <-3,0,0.95>}
    texture {
      pigment {rgb 0.68}
      normal {Blockwall_Normal scale 0.3}
      finish {Blockwall_Finish}
    }
  }

Example=8; A sequence of walls demonstrating the Blockwall_FollowArray macro with non-perpendicular corners
As was mentioned under Example 5 above, the Blockwall_FollowArray macro works best with wall segments that meet at right angles. Nevertheless, it does also support non-perpendicular corners. You may however get a few unwanted artifacts at, or near the corners. If you get artifacts that are particularly troublesome you may wish to try different settings for the Blockwall_SizeSeed seed stream to see if you can get a better randomised pattern for your purposes.

Example 8 shows a sequence of wall segments that could be used to represent garden planters to demonstrate the Blockwall_FollowArray macro with an array of arbitrary corner points that generate non-perpendicular corners. The tower in the centre illustrates how the array elements can be defined procedurally. The paving illustrates how you can adjust the horizontal and vertical bias and maximum block sizes. The horizontal and vertical settings usually differ for walling, whereas for paving it can be more realistic to make the horizontal and vertical settings the same.

  // Create some fairly randomly shaped planters.
  #declare Blockwall_WallHeight = 0.5;
  #declare Blockwall_MatrixSpacing   = 0.04;
  #declare Blockwall_HBias           = 0.5;
  #declare Blockwall_VBias           = 3;  
  #declare Blockwall_MaxHU           = 5;  
  #declare Blockwall_MaxVU           = 3;  
  #declare Blockwall_BlockThickness  = 0.30;
  #declare Blockwall_Finish = finish {ambient 0.01};
  #declare Blockwall_CornerArray = array [10] {
    <0.5  ,1.2>,
    <0.8  ,1.5>,
    <1.28 ,1.28>,  
    <1.5  ,0.8>,
    <1.2  ,0.5>,
    <2.2  ,0.5>,
    <2.2  ,1.5>,
    <1.5  ,2.2>,
    <0.5  ,2.2>,  
    <0.5  ,1.2>  
  } 
  #declare Blockwall_BlockThickness = 0.1;
  object {Blockwall_FollowArray("GreenBrick")}
  object {Blockwall_FollowArray("GreenBrick") rotate y*90}
  object {Blockwall_FollowArray("GreenBrick") rotate y*180}
  object {Blockwall_FollowArray("GreenBrick") rotate y*270}  
  
  // Add the central feature (maybe a little tower or something).
  #declare Blockwall_WallHeight = 1.4;
  #declare Blockwall_CornerArray = array[9];
  #local I = 0;
  #while (I<8)
    #declare Blockwall_CornerArray[I]=
    #local I = I + 1;
  #end
  #declare Blockwall_CornerArray[8]=Blockwall_CornerArray[0];
  #declare Blockwall_ClipBlock = 1;
  Blockwall_FollowArray("PinkBrick")
  
  // Paving. To use as paving, we can use a matching horizontal and 
  // vertical bias for the pattern and rotate the 'wall' to be horizontal. 
  Blockwall_Undef()
  #declare Blockwall_WallLength = 4.5;
  #declare Blockwall_WallHeight = Blockwall_WallLength;
  #declare Blockwall_MatrixSpacing   = 0.05;
  #declare Blockwall_HBias           = 2;
  #declare Blockwall_VBias           = 2;  
  #declare Blockwall_MaxHU           = 5;  
  #declare Blockwall_MaxVU           = 5;  
  #declare Blockwall_Finish = finish {ambient 0.01};
  object {Blockwall("")
    rotate x*90
    translate <-Blockwall_WallLength/2,0,-Blockwall_WallHeight/2>
  }
  
  // Add some grass
  plane {y,-0.01 texture {GrassTexture}}

Example=9; A rough stone wall.
Example 9 generates a rough stone wall that illustrates the use of various matrix settings that can be used to control the block distribution and relative size of blocks in the randomised blockwork pattern.

The Blockwall_MatrixSpacing variable is set to 0.02, which represents a size of 2cm. This is the size of the smallest possible block, but the Blockwall_MaxHU, which controls the maximum number of horizontal units that a block can have, is set quite high and the Blockwall_HBias variable is assigned a small value, so an above average number of wide blocks will be generated. The maximum height of a block is set to half the width (Blockwall_MaxVU) and the vertical bias is higher (Blockwall_VBias), generating a lot more short blocks than tall blocks. The surfaces of the blocks are clipped by setting Blockwall_ClipBlock to 1. Otherwise, with these sort of values, the blocks would protrude quite some distance out from the surface, giving quite a messy looking wall.

  #declare Blockwall_MinColor        = <0.98,0.65,0.25>;   
  #declare Blockwall_MaxColor        = <1.0 ,0.7 ,0.3>;
  #declare Blockwall_Contrast        = 0.6;             
  #declare Blockwall_ClipBlock       = 1;
  #declare Blockwall_MatrixSpacing   = 0.02;
  #declare Blockwall_HBias           = 0.3;
  #declare Blockwall_VBias           = 3;  
  #declare Blockwall_MaxHU           = 10;  
  #declare Blockwall_MaxVU           = 5;  
  #declare Blockwall_Finish = finish {phong 0 ambient 0}
  #declare Blockwall_Normal = normal {
    average
    normal_map {
      [0.5  granite 1 scale 0.25]
      [0.5  agate   1 scale 0.05]
      [1.0  marble  1 rotate z*90 turbulence 0.5 scale <0.3,0.1,0.5>]
    
    }
  }
  
  // Call the macro to generate a wall from a spline.
  // The default spline will produce a straight wall with a hump.
  object {Blockwall_FollowSpline("BuffStone")}
 // Add some grass
  plane {y,0 texture {GrassTexture}}

Example=10; A testbed
Example 10 is really more of a testbed than an example. It can be used for developing new styles of block. It contains a couple of camera settings and various optional boxes for aligning blocks.

Example=12; Color Settings
Example 12 renders three sections of blockwork with different color settings (having set the contrast to '0').

   #declare Blockwall_Contrast = 0;
   #declare Blockwall_Radius = 0.5;
   #declare Blockwall_MinColor = <0,0,0>;
   #declare Blockwall_MaxColor = <1,1,1>;
   object {Blockwall("")}
 
   #declare Blockwall_MinColor = <0.4,0.4,0.4>;
   #declare Blockwall_MaxColor = <0.8,0.8,0.8>;
   object {Blockwall("") translate -Blockwall_CentreToCentre*x}
 
   #declare Blockwall_MinColor = <1.0,0.7,0.6>;
   #declare Blockwall_MaxColor = <1.0,0.9,0.7>;
   object {Blockwall("") translate Blockwall_CentreToCentre*x}

The central block shows the full color range with the minimum color (Blockwall_MinColor) specified as <0,0,0> (Black) and the maximum color (Blockwall_MaxColor) as <1,1,1> (White). Because the Red, Blue and Green color components are randomised separately and can each vary between 0 and 1 you can get blocks of any color.

The block on the left shows a reduced colour range with the minimum set to <0.4,0.4,0.4> and the maximum to <0.8,0.8,0.8>. This clips off the brighter and darker extremes, but still allows a significant color variation.

The block on the right adds a buff (yellow/red) biase with the minimum set to <1.0,0.7,0.6> and the maximum to <1.0,0.9,0.7>. With these settings you always get a full red channel, the green component can vary from 0.7 to 0.9 and the blue component from 0.6 to 0.7. The result is a yellow/buff color with a limited degree of variation.

Example=13; Contrast Settings
Example 13 renders three sections of blockwork with different contrast settings using the default maximum and minimum color settings (Blockwall_MinColor=<0.5,0.3,0.3>; Blockwall_MaxColor=<0.55,0.35,0.35>;).

   #declare Blockwall_Radius = 0.5;
   #declare Blockwall_Contrast = 0;
   object {Blockwall("")}
  
   #declare Blockwall_Contrast = 1;
   object {Blockwall("") translate -Blockwall_CentreToCentre*x}
  
   #declare Blockwall_Contrast = 0.5;
   object {Blockwall("") translate Blockwall_CentreToCentre*x}

The central block shows the base color without contrast (Blockwall_Contrast=0).

The left hand block shows a contrast setting of '1'. This permits the colors to be darkened from their base colors all the way down to Black.

The right hand block uses a contrast setting of '0.5', permitting the colors to be darkened half way to black (the default setting).

Example=14; Finish and Normals
Example 14 illustrates the use of the finish and normal settings.

   object {Blockwall("")}
  
   #declare Blockwall_Normal = normal {agate scale <0.001,0.01,0.001>}
   object {Blockwall("") translate -Blockwall_CentreToCentre*x}
  
   #declare Blockwall_Normal = normal {granite scale 0.1}
   #declare Blockwall_Finish = finish {phong 1}
   object {Blockwall("") translate Blockwall_CentreToCentre*x}

The central block uses the default settings which apply a granite normal scaled by 0.1 and no finish (actually a setting of phong 0).

The left hand block uses a normal of agate scaled by <0.001,0.01,0.001> to give a fine grainy normal in the X and Z dimensions, with a more pronounced normal in the Y dimension to emphasize the effect (a deeply pitted surface).

The right hand block uses the granite normal with a phong of 1 to make the surface glisten as it might when wet. You could also add reflection in the finish definition, except that in this sample scene, there's no background to reflect.

Example=15; Three sections with different mortar gaps
Example 15 shows the affect of changing the mortar gap. The central section shows the default mortar gap. The section on the left shows a slightly increased mortar gap. The section on the right shows a more pronounced mortar gap.


  object {Blockwall("")}
  #declare Blockwall_MortarGap = 0.02;
  object {Blockwall("") translate -Blockwall_CentreToCentre*x}
  #declare Blockwall_MortarGap = 0.04;
  object {Blockwall("") translate  Blockwall_CentreToCentre*x}

Example=16; A demonstration of the Blockwall_BlockThicknessDecrement variable.
Example 16 shows how the Blockwall_BlockThicknessDecrement variable can be used to decrease the thickness of the blocks towards the top of the wall.

Four examples are shown, with the default settings on the left and a fairly exaggerated decrement on the right. The outer examples use the Blockwall macro while the inner ones use the Blockwall_FollowSpline macro. You are more likely to need a smaller decrement to produce a more subtle effect. Note that this does not alter the width of the blocks, which is usually ok, but which results in overlaps of interwoven blockwork with sharp corners as can be generated using the Blockwall_FollowArray macro.

  camera {location <0.8,1.25,-2.2> look_at 0.5*y }
  light_source {<0,20,-10>, rgb 1}

  #declare Blockwall_BlockThickness = 0.5;
  object {Blockwall("GreenBrick") rotate -y*90 translate -0.8*x}
  object {Blockwall_FollowSpline("GreenBrick") translate -0.1*x}

  #declare Blockwall_BlockThicknessDecrement = 0.035;
  object {Blockwall_FollowSpline("GreenBrick") translate 0.6*x}
  object {Blockwall("GreenBrick") rotate -y*90 translate 1.3*x}

Example=17; Colored Block Styles
Example 17 illustrates the use of predefined block styles. The block styles are defined using POV-Ray Superellipsoid objects to provide regular blocks with rounded corners. Surface normals are added to the texture definition to make the blocks look a bit rough. The following predefined colors are defined. The 'Blockwall_Block' macro is organised so as to try to make it easy for you to add new predefined color and texture styles if you wish.

   object {Blockwall("RedBrick"  ) translate  <-Blockwall_CentreToCentre,0,1>}
   object {Blockwall("BlueBrick" ) translate  <0,0,1>}
   object {Blockwall("GreenBrick") translate  < Blockwall_CentreToCentre,0,1>}
   object {Blockwall("PinkBrick" ) translate -x*Blockwall_CentreToCentre}
   object {Blockwall("BuffBrick" ) }
   object {Blockwall("GreyBrick" ) translate  x*Blockwall_CentreToCentre}

This example renders six different swatches showing 6 of the predefined color settings that can be specified using the style parameter on the 'Blockwall' macro call.

The styles illustrated in this example are:

  • "RedBrick" (Top Left)
  • "BlueBrick" (Top Centre)
  • "GreenBrick" (Top Right)
  • "PinkBrick" (Bottom Left)
  • "BuffBrick" (Bottom Centre)
  • "GreyBrick" (Bottom Right)

Example=18; Colored Stone Styles
Example 18 illustrates the use of predefined stone styles. The stone styles are defined using POV-Ray Blob objects and incorporate a degree of randomness intended to emulate rough stone. The following predefined colors are defined. The 'Blockwall_Block' macro is organised so as to try to make it easy for you to add new predefined color and texture styles if you wish.

   object {Blockwall("RedStone"  ) translate  <-Blockwall_CentreToCentre,0,1>}
   object {Blockwall("BlueStone" ) translate  <0,0,1>}
   object {Blockwall("GreenStone") translate  < Blockwall_CentreToCentre,0,1>}
   object {Blockwall("PinkStone" ) translate -x*Blockwall_CentreToCentre}
   object {Blockwall("BuffStone" ) }
   object {Blockwall("GreyStone" ) translate  x*Blockwall_CentreToCentre}

This example renders six different swatches showing 6 predefined color settings that can be specified using the style parameter on the 'Blockwall' macro call.

The styles illustrated in this example are:

  • "RedStone" (Top Left)
  • "BlueStone" (Top Centre)
  • "GreenStone" (Top Right)
  • "PinkStone" (Bottom Left)
  • "BuffStone" (Bottom Centre)
  • "GreyStone" (Bottom Right)

Example=19; Further standard style settings
Example 19 renders four different swatches showing alternative predefined styles used with the 'Blockwall' macro call. These styles all define shapes but no color settings, so it picks up whatever color settings you specify before making the macro call or, as in this case, the default color settings if you don't specify anything. The color and size randomisation seeds are reset between macro calls to illustrate how you can generate the same pattern from multiple calls to a Blockwall macro.


  #declare Blockwall_Rows       = 10;
  #declare Blockwall_Radius     = 0.8;   
  #declare Blockwall_ColorSeed  = seed(1);
  #declare Blockwall_SizeSeed   = seed(1);
  object {Blockwall("Pebbles"      ) translate  <-Blockwall_CentreToCentre/2,1,0>}
 
  #declare Blockwall_ColorSeed  = seed(1);
  #declare Blockwall_SizeSeed   = seed(1);
  object {Blockwall("RoughStone"   ) translate  }
 
 
  #declare Blockwall_MortarGap  = 0.015;   
  #declare Blockwall_ColorSeed  = seed(1);
  #declare Blockwall_SizeSeed   = seed(1);
  object {Blockwall("Box"          ) translate -x*Blockwall_CentreToCentre/2}
 
  #declare Blockwall_ColorSeed  = seed(1);
  #declare Blockwall_SizeSeed   = seed(1);
  object {Blockwall("Polygon"      ) translate  x*Blockwall_CentreToCentre/2}

The styles illustrated in this example are:

  • "Pebbles" (Top Left)
  • "RoughStone" (Top Right)
  • "Box" (Bottom Left)
  • "Polygon" (Bottom Right)

The "Pebbles" style uses POV-Ray sphere objects and the "Box" style uses POV-Ray box objects. The "Polygon" style uses POV-Ray polygon objects that are flat (2D) objects which therefore ignore the Blockwall_BlockThickness settings.

Note that, before using the "Box" and "Polygon" styles it is usual (as is done with this example) to increase the mortar gap because the default mortar gap leaves adjacent blocks virtually touching and relies upon the rounding of the front corners of the blocks to create distinct blocks.

Example=20; Adjusting for Different Lighting Levels
Example 20 illustrates the use of the Blockwall_Brightness setting to adjust for alternative lighting levels. Different scene files can use very different lighting levels. The brightness setting helps you to compensate for this.

The image on the left was rendered with the default settings and a single full intensity light source.

The central image shows bleaching caused by color saturation when ten times as much light is added to the scene.

The image on the right uses the same light settings as the central image, but is generated with:

   #declare Blockwall_Brightness = 0.1;
   object {Blockwall("")}

to redress the balance. The 'Blockwall_Brightness' variable is simply used as a multiplication factor for the color when the macro defines the block texture. It can therefore be used to help counteract lighting variations from one scene to another. As in this example, other factors such as the surface normal and finish settings can also influence the results, so this setting cannot necessarily give you a complete and exact match.

Example=21; A circular stone stairwell.
Example 21 declares a circular spline and calls the Blockwall_FollowSpline macro to form a circular stone tower. It adds a couple of straight walls using the Blockwall_Fill macro with the same style of stonework defined. The paving is generated using the Blockwall macro with the same color stone, but using different size and style settings. The remaining elements are standard POV-Ray objects with a CSG object used to build the circular stone staircase inside the tower.

The Blockwall_Wrap variable is set to 1 to generate the tower so that the two ends of the spline are interwoven. To provide deep shadows compatible with a nighttime scene the default ambient finish needs reducing quite significantly. This could be done using a global setting, but is done here for each texture as it provides a degree more control.

The Blockwall_Holes object is declared before the Blockwall_FollowSpline macro call so that the macro can cut individual blocks using corresponding texture settings. It would also have been possible to cut holes in the complete wall object after it had been generated by the macro , but this is usually less efficient and it can be difficult to get an appropriate texture onto the cut surfaces.

  // Declare a circular spline
  #declare Blockwall_Spline = spline {
    cubic_spline
    #local I = -0.25;
    #while (I<=1.25)  
      I, vrotate(1.4*z,-y*I*360)
      #local I = I + 0.01;
    #end
  }
  
  // Set up a very rough stone 
  #declare Blockwall_MinColor        = <0.98,0.65,0.25>;   
  #declare Blockwall_MaxColor        = <1.0 ,0.7 ,0.3>;
  #declare Blockwall_Contrast        = 0.6;             
  #declare Blockwall_ClipBlock       = 1;
  #declare Blockwall_MatrixSpacing   = 0.02;
  #declare Blockwall_HBias           = 0.3;
  #declare Blockwall_VBias           = 3;  
  #declare Blockwall_MaxHU           = 10;  
  #declare Blockwall_MaxVU           = 5;  
  #declare Blockwall_Finish = finish {phong 0 ambient 0}
  #declare Blockwall_Normal = normal {
    average
    normal_map {
      [0.5  granite 1 scale 0.25]
      [0.5  agate   1 scale 0.05]
      [1.0  marble  1 rotate z*90 turbulence 0.5 scale <0.3,0.1,0.5>]
    
    }
  }

  // Create a circular wall
  #declare Blockwall_Wrap = 1;  
  #declare Blockwall_WallHeight = 5;
  #declare Blockwall_Holes = union {
    box {<-0.401,0.099,-1.41><0.401,1.4,-1>}
    cylinder {<0,1.4,-1.41><0,1.4,-1>,0.4}
    translate 2*y
  }
   
  object {Blockwall_FollowSpline("GreyStone") translate -2*y} 
  
  // Add a little bridge
  object {Blockwall_Fill(< 0.55,0,-4>,< 0.8,1,-1.3>,"GreyStone")}
  object {Blockwall_Fill(<-0.6,0,-4>,<-0.9,0.6,-1.3>,"GreyStone")}

  // Paving. To use as paving, we can use a matching horizontal and 
  // vertical bias for the pattern and rotate the 'wall' to be horizontal. 
  Blockwall_Undef()
  #declare Blockwall_WallLength = 1.2;
  #declare Blockwall_WallHeight = 3;
  #declare Blockwall_MatrixSpacing   = 0.1;
  #declare Blockwall_HBias           = 2;
  #declare Blockwall_VBias           = 2;  
  #declare Blockwall_MaxHU           = 5;  
  #declare Blockwall_MaxVU           = 5;  
  #declare Blockwall_Finish = finish {ambient 0.001};
  difference {
    object {Blockwall("GreyBrick") rotate x*90 translate <-0.6,0,-4>}
    cylinder {-0.5*y,0.1*y,1.4}
  }

Example=22; A stone well
Example 22 provides a simple scene illustrating the use of the Blockwall_FollowSpline macro to generate a circular wall to represent a stone well. Standard CSG objects are used to add simple winding gear and a roof (see the 'blockwall.pov' file for details).

  // Declare a circular spline
  #declare Blockwall_Spline = spline {
    cubic_spline
    #local I = -0.25;
    #while (I<=1.25)  
      I, vrotate(0.6*z,-y*I*360)
      #local I = I + 0.01;
    #end
  }
  
  // Set up a very rough stone 
  #declare Blockwall_Contrast        = 0.8;             
  #declare Blockwall_ClipBlock       = 1;
  #declare Blockwall_MatrixSpacing   = 0.05;
  #declare Blockwall_HBias           = 0.3;
  #declare Blockwall_VBias           = 3;  
  #declare Blockwall_MaxHU           = 3;  
  #declare Blockwall_MaxVU           = 2; 
  #declare Blockwall_Finish = finish{ambient 0.01} 

  // Create a circular wall
  #declare Blockwall_Wrap = 1;  
  #declare Blockwall_WallHeight = 0.6;
  #declare Blockwall_BlockThickness = 0.18;
  #declare Blockwall_Holes = union {
    box {<-0.401,0.099,-1.41><0.401,1.4,-1>}
    cylinder {<0,1.4,-1.41><0,1.4,-1>,0.4}
    translate 2*y
  }
   
  object {Blockwall_FollowSpline("BuffBrick")}  

Example=23; A Fireplace
Example 23 uses the Blockwall_Fill macro to generate a stone fireplace and surround. The Blockwall_Holes object is defined before calling the Blockwall_Fill macro to create the gap for the fire and for the lintel. The lintel is defined as a single block and serves to illustrate how to call the Blockwall_Block macro directly (a macro that is more often called indirectly via one of the other Blockwall macros).

  global_settings {ambient_light 0.2}
  
  // Declare the holes to cut
  #declare Blockwall_Holes = union {
    box {<-0.251,-0.01 ,-0.01><0.251,0.501,0.301>}
    box {<-0.351, 0.499,-0.01><0.351,0.601,0.301>}
  }

  // Generate the masonry
  #declare Blockwall_MatrixSpacing = 0.05;
  object {Blockwall_Fill(<-0.6,0,0>,<0.6,0.8,0.3>,"BlueBrick")}  
  
  // Lintel
  Blockwall_Block(
    <-0.35, 0.6,0>,
    <0.35,0.6,0.0>,
    <0.35,0.5,0.0>,
    <-0.35, 0.5,0>,
    "GreyBrick"
  )

  // Surround 
  #undef Blockwall_Holes
  object {Blockwall_Fill(<-0.65,0,0>,<0.65,0.5,0.05>,"RedBrick")
    rotate x*90
    translate -z*0.2
  }  

  // Mantlepiece
  box {<-0.63,0.8,-0.03><0.63,0.83,0.33>
    pigment {wood scale 0.01 turbulence 0.4 rotate y*90}
  }
  
  // Mortar
  difference {
    box {<-0.59,0,0.011>,<0.59,0.8,0.29>}
    box {<-0.26,-0.01 ,-0.01><0.26,0.51,0.29>}
    texture {
      pigment {rgb 0.3}
      normal {agate scale 0.01}
    }
  }

Example=24; A Bridge
Example 24 uses several macros, but mostly the Blockwall_FollowSpline macro to generate the bridge shape illustrated below. The bridge is centred on the origin using a scale of 1 POV-Ray unit to represent 1 metre. It is oriented so that the road runs along the Z-axis for about 15 units in either direction.

The bridge is 'built' around a shape created using the POV-Ray blob object. This blob object is also used to cut the dip that the stream occupies. You can change the strengths of these blobs a little to adjust the shape of the bridge and the depth of the stream. The blob uses a long central cylindrical core and four negative strength cylindrical components to squash the front and back edges into two cusps. This leaves a rounded hump in the middle that the road goes over and a rounded dip in the middle used to cut the river valley. This object is not itself displayed in the scene but is simply used to define the main shapes.

Click for larger image The default image (right) uses a setting of 0.5 for the Blockwall_MatrixSpacing setting and was rendered at 640x480 (No AA) using a distant camera. These factors in combination took just 4 seconds to render on a 2 Quad 2.4GHz machine, using POV-Ray 3.7 Beta 27 (click the image to see it full-size). The example in the 'blockwall.pov' file contains an alternative camera setting for the close-up shot (shown below the code sample) where the Blockwall_MatrixSpacing variable is set to 0.05. This provides a high block density giving a very detailed bridge, but is slow to render, taking about 5 minutes at 800x600 (AA 0.3) on the above machine. Using a relatively high value for Blockwall_MatrixSpacing reduces the parse time very significantly.

The blob object also contains three cylindrical components that are used upstream and downstream of the bridge to disrupt the straightness of the river. One of these shoots off at 30 degrees upstream to represent a tributary joining the main body of water.

A spline is dropped onto the top surface of the blob object using the Blockwall_DropSplineToSurface macro to create a spline that defines a line across the top of the bridge. The sides of the bridge are defined using the Blockwall_FollowSpline macro with this spline. Before calling this macro an object named Blockwall_Holes is defined and is consequently used by the macro to cut out the overall shape of the bridge and the shape of the arches beneath it.

Strong rectangular walls are added to support the arches using the Blockwall_Fill macro. The 3 arches are added using the Blockwall_Arc macro (which itself calls the Blockwall_FollowSpline macro) to create semi-circular walls that are rotated to the vertical and translated into position.

The kurb and the walls along the roadside on top of the bridge use the Blockwall_FollowSpline macro, following the spline that was dropped onto the top of the blob object. The kurb stones protrude through the outer surfaces of the bridge walls to cap the horizontally coursed main body of the bridge.


  // Declare a line for the bridge to follow.
  #declare BridgeLineSpline = spline {
    cubic_spline 
    -0.25, < 15 ,10,-20  >
     0,    < 5  ,10,-15  >
     0.25, < 0.4,10, -7.5>
     0.5 , < 0  ,10,  0  >
     0.75, <-0.4,10,  7.5>
     1,    <-2  ,10, 15  >
     1.25, <-8  ,10, 20  >
  } 
  
  // Create a big long blobby object the shape of the top of the bridge 
  // and the indentation in the ground.
  #declare RiverCutting = blob { threshold 0.6 
    // Use a strong cylindrical core with 4 negative corner cylinders 
    // to compress the edges into cusps 
    cylinder{<-1000,0,0>, <1000,0,0>, 4  ,  1.5 scale <1,1,5> } 
    cylinder{<-1000,0,0>, <1000,0,0>, 2.5, -1   scale <1,1,3> translate <0, 2,7.5>} 
    cylinder{<-1000,0,0>, <1000,0,0>, 2.5, -1   scale <1,1,3> translate <0,-2,7.5>} 
    cylinder{<-1000,0,0>, <1000,0,0>, 2.5, -1   scale <1,1,3> translate <0, 2,-7.5>} 
    cylinder{<-1000,0,0>, <1000,0,0>, 2.5, -1   scale <1,1,3> translate <0,-2,-7.5>}
    // Add some components to break up the straight lines upstream and 
    // downstream of the bridge
    cylinder{<-1000,0,0>, <-3,0,0>, 2.5, 0.5
      scale <1,1,4> rotate <0,  3,-1> translate <  0,0,-1.5>
    }
    cylinder{<-1000,0,0>, < 3,0,0>, 4.5, 2
      scale <1,1,1> rotate <0,-30, 0> translate <-10,0, 0  >
    }
    cylinder{< 1000,0,0>, < 3,0,0>, 2.5, 1
      scale <1,1,3> rotate <0, -3, 3> translate <  4,0,-1.5>
    }
    scale <1,1,1.4>
  }
  
  // Declare an object that the Blockwall_FollowSpline macro can use to cut the 
  // bridge shape out of.
  // This includes arch holes and the top and bottom surfaces. 
  #declare Blockwall_Holes = union {
    box {<-2.5,-4,-5.15><2.5,-0.5,-2.45>}
    box {<-2.5,-4,-1.95><2.5,-0.5, 1.95>}
    box {<-2.5,-4, 5.15><2.5,-0.5, 2.45>}
    cylinder {<-2.5,-0.5,-3.8><2.5,-0.5,-3.8>,1.35}
    cylinder {<-2.5,-0.5, 0  ><2.5,-0.5, 0  >,1.95}
    cylinder {<-2.5,-0.5, 3.8><2.5,-0.5, 3.8>,1.35} 
    object {RiverCutting inverse translate -y*0.5} 
  }
  
  // Create the main body of the bridge (with holes)
  #declare Blockwall_Finish = finish {ambient 0.01}
  #declare Blockwall_MatrixSpacing   = MatrixSpacing;
  #declare Blockwall_WallHeight      = 6.75;
  #declare Blockwall_BlockThickness  = 0.4;
  // Create a spline that tracks along the bottom of the bridge
  #declare Blockwall_Target = plane {y,-4}
  #declare Blockwall_Spline = BridgeLineSpline;
  Blockwall_DropSplineToSurface() 
  object {Blockwall_FollowSpline("BuffStone") translate -1.8*x}
  object {Blockwall_FollowSpline("BuffStone") translate  2.3*x}

  // Add thick walls to support the arches
  Blockwall_Undef()
  #declare Blockwall_Finish = finish {ambient 0.01}
  #declare Blockwall_MatrixSpacing   = MatrixSpacing;
  Blockwall_Fill(<-2.4,-2.2,-5.45><2.4,-0.5,-4.95>,"BuffBrick")
  Blockwall_Fill(<-2.4,-3.0,-1.75><2.4,-0.5,-2.65>,"BuffBrick")
  Blockwall_Fill(<-2.4,-3.0, 1.75><2.4,-0.5, 2.65>,"BuffBrick")
  Blockwall_Fill(<-2.4,-2.2, 5.45><2.4,-0.5, 4.95>,"BuffBrick")
  
  // Insert the three arches
  Blockwall_Undef()
  #declare Blockwall_MatrixSpacing   = MatrixSpacing;
  #declare Blockwall_WallHeight      = 4.8;
  #declare Blockwall_Radius          = 1.15;
  #declare Blockwall_Finish = finish {ambient 0.01}
  object {Blockwall_Arc(180,"BuffBrick")
    rotate z*90 translate <2.4,-0.5,-3.80>
  }
  object {Blockwall_Arc(180,"BuffBrick")
    rotate z*90 translate <2.4,-0.5,3.80>
  }  
  #declare Blockwall_Radius          = 1.75;
  object {Blockwall_Arc(180,"BuffBrick")
    rotate z*90 translate <2.4,-0.5,0>
  }  

  // Reset control variables so we can use the defaults for the next type of wall
  Blockwall_Undef()

  // Create a spline that tracks along the top of the bridge
  #declare Blockwall_Target = object {RiverCutting translate -y*0.5}
  #declare Blockwall_Spline = BridgeLineSpline;
  Blockwall_DropSplineToSurface() 

  // Add Roadside Walls 
  #declare Blockwall_MatrixSpacing   = MatrixSpacing*1.2;
  #declare Blockwall_BlockThickness  = 0.3;
  #declare Blockwall_Finish          = finish {ambient 0.01}
  object {Blockwall_FollowSpline("BuffBrick") translate <-2.0,0.17,0>}
  object {Blockwall_FollowSpline("BuffBrick") translate < 2.3,0.17,0>}

  // Add kurbstones along the edges of the road and out through the bridge parapet
  #declare Blockwall_WallHeight      = 0.2;  
  #declare Blockwall_BlockThickness  = 0.5;  
  object {Blockwall_FollowSpline("BuffBrick") translate <-1.9,-0.02,0>}
  object {Blockwall_FollowSpline("BuffBrick") translate < 2.4,-0.02,0>}

Return to Table of Contents


Macros

The following macros are all contained in the 'blockwall.inc' file:

Blockwall macro
You can call the Blockwall macro to create a single, straight section of block walling. The functionality is controlled through a series of variables, each of which has a default value, so you can generate the default section of paving with the following code:
 camera {orthographic location <0,2.8,1.74> look_at 1.75*z }
 light_source {<-10,20,-5>, rgb 1}
 #include "blockwall.inc"
 Blockwall("")

This creates a 1 metre square and 8cm thick section of wall (where 1 POV-Ray unit = 1 metre) with its bottom left corner at the origin. You can use variables such as Blockwall_WallHeight, Blockwall_WallLength, Blockwall_BlockThickness and Blockwall_MortarGap to control the dimensions. For example:

 #include "blockwall.inc"
 #declare Blockwall_WallHeight = 2;
 #declare Blockwall_WallLength = 5;
 Blockwall("")

Other variables enable you to control the color, finish, surface normal and the maximum sizes and distribution of different sized blocks throughout the wall. You can also adjust the seed streams used for the randomisation of color and block size, so that, if a particular random pattern causes you problems, you can just use a different one (see Blockwall_ColorSeed and Blockwall_SizeSeed).

The Blockwall_Block macro has 1 parameter:
Blockwall_BlockType A string that can be used to specify a predefined block type (e.g. specific color settings or the object type to be generated). Pass an empty string into the macro ("") to use default settings or to use settings that you set inline within your code. The following set styles can be specified:
  • "RedBrick"
  • "BlueBrick"
  • "GreenBrick"
  • "PinkBrick"
  • "BuffBrick"
  • "GreyBrick"
  • "RoughStone"
  • "RedStone"
  • "BlueStone"
  • "GreenStone"
  • "PinkStone"
  • "BuffStone"
  • "GreyStone"
  • "Pebbles"
  • "Polygon"
  • "Box"
  • "Superellipsoid"
See example 17, example 18 and example 19 above for illustrations of these style settings.

Blockwall_Fill macro
You can call the Blockwall_Fill macro to create a single, straight section of block walling based on two vectors that delimit the extents of the wall, passed as parameters into the macro. This is an alternative to setting variables to define the size of the wall with the Blockwall macro.

This macro fills the area delimited by the minimum extent vector and a maximum extent vector with block walling. The wall is oriented so that the thinest horizontal dimension (X or Z) is used for the block thickness and the larger horizontal dimension is used as the wall length. The box used is aligned to the X, Y and Z axes but you can readily transform the returned object by wrapping the macro call inside an 'object' statement.

You can generate the default block wall with the following code:

 #include "blockwall.inc"
 Blockwall_Fill(<0,0,0>,<2,1,0.3>,"")

The functionality is still controlled through the same variables as the Blockwall macro, except that the dimensions specified in the parameters override any previous size settings.

The Blockwall_Fill macro has 3 parameters:
Blockwall_MinExtents A 3D coordinate vector specifying the bottom left corner of the wall. See example 2 for an illustration of this setting.
BlockwallMaxExtents A 3D coordinate vector specifying the top right corner of the wall. See example 2 for an illustration of this setting.
Blockwall_BlockType A string specifying a predefined style to use or an empty string ("") to not use a predefined style. See the Blockwall macro for a list of valid settings for this parameter .

Blockwall_Shell macro
You can call the Blockwall_Shell macro to wrap a wall around the perimeter of a box defined using the minimum and maximum extent vectors supplied as parameters to the macro call. This creates a form similar to the shell of a simple rectangular building inside a box aligned to the X, Y and Z axes. The macros functionality is controlled through a series of variables, each of which has a default value.

You can generate a shell wall with the following code:


  Blockwall_Shell(<-2,0,0>, <2,2.3,5>, "")

This gives you a wall structure that could be used as the outer shell of a building. These parameters generate a 4 unit wide, 2.3 unit high and 5 unit long rectangular wall centred on the +Z axis.

The Blockwall_Shell macro has 3 parameters:
Blockwall_MinExtents A 3D coordinate vector specifying the bottom left corner of the box. See example 6 for an illustration of this setting.
BlockwallMaxExtents A 3D coordinate vector specifying the top right corner of the box. See example 6 for an illustration of this setting.
Blockwall_BlockType A string specifying a predefined style to use or an empty string ("") to not use a predefined style. See the Blockwall macro for a list of valid settings for this parameter.

Blockwall_FollowArray macro
You can call the Blockwall_FollowArray macro to create a multi-segment wall comprising a series of connected, straight sections where the bottom front edge of the wall follows the 2D coordinate vectors specified in the Blockwall_CornerArray array. Only the X and Z coordinates need to be specified. The wall will sit on the XZ plane (ie at y=0). If the Blockwall_CornerArray array is not defined when the Blockwall_FollowArray macro is called then a default array will be created that describes a 1 unit square that will be delimited by the wall.

If the first and last point in the Blockwall_CornerArray array are the same the ends of the block wall will be interwoven. Otherwise the ends blocks at each of the two ends of the wall will be vertically aligned.

The functionality of this macro is controlled through a series of variables, each of which has a default value. You can generate the default block wall with the following code:


  Blockwall_FollowArray("")

See Example 8 for a slightly more complex example.

The Blockwall_FollowArray macro has 1 parameter:
Blockwall_BlockType A string specifying a predefined style to use or an empty string ("") to not use a predefined style. See the Blockwall macro for a list of valid settings for this parameter.

Blockwall_Arc macro
You can call the Blockwall_Arc macro to create a block wall that follows a circular path. This can either be a complete circle of 360 degrees, or an arc of a lesser number of degrees. The arc starts at the radius as defined using the variable Blockwall_Radius, which defaults to 1 POV-Ray unit (representing a radius of 1 metre) in the +Z direction. If a complete circle is produced (within 0.01 units) then the default value for Blockwall_Wrap is set to 1 to interleave the ends, otherwise the default for Blockwall_Wrap is 0 resulting in square cut ends. You can set Blockwall_Wrap before calling the macro to override the default behaviour.

If a positive value is specified for the number of degrees, the wall is drawn clockwise and the inner face follows the line described by the radius as it is rotated around the origin. In this case the outer face will contain wider mortar gaps as the blocks fan out. If a negative value is given for the number of degrees, the wall is drawn anticlockwise and the outer face follows the line described by the radius rotated around the origin. This results in a smaller wall where the mortar gap on the inner face is reduced, possibly resulting in some overlap of the blockwork on the inner face.

You can rotate and translate the results as required. Example 24 illustrates the use of this macro to generate arches under a bridge. Example 22 use this macro to generate the circular wall for a well.

Most of the functionality is controlled through a series of variables, each of which has a default value, so you can generate the default circular block wall with the following code:


  Blockwall_Arc(360, "")

This creates a circular (cylindrical) wall with an internal radius of 1 metre.

The Blockwall_Arc macro has 2 parameters:
Blockwall_ArcDegrees A decimal value used to specify the number of degrees of arc. Valid values are in the range -360 to 360. A positive value draws a clockwise arc with the dressed face on the inside. A negative value draws an anticlockwise arc with the dressed face on the outside.
Blockwall_BlockType A string specifying a predefined style to use, or an empty string ("") to not use a predefined style. See the Blockwall macro for a list of valid settings for this parameter.

Blockwall_FollowSpline macro
You can call the Blockwall_FollowSpline macro to create a wall that follows a spline. The front face of the base of the spline will follow the 3D spline assigned to the identifier Blockwall_Spline. If this identifier is not set the Blockwall_FollowSpline will define a default spline that creates a hump-baked bridge parapet as illustrated in Example 3.

It is usual to specify a curved spline rather than a linear spline as corners resulting from a linear spline will not interlace properly. To create a series of straight sections where the base of the wall is level you can use the Blockwall_FollowArray macro which should handle the corners better. The functionality of this macro is controlled through a series of variables, each of which has a default value, so you can generate the default block wall with the following code:


  Blockwall_FollowSpline("")

This macro can also be used in conjunction with the Blockwall_DropSplineToSurface macro to draw a wall that follows the contours of a surface as as illustrated in Example 4.

The Blockwall_FollowSpline macro has 1 parameter:
Blockwall_BlockType A string specifying a predefined style to use or an empty string ("") to not use a predefined style. See the Blockwall macro for a list of valid settings for this parameter.

Blockwall_DropSplineToSurface macro
You can call the Blockwall_DropSplineToSurface macro to drop the spline assigned to identifier Blockwall_Spline onto the surface of the target object assigned to the identifier Blockwall_Target. For example:

  Blockwall_DropSplineToSurface()

Example 4 illustrates the use of this macro in conjunction with the Blockwall_FollowSpline macro to create a wall that follows the contours of an object.

The Blockwall_DropSplineToSurface macro has 0 parameters:

Blockwall_Block macro
The Blockwall_Block macro is used to create an individual block based upon the specified settings. This macro is called repeatedly by the other Blockwall macros to draw each of the blocks that go to make up a section of blockwork.

You won't normally need to invoke this macro directly, it is called indirectly by the other Blockwall macros. However, you can if you wish to generate individual blocks.

The Blockwall_Block macro can easily be tailored to add more 'predefined' colors or shapes to those supplied. You can do this by adding a new '#case' clause to one of the two '#switch' statements. This usually only involves adding a couple of lines using basic coding elements, such as declarations of colors etc. and subsequently enables you to refer to your new style of block by name whenever you wish to use it in the future.

The Blockwall_Block macro has 5 parameters:
Blockwall_TopLeft A 3D vector defining the coordinates of the top left corner of the space into which this block needs to fit.
Blockwall_TopRight A 3D vector defining the coordinates of the top right corner of the space into which this block needs to fit.
Blockwall_BottomRight A 3D vector defining the coordinates of the bottom right corner of the space into which this block needs to fit.
Blockwall_BottomLeft A 3D vector defining the coordinates of the bottom left corner of the space into which this block needs to fit.
Blockwall_BlockType A string that can be used to specify a predefined block type (e.g. specific color settings or the object type to be generated). Pass an empty string into the macro ("") to use default settings. See example 17, example 18 and example 19 above for illustrations of the available style settings.

Blockwall_BlobBlock macro
This macro is called by the Blockwall_Block macro when a block type parameter of "RoughStone" is used with one of the Blockwall macros. This macro adds blob components together to create a rough stone shape of the block size required. By default the shape can extend slightly beyond the limits specified, but the Blockwall_ClipBlock variable can be used to clip the edges so that the shape is clipped to size, giving partially flat faces to the blocks. For example:

  Blockwall_BlobBlock(2, 3)

Returns a blob object that is 2 units wide by 3 units high. Blocks dimensions are defined as integer numbers of units. This macro contains dedicated code to generate smaller blocks and more generic code for categories of larger blocks. If you permit very large blocks e.g. 6x5 you may find that the generic code does a poor job. If this is a problem you can fairly simply add a #case statement to this macro to handle a particular new block size or new categories of block sizes with just a few lines of SDL.

Each block consists of a core formed using 3 squashed spherical components plus 8 spherical corner components that draw the shape out into a more rectangular shape.

The Blockwall_BlobBlock macro has 2 parameters:
Blockwall_BlockUnits_X An integer value used to specify the number of horizontal units occupied by this block.
Blockwall_BlockUnits_Y An integer value used to specify the number of vertical units occupied by this block.

Blockwall_CoreBlob macro
This macro is called by the Blockwall_Block macro when you use the "Roughstone" block style. This macro is called 3 times per block to add 3 large blobs to form the core of the block. You won't need to call this macro unless you are adjusting the blob definitions used for the "Roughstone" block style. Typical values passed to this macro could look something like this:
  Blockwall_CoreBlob(
    Blockwall_CoreBlobRadius,
    Blockwall_CoreStrength,
    Blockwall_CoreScale,
    Blockwall_CoreHeight
  )

The Blockwall_CoreBlob macro has 4 parameters:
Blockwall_CoreBlobRadius A decimal value used to define the radius of a sphere component of a blob.
Blockwall_CoreStrength A decimal value used to define the strength of a sphere component of a blob.
Blockwall_CoreScale A 3D vector used to define a scale factor for this sphere component.
Blockwall_CoreHeight A decimal value used to define the height at which this blob component is to be located. The value is relative to the centre of the blob.

Blockwall_CornerBlobs macro
This macro is called by the Blockwall_Block macro to add 8 corner blobs to a block core. You won't need to call this macro unless you are adjusting the blob definitions used for the "Roughstone" block style. Typical values passed to this macro could look something like this:

  Blockwall_CornerBlobs(0.8, 0.3, <0.55,0.55,0.55>, 1)

The Blockwall_CornerBlobs macro has 4 parameters:
Blockwall_CornerBlobRadius A decimal value specifying the radius of each of the corner blob components.
Blockwall_CornerStrength A decimal value specifying the strength of each of the corner blob components.
Blockwall_CornerPosition A 3D vector specifying how far out from the centre in the x, y and z directions each of the corner blob components is to be positioned.
Blockwall_CornerDepth A decimal scale value used to scale each corner blob in the z dimension. A value of 1 produces no scaling. Increasing the value causes each of the corner blob components to have more influence deeper into the blocks. Reducing it constrains the influence of the corner blocks more to the front and back surfaces.

Blockwall_AdjustCorner macro
This macro is called by the Blockwall_FollowArray macro against the matrix that stores the blockwork pattern to adjust blocksizes at the corner positions so that they don't overlap the corners. It adjusts the matrix so that there is a mortar gap either to the left or right of each corner stone for a specified corner position. It follows a line up the matrix and, if there is no suitable junction it creates one by shortening blocks so that the matrix can fold along the required line. For example:

  Blockwall_AdjustCorner(12)

Follows the matrix up at column 12 so that it can fold cleanly after column 11.

The Blockwall_AdjustCorner macro has 1 parameter:
Blockwall_MatrixIndex An integer value that specifies the column in the matrix that will form the first column on a straight section of walling following a corner. This value must be within the horizontal matrix dimension and can't point to the last column or a parse error will occur.

Blockwall_MakeMatrix macro
You can call this macro to generate a randomised blockwork pattern. This macro defines and populates a matrix that describes the positions and sizes of a series of blocks. The start position of each block corresponds to one of the grid positions in the matrix. The X and Y dimensions of a block are randomly generated but are always whole numbers of grid positions and meet a certain set of user defined criteria which control the relative distribution of large and small blocks.

The functionality of this macro is controlled through a series of variables. Blockwall_MatrixDimX and Blockwall_MatrixDimY control the number of units in the horizontal and vertical dimensions of the matrix. The Blockwall_MaxHU and Blockwall_MaxVU settings define maximum block sizes in terms of horizontal and vertical units. The Blockwall_HBias and Blockwall_VBias variables control the proportion of blocks that will be large in a given dimension.

Each of these variables has a default value, so you can generate the default block wall with the following code:


  Blockwall_MakeMatrix()

The Blockwall_MakeMatrix macro has no parameters:

Blockwall_Undef macro
The Blockwall_Undef macro can be used to undefine all of the key control variables between calls to the 'Blockwall' macro. This is often not necessary, but can be useful if you have set a lot of control variables for one call and you want to return most of those settings to their default values the next time the 'Blockwall' macro is called. This can also be useful if you are using named block types as it avoids you having to work out which variables were set during the first call. By undefining them all between macro calls you can avoid that the settings for one predefined block type interfere with the next.

The Blockwall_Undef macro has no parameters:

Return to Table of Contents


Control Variables

The following variables are used to control the operation of the 'Blockwall' macros. Each has a default setting, so you only need to specify settings that you wish to override.
VariableDescription
Blockwall_MortarGap Decimal value used by the Blockwall_Block macro to control the average space between blocks. The generated blocks are defined to fit into the space calculated using the Blockwall_BlockThicness setting with half this gap all around them. The default value is 0.0001 which represents 0.01mm to produce blocks that butt right up against each other. Because the Superellipsoid shape is usually used to generate rounded blocks, the space available for mortar will actually appear to be substantially larger. If you use the "Box" or "Polygon" shapes you should increase this value to about 0.01 to give a 1cm gap because these shapes don't have rounded edges (see example 18).

The general default is set in the Blockwall_Block macro. The Blockwall_FollowArray macro also sets the same default value because it uses the value in its calculations and therefore needs a value to avoid errors.

Blockwall_BlockThickness Decimal value used by the Blockwall_Block macro to control the Block Thickness. The general default value is 0.08 POV-Ray units and is intended to represent an 8 centimetre thick block except that:
  • The Blockwall_FollowArray macro declares a default value based upon the values of the Blockwall_MatrixSpacing and Blockwall_MortarGap variables to attempt to construct decent corners.
  • The Blockwall_FollowSpline macro sets a default of 0.25 POV-Ray units and is intended to represent a thickness of 25 centimetres as this is likely to be more suitable for the sort of walls that this macro generates.
Blockwall_BlockThicknessDecrement Decimal value used by the Blockwall macros to control the Block Thickness Decrement measured in metres. The default value is 0 POV-Ray units and leaves the block thickness constant through the height of the wall. Using a value of 0.01 decreases the block thickness by 1cm for each layer of blocks, where a layer is defined as the setting of Blockwall_MatrixSpacing. If you have a 1m high wall of 10 courses a decrement of 0.01 will make the top block 10cm thinner than the bottom block.

See example 16 for an illustration of this setting.

Blockwall_BlockRoundness Decimal value between 0 and 1 used by the Blockwall_Block macro to control the roundness of the blocks when using the Superellipsoid object, which is used to create all of the colored brick objects and is the default shape. The default value is 0.2 which produces a superellipsoid block with a distinctly rounded edge. A value of 0 gives square edges and 1 makes the blocks spherical.
Blockwall_MinColor 3D RGB color vector used by the Blockwall_Block macro to control the selection of colors. This vector provides the minimum red, green and blue values. The default value is <0.7,0.4,0.4> which makes the minimum color mostly red. Each color element is generated independently, so a minimum of <0,0,0> with a maximum of <1,1,1> will permit any valid color to be selected. See example 12 for an illustration of this setting.
Blockwall_MaxColor 3D RGB color vector used by the Blockwall_Block macro to control the selection of colors. This vector provides the maximum red, green and blue values. The default value is <0.9,0.45,0.45> which makes the maximum color a fairly bright red. Each color element is generated independently, so a minimum of <0,0,0> with a maximum of <1,1,1> will permit any valid color to be selected.See example 12 for an illustration of this setting.
Blockwall_Contrast Decimal value between 0 and 1 used by the Blockwall_Block macro to control the degree by which randomly selected colors can be randomnly darkened. The default value is 0.8 which results in each generated color value being multiplied by a random factor between 1 and 0.2. A setting of 0 results in the colors being within the range specified using Blockwall_MinColor and Blockwall_MaxColor. A setting of 1 means that randomly selected blocks could be darkened all the way down to black.

Most real blockwork consists of a base color range with some blocks being a darker version of that same limited range. This setting allows that sort of control to be applied. See example 13 for an illustration of this setting.

Blockwall_Brightness Decimal value used by the Blockwall_Block macro to control the overall brightness of the block texture. The default value of 1 doesn't adjust the colors at all.

This setting is designed to accommodate the hugely different lighting settings used in POV-Ray scene files. Some people use a lot of light and dim colors. Others use low light levels and bright colors. The default settings and most of the examples use a single, full light source. If your scene uses more light you can reduce this value. If you use less light in your scene you can increase this value. See example 20, which uses a light source that is 10 times brighter, setting this value to 0.1 to compensate and avoid color saturation artifacts.

Blockwall_ClipBlock Integer value used by the Blockwall_Block macro when the "RoughStone" block type is specified to control whether or not a block made up of blobs is clipped so that it fits completely within the block size specified. The default value is 0 which permits the blocks to overlap the edges of the theoretical container. A value of 1 cuts off the overlaps leaving a partially flat surface on the face of any block that extends beyond the container.
Blockwall_Normal A normal definition used by the Blockwall_Block macro to define the normal component of a texture used for the blocks. The default normal averages a granite and an agate normal. See example 14, which demonstrates how to override this default by specifying an agate normal for the blocks on the left.
Blockwall_Finish A finish definition used by the Blockwall_Block macro to define the finish component of a texture used for the blocks. The default finish uses a small amount of specular and a little roughness. See example 14, which demonstrates how to override this default by specifying a phong setting of 1 for the blocks on the right.

Adding phong or reflection to the finish setting can provide a simple way of emulating wet blocks.

Blockwall_CornerDepth Integer value used by the Blockwall_BlobBlock macro to control the depth of the blobs (the Z dimension) used to influence the shape of the corners of blocks created using the blob object. This object is only used if the "RoughStone" block style is used. None of the other object types use this setting. The default value is 1 which results in no scaling of the depth of the corner blobs. A value of 0.5 scales in Z by 0.5 reducing the influence of the corner blobs back through the depth of the block.
Blockwall_MatrixArray An array with 3 dimensions populated by the Blockwall_MakeMatrix macro with a randomized blockwork pattern and used by the other Blockwall macros to construct a wall. You should not normally need to manipulate this array directly. The only macro that alters this array once it's been defined is the Blockwall_AdjustCorner macro which adjusts block sized along a specified vertical line so that the blocks will fold neatly around corners.

The first two dimensions are used to index a location in the matrix. The third dimension stores two values. The first value is used to store the number of horizontal units occupied by a block starting with its bottom left corner at that location, or 0 if no block starts here. The second dimension is used to store the number of vertical units occupied by a block starting with its bottom left corner at the location. If the second dimension is not set by the Blockwall_MakeMatrix macro then that position is inside a block.

Blockwall_MatrixDimX Integer value used by the Blockwall_MakeMatrix macro to define the X dimension of the matrix used to construct a blockwork pattern. The Blockwall_MakeMatrix sets a default value of 50 POV-Ray units, but this default value is seldom used as the Blockwall macros generally explicitly define this value. For example, the Blockwall macro defines this value as floor(max(1,Blockwall_WallLength/Blockwall_MatrixSpacing+0.5)) to derive the whole number of blockwork units that will fit into the required wall length.
Blockwall_MatrixDimY Integer value used by the Blockwall_MakeMatrix macro to define the Y dimension of the matrix used to construct a blockwork pattern. The Blockwall_MakeMatrix sets a default value of 40 POV-Ray units, but this default value is seldom used as the Blockwall macros generally explicitly define this value. For example, the Blockwall macro defines this value as floor(max(1,Blockwall_WallHeight/Blockwall_MatrixSpacing+0.5)) to derive the whole number of blockwork units that will fit into the required wall height.
Blockwall_HBias Decimal value used by the Blockwall_MakeMatrix macro to control the Horizontal Bias when selecting randomised block sizes. If the same number of big and small blocks are selected then the larger blocks tend to overwhelm the smaller blocks as they occupy a far greater surface area in the pattern. This variable allows you to influence the blocksize selection to create more blocks with a smaller horizontal dimension. This value is used as an exponent on the random decimal fraction used to select the number of horizontal units used for the block dimensions. Increasing the value of this exponent increases the number of smaller values generated.

The default value is 2.5. A value of 1 would create a uniform distribution of small and large values. A value of 30 produces the occasional large block.

Blockwall_VBias Decimal value used by the Blockwall_MakeMatrix macro to control the Vertical Bias when selecting randomised block sizes. If the same number of big and small blocks are selected then the larger blocks tend to overwhelm the smaller blocks as they occupy a far greater surface area in the pattern. This variable allows you to influence the blocksize selection to create more blocks with a smaller vertical dimension. This value is used as an exponent on the random decimal fraction used to select the number of horizontal units used for the block dimensions. Increasing the value of this exponent increases the number of smaller values generated.

The default value is 3. A value of 1 would create a uniform distribution of small and large values. A value of 30 produces the occasional large block. To get a wall made mainly of long low blocks you can increase this value and use a low value for Blockwall_HBias.

Blockwall_MaxHU Integer value used by the Blockwall_MakeMatrix macro to limit the number of horizontal units that a block can occupy. The default value is 5.
Blockwall_MaxVU Integer value used by the Blockwall_MakeMatrix macro to limit the number of vertical units that a block can occupy. The default value is 3. If Blockwall_MaxHU is set to 5 then the largest block you can get in a pattern will be 5x3, but a particular random pattern may not contain any blocks that big.
Blockwall_MatrixSpacing Decimal value used by the various Blockwall macros to control the Matrix Spacing (the distance from a one unit cell to the adjacent cell). The default value is 0.1 POV-Ray units and is intended to represent a spacing of 10 centimetres. This size represents the size of the smallest block (before the mortar gap is trimmed off the blocksize) that can be used in the wall and all other sizes are multiples of this size so, with the default matrix spacing a 3x2 block will be 30 centimetres by 20 centimetres (minus any mortar gap defined).
Blockwall_Wrap Integer value used by the Blockwall_MakeMatrix macro to control whether or not the blockwork pattern is able to wrap around from the last column to the first column in the blockwork pattern matrix. The default value is 0 which switches wrapping off. A value of 1 switches wrapping on. The Blockwall_FollowArray macro switches wrapping on automatically if the first and last points of the array are the same, creating a closed shell. The Blockwall_Shell macro uses the Blockwall_FollowArray macro to draw a closed shape, so effectively uses wrapping by default.

You should set this value to 1 if you specify a closed spline for use with the Blockwall_FollowSpline macro to avoid having a seam at the join. Setting this value to 1 when using the Blockwall macro or the Blockwall_Fill gives you a panel that you can tile horizontally without apparent seams, but will give you wiggly ends, so you may wish to use CSG to trim them.

Blockwall_RoughStoneRandomness Decimal value used by the Blockwall_Block macro to control the randomness of rough stone walling. The default value is 1 which adds quite a lot of randomness. Normal values range from 0 to 1, but you can go over 1 if you wish.
Blockwall_RoughStoneSeed Randomisation seed stream definition used by the Blockwall_Block macro to control the randomisation used for generating rough stone walling. The default stream is seed(1). If the randomisation generates an unwanted pattern you can set this seed to generate a different pattern.
Blockwall_ColorSeed Randomisation seed stream definition used by the Blockwall_MakeMatrix macro to control the color seed. The default stream is seed(1) and normally you don't need to alter this value as it is initialised with the first macro call, producing a unique sequence of randomised colors for each subsequent call. However, if a particular call to one of the Blockwall macros produces a randomised pattern that causes you problems you can redeclare this seed stream before making the macro call to generate a different randomised color pattern.
Blockwall_SizeSeed Randomisation seed stream definition used by the Blockwall_MakeMatrix macro to control the size seed. The default stream is seed(2) and normally you don't need to alter this value as it is initialised with the first macro call, producing a unique sequence of randomised block sizes for each subsequent call. However, if a particular call to one of the Blockwall macros produces a randomised pattern that causes you problems you can redeclare this seed stream before making the macro call to generate a different randomised block size pattern.
Blockwall_WallLength Decimal value used by the Blockwall macros to control the Wall Length. You can use this value with the Blockwall macro to set the wall length. The default value defined by the Blockwall macro is 1 POV-Ray unit which is intended to represent a wall length of 1 metre. Most of the Blockwall macros calculate this value based upon other settings. For example, the Blockwall_FollowSpline macro calculates the length of the Blockwall_Spline spline and the Blockwall_FollowArray macro adds up the lengths of the lines joining the corners defined in the Blockwall_CornerArray array.
Blockwall_WallHeight Decimal value used by the Blockwall macros to control the height of the generated wall. The Blockwall and Blockwall_FollowArray macros use a default of 1 POV-Ray unit (to represent 1 metre). The Blockwall_FollowSpline macro uses a default of 0.8 (to represent 80 centimetres). The Blockwall_Shell and Blockwall_Fill macros both explicitly set the wall height based upon the parameters passed on the macro call.
Blockwall_Radius Decimal value used by the Blockwall_Arc macro to control the radius of the arc used to create a wall that follows a circular path. The default value is 1 POV-Ray unit and is intended to represent a radius of 1 metre. This value defines the radius of the "dressed" face, which can be the inside face or the outside face depending upon whether a positive or negative rotation is specified on the Blockwall_Arc macro call. If a positive rotation is specified, Blockwall_Radius is used to define the internal radius of the arc. If a negative rotation is specified on the macro call, Blockwall_Radius is used to define the external radius of the arc.
Blockwall_CornerArray Array of 2D (X and Z) coordinates used by the Blockwall_FollowArray macro as the corner points of the base of the front face of the wall that it creates. If not already defines, an array is defined that creates a 1 unit cube with its bottom left corner at the origin.

The wall generated by the Blockwall_FollowArray macro sits on the XZ plane (y=0), but you can transform it from there to wherever you need to use it in your scene by wrapping the macro call in an object statement (see example 2)

Blockwall_Spline Spline definition used by the Blockwall_FollowSpline macro to determine the line that the base of the front face of the wall that it creates will follow. If not specified, the Blockwall_FollowSpline macro defines a default cubic spline that starts at the origin and extends 1.25 units along the +Z axis. This default spline has a slight vertical hump in the middle intended to represent the shape of the parapet on a hump-backed bridge.

The Blockwall_DropSplineToSurface macro can be used to manipulate the spline assigned to the Blockwall_Spline identifier by dropping it onto the surface of an object assigned to the Blockwall_Target identifier. This is done using the POV-Ray trace command to drop a line down from a large number of points on the original spline, usually resulting in a larger spline. The results are written back into the same spline identifier (Blockwall_Spline) as a cubic spline (irrespective of the original spline type).

It's up to you to make sure that the spline is entirely above the surface onto which it needs to be dropped.

Blockwall_Target A POV-Ray object used by the Blockwall_DropSplineToSurface macro to manipulate a spline assigned to the Blockwall_Spline identifier. The spline will be dropped onto the surface of this object. The default value is plane {y,-0.01}.

It's up to you to make sure that the spline is entirely above the surface onto which it needs to be dropped.

Blockwall_Holes A POV-Ray object used by the Blockwall macros to cut holes in the wall objects they generate. You can declare this object before calling one of the macros and it will cut each block individually so that you get the correct texture on each cut surface. Alternatively you can use the object generated by one of these macros in a CSG operation to cut holes in it, but that is slower and you are likely to find it difficult to get anything more than a single texture on the cut surfaces. See Example 6, Example 7 and Example 21. Note that you should #undef this object between macro calls unless you want the same holes cut in subsequently generated walls.
Blockwall_ThisBlockTexture A read-only texture setting that returns the last texture definition used to create a block. In fact you can set this texture, but it has no affect on the operation of the macro which will simply overwrite it on each call.

This can be handy when cutting a section of blocks using CSG (Constructive Solid Geometry) operations to apply a credible texture to the cut surface (See example 7)

Blockwall_CentreToCentre A read-only variable that returns the distance in X that you need to translate one panel to the left or right to join two copies of the same panel seamlessly together (See example 1). This is only really of use with walls generated using the Blockwall and Blockwall_Fill macros. These macros overwrite this value each time they are called.
Blockwall_Debug Integer value used by the Blockwall_FollowArray macro to switch on or off a small number of debug messages. The default value is 0 (no debug messages) a value of 1 displays the debug messages.

Return to Table of Contents


Version History

VersionDateBy
V1.024th December 2008ChrisB
A range of macros for generating walls. Some draw different wall shapes, such as rectangular or curved wall segments, others simply provide alternative means for specifying the wall.
V1.11st January 2009ChrisB
Fixed a bug with the Blockwall_FollowSpline macro so that the final end position is more precise, enabling closed splines to form perfect circles.
Fixed a bug with the precision of the wall height in the Blockwall_FollowSpline macro.
Added the Blockwall_Wrap function to the Blockwall_FollowSpline macro to enable the ends of closed splines to be interwoven.
Added the Blockwall_Holes identifier to direct the macros to cut CSG holes in walls as they are being generated. This enables correct texturing to be applied to the cut surfaces and is much more performant than cutting the holes afterwards.
Added examples 21, 22, 23 and 24.
V1.1.113th January 2009ChrisB
Fixed a bug with the Blockwall_FollowSpline macro that caused occasional parser errors.

Return to Table of Contents