POV-Ray : Newsgroups : povray.binaries.images : Problem with f_rounded_box function Server Time
6 Nov 2024 02:21:59 EST (-0500)
  Problem with f_rounded_box function (Message 1 to 10 of 13)  
Goto Latest 10 Messages Next 3 Messages >>>
From: Sebastian H 
Subject: Problem with f_rounded_box function
Date: 9 Mar 2006 05:57:20
Message: <44100a10@news.povray.org>
Hello

There seems to be a bug in the f_rounded_box function
when used with a zero radius. The documentation reads
for this case: "Zero gives square corners".
When used in an isosurface this appears to right only if
the bounding box exactly fits the now not more *rounded* box.
But if the bounding box is slightly increase there appears
a broken surface.

The first image shows an isosurface with exactly fitting bounding
box (means contained_by{ box{...} }) whereas the second one
shows the same isosurface with slightly increased bounding box.

The scene file is in p.b.scene-files.

Is this a known problem/bug?
I'm using POV-Ray 3.6.1
linux gcc (GCC) 3.3.5 (Debian 1:3.3.5-13).

Regards,
Sebastian


Post a reply to this message


Attachments:
Download 'frb_nobug.png' (5 KB) Download 'frb_bug.png' (4 KB)

Preview of image 'frb_nobug.png'
frb_nobug.png

Preview of image 'frb_bug.png'
frb_bug.png


 

From: Sebastian H 
Subject: Re: Problem with f_rounded_box function
Date: 9 Mar 2006 09:04:12
Message: <441035dc$1@news.povray.org>
Sebastian H. wrote:

> problem/bug?

I dug a bit in the source code and found that a
change in fnintern.cpp fixes the problem.
In the f_rounded_box function there is an offset
of 1e-6 subtracted from the actual result.

return (... - 1e-6);

With an increased offset magnitude of 1e-3
the problem disappears and the isosurface looks correct.
Why this offset is there is beyond me but removing it
slows down the isosurface rendering a lot.

Sebastian


Post a reply to this message

From: Mike Williams
Subject: Re: Problem with f_rounded_box function
Date: 9 Mar 2006 11:23:46
Message: <PSOA7GAVPFEEFw6T@econym.demon.co.uk>
Wasn't it Sebastian H. who wrote:
>Sebastian H. wrote:
>
>> problem/bug?
>
>I dug a bit in the source code and found that a
>change in fnintern.cpp fixes the problem.
>In the f_rounded_box function there is an offset
>of 1e-6 subtracted from the actual result.
>
>return (... - 1e-6);
>
>With an increased offset magnitude of 1e-3
>the problem disappears and the isosurface looks correct.
>Why this offset is there is beyond me but removing it
>slows down the isosurface rendering a lot.

I noticed that the slow down only seems to be happening with the
processing of shadows. If you add the no_shadow keyword, or move both
lights round to the front, then the isosurface renders quickly, but it
still has speckles.

-- 
Mike Williams
Gentleman of Leisure


Post a reply to this message

From: Christoph Hormann
Subject: Re: Problem with f_rounded_box function
Date: 9 Mar 2006 11:55:03
Message: <dupme5$rqb$1@chho.imagico.de>
Sebastian H. wrote:
> Sebastian H. wrote:
> 
>> problem/bug?
> 

The docs are wrong, f_rounded_box() should only be used with radius > 0. 
  This is not a bug but simply a limitation (although it would of course 
make sense to add an efficient handling of the case radius=0).

Note the current f_rounded_box() is not a very efficient solution anyway 
(you don't need an sqrt() for every evaluation).

> I dug a bit in the source code and found that a
> change in fnintern.cpp fixes the problem.
> In the f_rounded_box function there is an offset
> of 1e-6 subtracted from the actual result.
> 
> return (... - 1e-6);
> 
> With an increased offset magnitude of 1e-3
> the problem disappears and the isosurface looks correct.
> Why this offset is there is beyond me but removing it
> slows down the isosurface rendering a lot.

To me it seems this offset is specifically for handling the degenerate 
case.  Choosing 1e-3 simply gets you beyond your accuracy limit.

Christoph

-- 
POV-Ray tutorials, include files, Landscape of the week:
http://www.imagico.de/ (Last updated 31 Oct. 2005)
MegaPOV with mechanics simulation: http://megapov.inetart.net/


Post a reply to this message

From: Sebastian H 
Subject: Re: Problem with f_rounded_box function
Date: 12 Mar 2006 16:51:44
Message: <441497f0$1@news.povray.org>
Mike Williams wrote:

> I noticed that the slow down only seems to be happening with the
> processing of shadows. If you add the no_shadow keyword, or move both
> lights round to the front, then the isosurface renders quickly, but it
> still has speckles.
> 

I tried a scene with many isosurface with different parameters for
f_rounded_box and found that removing the offset reduces the overall
render time for the scene by about 2%. Though "a lot" slowdown is
overestimated it is noticeable.

I have a wip scene which uses f_rounded_box a lot and unfortunately
no shadow is not an option. But thank you for the hint anyway.

Sebastian


Post a reply to this message

From: Sebastian H 
Subject: Re: Problem with f_rounded_box function
Date: 12 Mar 2006 17:09:40
Message: <44149c24@news.povray.org>
Christoph Hormann wrote:
> The docs are wrong, f_rounded_box() should only be used with radius > 0. 
>  This is not a bug but simply a limitation (although it would of course 
> make sense to add an efficient handling of the case radius=0).
> 
> Note the current f_rounded_box() is not a very efficient solution anyway 
> (you don't need an sqrt() for every evaluation).
Actually I tried the following expression.

return (PARAM_X * PARAM_X
  + PARAM_Y * PARAM_Y
  + PARAM_Z * PARAM_Z
  - PARAM(0)*PARAM(0));

against

return (
  sqrt(PARAM_X * PARAM_X
  + PARAM_Y * PARAM_Y
  + PARAM_Z * PARAM_Z)
  - PARAM(0));

And found that the latter was always faster by about 30%.
I'm not exactly sure why it is that way but one problem
is that a the max_gradient needs higher values.
For the former version a max_gradient of 1.0 is always
suitable whereas for the latter one something
like

2.0*sqrt(3)*RADIUS

is neccessary.
There may be parameters for which the latter one is faster
but in the geral case the square root beats the square.
A least this is the result from the tests renders I did
on my pentium-m 1300MHz machine.

The most promissing solution I found looks like this.

DBL f_rounded_box(DBL *ptr, unsigned int) // 60
{

   DBL x2, y2, z2, x3, y3, z3;

   x2 = PARAM(1) - PARAM(0);
   y2 = PARAM(2) - PARAM(0);
   z2 = PARAM(3) - PARAM(0);

   x3 = fabs(PARAM_X);
   y3 = fabs(PARAM_Y);
   z3 = fabs(PARAM_Z);

   PARAM_X = (x3 < x2) ? 0 : (x3 - x2);
   PARAM_Y = (y3 < y2) ? 0 : (y3 - y2);
   PARAM_Z = (z3 < z2) ? 0 : (z3 - z2);

return (sqrt(PARAM_X * PARAM_X + PARAM_Y * PARAM_Y + PARAM_Z * PARAM_Z) 
  - PARAM(0));

}

Using fabs gave me approx. 2% speed increase in the test scene
(p.b.images).

> 
> To me it seems this offset is specifically for handling the degenerate 
> case.  Choosing 1e-3 simply gets you beyond your accuracy limit.

This was my intention. And yes, this is very likely. I tried the
degenerated case without the offset and the render process stuck
on the first line until I aborted after some minutes.

Sebastian


Post a reply to this message

From: Sebastian H 
Subject: Re: Problem with f_rounded_box function
Date: 12 Mar 2006 17:15:38
Message: <44149d8a@news.povray.org>
Here's the image of the test scene I used for comparing
the speed of different incarnations of f_rounded_box.

Actually I desired a more ordered scene but a typo ended
in this fractal beauty...

Sebastian


Post a reply to this message


Attachments:
Download 'frb_benchmark.jpg' (44 KB)

Preview of image 'frb_benchmark.jpg'
frb_benchmark.jpg


 

From: Christoph Hormann
Subject: Re: Problem with f_rounded_box function
Date: 12 Mar 2006 17:35:02
Message: <dv27jm$bsr$1@chho.imagico.de>
Sebastian H. wrote:
>>
>> Note the current f_rounded_box() is not a very efficient solution 
>> anyway (you don't need an sqrt() for every evaluation).
> 
> Actually I tried the following expression.
> 
> return (PARAM_X * PARAM_X
>  + PARAM_Y * PARAM_Y
>  + PARAM_Z * PARAM_Z
>  - PARAM(0)*PARAM(0));
> 

That's not what i meant.  You don't need the sqrt() on the faces of the 
rounded cube - there a simple plane function is sufficient.

Christoph

-- 
POV-Ray tutorials, include files, Landscape of the week:
http://www.imagico.de/ (Last updated 31 Oct. 2005)
MegaPOV with mechanics simulation: http://megapov.inetart.net/


Post a reply to this message

From: Sebastian H 
Subject: Re: Problem with f_rounded_box function
Date: 12 Mar 2006 18:39:55
Message: <4414b14b$1@news.povray.org>
Christoph Hormann wrote:
> Sebastian H. wrote:
> 
> That's not what i meant.  You don't need the sqrt() on the faces of the 
> rounded cube - there a simple plane function is sufficient.

Hmm, needs some "if" calls but gives another speed boost of
approx. 8% in the test image.
The function now looks like this.

DBL f_rounded_box(DBL *ptr, unsigned int) // 60
{
   DBL x2, y2, z2, x3, y3, z3;

   x2 = PARAM(1) - PARAM(0);
   y2 = PARAM(2) - PARAM(0);
   z2 = PARAM(3) - PARAM(0);

   x3 = fabs(PARAM_X);
   y3 = fabs(PARAM_Y);
   z3 = fabs(PARAM_Z);

   PARAM_X = (x3 < x2) ? 0 : (x3 - x2);
   PARAM_Y = (y3 < y2) ? 0 : (y3 - y2);
   PARAM_Z = (z3 < z2) ? 0 : (z3 - z2);

   // With coitus interruptus
   if(!PARAM_X)
     {
       if(!PARAM_Y)
	{
	  return (z3 - PARAM(3));
	}
       if(!PARAM_Z)
	{
	  return (y3 - PARAM(2));
	}
     }

   if((!PARAM_Y) && (!PARAM_Z))
     {
       return (x3 - PARAM(1));
     }

   return (sqrt(PARAM_X * PARAM_X + PARAM_Y * PARAM_Y + PARAM_Z * 
PARAM_Z)  - PARAM(0));

}

Now there appear gradients above 1.0 but I could not find
any surface errors so I think a max_gradient of 1.0 is still fine.

If anyone wants to put this code or part of into the official source
feel free.

Sebastian


Post a reply to this message

From: Christoph Hormann
Subject: Re: Problem with f_rounded_box function
Date: 13 Mar 2006 04:25:03
Message: <dv3do9$j7c$1@chho.imagico.de>
Sebastian H. wrote:
> 
>> Sebastian H. wrote:
>>
>> That's not what i meant.  You don't need the sqrt() on the faces of 
>> the rounded cube - there a simple plane function is sufficient.
> 
> 
> Hmm, needs some "if" calls 

Yes, that's what i meant.  I would however do it somewhat differently 
(untested, based on what you wrote):

{
   DBL x2, y2, z2, x3, y3, z3;

   x2 = PARAM(1) - PARAM(0);
   y2 = PARAM(2) - PARAM(0);
   z2 = PARAM(3) - PARAM(0);

   x3 = fabs(PARAM_X);
   y3 = fabs(PARAM_Y);
   z3 = fabs(PARAM_Z);

   if (x3 < x2)
   {
     if (y3 < y2)
     {
       if (z3 < z2)
       {
         return -PARAM(0);
       }
       return (z3 - PARAM(3));
     }
     if (z3 < z2)
     {
       return (y3 - PARAM(2));
     }
     return (sqrt(PARAM_Y * PARAM_Y + PARAM_Z * PARAM_Z)  - PARAM(0));
   }

   if (y3 < y2)
   {
     if (z3 < z2)
     {
       return (x3 - PARAM(1));
     }
     return (sqrt(PARAM_X * PARAM_X + PARAM_Z * PARAM_Z)  - PARAM(0));
   }

   if (z3 < z2)
   {
     return (sqrt(PARAM_X * PARAM_X + PARAM_Y * PARAM_Y)  - PARAM(0));
   }

   return (sqrt(PARAM_X * PARAM_X + PARAM_Y * PARAM_Y + PARAM_Z * 
PARAM_Z)  - PARAM(0));
}

It would BTW be easy to add a correct distance function for the interior 
as well by replacing the 'return -PARAM(0);'.  This would of course 
break backwards compatibility so it might not be a good idea.

Christoph

-- 
POV-Ray tutorials, include files, Landscape of the week:
http://www.imagico.de/ (Last updated 31 Oct. 2005)
MegaPOV with mechanics simulation: http://megapov.inetart.net/


Post a reply to this message

Goto Latest 10 Messages Next 3 Messages >>>

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