Skip to content
LeForgeron edited this page Mar 12, 2016 · 7 revisions

Hgpovray


Tesselation

Yoda: Yes, run! Yes, a Jedi's strength flows from the Renderer. But beware
      of the dark side. Mesh, Heightfield, Bicubic Patch; the dark side of 
      the Force are they. Easily they flow, quick to join you in a fight. 
      If once you start down the dark path, forever will it dominate your 
      destiny, consume you it will, as it did Isosurface's apprentice.
Luke: Parametric precompute... Is the dark side stronger?
Yoda: No, no, no. Quicker, easier, more seductive.
Luke: But how am I to know the good side from the bad?
Yoda: You will know... when you are calm, at peace, passive. 
      A Jedi uses the Renderer for knowledge and defense, NEVER for attack.
Luke: But tell my why I can't...
Yoda: No, no! There is no "why".

Mesh from 3D finite object

  • it must be 3D, to have an inside test which is meaningfull
  • it must be finite, because the bounding box is use to specify the volume which will be sampled

Whatever the method used (it will always end as a mesh object, or inside a mesh object). there is some common parameters:

  • original is followed by the object to sample. It is really mandatory.
  • accuracy is followed by a 3D vector which specify the number of slices in each direction (it defaults to 10)

When used inside a Mesh object, the created part of mesh can be painted with explicit texture:

  • texture is followed by a texture identifier

Without texture, using only Inside test (fast)

These approaches use a marching cube algorithm, hence their usage were forbidden on the USA thanks to a now expired patent (17 years after December 1987).

Bourke

  • heller ( alternate table from Bourke page made by Geoffrey Heller)

Heller

  • cubicle (simplistic approach using a cube)

Cubicle

  • cristal (same as cubicle, with inclined face)

Cristal

bourke & heller allow additional options :

  • precision with a float, which supersample along the interecting line (by the amount of the float, so only positive integer are of any real interest) for a better fit.
  • offset is followed by a float which move outward the position of each face of the bounding box used for scanning (default to 0, so beware of very tight perfect bounding box)
mesh { ...
  (bourke|heller) {
    original finite3D_obj
    [accuracy vector] [precision float] [offset float] [texture { Tid } ]
  }
...
}

OR

(bourke|heller) {
  original finite3D_obj
  [accuracy vector] [precision float] [offset float]

[Object_Mods...]
}
mesh { ...
  (cubicle|cristal) {
    original finite3D_obj
    [accuracy vector] [texture { Tid } ]
  }
...
}

OR

(cubicle|cristal) {
  original finite3D_obj
  [accuracy vector]

[Object_Mods...]
}

Using Inside test & trace (slower)

No marching cube per itself here, the inside test is used to trigger the usage of trace to get the actual intersection.

  • tesselate

Tesselate

 mesh { ...
  tesselate { 
    original finite3D_obj
    [accuracy vector] [albinos] [offset float] [smooth] [texture { Tid }]
  }
 ...
 }

OR

 tesselate { 
   original finite3D_obj
   [accuracy vector] [albinos] [offset float] [smooth] 

 [Object_Mods...]
 }
  • tessel

Tessel

 mesh { ...
  tessel { 
    original finite3D_obj
    [accuracy vector] [albinos] [offset float] [smooth] [texture { Tid }]
  }
 ...
 }

OR

 tessel { 
   original finite3D_obj
   [accuracy vector] [albinos] [offset float] [smooth] 

 [Object_Mods...]
 }

As trace is used, the texture from the intersection point is available and can be pushed on the vertex of each generated triangle. This can be prevented with the use of the albinos option.

  • a possible parameter is smooth which would also use the normal reported by the intersection to make smooth_triangle instead of triangle in the resulting mesh.
  • offset is followed by a float which move outward the position of each face of the bounding box used for scanning (default to 0, so beware of very tight perfect bounding box)

Mesh from and to file

Loading

GTS

A GTS file can be loaded with gts_load.

#include "colors.inc"
camera { location <3,5,-4>
        direction z
                up y
                right image_width/image_height*x
                look_at <-1/2,1/2,0>
                angle 35
}

light_source{ <-5, 20, -20>, 1}
light_source{ <0, 2, 0>, 1/2}

gts_load{ "bunny.gts"
        right
        rotate 180*y
        scale 17
        translate -2*y
        texture { pigment { color Aquamarine}}
}

GtsLoad

Aside from the filename of the file to load, the right keyword can be used to change the default left-handed coordinate system to a right-handed one.

gts_load can be used to create a mesh of its own or to incorporate the mesh of the file into a larger mesh, in which case a texture identifier can be applied over the loaded GTS mesh.

 mesh { ...
    gts_load { filename [right] [texture { Tid }] }
  ...
 }

OR

 gts_load { filename [right] 

 [Object_Mods...]
 }

STL

A mesh can be loaded with stl_load. Beware of I/O restrictions.

Aside from the filename of the file to load, the right keyword can be used to change the default left-handed coordinate system to a right-handed one.

stl_load is used to create a mesh of its own.

Only a binary stl file can be loaded:

  • text stl file format is not supported
  • normal and attribute are not taken into account
 stl_load { filename [right] 

 [Object_Mods...]
 }

Saving

GTS

A mesh can be saved with gts_save. Beware of I/O restrictions.

gts_save { filename, mesh_object }

GTS format saves the geometry, but neither the faked normal or the textures or transformations.

STL

A mesh can be saved with stl_save. Beware of I/O restrictions.

stl_save { filename, mesh_object }

STL format saves the geometry, but neither the faked normal or the textures or transformations and so far stl_save does not save any colour information.

  • The pov-unit are mapped directly as the stl-unit.
  • stl is usually a right-handed coordinate system, so keep it in mind when creating the mesh to save

Transformations

The following method (or pseudo-object) can be used only on a mesh, whatever its origin.

Whatever the method used (it will always end as a mesh object, or inside a mesh object). there is some common parameters:

  • original is the mesh used as the base object (it is not updated, it is used as data source)
  • albinos is an option which remove all textures on the generated triangles

bend

Curve the mesh along a line, using a reference half-plane containing that line.

bend  { original Objiii
        origin 0
        amount 30
        fixed z
        direction y
        minimal -0.0
        maximal 2.0 }

Bend

bend  { original Objiii
        origin 0
        amount 30
        fixed y
        direction z
        minimal -50.0
        maximal 2.0 }
 mesh { ...
   bend {
    original mesh_object
    [albinos]  [amount float]  [direction vector]  [fixed vector]  [maximal float]  [minimal float]
    [modulation { texture_description }]  [origin vector]  [texture { Tid }]
   } 
 ...
 }

OR

 bend {
  original mesh_object
  [albinos]  [amount float]  [direction vector]  [fixed vector]  [maximal float]  [minimal float]
  [modulation { texture_description }]  [origin vector]

 [Object_Mods...]
 } 
  • original mesh_object : the original mesh object whose data are used as source for the new mesh
  • albinos : do not copy the texture from the original mesh
  • amount float : angle of rotation (in degree) for a unit length. The rotation is proportional to the length.
  • direction vector : axis of the rotation, only the direction is taken into account.
  • fixed vector : axis of the zero-plane (origin, origin+direction & origin+fixed points are all contained inside the zero-plane: the plane with no transformation)
  • maximal float : when length is bigger, the transformation is limited to the float.
  • minimal float : when length is smaller, the transformation is limited to the float.
  • modulation { texture_description } : the luminosity of the colour from the texture evaluated at the vertex is used to ponder the deformation effect; full black means no transformation, white (<1,1,1>) means 100%.
  • origin vector : vertex used as the origin of the transformation's reference base.

displace

Move each vertex of a triangle along its normal.

Be careful: as a vertex might appears in more than one triangle, if the normal at a vertex is not the same for all the triangles sharing that vertex, the displacement would create cracks in the resulting mesh as each triangles move away.

Displace

 mesh{ ...
  displace {
    modulation { texture_description }
    original mesh_object
    [albinos]  [amount float]  [offset float] [inside_point vector] [texture { Tid } ]
  }
  ...
 }

OR
 
 displace {
  modulation { texture_description }
  original mesh_object
  [albinos] [amount float] [offset float] [inside_point vector]

 [Object_Mods...]
 } 
  • original mesh_object : the original mesh object whose data are used as source for the new mesh
  • modulation { texture_description } : the luminosity of the colour from the texture evaluated at the vertex is used to ponder the deformation effect; full black means no transformation, white (<1,1,1>) means 100%.
  • albinos : do not copy the texture from the original mesh
  • amount float : length of displacement for 100%.
  • offset : offset applied to the luminosity. (default value is 0.5, so full black is -50% and white is 50%)
  • inside_point : when present, normals are flipped (for the displacement) whenever it would not be centrifuge with the vector of the position relative to the inside_point. Allow to get consistent displacement on mesh with random normal distribution.

keep

Keep

Keep only part(s) of a mesh, relative to a 3D object. Four parts are possible:

  • inner all 3 vertices of a triangle are inside the 3D object.
  • inbound only 2 vertices of a triangle are inside.
  • outbound only 1 vertex of a triangle is inside.
  • outside all 3 vertices of a triangle are not inside the 3D object.

A keep selection can select as many parts as wanted for the resulting mesh, but will only use a single 3D object.

keep { original Foobar_Mesh
  with intersection {
            box { <-1,-1,-1>,<4,haut+1,0.04> }
            sphere { <1.5,haut/2,0>,haut*2/5 }
       }
   outside
}
mesh{ ...
  keep {
    original mesh_object
    with solid_object
    [albinos] [inbound] [inner] [outbound] [outside]
    [texture { Tid }]
  }
  ...
}

OR

keep {
    original mesh_object
    with solid_object
    [albinos] [inbound] [inner] [outbound] [outside]

[Object_Mods...]
}

move

Transforms the coordinates of each points.

mesh { ...
  move {
   original mesh_object
   [albinos] [modulation { texture_description } ] [move < coeff_of_matrix(12) >] [ texture { Tid } ]

} 
  ...
}

OR

move {
    original mesh_object
    [ albinos ] [modulation { texture_description } ] [ move < coeff_of_matrix(12) > ]

[Object_Mods...]
} 

The starting point is used with the move matrix to produce a end point. The resulting deplacement is then modulated by the luminosity of the modulation texture to produce the final point.

The matrix is the usual transformation matrix.

#include "colors.inc"
#default { finish { ambient 0.5 specular 0.5 } }
camera { location <6,6,12> direction  -z right x up y look_at 0 angle 25 }
light_source { <-30,100,50>, 1 }

#declare tt=texture { pigment { spiral2 6 scale 2 translate -y*0.95 pigment_map {
[0 Black]
[1 Gray20]
} } }

#declare msize=3.0;
move { original cristal { accuracy 150 original sphere { 0,msize } }
modulation { tt }
move < 0.6,+0.4,0, 0,1,0, 0,-0.2,0.1, 0,0,0 >
pigment { Yellow }
}

Move

planet

planet {
    original mesh_object
    [ albinos ] [amount float] [repeat float[,float] ] [origin vector] [jitter float]

[Object_Mods...]
} 
  • original mesh_object : the original mesh object whose data are used as source for the new mesh
  • albinos : do not copy the texture from the original mesh
  • amount float : maximal distance of displacement, default to 0
  • jitter float : radius of jitter sphere around origin, default to 0
  • origin vector : vertex used as the origin of the jitter sphere
  • repeat float, float : first value is the number of iterations, second number is the seed for the internal random numbers generator. Both default to 0.

For each iteration:

  1. Select anisotropic random direction : V
  2. Choose a random value between -jitter and +jitter : D
  3. create a plane with offset of D from origin and normal vector V
  4. use the plane to split the universe in two parts
  5. for each vertices in the first part, move away from origin
  6. for each vertices in the second part, move toward origin

Planet

#version 3.7;
global_settings{ assumed_gamma 1.0 }
#default{ finish{ ambient  0 emission 0.5 diffuse 0.5 reflection 0 } }
#declare EarthRadius=6371;
#declare GeoStat=35784;
camera { orthographic 
  location -GeoStat*z 
  direction GeoStat*z 
  up EarthRadius*2.2*y 
  right EarthRadius*2.2*image_width/image_height*x 
  angle 29 }

#include "colors.inc"
#declare DEP=500;
background { Black }

#declare Basic=texture {pigment { color rgb 1 } }
#local MT=0.007*DEP/50;
#declare Planet = texture { pigment {
spherical 
        pigment_map{
                [0  White ]
                [MT/10  Brown]
                [MT/2  ForestGreen]
                [MT  ForestGreen]
                [MT  Yellow]
                [MT*4/3  Blue]
                [MT*2  Black]
        }
scale EarthRadius+DEP

}}
#declare Source=sphere { 0, EarthRadius texture {  Basic } }
#declare MSource= tessel { original Source accuracy 251 albinos  } 
#local Itera=100000;
#declare Di= planet { original  MSource origin <0,0,0> amount DEP repeat Itera,23 jitter EarthRadius*2/3 }

light_source { <-1,1,-1>*35786 , rgb<1,1,1> } 
light_source { -1*<-1,1,-1>*35786 , rgb<1,1,1> } 
object { Di texture { Planet } }

roll

Roll

  • original mesh_object : the original mesh object whose data are used as source for the new mesh
  • albinos : do not copy the texture from the original mesh
  • modulation { texture_description } : the luminosity of the colour from the texture evaluated at the vertex is used to ponder the deformation effect; full black means no transformation, white (<1,1,1>) means 100%.
  • direction vector : vector of the rotation (as usual) for a unit length along that vector.
  • maximal float : when rotation's angle is bigger, the transformation is limited to the float.
  • minimal float : when rotation's angle is smaller, the transformation is limited to the float.
  • origin vector : vertex used as the origin of the transformation's reference base.
mesh{ ...
  roll {
    original mesh_object
    [albinos] [direction vector] [maximal float] [minimal float] [modulation { texture_description }]
    [origin vector]
    [texture { Tid }]
  }
  ...
}

OR

roll {
    original mesh_object
    [albinos] [direction vector] [maximal float] [minimal float] [modulation { texture_description }]
    [origin vector]

[Object_Mods...]
}

screw

Screw

#default { pigment { rgb <1,.8,.6> } finish { specular .5 } }
#declare Objiii = cubicle { original box { <-0.5,-3.5,-0.5>,<0.5,3.5,0.5>  } accuracy <20,120,20> }
#local i=0;
#while (i<15)
screw  { original Objiii origin 0  direction i*20*y
  #if (mod(i,3)=1) minimal -30.0 maximal i*45.0 #end
  #if (mod(i,4)=0) right #end
rotate 30*x*mod(i+1,2)  translate i*2*x }
#local i=i+1;
#end
camera { location <14.0,0,150> up 8*y right 8*x*image_width/image_height direction -z angle 12 }
light_source { <200,100,-150>, z }
light_source { <00,10,150>, 1 }
light_source { <200,100,100>, x }
light_source { 0, y }
  • original mesh_object : the original mesh object whose data are used as source for the new mesh
  • albinos : do not copy the texture from the original mesh
  • modulation { texture_description } : the luminosity of the colour from the texture evaluated at the vertex is used to ponder the deformation effect; full black means no transformation, white (<1,1,1>) means 100%.
  • direction vector : vector of the rotation (as usual) for a unit length along that vector.
  • maximal float : when rotation's angle is bigger, the transformation is limited to the float.
  • minimal float : when rotation's angle is smaller, the transformation is limited to the float.
  • origin vector : vertex used as the origin of the transformation's reference base.
  • right : inverse the handedness of the the screw (on a default left-handed scene, the default screw is the traditional clockwise; right allows to produce the chiral one)
mesh{ ...
  screw {
    original mesh_object
    [albinos] [direction vector] [maximal float] [minimal float] [modulation { texture_description }]
    [origin vector] [right]
    [texture { Tid }]
  }
  ...
}

OR

screw {
    original mesh_object
    [albinos] [direction vector] [maximal float] [minimal float] [modulation { texture_description }]
    [origin vector] [right]

[Object_Mods...]
}

smooth

Smooth

#include "colors.inc"
background { rgb z *.5}
#declare T1= texture { pigment { rgb <1,.8,.6> } finish { specular .5 } };
#declare T2= texture { pigment { rgb <.8,.6,1> } finish { specular .5 } };
#declare T3= texture { pigment { rgb <.6,1,.8> } finish { specular .5 } };
#default { texture { T1 }}
#declare Obj = sphere { 0,1 texture { T3} }
#declare Spacing = 2.1;
#declare Tes= tessel { original Obj accuracy 3 offset 0.1 albinos texture { T2 } }
object { Obj translate x*4*Spacing }

object { Tes translate -x*Spacing }
#for(i,0,3,1)
smooth { original Tes method i translate Spacing*x*i }
#end

camera { orthographic location < 0, 4, -18 > *2.1 up y right image_width/image_height*x
look_at < 0, 0, 0 > angle 37 / 2 translate Spacing*x*1.5 }
light_source { <200, 100, -150 >, 1}
light_source { <-200, 100, -100 >, x * .5}
mesh{...
  smooth {
    original mesh_object
    [albinos] [amount float] [method float] [texture { Tid }]
  } 
...
}

OR

smooth {
    original mesh_object
    [albinos] [amount float] [method float ]

  [Object_Mods...]
} 

Perturbate the normal of each triangle. By default the perturbation is toward a smoother surface.

  • amount float : the amount of displacement of the normals toward the unified normal at that vertex. 1 (=100%) by default.
  • method index : how to compute the unified normal (default to 0)
    • 0 : basic average of all contributing normals
      
    • 1 : weighted average, the weight is the angle at the vertex
      
    • 2 : weighted average, the weight is the product of the lengths of segments at the vertex
      
    • 3 : weighted average, the weight is the surface of the triangle 
      

warp

Warp

#version 3.7;
global_settings { assumed_gamma 1.0 }
#include "colors.inc"

camera { location <9.3,1.5/2,-100> up y direction z
right image_width/image_height*x look_at <9.3,1.5/2,0> angle 11 }
#declare T0= texture { pigment { Gold } }

light_source { <-30,100,-100>,1 }
light_source { <0,00,-100>,1 }

#declare Obj1= union {
        box { <0,0,0>,<1,1.5,30> texture { pigment { Blue } } }
        box { <1,0,0>,<2,1.5,30> texture { pigment { White } } }
        box { <2,0,0>,<3,1.5,30> texture { pigment { Red } } }
        box { <1.45,0.3,-0.001>,<1.55,1.2,0> texture { T0 } }
        box { <1.2,0.70,-0.001>, <1.8,0.80,0> texture { T0 } }
        box { <1.325,0.925,-0.001>, <1.675,1.025,0> texture { T0 } }
      }

#declare Vector =  <0.1,0.2,0.3>;

#declare Boring_mesh= keep { original tesselate { original  Obj1 offset 0.1 accuracy <100,50,2> }
		with box { <-1,-1,-1>,<4,1.5+1,0.04> } inner };

object { Boring_mesh  }
#for(i,1,5,1)
warp { original Boring_mesh warp { turbulence Vector octaves i }
			 translate 3.15*i*x }
#end
mesh{...
  warp {
    original mesh_object warp warp_description
    [albinos] [modulation { texture_description } ] [move <coeff_ot_matrix(12)>] [texture { Tid }]
  } 
...
}

OR
warp {
    original mesh_object warp warp_description
    [albinos] [modulation { texture_description } ] [move <coeff_ot_matrix(12)>]
    
  [Object_Mods...]
} 

See move for the details about modulation. The matrix provided with move is applied to the points before evaluating the warp (useful in animation for moving an object in the wind: as the wind progress, the translation of the matrix does also).