POV-Ray : Newsgroups : povray.programming : Parametric object fix Server Time
22 Dec 2024 18:00:50 EST (-0500)
  Parametric object fix (Message 1 to 3 of 3)  
From: Wolfgang Wieser
Subject: Parametric object fix
Date: 3 Jul 2004 14:38:50
Message: <40e6fd38@news.povray.org>
As already mentioned in the previous thread, I have come up with a 
"solution" for the parametric object bug (crash) as reported by me 
(on 20 Jun 2003 21:49:03 in p.programming)

There are two problems: 
(1) When accuracy is made too small, an internal fixed-size array overflows. 
(2) Unless using no_shadow, the parametric object may be completely black. 

This (completely black object) can be seen e.g. using: 

------------------------------------------
#include "functions.inc"

global_settings { assumed_gamma 2.2 }
light_source { <-0.4,0.2,-0.3>*20, rgb <2,2,2>/2 }
light_source { <0.2,1,-0.8>*20, rgb <2,2,2>/1.7 }

#declare m=3;
parametric {










}


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

Let's come to the black object (2) first:
-----------------------------------------

Somebody (I do not know who) supposed a patch for this which was 
as follows (IMO): 

We need DEPTH_TOLERANCE again...




...and insert the two lines indicated with "+" below: 

---------------<fpmetric.cpp around line 220>------------------













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

This will make the above code render a nice green parametric object. 

I must admit that I do not completely understand why this works and 
it was not me who suggested it. I recall that some of my tests made 
the object have no self-shadow, so here comes a modified test scene which 
was used to verify that shadow and self-shadow work correctly for 
accuracies 0.01 and 1e-9: (NOTE! This needs the patch for (1) applied, 
see below.)

I do not know if we should apply this. Somebody with more clue about 
the code should comment on that. This change may have side effects 
which I am not aware of. But it seems, this solution is at least better 
than the current one. 

------------------------------
#include "functions.inc"

global_settings { assumed_gamma 2.2 }
light_source { <0.2,0.3,-0.3>*20*5, rgb <2,2,2>/1.7 }

#declare m=3;
parametric {










}

plane { y,-15 pigment { rgb x }}

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

Solution for (1)
----------------

This is what I verified to work with a test scene (the one above with 
different accuracy values in range 1e-3 to <1e-10): 

First of all, we should get rid of the fixed array sizes 32 for internal 
solver sectors: 

Around line 120, replacing 

-static DBL Intervals_Low[2][32], Intervals_Hi[2][32]; // GLOBAL VARIABLE
-static int SectorNum[32]; // GLOBAL VARIABLE

+static DBL Intervals_Low[2][SECT_DIM], Intervals_Hi[2][SECT_DIM];
+static int SectorNum[SECT_DIM]; // GLOBAL VARIABLE

should do the trick. This will use fixed-size SECT_DIM=48. It showed, that 
using more does not make sense given double precision. Actually, the old 
value 32 would also suffice for most tasks but no disortion appears with 
accuracies which need 48 or even 64 sectors. (One could use 64 to be on 
an even safer side.)

Around line 408, the solver bailout test reads: 

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





















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

The best thing we can probably do is to also bail out if the number 
of available sectors is insufficient. This means that the accuracy will 
no longer be guaranteed but OTOH dynamically increasing the 
number of sectors without any limit may IMHO trap us in an endless 
(or neraly endless) loop when fed with pathological functions. 
Hence, I suggest to do the following: 

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






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

I verified that this works as expected with the test scene with different 
accuracy settings and with different values for SECT_DIM (16..64). 

Somebody with more clue about the code could please comment on 
that. At least my solution should be better than the current behaviour. 

Furthermore, there is an uneccessary test: 

Around line 350: 

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

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

There is IMO no way how SectorNum could get zero or negative. The second 
test can be left away for the Z component (it is actually BOT present for X 
and Y). 

Hence, 

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

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

should work just fine. At least no problem showed up in my tests. 


Regards,
Wolfgang


Post a reply to this message

From: Massimo Valentini
Subject: Re: Parametric object fix
Date: 6 Jul 2004 07:01:21
Message: <40ea8681@news.povray.org>
"Wolfgang Wieser" ha scritto ...
> As already mentioned in the previous thread, I have come up with a 
> "solution" for the parametric object bug (crash) as reported by me 
> (on 20 Jun 2003 21:49:03 in p.programming)
> 
> There are two problems: 
> (1) When accuracy is made too small, an internal fixed-size array overflows. 
> (2) Unless using no_shadow, the parametric object may be completely black. 
> 
> This (completely black object) can be seen e.g. using: 
> 
> ------------------------------------------
> #include "functions.inc"
> 
> global_settings { assumed_gamma 2.2 }
> light_source { <-0.4,0.2,-0.3>*20, rgb <2,2,2>/2 }
> light_source { <0.2,1,-0.8>*20, rgb <2,2,2>/1.7 }
> 
> #declare m=3;
> parametric {
> function { u*sin(v) }
> function { 15*sqrt(pow(sin(m*v)*sin(u/2)/3,2)+
> pow(cos(m*v)*m/u*sin(u/2)/3,2)) }
> function { u*cos(v) }
> <0.001,0>, <15,2*pi>
> contained_by { sphere { 0, 15 } }
> precompute 12 x,y,z
> accuracy 0.00001
> 
> pigment { rgb y }
> }
> 
> camera { location <0,0.6,-1>*8.3*3 up y look_at <0,0,0> }
> --------------------------------------------
> 
> Let's come to the black object (2) first:
> -----------------------------------------
> 
> Somebody (I do not know who) supposed a patch for this which was 
> as follows (IMO): 

I suggested it

...
> Depth1 = 0;
> 
> + if (Depth1 < DEPTH_TOLERANCE)
> + Depth1 = DEPTH_TOLERANCE;
> 
> if ((Depth1 += 4 * Par->accuracy) > Depth2)
> return false;
> 
> Intervals_Low[INDEX_U][0] = Par->umin;
> -------------------------------------------------------------
> 
> This will make the above code render a nice green parametric object. 
> 
> I must admit that I do not completely understand why this works and 
> it was not me who suggested it. I recall that some of my tests made 
> the object have no self-shadow, so here comes a modified test scene which 
> was used to verify that shadow and self-shadow work correctly for 
> accuracies 0.01 and 1e-9: (NOTE! This needs the patch for (1) applied, 
> see below.)
> 
> I do not know if we should apply this. Somebody with more clue about 
> the code should comment on that. This change may have side effects 
> which I am not aware of. But it seems, this solution is at least better 
> than the current one. 
> 

I do agree, IMO it is better than the current.

My (short) comment on why the fix works:

The problem is that the surface is getting self shadowed for accuracy 
problems. The black color is the result of the surface being shadowed 
by itself.

The intersections between a ray and the parametric surface are not 
computed exactly, the algorithm would eventually converge to the solution, 
but you need to stop it at some point. So you obtain an approximated 
intersection, that's likely NOT on the surface, it is near, but either 
in front or behind the surface. 
Shooting a ray from the approximated (behind) intersection point to the 
light, it will find the same surface at a small distance from the start.

So the sense of the fix is to reduce the range in which to search a valid 
intersection. It is something that is done for nearly every primitive in 
POVray.

HTH 
Massimo


Post a reply to this message

From: Wolfgang Wieser
Subject: Re: Parametric object fix
Date: 10 Jul 2004 04:04:20
Message: <40efa304@news.povray.org>
Massimo Valentini wrote:
> "Wolfgang Wieser" ha scritto ...
>> Somebody (I do not know who) supposed a patch for this which was
>> as follows (IMO):
> 
> I suggested it
> 
I just added a note (and your explanation) to the sources so that I know 
next time... :)

Wolfgang


Post a reply to this message

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