POV-Ray : Newsgroups : povray.advanced-users : Phase 2: cutting a mask of height field style mesh : Re: Phase 2: cutting a mask of height field style mesh Server Time
29 Jul 2024 06:28:08 EDT (-0400)
  Re: Phase 2: cutting a mask of height field style mesh  
From: Dennis Miller
Date: 18 Nov 2002 20:43:26
Message: <3dd9973e$1@news.povray.org>
Love to see this when it is done.
Best,
D.

"normdoering" <nor### [at] yahoocom> wrote in message
news:web.3dd6de06ccdca5b11a927f560@news.povray.org...
> Okay, I'm not as finished as I hoped. I've got a problem in that I'm
> doubling up the triangles, or facets, that make up the array -- I think.
>
> Here's the code:
>
> //-----------------------------------------------------------
> // How to cut a mask from an imported picture before making mesh
> #version 3.5;
> #include "colors.inc"
> global_settings { assumed_gamma 1.0 }
> // ----------------------------------------
>
> camera
> { location  <0, 0, -850.0>
>   look_at   <0, 0, 0>
>   angle 35
> }
>
> background {rgb <0.25, 0.25, 0.5>}
> //No light source needed to test these assumptions use ambient finish
>
> // -----------------------------
> //test assumption: Cutting pictures with a mask and making meshes
> //==============================
>
> #declare xPixels = 271; // 271 is number of pixels in x dimension
> #declare yPixels = 496; // 496 in y dimension
> // These numbers are the size of the image in pixels, you have to get
these
> // from a paint program or such. POV can't get them for you.
>
> #declare ScX = 1;    // scale has to be declared because it's shared with
> the
> #declare ScY = 1.83; // #while loops. Difference in scale because the
> function
>                      // wants to create a square picture and fills the
> square
>                      // area from (x,y) coordinates (0,0) to (1,1)
> regardless
>                      // of the image's original size in pixels.
> #declare MsclX = 50;  // The mesh itself needs to be scaled on x, y and z
> #declare MsclY = 50;  // All these might be variables for a macro later.
> #declare MsclZ = 30;
>
> // these mark how the picture goes exactly to upper right
> cylinder {-200*x, 200*x, 1 pigment {rgb <1,1,0>} finish {ambient 1}}
> cylinder {-200*y, 200*y, 1 pigment {rgb <1,1,0>} finish {ambient 1}}
>
>
> #declare thePicture = function   // To get the picture we wish to use as a
> { pigment                        // mesh height field we declare it as a
>   { image_map                    // function.
>     { jpeg "12.jpg" map_type 0   // This pigment function returns a
vector,
> 3 numbers at least <r,g,b>.
>       once                       // 3 numbers at least: <r,g,b>.
>     }                            // We have to convert its output to a
> single float.
>     scale <ScX, ScY, 1>          // a float between 0 and 1
>   }
> }
> #declare HFChn = function {thePicture(x,y,z).hf}
> #declare Mask = function {thePicture(x,y,z).blue}
>    // This assumes that .blue will be used as our cutting mask
>    // and .hf is red and green combined to get a 16 bit hieght value.
>    // The dot-operators used below are explained in the POV help docs.
>
> #declare Resx = xPixels/6; // actual size takes too long to render
> #declare Resy = yPixels/6; // so we scale it down till were ready to do
>                            // the whole thing and mesh it.
>
> #declare Pary = array[(Resy*ScY)+1][(Resx*ScX)+1];
>
> #declare incx = 1/Resx; // This is how far we travel to check the next
pixel
> #declare incy = 1/Resy; // in our tiny <0,0> to <1,1> square.
>
>
> //Step 1: count up unmasked "pixels" to size mesh array: Mary
> #declare xloc = 0;     // xloc & yloc are coordinates for scanning the
> picture
> #declare yloc = 0;
> #declare totalV = 0;   // size of mesh array
> #declare ycnt = 0;     // loop counter
> #while (ycnt <= (Resy*ScY))
> #declare xcnt = 0;
> #declare xloc = 0;
>    #while (xcnt <= (Resx*ScX))       // scan a horizontal line.
>
>       #if (Mask(xloc,yloc,0) > 0.08) // If it's black, less than 0.08, we
>                                      // cut it out and don't count it.
>       #declare totalV = totalV + 1;  // Count vertices to be used only.
>       #end
>
>    #declare xloc = xloc+incx;
>    #declare xcnt = xcnt+1;
>    #end
> #declare yloc = yloc+incy;
> #declare ycnt = ycnt+1;
> #end
>
> #declare Mary = array[totalV];    // vertices of mesh2 array
> #declare triang = array[totalV+totalV];
>  // represents facet making data for mesh2
>  // The size of the triang array is too large, my code must be doubling
>  // up the triangles -- no time to fix it today -- help needed here.
>
> //Step 2: Load the arrays
> #declare xloc = 0;
> #declare yloc = 0;
> #declare totalV = 0;
> #declare ycnt = 0;
> #while (ycnt <= (Resy*ScY))
> #declare xcnt = 0;
> #declare xloc = 0;
>    #while (xcnt <= (Resx*ScX)) // scan a horizontal line.
>
>       #if (Mask(xloc,yloc,0) > 0.08) // If it's black, less than 0.08, we
>                                      // cut it out and didn't count it.
>         #declare Mary[totalV] = < xloc*MsclX,
>                                   yloc*MsclY,
>                                   HFChn(xloc,yloc,0)*MsclZ
>                                 >;
>         #declare Pary[ycnt][xcnt] = totalV;
>         #declare totalV = totalV+1;
>
>       #else
>         #declare Pary[ycnt][xcnt] = -1000; // negative flag
>
>       #end //if
>
>    #declare xloc = xloc+incx;
>    #declare xcnt = xcnt+1;
>    #end //while(x)
> #declare yloc = yloc+incy;
> #declare ycnt = ycnt+1;
> #end //while(y)
>
> // * --- use something like this only if testing small, low res pictures
> #declare checkMary = union
> {
> #declare cnt = 0;
> #while (cnt < totalV)
> sphere
> { <Mary[cnt].x, Mary[cnt].y, 0> 0.83
>   texture
>    { pigment
>      { rgb <Mary[cnt].z/MsclZ, Mary[cnt].z/MsclZ, Mary[cnt].z/MsclZ>
>      }
>    }
>   finish{ambient 0.7}
> }
> #declare cnt = cnt+1;
> #end
> }
>
> object {checkMary translate <0,0,0>}
> //*/
>
>
> // Step 3: Make the triangles
> #declare totalF = 0;
> #declare ycnt = 1;
> #while (ycnt < (Resy*ScY))  //A
>    #declare xcnt = 0;
>    #while (xcnt < (Resx*ScX)) //B
>
>        #if(xcnt < (Resx-1)) // C
>        #if(Pary[ycnt][xcnt] > -10 & Pary[ycnt-1][xcnt] > -10
>             & Pary[ycnt-1][xcnt+1] > -10
>            ) // D // <y,x><y-,x><y-,x+>
>             #declare triang[totalF] =
>              < Pary[ycnt][xcnt], Pary[ycnt-1][xcnt], Pary[ycnt-1][xcnt+1]
>;
>                  // <y,x> <y-,x> <y-,x+> is a triangle with
>                  // right angle on upper right
>              #declare totalF = totalF+1;
>            #end // D
>
>            #if( Pary[ycnt][xcnt] > -10 & Pary[ycnt][xcnt+1] > -10 &
>                 Pary[ycnt-1][xcnt+1] > -10
>                 ) // E
>              #declare triang[totalF] =
>              < Pary[ycnt][xcnt], Pary[ycnt][xcnt+1], Pary[ycnt-1][xcnt+1]
>;
>                  // <y,x> <y,x+> <y-,x+> is a triangle with
>                  // right angle on lower left
>              #declare totalF = totalF+1;
>              #end // E
>
>              //----- These two triangles use another diagonal -----:
>              #if( Pary[ycnt][xcnt] > -10 & Pary[ycnt][xcnt+1] > -10 &
>                 Pary[ycnt-1][xcnt+1] < -10 & Pary[ycnt-1][xcnt] > -10
>                 ) // E
>              #declare triang[totalF] =
>              < Pary[ycnt][xcnt], Pary[ycnt][xcnt+1], Pary[ycnt-1][xcnt] >;
>              #declare totalF = totalF+1;
>              #end // E
>              // ---
>              #if( Pary[ycnt][xcnt] < -10 & Pary[ycnt][xcnt+1] > -10 &
>                 Pary[ycnt-1][xcnt+1] > -10 & Pary[ycnt-1][xcnt] > -10
>                 ) // E
>              #declare triang[totalF] =
>              < Pary[ycnt-1][xcnt+1], Pary[ycnt][xcnt+1],
Pary[ycnt-1][xcnt]
> >;
>              #declare totalF = totalF+1;
>              #end // E
>              // ---
>
>         #end // C
>
>
>    #declare xcnt = xcnt+1;
>    #end // B
> #declare ycnt = ycnt+1;
> #end // A
>
> /* ---- check the data ----
> #declare cnt = 0;
> #while (cnt < totalF)
>   cylinder
>   { Mary[triang[cnt].x], Mary[triang[cnt].y], 0.14
>     pigment {rgb <1,1,0>} finish {ambient 0.7}
>   }
>   cylinder
>   { Mary[triang[cnt].x], Mary[triang[cnt].z], 0.14
>     pigment {rgb <1,0,1>} finish {ambient 0.7}
>   }
>   cylinder
>   { Mary[triang[cnt].y], Mary[triang[cnt].z], 0.14
>     pigment {rgb <0,1,1>} finish {ambient 0.7}
>   }
> #declare cnt = cnt+1;
> #end
> */
>
>
> /*
>
//==========================================================================
>
> The meshes I need usually don't have square edges, so I've developed a
> method
> for pre-cutting the mesh. The final system will work this way:
>
> 1) Draw a picture or a few that represents a height-feild portion of the
>    mesh sculpture you wish to make. Draw it in pencil and scan at least
>    one of them as a color image.
> 2) Take the picture into a photo-paint program like Corel's Photopaint
>    and split it into red, green and blue channels.
> 3) Turn the blue channel into a mask by painting all unwanted areas black
>    and all desired areas white. This is what an #if statement above tests
>    for. If the value in the blue channel is less than 0.08 it's considered
>    black enough to cut. In the future, areas that measure above 0.08 and
>    below 0.93 might be used to describe more grey info or "undercutting."
>    Undercutting means bending the mesh back under itself.
> 4) Because a color scan of a black and white drawing doesn't really give
>    you 16 bits worth of grey scale information the .hf dot operator can
use,
>    but only 3 repeated 8 bit grey scale images, one for each color
channel,
>    a second drawing can replace either the red or green channel that the
>    height field.
> 5) Then you will import your drawing into POV-ray as done above and an as
>    yet unfinished series of macros will turn it into a "mesh sheet."
> 6) The final mesh sculpture will be made from a series of these sheets
>    that are translated, rotated, warped, bent and joined together to make
>    something more 3 dimensional.
>
> */
>
> --normdoering
>
>


Post a reply to this message

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