| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060 |
- /****************************************************************************
- * csg.c
- *
- * This module implements routines for constructive solid geometry.
- *
- * from Persistence of Vision(tm) Ray Tracer
- * Copyright 1996,1999 Persistence of Vision Team
- *---------------------------------------------------------------------------
- * NOTICE: This source code file is provided so that users may experiment
- * with enhancements to POV-Ray and to port the software to platforms other
- * than those supported by the POV-Ray Team. There are strict rules under
- * which you are permitted to use this file. The rules are in the file
- * named POVLEGAL.DOC which should be distributed with this file.
- * If POVLEGAL.DOC is not available or for more info please contact the POV-Ray
- * Team Coordinator by email to team-coord@povray.org or visit us on the web at
- * http://www.povray.org. The latest version of POV-Ray may be found at this site.
- *
- * This program is based on the popular DKB raytracer version 2.12.
- * DKBTrace was originally written by David K. Buck.
- * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
- *
- *****************************************************************************/
- #include "frame.h"
- #include "povray.h"
- #include "vector.h"
- #include "povproto.h"
- #include "bbox.h"
- #include "csg.h"
- #include "hfield.h"
- #include "matrices.h"
- #include "objects.h"
- #include "planes.h"
- #include "quadrics.h"
- /*****************************************************************************
- * Local preprocessor defines
- ******************************************************************************/
- /*****************************************************************************
- * Static functions
- ******************************************************************************/
- static int All_CSG_Union_Intersections (OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack);
- static int All_CSG_Merge_Intersections (OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack);
- static int All_CSG_Intersect_Intersections (OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack);
- static int Inside_CSG_Union (VECTOR point, OBJECT *Object);
- static int Inside_CSG_Intersection (VECTOR point, OBJECT *Object);
- static CSG *Copy_CSG (OBJECT *Object);
- static void Translate_CSG (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
- static void Rotate_CSG (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
- static void Scale_CSG (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
- static void Transform_CSG (OBJECT *Object, TRANSFORM *Trans);
- static void Destroy_CSG (OBJECT *Object);
- static void Invert_CSG_Union (OBJECT *Object);
- static void Invert_CSG_Intersection (OBJECT *Object);
- /*****************************************************************************
- * Local variables
- ******************************************************************************/
- METHODS CSG_Union_Methods =
- {
- All_CSG_Union_Intersections,
- Inside_CSG_Union, NULL /*Normal*/,
- (COPY_METHOD)Copy_CSG,
- Translate_CSG, Rotate_CSG,
- Scale_CSG, Transform_CSG, Invert_CSG_Union, Destroy_CSG
- };
- METHODS CSG_Merge_Methods =
- {
- All_CSG_Merge_Intersections,
- Inside_CSG_Union, NULL /*Normal*/,
- (COPY_METHOD)Copy_CSG,
- Translate_CSG, Rotate_CSG,
- Scale_CSG, Transform_CSG, Invert_CSG_Union, Destroy_CSG
- };
- METHODS CSG_Intersection_Methods =
- {
- All_CSG_Intersect_Intersections,
- Inside_CSG_Intersection, NULL /*Normal*/,
- (COPY_METHOD)Copy_CSG,
- Translate_CSG, Rotate_CSG,
- Scale_CSG, Transform_CSG, Invert_CSG_Intersection, Destroy_CSG
- };
- /*****************************************************************************
- *
- * FUNCTION
- *
- * All_CSG_Union_Intersections
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * Sep 1994 : Added code to count intersection tests. [DB]
- *
- ******************************************************************************/
- static int All_CSG_Union_Intersections (OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack)
- {
- int Found;
- OBJECT *Current_Sib, *Clip;
- ISTACK *Local_Stack;
- INTERSECTION *Sibling_Intersection;
- Increase_Counter(stats[Ray_CSG_Union_Tests]);
- Found = FALSE;
- /* Use shortcut if no clip. */
- if ((Clip = Object->Clip) == NULL)
- {
- for (Current_Sib = ((CSG *)Object)->Children; Current_Sib != NULL; Current_Sib = Current_Sib->Sibling)
- {
- if (Ray_In_Bound (Ray, Current_Sib->Bound))
- {
- if (All_Intersections (Current_Sib, Ray, Depth_Stack))
- {
- Found = TRUE;
- }
- }
- }
- }
- else
- {
- Local_Stack = open_istack();
- for (Current_Sib = ((CSG *)Object)->Children; Current_Sib != NULL; Current_Sib = Current_Sib->Sibling)
- {
- if (Ray_In_Bound (Ray, Current_Sib->Bound))
- {
- if (All_Intersections (Current_Sib, Ray, Local_Stack))
- {
- while ((Sibling_Intersection = pop_entry(Local_Stack)) != NULL)
- {
- if (Point_In_Clip (Sibling_Intersection->IPoint, Clip))
- {
- push_copy (Depth_Stack, Sibling_Intersection);
- Found = TRUE;
- }
- }
- }
- }
- }
- close_istack (Local_Stack);
- }
- if (Found)
- {
- Increase_Counter(stats[Ray_CSG_Union_Tests_Succeeded]);
- }
- return (Found);
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * All_CSG_Intersection_Intersections
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * Sep 1994 : Added code to count intersection tests. [DB]
- *
- ******************************************************************************/
- static int All_CSG_Intersect_Intersections (OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack)
- {
- int Maybe_Found, Found;
- OBJECT *Current_Sib, *Inside_Sib;
- ISTACK *Local_Stack;
- INTERSECTION *Sibling_Intersection;
- Increase_Counter(stats[Ray_CSG_Intersection_Tests]);
- Local_Stack = open_istack ();
- Found = FALSE;
- for (Current_Sib = ((CSG *)Object)->Children; Current_Sib != NULL; Current_Sib = Current_Sib->Sibling)
- {
- if (Ray_In_Bound (Ray, Current_Sib->Bound))
- {
- if (All_Intersections (Current_Sib, Ray, Local_Stack))
- {
- while ((Sibling_Intersection = pop_entry(Local_Stack)) != NULL)
- {
- Maybe_Found = TRUE;
- for (Inside_Sib = ((CSG *)Object)->Children; Inside_Sib != NULL; Inside_Sib = Inside_Sib->Sibling)
- {
- if (Inside_Sib != Current_Sib)
- {
- if (!Inside_Object (Sibling_Intersection->IPoint, Inside_Sib))
- {
- Maybe_Found = FALSE;
- break;
- }
- }
- }
- if (Maybe_Found)
- {
- if (Point_In_Clip (Sibling_Intersection->IPoint, Object->Clip))
- {
- push_copy(Depth_Stack, Sibling_Intersection);
- Found = TRUE;
- }
- }
- }
- }
- }
- }
- close_istack (Local_Stack);
- if (Found)
- {
- Increase_Counter(stats[Ray_CSG_Intersection_Tests_Succeeded]);
- }
- return (Found);
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * All_CSG_Merge_Intersections
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * Sep 1994 : Added code to count intersection tests. [DB]
- *
- ******************************************************************************/
- static int All_CSG_Merge_Intersections (OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack)
- {
- int Found, inside_flag;
- OBJECT *Sib1, *Sib2;
- ISTACK *Local_Stack;
- INTERSECTION *Sibling_Intersection;
- Increase_Counter(stats[Ray_CSG_Merge_Tests]);
- Found = FALSE;
- Local_Stack = open_istack ();
- for (Sib1 = ((CSG *)Object)->Children; Sib1 != NULL; Sib1 = Sib1->Sibling)
- {
- if (Ray_In_Bound (Ray, Sib1->Bound))
- {
- if (All_Intersections (Sib1, Ray, Local_Stack))
- {
- while ((Sibling_Intersection = pop_entry (Local_Stack)) != NULL)
- {
- if (Point_In_Clip (Sibling_Intersection->IPoint, Object->Clip))
- {
- inside_flag = TRUE;
- for (Sib2 = ((CSG *)Object)->Children; Sib2 != NULL && inside_flag == TRUE; Sib2 = Sib2->Sibling)
- {
- if (Sib1 != Sib2)
- {
- if (Inside_Object(Sibling_Intersection->IPoint, Sib2))
- {
- inside_flag = FALSE;
- }
- }
- }
- if (inside_flag == TRUE)
- {
- Found = TRUE;
- push_copy (Depth_Stack, Sibling_Intersection);
- }
- }
- }
- }
- }
- }
- close_istack (Local_Stack);
- if (Found)
- {
- Increase_Counter(stats[Ray_CSG_Merge_Tests_Succeeded]);
- }
- return (Found);
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Inside_CSG_Union
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
- static int Inside_CSG_Union (VECTOR IPoint, OBJECT *Object)
- {
- OBJECT *Current_Sib;
- for (Current_Sib = ((CSG *)Object)->Children; Current_Sib != NULL; Current_Sib = Current_Sib->Sibling)
- {
- if (Inside_Object (IPoint, Current_Sib))
- {
- return (TRUE);
- }
- }
- return (FALSE);
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Inside_CSG_Intersection
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
- static int Inside_CSG_Intersection (VECTOR IPoint, OBJECT *Object)
- {
- OBJECT *Current_Sib;
- for (Current_Sib = ((CSG *)Object)->Children; Current_Sib != NULL; Current_Sib = Current_Sib->Sibling)
- {
- if (!Inside_Object (IPoint, Current_Sib))
- {
- return (FALSE);
- }
- }
- return (TRUE);
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Translate_CSG
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
- static void Translate_CSG (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
- {
- OBJECT *Sib;
- for (Sib = ((CSG *) Object)->Children; Sib != NULL; Sib = Sib->Sibling)
- {
- Translate_Object(Sib, Vector, Trans);
- }
- Recompute_BBox(&Object->BBox, Trans);
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Rotate_CSG
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
- static void Rotate_CSG (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
- {
- OBJECT *Sib;
- for (Sib = ((CSG *) Object)->Children; Sib != NULL; Sib = Sib->Sibling)
- {
- Rotate_Object(Sib, Vector, Trans);
- }
- Recompute_BBox(&Object->BBox, Trans);
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Scale_CSG
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
- static void Scale_CSG (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
- {
- OBJECT *Sib;
- for (Sib = ((CSG *) Object)->Children; Sib != NULL; Sib = Sib->Sibling)
- {
- Scale_Object(Sib, Vector, Trans);
- }
- Recompute_BBox(&Object->BBox, Trans);
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Transform_CSG
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
- static void Transform_CSG (OBJECT *Object, TRANSFORM *Trans)
- {
- OBJECT *Sib;
- for (Sib = ((CSG *) Object)->Children; Sib != NULL; Sib = Sib->Sibling)
- {
- Transform_Object (Sib, Trans);
- }
- Recompute_BBox(&Object->BBox, Trans);
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Invert_CSG_Union
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
- static void Invert_CSG_Union (OBJECT *Object)
- {
- OBJECT *Sib;
- Object->Methods = &CSG_Intersection_Methods;
- for (Sib = ((CSG *)Object)->Children; Sib != NULL; Sib = Sib->Sibling)
- {
- Invert_Object (Sib);
- }
- Invert_Flag(Object, INVERTED_FLAG);
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Invert_CSG_Intersection
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
- static void Invert_CSG_Intersection (OBJECT *Object)
- {
- OBJECT *Sib;
- Object->Methods = &CSG_Merge_Methods;
- for (Sib = ((CSG *)Object)->Children; Sib != NULL; Sib = Sib->Sibling)
- {
- Invert_Object (Sib);
- }
- Invert_Flag(Object, INVERTED_FLAG);
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Create_CSG_Union
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
- CSG *Create_CSG_Union ()
- {
- CSG *New;
- New = (CSG *)POV_MALLOC(sizeof (CSG), "union");
- INIT_OBJECT_FIELDS(New, UNION_OBJECT, &CSG_Union_Methods)
- New->Children = NULL;
- return (New);
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Create_CSG_Merge
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
- CSG *Create_CSG_Merge ()
- {
- CSG *New;
- New = (CSG *)POV_MALLOC(sizeof (CSG), "merge");
- INIT_OBJECT_FIELDS(New, MERGE_OBJECT, &CSG_Merge_Methods)
- New->Children = NULL;
- return (New);
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Create_CSG_Intersection
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
- CSG *Create_CSG_Intersection ()
- {
- CSG *New;
- New = (CSG *)POV_MALLOC(sizeof (CSG), "intersection");
- INIT_OBJECT_FIELDS(New, INTERSECTION_OBJECT, &CSG_Intersection_Methods)
- New->Children = NULL;
- return (New);
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Copy_CSG
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
- static CSG *Copy_CSG (OBJECT *Object)
- {
- CSG *New;
- OBJECT *Old_Sib, *New_Sib, *Prev_Sib;
- New = (CSG *)POV_MALLOC(sizeof (CSG), "csg");
- *New = *(CSG *)Object;
- New->Children = Prev_Sib = NULL;
- for (Old_Sib = ((CSG *)Object)->Children; Old_Sib != NULL; Old_Sib = Old_Sib->Sibling)
- {
- New_Sib = Copy_Object (Old_Sib);
- if (New->Children == NULL)
- {
- New->Children = New_Sib;
- }
- if (Prev_Sib != NULL)
- {
- Prev_Sib->Sibling = New_Sib;
- }
- Prev_Sib = New_Sib;
- }
- return (New);
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Destroy_CSG
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
- static void Destroy_CSG (OBJECT *Object)
- {
- Destroy_Object (((CSG *) Object)->Children);
- POV_FREE (Object);
- }
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Compute_CSG_BBox
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * Sep 1994 : Improved bounding of quadrics used in CSG intersections. [DB]
- *
- ******************************************************************************/
- void Compute_CSG_BBox (OBJECT *Object)
- {
- int i, count;
- DBL Old_Volume, New_Volume;
- VECTOR NewMin, NewMax, TmpMin, TmpMax, Min, Max;
- OBJECT *Sib;
- QUADRIC **Quadrics;
- if (Object->Methods == &CSG_Intersection_Methods)
- {
- /*
- * Calculate the bounding box of a CSG intersection
- * by intersecting the bounding boxes of all children.
- */
- Make_Vector(NewMin, -BOUND_HUGE, -BOUND_HUGE, -BOUND_HUGE);
- Make_Vector(NewMax, BOUND_HUGE, BOUND_HUGE, BOUND_HUGE);
- count = 0;
- Quadrics = NULL;
- /* Process all children. */
- for (Sib = ((CSG *)Object)->Children; Sib != NULL; Sib = Sib->Sibling)
- {
- /* Inverted objects and height fields mustn't be considered */
- if (!Test_Flag(Sib, INVERTED_FLAG) && (Sib->Methods != &HField_Methods))
- {
- /* Store quadrics since they'll be processed last. */
- if (Sib->Methods == &Quadric_Methods)
- {
- Quadrics = (QUADRIC **)POV_REALLOC(Quadrics, (count+1)*sizeof(QUADRIC *), "temporary quadric list");
- Quadrics[count++] = (QUADRIC *)Sib;
- }
- else
- {
- if (Sib->Methods == &Plane_Methods)
- {
- Compute_Plane_Min_Max((PLANE *)Sib, TmpMin, TmpMax);
- }
- else
- {
- Make_min_max_from_BBox(TmpMin, TmpMax, Sib->BBox);
- }
- NewMin[X] = max(NewMin[X], TmpMin[X]);
- NewMin[Y] = max(NewMin[Y], TmpMin[Y]);
- NewMin[Z] = max(NewMin[Z], TmpMin[Z]);
- NewMax[X] = min(NewMax[X], TmpMax[X]);
- NewMax[Y] = min(NewMax[Y], TmpMax[Y]);
- NewMax[Z] = min(NewMax[Z], TmpMax[Z]);
- }
- }
- }
- /* Process any quadrics. */
- for (i = 0; i < count; i++)
- {
- Assign_Vector(Min, NewMin);
- Assign_Vector(Max, NewMax);
- Compute_Quadric_BBox(Quadrics[i], Min, Max);
- Make_min_max_from_BBox(TmpMin, TmpMax, Quadrics[i]->BBox);
- NewMin[X] = max(NewMin[X], TmpMin[X]);
- NewMin[Y] = max(NewMin[Y], TmpMin[Y]);
- NewMin[Z] = max(NewMin[Z], TmpMin[Z]);
- NewMax[X] = min(NewMax[X], TmpMax[X]);
- NewMax[Y] = min(NewMax[Y], TmpMax[Y]);
- NewMax[Z] = min(NewMax[Z], TmpMax[Z]);
- }
- if (Quadrics != NULL)
- {
- POV_FREE(Quadrics);
- }
- }
- else
- {
- /* Calculate the bounding box of a CSG merge/union object. */
- Make_Vector(NewMin, BOUND_HUGE, BOUND_HUGE, BOUND_HUGE);
- Make_Vector(NewMax, -BOUND_HUGE, -BOUND_HUGE, -BOUND_HUGE);
- for (Sib = ((CSG *)Object)->Children; Sib != NULL; Sib = Sib->Sibling)
- {
- Make_min_max_from_BBox(TmpMin, TmpMax, Sib->BBox);
- NewMin[X] = min(NewMin[X], TmpMin[X]);
- NewMin[Y] = min(NewMin[Y], TmpMin[Y]);
- NewMin[Z] = min(NewMin[Z], TmpMin[Z]);
- NewMax[X] = max(NewMax[X], TmpMax[X]);
- NewMax[Y] = max(NewMax[Y], TmpMax[Y]);
- NewMax[Z] = max(NewMax[Z], TmpMax[Z]);
- }
- }
- if ((NewMin[X] > NewMax[X]) || (NewMin[Y] > NewMax[Y]) || (NewMin[Z] > NewMax[Z]))
- {
- Warning(0.0, "Degenerate CSG bounding box (not used!).\n");
- }
- else
- {
- New_Volume = (NewMax[X] - NewMin[X]) * (NewMax[Y] - NewMin[Y]) * (NewMax[Z] - NewMin[Z]);
- BOUNDS_VOLUME(Old_Volume, Object->BBox);
- if (New_Volume < Old_Volume)
- {
- Make_BBox_from_min_max(Object->BBox, NewMin, NewMax);
- /* Beware of bounding boxes to large. */
- if ((Object->BBox.Lengths[X] > CRITICAL_LENGTH) ||
- (Object->BBox.Lengths[Y] > CRITICAL_LENGTH) ||
- (Object->BBox.Lengths[Z] > CRITICAL_LENGTH))
- {
- Make_BBox(Object->BBox, -BOUND_HUGE/2, -BOUND_HUGE/2, -BOUND_HUGE/2,
- BOUND_HUGE, BOUND_HUGE, BOUND_HUGE);
- }
- }
- }
- }
|