POV-Ray : Newsgroups : povray.advanced-users : function select logic Server Time: 26 Jun 2019 20:01:08 GMT
 function select logic (Message 1 to 10 of 17)
 From: Mike Horvath Subject: function select logic Date: 23 Nov 2016 06:59:17 Message: <58353e45\$1@news.povray.org>
```I have the following three functions:

#declare correctRGB_R = function(R,G,B) {min(max(R,0),1)}
#declare correctRGB_G = function(R,G,B) {min(max(G,0),1)}
#declare correctRGB_B = function(R,G,B) {min(max(B,0),1)}

They each process input and output one component of an R,G,B color vector.

However, instead of the above, I want the entire vector discarded if
*any* of R, G or B is less than zero or greater than one.

I'm not sure how to form the select statement. What is the best way to
do this?

Mike
```
 From: Bald Eagle Subject: Re: function select logic Date: 23 Nov 2016 12:55:00 Message:
```Mike Horvath <mik### [at] gmailcom> wrote:
> I have the following three functions:
>
> #declare correctRGB_R = function(R,G,B) {min(max(R,0),1)}
> #declare correctRGB_G = function(R,G,B) {min(max(G,0),1)}
> #declare correctRGB_B = function(R,G,B) {min(max(B,0),1)}
>
> They each process input and output one component of an R,G,B color vector.
>
> However, instead of the above, I want the entire vector discarded if
> *any* of R, G or B is less than zero or greater than one.
>
> I'm not sure how to form the select statement. What is the best way to
> do this?
>
> Mike

Wrap all three #declares in a conditional block?

#if (R>1 | R<0 | G>1 | G<0 | B>1 | B<0)
// do nothing, or whatever else you want
#else
#declare correctRGB_R = function(R,G,B) {min(max(R,0),1)}
#declare correctRGB_G = function(R,G,B) {min(max(G,0),1)}
#declare correctRGB_B = function(R,G,B) {min(max(B,0),1)}
#end

or something along those lines....
```
 From: scott Subject: Re: function select logic Date: 23 Nov 2016 14:30:26 Message: <5835a802\$1@news.povray.org>
```On 23/11/2016 12:51, Bald Eagle wrote:
> Mike Horvath <mik### [at] gmailcom> wrote:
>> I have the following three functions:
>>
>> #declare correctRGB_R = function(R,G,B) {min(max(R,0),1)}
>> #declare correctRGB_G = function(R,G,B) {min(max(G,0),1)}
>> #declare correctRGB_B = function(R,G,B) {min(max(B,0),1)}
>>
>> They each process input and output one component of an R,G,B color vector.
>>
>> However, instead of the above, I want the entire vector discarded if
>> *any* of R, G or B is less than zero or greater than one.
>>
>> I'm not sure how to form the select statement. What is the best way to
>> do this?
>>
>> Mike

What do you mean by discarded? A function must always return a value,
there is no "discarded" option. Where/how are you going to use these
three functions and what do you want the final result to be if the input
RGB is out of range? You could return a special value like -1 to
indicate a "discarded" vector - but it depends what you're going to do
next with the result.

> Wrap all three #declares in a conditional block?
>
> #if (R>1 | R<0 | G>1 | G<0 | B>1 | B<0)
>      // do nothing, or whatever else you want
> #else
>      #declare correctRGB_R = function(R,G,B) {min(max(R,0),1)}
>      #declare correctRGB_G = function(R,G,B) {min(max(G,0),1)}
>      #declare correctRGB_B = function(R,G,B) {min(max(B,0),1)}
> #end
>
> or something along those lines....

That's just going to decide whether or not to declare the functions in
the scene, on some unrelated RGB variables (RGB in the function
definitions are just parameters). It won't affect the behaviour of the
function when it is actually used later on (apart from getting an error
that it is undefined).
```
 From: Bald Eagle Subject: Re: function select logic Date: 23 Nov 2016 15:05:01 Message:
```scott <sco### [at] scottcom> wrote:

> What do you mean by discarded? A function must always return a value,
> there is no "discarded" option. Where/how are you going to use these
> three functions and what do you want the final result to be if the input
> RGB is out of range? You could return a special value like -1 to
> indicate a "discarded" vector - but it depends what you're going to do
> next with the result.

That was my concern as well.
I thought of a similar -1 or other "flag" value - and then he could set transmit
to 1 so it's essentially invisible.

> That's just going to decide whether or not to declare the functions in
> the scene, on some unrelated RGB variables (RGB in the function
> definitions are just parameters). It won't affect the behaviour of the
> function when it is actually used later on (apart from getting an error
> that it is undefined).

Well that was the "or..." part of the "do nothing" conditional result.
#declare RGB = color rgbt <1, 1, 1, 1>;

would be a default "hide / 'discard' this out of range result"
```
 From: scott Subject: Re: function select logic Date: 23 Nov 2016 15:40:14 Message: <5835b85e\$1@news.povray.org>
```>> That's just going to decide whether or not to declare the functions in
>> the scene, on some unrelated RGB variables (RGB in the function
>> definitions are just parameters). It won't affect the behaviour of the
>> function when it is actually used later on (apart from getting an error
>> that it is undefined).
>
> Well that was the "or..." part of the "do nothing" conditional result.
> #declare RGB = color rgbt <1, 1, 1, 1>;
>
> would be a default "hide / 'discard' this out of range result"

I think you misunderstand my point. Any #if, #declare etc will only get
evaluated once when the scene is parsed. You'll end up with either your
function declared or not declared. When you come to use that function in
a pigment or isosurface or whatever your #if #declare statements won't
be executed again. Any logic needs to go inside the function declaration
using the select function, not #if.

Using the transmit channel is a good idea though. You could define
another function for calculating the transmit value, that just returns 1
if any of RGB parameters are out of range, or zero otherwise. This needs
to be a select statement inside a function though, not using #if.
```
 From: Bald Eagle Subject: Re: function select logic Date: 23 Nov 2016 16:00:01 Message:
```scott <sco### [at] scottcom> wrote:

> I think you misunderstand my point. Any #if, #declare etc will only get
> evaluated once when the scene is parsed. You'll end up with either your
> function declared or not declared. When you come to use that function in
> a pigment or isosurface or whatever your #if #declare statements won't
> be executed again. Any logic needs to go inside the function declaration
> using the select function, not #if.

True.
Though I was looking at "equations" not any declared functions.

> Using the transmit channel is a good idea though. You could define
> another function for calculating the transmit value, that just returns 1
> if any of RGB parameters are out of range, or zero otherwise. This needs
> to be a select statement inside a function though, not using #if.

I think that Mike is going to have a devil of a time trying to get that to go
with an isosurface.  That needs to be an implicit surface, no?

I'm leaning towards a parametric using splines defined by points resulting from
his stack-of-blocks code.

Maybe someone more clever, and with more round-tuits has a more elegant
solution....
```
 From: scott Subject: Re: function select logic Date: 23 Nov 2016 16:09:42 Message: <5835bf46\$1@news.povray.org>
```>> I think you misunderstand my point. Any #if, #declare etc will only get
>> evaluated once when the scene is parsed. You'll end up with either your
>> function declared or not declared. When you come to use that function in
>> a pigment or isosurface or whatever your #if #declare statements won't
>> be executed again. Any logic needs to go inside the function declaration
>> using the select function, not #if.
>
> True.
> Though I was looking at "equations" not any declared functions.

If this is the case then it's very easy, no need to use any functions or
select at all ... sorry, blatant copy&paste of your example :-)

#if (R>1 | R<0 | G>1 | G<0 | B>1 | B<0)
// do nothing, or whatever else you want
#else
// we know here that RGB are all within the 0...1 range, so no need
// to clamp with min/max
object{ blah blah pigment{ color rgb <R,G,B>} }
#end

But I got the impression from Mike's post that he needed a function to
do this for use later (maybe in a pigment?).
```
 From: Bald Eagle Subject: Re: function select logic Date: 23 Nov 2016 17:20:01 Message:
```scott <sco### [at] scottcom> wrote:

> But I got the impression from Mike's post that he needed a function to
> do this for use later (maybe in a pigment?).

Does this work?

========================================================================

#version 3.7;

global_settings {assumed_gamma 1.0}

#declare LimitRange = function (Number) {
select (Number,      // Input
666,        // special flag value for values less than zero
select (1-Number, 666, Number)  // second select operation
)        // 1 - 0 = 1
}         // 1 - 1 = 0
// 1 - 1.1 = - 0.1
// so using (1 - Number) then filters out numbers greater than 1
#for (Number, -1, 2, 0.5)
#declare Result = LimitRange (Number);
#debug concat( "Number = ", str(Number, 3, 1),  "     Result = ", str(Result,
3, 1), "\n")
#end
```
 From: Mike Horvath Subject: Re: function select logic Date: 23 Nov 2016 17:20:15 Message: <5835cfcf\$1@news.povray.org>
```On 11/23/2016 9:30 AM, scott wrote:
> What do you mean by discarded? A function must always return a value,
> there is no "discarded" option. Where/how are you going to use these
> three functions and what do you want the final result to be if the input
> RGB is out of range? You could return a special value like -1 to
> indicate a "discarded" vector - but it depends what you're going to do
> next with the result.
>

It's for an isosurface, actually, not a color. It just so happens I'm
modeling a color solid. So color = shape. Sorry.

When any of R, G or B are outside the range 0..1, then I do not want it
to be part of the shape. I think a select statement can do this.

Mike
```
 From: Mike Horvath Subject: Re: function select logic Date: 23 Nov 2016 20:50:24 Message: <58360110\$1@news.povray.org>
```On 11/23/2016 12:19 PM, Bald Eagle wrote:
> #declare LimitRange = function (Number) {
>  select (Number,      // Input
>  666,        // special flag value for values less than zero
>  select (1-Number, 666, Number)  // second select operation
>  )        // 1 - 0 = 1
> }         // 1 - 1 = 0
>          // 1 - 1.1 = - 0.1
>          // so using (1 - Number) then filters out numbers greater than 1
> #for (Number, -1, 2, 0.5)
>  #declare Result = LimitRange (Number);
>  #debug concat( "Number = ", str(Number, 3, 1),  "     Result = ", str(Result,
> 3, 1), "\n")
> #end

Can this be used to generate an isosurface? Will the 666 break an
isosurface?

Mike
```