POV-Ray : Newsgroups : povray.advanced-users : passing variable to macro for use in #for statement : Re: passing variable to macro for use in #for statement Server Time: 19 Jan 2019 04:23:27 GMT
  Re: passing variable to macro for use in #for statement  
From: clipka
Date: 19 Sep 2018 17:57:47
Am 19.09.2018 um 17:58 schrieb Bald Eagle:
> Is it possible to start a loop in a macro using a variable name passed into the
> macro?
> 
> I think not, but maybe it's one of those #write #read workaround things.
> 
> Like so:
> #macro Loop (_Var, _Begin, _End, _Step)
>  #for (_Var, _Begin, _End, _Step)
>  ....
>  #end
> #end

That depends on what you actually want to achieve.

If you actually want to pass the /name/ of an identifier into the macro
(presumably as a string), you're pretty much out of luck.(*)

Theoretically you could probably use:

    #macro Loop (VarName, Begin, End, Step)
      #for (Parse_String(VarName), Begin, End, Step)
        ...
      #end
    #end

    Loop("Fnord",0,10,2)

but then the loop will actually use the macro-local variable `Fnord`,
not some global variable.


If however you just pass the variable itself (rather than its name),
then the following should work fine:

    #macro Loop (Var, Begin, End, Step)
      #for (Var, Begin, End, Step)
        ...
      #end
    #end

    #local Fnord = 42;
    Loop(Fnord,0,10,2)
    #debug concat("Fnord is now ", str(Fnord,0,0), "\n")

In this case, the macro-local name `Var` is used as an alias for the
"more global" variable named `Fnord`, and the for loop should use
exactly that same variable.


(* As of v3.8.0-alpha, another approach /may/ be viable; I haven't
tested it, and it may or may not work:

    #macro Loop (VarName, Begin, End, Step)
      #for (global[VarName], Begin, End, Step)
        ...
      #end
    #end

    #declare Fnord = 42;
    Loop("Fnord",0,10,2)
    #debug concat("Fnord is now ", str(Fnord,0,0), "\n")

If this works, it's because along with the introduction of dictionaries,
two pseudo-dictionaries have been added, `global` and `local`, which
allow access to the global and "most local" variables, respectively,
using dictionary-style syntax.

The caveat is that `#for` is specifically designed to use a local
variable as the loop counter, and it may gag on this construct. )


> Along the same lines, is it possible to assign an image_map file type to a
> variable
> like png, jpeg, etc. ?

Only using the `Parse_String` approach (or an equivalent homebrew
`#write`/`#include` workaround; as a matter of fact that's how the
`Parse_String` macro works behind the scenes):

    #declare Format = "png";
    image_map { Parse_String(Format) "foo.png" }

In the case of `image_map` it's probably easier and cleaner to use the
filename extension to convey the type information.

Also reasonably clean would be the following construct:

    #macro FormatKeyword(Format)
      #if (Format = "png")
        png
      #elif (Format = "jpeg")
        jpeg
      ....
      #end
    #end

    #declare Format = "png";
    image_map { FormatKeyword(Format) "foo.png" }


Post a reply to this message

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