/** Macro for creating mesh with 3-sided bezier patches of degree 3. Call with bezier3triangles(A,B,C,D,E,F,G,H,I,J,K,L,depth,smooth,visible_points) where A..L are control points: - A..I points on the border in cyclic order. A,D,G are edges, B,C, between A and D and so on. - J,K,L are inner points, J closest to A, K closest to D, L closest to G and - depth: tesselation depth - smooth: if set to 1 smooth_triangles are generated - visible_points: if set to 1 control points are made visible @author Micha Riser created 21 August 2002 */ // some small values bigger than zero #declare epsilon1 = 0.001; #declare epsilon2 = 0.001; #macro pnormal(fx,fy,fz,uv) #local uu = uv.x; #local vv=uv.y; #local ru = -; #local rv = ru; #local uu = uu+epsilon2; #local ru = ru + ; #local uu = uv.x; #local vv = vv+epsilon2; #local rv = rv + ; vcross(ru,rv) #end #macro bezier3triangles_rec(uv1, uv2, uv3, fx, fy, fz, smoothing, depth) #if (depth =0) #if (smoothing != 1) triangle{ , , } #else smooth_triangle{ ,pnormal(fx,fy,fz,uv1), ,pnormal(fx,fy,fz,uv2), ,pnormal(fx,fy,fz,uv3)} #end #else #local uv12 = (uv1+uv2)/2; #local uv13 = (uv1+uv3)/2; #local uv23 = (uv2+uv3)/2; bezier3triangles_rec(uv1,uv12,uv13,fx,fy,fz,smoothing,depth-1) bezier3triangles_rec(uv2,uv12,uv23,fx,fy,fz,smoothing,depth-1) bezier3triangles_rec(uv3,uv23,uv13,fx,fy,fz,smoothing,depth-1) bezier3triangles_rec(uv12,uv13,uv23,fx,fy,fz,smoothing,depth-1) #end #end #macro w() (1-u-v)/max( 1-2*u*v,epsilon1 ) #end #macro bezier3triangles(A,B,C,D,E,F,G,H,I,J,K,L,depth,smoothing,visible_points) #local r003x=A.x; #local r003y=A.y; #local r003z=A.z; #local r012x=B.x; #local r012y=B.y; #local r012z=B.z; #local r021x=C.x; #local r021y=C.y; #local r021z=C.z; #local r030x=D.x; #local r030y=D.y; #local r030z=D.z; #local r120x=E.x; #local r120y=E.y; #local r120z=E.z; #local r210x=F.x; #local r210y=F.y; #local r210z=F.z; #local r300x=G.x; #local r300y=G.y; #local r300z=G.z; #local r201x=H.x; #local r201y=H.y; #local r201z=H.z; #local r102x=I.x; #local r102y=I.y; #local r102z=I.z; #local r112x=J.x; #local r112y=J.y; #local r112z=J.z; #local r121x=K.x; #local r121y=K.y; #local r121z=K.z; #local r211x=L.x; #local r211y=L.y; #local r211z=L.z; #local fx = function(u,v){ pow(w(),3)*(1-3*v*u)*r300x + pow(v,3)*(1-3*w()*u)*r030x + pow(u,3)*(1-3*w()*v)*r003x + 3*w()*w()*v*(1-u*(1+v))*r210x + 3*w()*v*v*(1-u*(1+w()))*r120x + 3*v*v*u*(1-w()*(1+u))*r021x + 3*v*u*u*(1-w()*(1+v))*r012x + 3*u*u*w()*(1-v*(1+w()))*r102x + 3*w()*w()*u*(1-v*(1+u))*r201x + 9*w()*v*u*u*r112x + 9*w()*v*v*u*r121x + 9*w()*w()*v*u*r211x } #local fy = function(u,v){ pow(w(),3)*(1-3*v*u)*r300y + pow(v,3)*(1-3*w()*u)*r030y + pow(u,3)*(1-3*w()*v)*r003y + 3*w()*w()*v*(1-u*(1+v))*r210y + 3*w()*v*v*(1-u*(1+w()))*r120y + 3*v*v*u*(1-w()*(1+u))*r021y + 3*v*u*u*(1-w()*(1+v))*r012y + 3*u*u*w()*(1-v*(1+w()))*r102y + 3*w()*w()*u*(1-v*(1+u))*r201y + 9*w()*v*u*u*r112y + 9*w()*v*v*u*r121y + 9*w()*w()*v*u*r211y } #local fz = function(u,v){ pow(w(),3)*(1-3*v*u)*r300z + pow(v,3)*(1-3*w()*u)*r030z + pow(u,3)*(1-3*w()*v)*r003z + 3*w()*w()*v*(1-u*(1+v))*r210z + 3*w()*v*v*(1-u*(1+w()))*r120z + 3*v*v*u*(1-w()*(1+u))*r021z + 3*v*u*u*(1-w()*(1+v))*r012z + 3*u*u*w()*(1-v*(1+w()))*r102z + 3*w()*w()*u*(1-v*(1+u))*r201z + 9*w()*v*u*u*r112z + 9*w()*v*v*u*r121z + 9*w()*w()*v*u*r211z } union{ #if (visible_points) sphere{A,rad pigment{Red}} sphere{D,rad pigment{Red}} sphere{G,rad pigment{Red}} sphere{B,rad pigment{Green}} sphere{C,rad pigment{Green}} sphere{E,rad pigment{Green}} sphere{F,rad pigment{Green}} sphere{H,rad pigment{Green}} sphere{I,rad pigment{Green}} sphere{J,rad pigment{Yellow}} sphere{K,rad pigment{Yellow}} sphere{L,rad pigment{Yellow}} #end mesh{ bezier3triangles_rec(<0,0>,<0,1>,<1,0>,fx,fy,fz,smoothing,depth) } } #end ///////////////////////////////////////////////////////////////////////////////////////// // SAMPLE SCENE // Render as animation with these command line settings: // +kc +kff50 #include "colors.inc" // Length of tangent vectors #declare Pd = 2.0-1.5*cos(clock*2*pi); #local rad=0.1; union { object{ // rounded corner (red tint) bezier3triangles( <2,0,2>,<2,0,2>-Pd*z,<2,2,0>-Pd*y, <2,2,0>,<2,2,0>-Pd*x,<0,2,2>-Pd*z, <0,2,2>,<0,2,2>-Pd*y,<2,0,2>-Pd*x, <2,0,2>-Pd*(x+z),<2,2,0>-Pd*(x+y),<0,2,2>-Pd*(y+z), // inner points 4,1,1) // depth, smoothing, enable visible control points pigment {rgb <1.0,0.8,0.8>} finish {phong 0.5} } #declare Patch1 = // rounded edges (blue tint) bicubic_patch { type 1 u_steps 4 v_steps 4 <2,0,2>,<2,0,2>-Pd*z,<2,2,0>-Pd*y,<2,2,0>, <3,0,2>,<3,0,2>-Pd*z,<3,2,0>-Pd*y,<3,2,0>, <4,0,2>,<4,0,2>-Pd*z,<4,2,0>-Pd*y,<4,2,0>, <5,0,2>,<5,0,2>-Pd*z,<5,2,0>-Pd*y,<5,2,0> pigment {rgb <0.8,0.8,1.0>} finish {phong 0.5} } object {Patch1} object {Patch1 matrix <0,1,0,0,0,1,1,0,0,0,0,0>} object {Patch1 matrix <0,0,1,1,0,0,0,1,0,0,0,0>} #declare Patch2 = // flat sides (green tint) bicubic_patch { type 1 u_steps 4 v_steps 4 <2,0,2>,<2,0,3>,<2,0,4>,<2,0,5>, <3,0,2>,<3,0,3>,<3,0,4>,<3,0,5>, <4,0,2>,<4,0,3>,<4,0,4>,<4,0,5>, <5,0,2>,<5,0,3>,<5,0,4>,<5,0,5> pigment {rgb <0.9,1.0,0.9>} finish {phong 0.5} } object {Patch2} object {Patch2 matrix <0,1,0,0,0,1,1,0,0,0,0,0>} object {Patch2 matrix <0,0,1,1,0,0,0,1,0,0,0,0>} scale <1,-1,1> } camera { location <-2,3,-4> look_at <1,-1,1> } light_source {<1,2,-3>*1000, color 1} background {rgb 1}