POV-Ray : Newsgroups : povray.binaries.images : Another brick - plus source : Another brick - plus source Server Time
7 Aug 2024 07:17:16 EDT (-0400)
  Another brick - plus source  
From: Bill Pragnell
Date: 3 May 2006 11:30:00
Message: <web.4458cba5e8dd02a8731f01d10@news.povray.org>
What ho

Here is a slightly more complex example of the brick mesh, with two combined
pigment functions. If anybody wants a go at it, here's the code (no
smoothing):

/* --------- begin SDL --------- */
#include "shapes.inc"
#include "colors.inc"

global_settings {
  assumed_gamma 1 }

camera {
  location <18, 10, -10>
  up <0, 1, 0>
  right <4/3, 0, 0>
  direction <0, 0, FoV_45>
  look_at <0, 0, 0> }

light_source { <300, 500, -100> color White }

// calculate curvature displacement:
// result1 = inward displacement vector due to curvature
// result2 = outward unit vector for pigment displacement
#macro Curv(posx, posy, rad, sx, sy, vx, vy, nml, result1, result2)
  #local vecx = vnormalize(vx);
  #local vecy = vnormalize(vy);
  #local t1 = 0;
  #local t2 = 0;
  #if (vlength(posx) < rad)
    #local t1 = -(rad-vlength(posx));
  #end
  #if (vlength(posy) < rad)
    #local t2 = -(rad-vlength(posy));
  #end
  #if (vlength(posx) > sx-rad)
    #local t1 = rad-(sx-vlength(posx));
  #end
  #if (vlength(posy) > sy-rad)
    #local t2 = rad-(sy-vlength(posy));
  #end
  #local nn = vnormalize(nml);
  #local vecr = t1*vecx + t2*vecy + nn*rad;
  #local result1 = -(vlength(vecr)-rad)*vnormalize(vecr);
  #local result2 = vnormalize(vecr);
#end

// calculate pigment displacement
#macro Displace(posi, vect, scal, ampl)
  ( (ampl-ampl/2) * vect * fn_brick_surface(posi.x/scal, posi.y/scal,
posi.z/scal).x )
#end

// single facet macro
#macro Face(posit, sx,sy, nx,ny, vx,vy,norm, rad, sc, amp)
#local dpx = vx*sx/(nx-1);
#local dpy = vy*sy/(ny-1);
#local ox = -vx*sx/2;
#local oy = -vy*sy/2;
#local px = <0,0,0>;
#local py = <0,0,0>;
#local n = 0;
#local result1 = <0,0,0>;
#local result2 = <0,0,0>;
#while (n < (nx-1)*(ny-1))
  #local pos1 = posit + ox + oy + px + py;
  #local pos2 = posit + ox + oy + px+dpx + py;
  #local pos3 = posit + ox + oy + px + py+dpy;
  Curv(px, py, rad, sx, sy, vx, vy, norm, result1, result2)
  #local pos1 = pos1 + result1 + Displace(pos1, result2, sc, amp);
  Curv(px+dpx, py, rad, sx, sy, vx, vy, norm, result1, result2)
  #local pos2 = pos2 + result1 + Displace(pos2, result2, sc, amp);
  Curv(px, py+dpy, rad, sx, sy, vx, vy, norm, result1, result2)
  #local pos3 = pos3 + result1 + Displace(pos3, result2, sc, amp);
  triangle { pos1, pos2, pos3 }
  #local pos1 = posit + ox + oy + px + py+dpy;
  #local pos2 = posit + ox + oy + px+dpx + py;
  #local pos3 = posit + ox + oy + px+dpx + py+dpy;
  Curv(px, py+dpy, rad, sx, sy, vx, vy, norm, result1, result2);
  #local pos1 = pos1 + result1 + Displace(pos1, result2, sc, amp);
  Curv(px+dpx, py, rad, sx, sy, vx, vy, norm, result1, result2);
  #local pos2 = pos2 + result1 + Displace(pos2, result2, sc, amp);
  Curv(px+dpx, py+dpy, rad, sx, sy, vx, vy, norm, result1, result2);
  #local pos3 = pos3 + result1 + Displace(pos3, result2, sc, amp);
  triangle { pos1, pos2, pos3 }
  #local px = px + dpx;
  #if (vlength(px) >= sx)
    #local px = 0;
    #local py = py + dpy;
  #end
  #local n = n + 1;
#end
#end

// top-level brick macro
// <xs,ys,zs> = size (actually box 'radii')
// rad = radius of curvature at corner
// res = resolution setting: scale factor * res
// sc = pigment function scale factor
// amp = amplitude of surface roughness:
//       NB this will be added to surface, so extent of
//       surface is e.g. xs + amp in +ve x-direction
#macro RealBrick(xs, ys, zs, rad, res, sc, amp)
  mesh {
    Face(<0,ys,0>, xs*2,zs*2, int(xs*res),int(zs*res), <1,0,0>, <0,0,1>,
<0,1,0>, rad, sc, amp)
    Face(<0,-ys,0>, xs*2,zs*2, int(xs*res),int(zs*res), <-1,0,0>, <0,0,1>,
<0,-1,0>, rad, sc, amp)
    Face(<xs,0,0>, ys*2,zs*2, int(ys*res),int(zs*res), <0,-1,0>, <0,0,1>,
<1,0,0>, rad, sc, amp)
    Face(<-xs,0,0>, ys*2,zs*2, int(ys*res),int(zs*res), <0,1,0>, <0,0,1>,
<-1,0,0>, rad, sc, amp)
    Face(<0,0,-zs>, xs*2,ys*2, int(xs*res),int(ys*res), <1,0,0>, <0,1,0>,
<0,0,-1>, rad, sc, amp)
    Face(<0,0,zs>, xs*2,ys*2, int(xs*res),int(ys*res), <1,0,0>, <0,-1,0>,
<0,0,1>, rad, sc, amp)
  }
#end

#declare gran1 = function {
  pigment {
    granite
    color_map {
      [0 color 1]
      [0.5 color 1]
      [1 color 0] } } }
#declare gran2 = function {
  pigment {
    granite
    color_map {
      [0 color 0]
      [1 color 1] } } }
#declare fn_brick_surface = function {
  gran1(x,y,z).x + 0.1*gran2(x/0.2,y/0.2,z/0.2).x }

object {
  RealBrick(2,1.5,4, 0.5, 50, 10,0.5)
  pigment { color White }
  finish { ambient 0 } }
/* --------- end SDL --------- */

All the parameters required can be passed to the macro, except the pigment
function (I couldn't get it to work for some reason). The macro therefore
assumes a pre-declared function called fn_brick_surface.

It should be noted there is a severe limitation to this technique. Using too
large a pigment amplitude with too small a curvature radius (rad) can cause
the surface displacement to diverge too much at the edges, resulting in a
loss of resolution. This effect is also slightly dependent on the
resolution setting. Have a play and I'm sure you'll see what I mean...

Bill


Post a reply to this message


Attachments:
Download 'isomesh1.jpg' (45 KB)

Preview of image 'isomesh1.jpg'
isomesh1.jpg


 

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.