POV-Ray : Newsgroups : povray.general : how to call multiple instances of a macro? Server Time
4 Nov 2024 23:19:18 EST (-0500)
  how to call multiple instances of a macro? (Message 1 to 10 of 13)  
Goto Latest 10 Messages Next 3 Messages >>>
From: [GDS|Entropy]
Subject: how to call multiple instances of a macro?
Date: 15 Feb 2009 08:51:52
Message: <49981df8$1@news.povray.org>
I have the following macro, but I can't call multiple instances of it 
without overriding the previous values...how can I rewrite this macro to fix 
this?

I think the #declare is to blame, but it is also what makes it work...catch 
22?

It is terribly annoying.

#declare Sp = 60;

#macro randVector(ctr,Min,Max,Method)
 #local i=0;
 #while (i<ctr)
  #switch (Method)
   #case (0)
    #declare randVectArray[i] = <RRand(RsA, Min, Max),RRand(RsA, Min, 
Max),RRand(RsA, Min, Max)>;
   #break
   #case (1)
    #declare randVectArray[i] = <sin(RRand(RsA, Min, Max)),RRand(RsA, Min, 
Max),tan(RRand(RsA, Min, Max))>;
   #break
   #case (2)
    #declare randVectArray[i] = <sin(RRand(RsA, Min, Max)),atanh(RRand(RsA, 
Min, Max)),tan(RRand(RsA, Min, Max))>;
   #break
   #case (3)
    #declare randVectArray[i] = <asin(RRand(RsA, Min, Max)),atanh(RRand(RsA, 
Min, Max)),tan(RRand(RsA, Min, Max))>;
   #break
   #case (4)
    #declare randVectArray[i] = <acosh(RRand(RsA, Min, 
Max)),asinh(RRand(RsA, Min, Max)),tan(RRand(RsA, Min, Max))>;
   #break
   #case (5)
    #declare randVectArray[i] = <cos(i),i,sin(i)>;
   #break
  #end
 #set i=i+1;
 #end
#end

#declare randVectArray = array [Sp];

thanks!
ian


Post a reply to this message

From: Christian Froeschlin
Subject: Re: how to call multiple instances of a macro?
Date: 15 Feb 2009 11:19:33
Message: <49984095@news.povray.org>
[GDS|Entropy] wrote:
> I have the following macro, but I can't call multiple instances of it 
> without overriding the previous values...how can I rewrite this macro to fix 
> this?

Try something like this:

#macro Fill(A,N)
   #local i = 0;
   #while (i < N)
     #declare A[i] = i;
     #local i = i + 1;
   #end
#end

#declare Sp = 60;
#declare randVectArray = array[Sp];
Fill(randVectArray, Sp)

#declare Sp2 = 50;
#declare randVectArray2 = array[Sp2];
Fill(randVectArray2, Sp2)


Post a reply to this message

From: [GDS|Entropy]
Subject: Re: how to call multiple instances of a macro?
Date: 15 Feb 2009 12:06:25
Message: <49984b91$1@news.povray.org>
Ahhh...

That makes sense, now that I see it.

Would one be able to pass signs (+ - / *), isosurface function names and 
things like atan and sin in some manner as that as well?

I've been trying to do something like this: (pardon the crapcode)
#macro isoFunction(operator, funcName, xVal, yVal, zVal, P0, P1, P2, P3, P4, 
P5, P6)
 #local isoFunc = function {operator((funcName(xVal*x, xVal*y, zVal*z))};
 isoFunc(x,y,z)
#end

#declare foo = isoFunction(x+,f_noise3d,5,5,0.1,0,0,0,0,0,0);

No joy obviously.

You wouldn't happen to know if it is possible to concat strings as variable 
names, would you? #local myObj = concat(obj + i); would be great... :-D

Thanks!
ian

"Christian Froeschlin" <chr### [at] chrfrde> wrote in message 
news:49984095@news.povray.org...
> [GDS|Entropy] wrote:
>> I have the following macro, but I can't call multiple instances of it 
>> without overriding the previous values...how can I rewrite this macro to 
>> fix this?
>
> Try something like this:
>
> #macro Fill(A,N)
>   #local i = 0;
>   #while (i < N)
>     #declare A[i] = i;
>     #local i = i + 1;
>   #end
> #end
>
> #declare Sp = 60;
> #declare randVectArray = array[Sp];
> Fill(randVectArray, Sp)
>
> #declare Sp2 = 50;
> #declare randVectArray2 = array[Sp2];
> Fill(randVectArray2, Sp2)
>


Post a reply to this message

From: Christian Froeschlin
Subject: Re: how to call multiple instances of a macro?
Date: 15 Feb 2009 13:26:30
Message: <49985e56@news.povray.org>
[GDS|Entropy] wrote:

> Would one be able to pass signs (+ - / *)

no

> isosurface function names and 

yes (well, the function itself, not the name as string)

#macro DoubleFunc(F)
   function {2*F(x,y)}
#end

#declare f            = function(x,y){x*y}
#declare f_double     = DoubleFunc(f)

> things like atan and sin in some manner as that as well?

sort of - SDL seems to handle the built-in functions
differently from user-defined functions:

#declare atan2_double = DoubleFunc(atan2) // error
#declare atan2_double = DoubleFunc(function(x,y){atan2(x,y)}) // works

> I've been trying to do something like this: (pardon the crapcode)

Yuck ;) Actually I wasn't even sure if you intended
this to return a function or a value.

> You wouldn't happen to know if it is possible to concat strings as variable 
> names, would you? #local myObj = concat(obj + i); would be great... :-D

No. "POV-Ray macros are a strange mix of macros and functions",
and yes I'm quoting the documentation ;) But that's beside the
point, you should use an array whenever you even think about
appending an index to a variable name in code.


Post a reply to this message

From: Christian Froeschlin
Subject: Re: how to call multiple instances of a macro?
Date: 15 Feb 2009 13:40:27
Message: <4998619b$1@news.povray.org>
Christian Froeschlin wrote:

> [GDS|Entropy] wrote:
> 
>> Would one be able to pass signs (+ - / *)
> 
> no

Of course, no one prevents you from passing a function
which performs the operation, whatever your reasons:

   #declare op_add  = function(x,y){x+y}
   #declare op_sub  = function(x,y){x-y}
   #declare op_mult = function(x,y){x*y}
   #declare op_div  = function(x,y){x/y}
   #declare op_avg  = function(x,y){0.5*op_add(x,y)}

   #macro ConcatFunc(OP,F1,F2)
     function {OP(F1(x,y,z),F2(x,y,z))}
   #end

   #declare f_combined = ConcatFunc(op_avg, f_bozo, f_agate)

Just think clearly about what you wish to achieve before doing it ;)


Post a reply to this message

From: [GDS|Entropy]
Subject: Re: how to call multiple instances of a macro?
Date: 15 Feb 2009 14:29:05
Message: <49986d01$1@news.povray.org>
Hmm..well it seems that due to those limitations what I wish to do would 
actually be counterproductive.

The main reason that I wished to pass signs and iso func names was to create 
what would essentially be an overloaded an isosurface function builder macro 
(well..as close as pov can come to overloaded functions) that could be 
linked to various loops and PRNGs, mainly to decrease the code needed to 
accomplish certain things and compress all possible incarnations of 
isosurface into a single line macro call.

I wanted to do something similar with the build-in functions too.

It is times like these that I wish pov was more like c# and less like SDL.. 
;-)

Yeah the crapcode came about from the fact that while I was writing it, I 
thought: "hells..this isn't going to work..damned SDL" and I just stopped 
writing at that point. :-)

Ah, well..off to divine the depths of the Trace() function.

Thanks!
ian
"Christian Froeschlin" <chr### [at] chrfrde> wrote in message 
news:49985e56@news.povray.org...
> [GDS|Entropy] wrote:
>
>> Would one be able to pass signs (+ - / *)
>
> no
>
>> isosurface function names and
>
> yes (well, the function itself, not the name as string)
>
> #macro DoubleFunc(F)
>   function {2*F(x,y)}
> #end
>
> #declare f            = function(x,y){x*y}
> #declare f_double     = DoubleFunc(f)
>
>> things like atan and sin in some manner as that as well?
>
> sort of - SDL seems to handle the built-in functions
> differently from user-defined functions:
>
> #declare atan2_double = DoubleFunc(atan2) // error
> #declare atan2_double = DoubleFunc(function(x,y){atan2(x,y)}) // works
>
>> I've been trying to do something like this: (pardon the crapcode)
>
> Yuck ;) Actually I wasn't even sure if you intended
> this to return a function or a value.
>
>> You wouldn't happen to know if it is possible to concat strings as 
>> variable names, would you? #local myObj = concat(obj + i); would be 
>> great... :-D
>
> No. "POV-Ray macros are a strange mix of macros and functions",
> and yes I'm quoting the documentation ;) But that's beside the
> point, you should use an array whenever you even think about
> appending an index to a variable name in code.
>


Post a reply to this message

From: CShake
Subject: Re: how to call multiple instances of a macro?
Date: 11 Mar 2009 16:30:46
Message: <49b81f76@news.povray.org>
Christian Froeschlin wrote:
> Christian Froeschlin wrote:
> 
>> [GDS|Entropy] wrote:
>>
>>> Would one be able to pass signs (+ - / *)
>>
>> no
> 
> Of course, no one prevents you from passing a function
> which performs the operation, whatever your reasons:
> 
>   #declare op_add  = function(x,y){x+y}
>   #declare op_sub  = function(x,y){x-y}
>   #declare op_mult = function(x,y){x*y}
>   #declare op_div  = function(x,y){x/y}
>   #declare op_avg  = function(x,y){0.5*op_add(x,y)}
> 
>   #macro ConcatFunc(OP,F1,F2)
>     function {OP(F1(x,y,z),F2(x,y,z))}
>   #end
> 
>   #declare f_combined = ConcatFunc(op_avg, f_bozo, f_agate)
> 
> Just think clearly about what you wish to achieve before doing it ;)

I have a related question - is it possible to pass the name of a macro 
as a parameter in another macro? I notice in the documentation that it 
doesn't say that RVALUE can be a function, though apparently it can 
based on your example, so can it be other things as well?

cshake

example:
#macro lamp1(location,pointat,brightness)
   light_source{...}
#end
...
#macro lamp24(location,pointat,brightness)
   light_source{...}
#end

#macro stringOfLights(Lamp,Center,Brightness)
   #local i=1;
   #while(i<10)
     Lamp(Center+i*x,Center+i*x+<point_vector>,Brightness)
     #local i=i+1;
   #end
#end

stringOfLights("lamp1",<1,2,3>,10)


Post a reply to this message

From: Christian Froeschlin
Subject: Re: how to call multiple instances of a macro?
Date: 11 Mar 2009 18:15:52
Message: <49b83818$1@news.povray.org>
CShake wrote:

> I have a related question - is it possible to pass the name of a macro 
> as a parameter in another macro? 

I don't think that's possible.

> I notice in the documentation that it 
> doesn't say that RVALUE can be a function

Well it does say RVALUE can be a USER_FUNCTION in 3.8.4.2.

> stringOfLights("lamp1",<1,2,3>,10)

I you want to have multiple macros building on your lamp1
to lamp24 you might write a wrapper macro as follows

#macro lamp(lamp_type,location,pointat,brightness)
#switch (lamp_type)
#case(1) lamp1(location,pointat,brightness) #break
#case(2) lamp2(location,pointat,brightness) #break
...
#end
#end


Post a reply to this message

From: clipka
Subject: Re: how to call multiple instances of a macro?
Date: 11 Mar 2009 22:05:00
Message: <web.49b86bb4dc08335801985dd0@news.povray.org>
-------------
#macro lamp1(location,pointat,brightness)
  light_source{...}
#end

#macro lamp2(location,pointat,brightness)
  light_source{...}
#end

.....

#macro ParseLiteral(s)
  #local FileName = "ParseLiteral_$$$.inc";
  #fopen ParseLiteral_FD FileName write
  #write (ParseLiteral_FD, s)
  #fclose ParseLiteral_FD
  #include FileName
#end

#macro stringOfLights(Lamp,Center,Brightness)
  #local i=1;
  #while(i<10)
    ParseLiteral(Lamp) (Center+i*x,Center+i*x+<point_vector>,Brightness)
    #local i=i+1;
  #end
#end

stringOfLights("lamp1",<1,2,3>,10)

#local i=rand(R)*10;
stringOfLights(concat("lamp", str(i,0,0)),<4,5,6>,10)

-------------

POV SDL may be cumbersome at times, but let nobody say it wasn't flexible...


Post a reply to this message

From: CShake
Subject: Re: how to call multiple instances of a macro?
Date: 12 Mar 2009 02:15:38
Message: <49b8a88a$1@news.povray.org>
clipka wrote:
> #macro ParseLiteral(s)
>   #local FileName = "ParseLiteral_$$$.inc";
>   #fopen ParseLiteral_FD FileName write
>   #write (ParseLiteral_FD, s)
>   #fclose ParseLiteral_FD
>   #include FileName
> #end
> 
> #macro stringOfLights(Lamp,Center,Brightness)
>   #local i=1;
>   #while(i<10)
>     ParseLiteral(Lamp) (Center+i*x,Center+i*x+<point_vector>,Brightness)
>     #local i=i+1;
>   #end
> #end
> 
> stringOfLights("lamp1",<1,2,3>,10)
> 
> #local i=rand(R)*10;
> stringOfLights(concat("lamp", str(i,0,0)),<4,5,6>,10)
> 
> -------------
> 
> POV SDL may be cumbersome at times, but let nobody say it wasn't flexible...
> 
> 

Most helpful. Very much looks like a hack that wasn't exactly intended, 
but works perfectly.

I decided to use a slightly more segmented version to reduce a little 
bit of disk writing during parse:

#macro ParseLiteral(s)
   #declare ParsedLiteralFile = "ParseLiteral_$$$.inc";
   #fopen ParseLiteral_FD ParsedLiteralFile write
   #write (ParseLiteral_FD,s)
   #fclose ParseLiteral_FD
#end

#macro ParsedLiteral()
   #include ParsedLiteralFile
#end

......

ParseLiteral(macroName)
#local i=1;
#while(i<20)
   ParsedLiteral()(macro parameters)
   #local i=i+1;
#end

-------------

I wonder how much overhead this really causes, I figure that Christian 
Froeschlin's method of just using a selection macro and assigning 
numerical values to each macro name would be slightly more efficient 
when parsing, but involves more work for the user and is not very flexible.


Post a reply to this message

Goto Latest 10 Messages Next 3 Messages >>>

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