POV-Ray : Newsgroups : povray.general : Cone bug and the bounding box : Re: Cone bug and the bounding box Server Time
11 Aug 2024 01:25:49 EDT (-0400)
  Re: Cone bug and the bounding box  
From: smellenbergh
Date: 5 Oct 1999 12:12:31
Message: <1dz5z0s.1qu7w92sztpigN@dialup69.leuven.skynet.be>
J. Grimbert <jgr### [at] atos-groupcom> wrote:

> I had some time this sunday to investigate the problem.
> The bounding box in the std distribution include a complete cone
> (with the pointy extremity), even if the specified cone is truncated.
> 
> 
> The correction is so easy, if you know were to look at
> and understand the Cones code...
> My guess is that the bounding box for the cone was made
> when the cone was always complete, and then never touched again.
> 
> In cones.c, just replace the 0.0 by Cone->dist in Compute_Cone_BBox

> That's all Folks!
> I have put an explanation with a picture on
> http://www.altern.org/grimbert/pov/index.html
> --
> J. Grimbert
Well, we tried it and it certainly is an improvement. However, the
bounding boxes are not as tight as they might be.
You can see this right away if you turn on the 'draw vista buffer'
option.

Please, try our fix and notice the difference. We have been waiting a
long time for someone to fix it. Our method is  a fix but it should be
possible to make it easier with less memory use.
Ok, we include our message from a while ago so you can try this. It
involves a bit more than replacing 0.0 by Cone->dist :-) but please try
it and see the difference.

If you can and are willing to do so, try to fix it even more. It makes
quite a difference if you have images with lots of those cones.

Best regards,
Smellenbergh

-- 
e-mail:sme### [at] skynetbe

http://users.skynet.be/smellenbergh

Here is our original message:


We discovered this a long time ago and reported it to the POV-Ray Team.
You will notice this bug easely when you use the draw vista buffer
option.

We have a solution for it (and it is implemented in our unofficial
compile for the Macintosh) but it is a workaround and certainly not a
bug fix. (but it works and decreases rendering time a lot).

Replace the following functions in the source files (you can use
3.1a,d,e or g sources) and make sure you define QUICK_CONES somewhere so
your compiler use the changes:

1)Cones.c
********
static void Transform_Cone(OBJECT *Object, TRANSFORM *Trans)
{
  CONE *Cone = (CONE *)Object;
  
  Compose_Transforms(Cone->Trans, Trans);
#ifdef QUICK_CONES
  if ( Cone->Trans->next != 0)
        Compose_Transforms(Cone->Trans->next,Trans);
#endif
  Compute_Cone_BBox(Cone);
}

void Compute_Cone_Data(OBJECT *Object)
{
  DBL tlen, len, tmpf;
  VECTOR tmpv, axis, origin;
  CONE *Cone = (CONE *)Object;

  /* Process the primitive specific information */
  if (fabs(Cone->apex_radius - Cone->base_radius) < EPSILON)
  {
    /* What we are dealing with here is really a cylinder */
    Set_Flag(Cone, CYLINDER_FLAG);
    Compute_Cylinder_Data(Object);
    return;
  }

  if (Cone->apex_radius < Cone->base_radius)
  {
    /* Want the bigger end at the top */
    Assign_Vector(tmpv,Cone->base);
    Assign_Vector(Cone->base,Cone->apex);
    Assign_Vector(Cone->apex,tmpv);
    tmpf = Cone->base_radius;
    Cone->base_radius = Cone->apex_radius;
    Cone->apex_radius = tmpf;
  }
#ifdef QUICK_CONES
        Cone->Trans->next=Create_Transform();
#endif

  /* Find the axis and axis length */
  VSub(axis, Cone->apex, Cone->base);
  VLength(len, axis);
  if (len < EPSILON)
  {
    Error("Degenerate cone/cylinder.\n");
  }
  else
  {
    VInverseScaleEq(axis, len)
  }
#ifdef QUICK_CONES
        Compute_Coordinate_Transform(Cone->Trans->next,Cone->base, axis,
Cone->apex_radius, len);
#endif

  /* Determine alignment */
  tmpf = Cone->base_radius * len / (Cone->apex_radius -
Cone->base_radius);
  VScale(origin, axis, tmpf);
  VSub(origin, Cone->base, origin);
  tlen = tmpf + len;
  Cone->dist = tmpf / tlen;
  Compute_Coordinate_Transform(Cone->Trans, origin, axis,
Cone->apex_radius, tlen);
  /* Recalculate the bounds */
  Compute_Cone_BBox(Cone);
}
static void Destroy_Cone(OBJECT *Object)
{
  #ifdef QUICK_CONES
        TRANSFORM *trans;
        trans= ((CONE*)Object)->Trans;
        if ( trans!= 0 && trans->next != 0)
                POV_FREE(trans->next);
#endif
  Destroy_Transform(((CONE *)Object)->Trans);

  POV_FREE (Object);
}
void Compute_Cone_BBox(CONE *Cone)
{
  Make_BBox(Cone->BBox, -1.0, -1.0, 0.0, 2.0, 2.0, 1.0);
#ifdef QUICK_CONES
        if ( Cone->Trans->next)
                Recompute_BBox(&Cone->BBox, Cone->Trans->next);
        else
                Recompute_BBox(&Cone->BBox, Cone->Trans);
#else
  Recompute_BBox(&Cone->BBox, Cone->Trans);
#endif
}

2)frame.h
********
typedef struct Transform_Struct TRANSFORM;

struct Transform_Struct
{
  MATRIX matrix;
  MATRIX inverse;
#ifdef QUICK_CONES
        TRANSFORM *next;
#endif
  
};

3)Matrices.c
**********
TRANSFORM *Create_Transform()
{
  TRANSFORM *New;

  New = (TRANSFORM *)POV_MALLOC(sizeof (TRANSFORM), "transform");

  MIdentity (New->matrix);
  MIdentity (New->inverse);
#ifdef QUICK_CONES
        New->next=0l;
#endif
  return (New);
}
TRANSFORM *Copy_Transform (TRANSFORM *Old)
{
  TRANSFORM *New;
  if (Old != NULL)
  {
    New  = Create_Transform ();
    *New = *Old;
#ifdef QUICK_CONES
        if ( Old->next != 0)
        {
                New->next=Create_Transform();
                *New->next=*Old->next;
        } 
#endif 

  }
  else
  {
    New = NULL;
  }

  return (New);
}

And that is all. Please notice that the memory requirements will
increase for every cone. 
Perhaps there is someone out there who can fix this bug and send it on
to the POV-Ray Team.
Everyone generating scenes with utilities like CTDS or some of our older
utilities will benefit from this fix.


Post a reply to this message

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