Exemple #1
0
/* Releases all unfree'd memory from current memory pool */
void mem_release()
{
#if defined(MEM_RECLAIM)
  OStream *f = NULL;
  MEMNODE *p, *tmp;
  size_t totsize;

  p = memlist;
  totsize = 0;

#if defined(MEM_TRACE)
  if (p != NULL && (p->poolno == poolno))
    f = New_OStream(MEM_LOG_FNAME, POV_File_Data_LOG, true);
#endif /* MEM_TRACE */

  while (p != NULL && (p->poolno == poolno))
  {
#if defined(MEM_TRACE)

#if defined(MEM_TAG)
    if (!mem_check_tag(p))
      Debug_Info("mem_release(): Memory pointer corrupt!\n");
#endif /* MEM_TAG */

    totsize += (p->size - NODESIZE - (MEM_GUARD_SIZE * 2));
    if (!leak_msg)
    {
      Debug_Info("Memory leakage detected, see file '%s' for list\n",MEM_LOG_FNAME);
      leak_msg = true;
    }

    if (f != NULL)
      f->printf("File:%13s  Line:%4d  Size:%lu\n", p->file, p->line, (unsigned long)(p->size - NODESIZE - (MEM_GUARD_SIZE * 2)));
#endif /* MEM_TRACE */

#if defined(MEM_STATS)
    mem_stats_free(p->size);
#endif

    tmp = p;
    p = p->next;
    remove_node(tmp);
    FREE(tmp);
  }

  if (f != NULL)
    delete f;

  if (totsize > 0)
    Debug_Info("%lu bytes reclaimed (pool #%d)\n", totsize, poolno);

  if (poolno > 0)
    poolno--;

#if defined(MEM_STATS)
  /* reinitialize the stats structure for next time through */
  mem_stats_init();
#endif

#endif /* MEM_RECLAIM */
}
Exemple #2
0
/* Released all unfree'd memory from all pools */
void mem_release_all()
{
#if defined(MEM_RECLAIM)
    OStream *f = NULL;
    MEMNODE *p, *tmp;
    size_t totsize;

//  Send_Progress("Reclaiming memory", PROGRESS_RECLAIMING_MEMORY);

    p = memlist;
    totsize = 0;

#if defined(MEM_TRACE)
    if (p != NULL)
        f = New_OStream(MEM_LOG_FNAME, POV_File_Data_LOG, true);
#endif

    while (p != NULL)
    {
#if defined(MEM_TRACE)

        #if defined(MEM_TAG)
        if (!mem_check_tag(p))
            Debug_Info("mem_release_all(): Memory pointer corrupt!\n");
        #endif /* MEM_TAG */

        totsize += (p->size - NODESIZE - (MEM_GUARD_SIZE * 2));
        if (!leak_msg)
        {
            Debug_Info("Memory leakage detected, see file '%s' for list\n",MEM_LOG_FNAME);
            leak_msg = true;
        }

        if (f != NULL)
            f->printf("File:%13s  Line:%4d  Size:%lu\n", p->file, p->line, (unsigned long)(p->size - NODESIZE - (MEM_GUARD_SIZE * 2)));
#endif

#if defined(MEM_STATS)
        /* This is after we have printed stats, and this may slow us down a little,      */
        /* so we may want to simply re-initialize the mem-stats at the end of this loop. */
        mem_stats_free(p->size);
#endif

        tmp = p;
        p = p->next;
        remove_node(tmp);
        FREE(tmp);
    }

    if (f != NULL)
        delete f;

//  if (totsize > 0)
//      Debug_Info("\n%lu bytes reclaimed\n", totsize);

    poolno = 0;
    memlist = NULL;
#endif

#if defined(MEM_STATS)
    /* reinitialize the stats structure for next time through */
    mem_stats_init();
#endif

}
Exemple #3
0
void Destroy_IsoSurface(OBJECT* Object)
{
	ISOSURFACE *Isosrf = (ISOSURFACE *)Object;
	ISO_Max_Gradient *mginfo = Isosrf->mginfo;

	mginfo->refcnt--;
	mginfo->gradient = max(Isosrf->gradient, mginfo->gradient);
	mginfo->max_gradient = max(Isosrf->max_gradient, mginfo->max_gradient);

	if((Stage == STAGE_SHUTDOWN) && (mginfo->refcnt == 0))
	{
		FunctionCode *fn = POVFPU_GetFunction(*(Isosrf->Function));

		if(fn != NULL)
		{
			if(Isosrf->eval == false)
			{
				// Only show the warning if necessary!
				// BTW, not being too picky here is a feature and not a bug ;-)  [trf]
				if((mginfo->gradient > EPSILON) && (mginfo->max_gradient > EPSILON))
				{
					DBL diff = mginfo->max_gradient - mginfo->gradient;
					DBL prop = fabs(mginfo->max_gradient / mginfo->gradient);

					if(((prop <= 0.9) && (diff <= -0.5)) ||
					   (((prop <= 0.95) || (diff <= -0.1)) && (mginfo->max_gradient < 10.0)))
					{
						WarningAt(0, fn->filename, fn->filepos.lineno, fn->filepos.offset,
						          "The maximum gradient found was %0.3f, but max_gradient of the\n"
						          "isosurface was set to %0.3f. The isosurface may contain holes!\n"
						          "Adjust max_gradient to get a proper rendering of the isosurface.",
						          (float)(mginfo->gradient),
						          (float)(mginfo->max_gradient));
					}
					else if((diff >= 10.0) || ((prop >= 1.1) && (diff >= 0.5)))
					{
						WarningAt(0, fn->filename, fn->filepos.lineno, fn->filepos.offset,
						          "The maximum gradient found was %0.3f, but max_gradient of\n"
						          "the isosurface was set to %0.3f. Adjust max_gradient to\n"
						          "get a faster rendering of the isosurface.",
						          (float)(mginfo->gradient),
						          (float)(mginfo->max_gradient));
					}
				}
			}
			else
			{
				DBL diff = (mginfo->eval_max / max(mginfo->eval_max - mginfo->eval_var, EPSILON));

				if((Isosrf->eval_param[0] > mginfo->eval_max) ||
				   (Isosrf->eval_param[1] > diff))
				{
					mginfo->eval_cnt = max(mginfo->eval_cnt, 1.0); // make sure it won't be zero

					WarningAt(0, fn->filename, fn->filepos.lineno, fn->filepos.offset,
					          "Evaluate found a maximum gradient of %0.3f and an average\n"
					          "gradient of %0.3f. The maximum gradient variation was %0.3f.\n",
					          (float)(mginfo->eval_max),
					          (float)(mginfo->eval_gradient_sum / mginfo->eval_cnt),
					          (float)(mginfo->eval_var));

					if(opts.Options & VERBOSE)
					{
						diff = max(diff, 1.0); // prevent contradicting output

						Debug_Info("It is recommended to adjust the parameters of 'evaluate' to:\n"
					               "First parameter less than %0.3f\n"
					               "Second parameter less than %0.3f and greater than 1.0\n"
					               "Third parameter greater than %0.3f and less than 1.0\n",
						          (float)(mginfo->eval_max),
						          (float)(diff),
						          (float)(1.0 / diff));
					}
				}
			}
		}
	}

	if(mginfo->refcnt == 0)
		POV_FREE(mginfo);

	Destroy_Function(Isosrf->Function);
	Destroy_Transform(Isosrf->Trans);
	POV_FREE(Object);
}
Exemple #4
0
void ot_index_box(const Vector3d& min_point, const Vector3d& max_point, OT_ID *id)
{
// TODO OPTIMIZE

    DBL dx, dy, dz, desiredSize;
    DBL bsized, maxord;
    POW2OP_DECLARE()

    // Calculate the absolute minimum required size of the node, assuming it is perfectly centered within the node;
    // Node size must be a power of 2, and be large enough to accomodate box's biggest dimensions with maximum overhang to all sides

    // compute ideal size of the node for a perfect fit without any overhang
    dx = max_point.x() - min_point.x();
    dy = max_point.y() - min_point.y();
    dz = max_point.z() - min_point.z();
    desiredSize = max3(dx, dy, dz);

    // compute ideal size of the node for a perfect fit with full overhang to all sides
    // desiredSize /= (1 + 2 * 0.5);

    // compute best-matching power-of-two size for a perfect fit with overhang
    // (Note: theoretically this might pick a size larger than required if desiredSize is already a power of two)
    // desiredSize *= 2.0;
    POW2OP_FLOOR(bsized,desiredSize)

    // avoid divisions by zero
    if(bsized == 0.0)
        bsized = 1.0;

#ifdef SAFE_METHOD

    // This block checks for the case where the node id would cause integer
    // overflow, since it is a small buffer far away
    maxord = max3(fabs(min_point[X]), fabs(min_point[Y]), fabs(min_point[Z]));
    maxord += OT_BIAS;
    while (maxord / bsized > 1000000000.0)
    {
#ifdef RADSTATS
        overflows++;
#endif
        bsized *= 2.0;
    }
#endif // SAFE_METHOD

    // The node we chose so far would be ideal for a box of identical size positioned at the node's center,
    // but the actual box is probably somewhat off-center and therefore may have excessive overhang in some directions;
    // check and possibly fix this.

    Vector3d center = (min_point + max_point) / 2;
    id->x = (int) floor((center[X] + OT_BIAS) / bsized);
    id->y = (int) floor((center[Y] + OT_BIAS) / bsized);
    id->z = (int) floor((center[Z] + OT_BIAS) / bsized);
    POW2OP_ENCODE(id->Size, bsized)

#ifdef RADSTATS
    thisloops = 0;
#endif
    while (!ot_point_in_node(min_point, id) || !ot_point_in_node(max_point, id))
    {
        // Debug_Info("looping %d,%d,%d,%d  min=%d, max=%d\n", test_id.x, test_id.y,
        // test_id.z, test_id.Size, ot_point_in_node(min_point, &test_id),
        // ot_point_in_node(max_point, &test_id));
        ot_parent(id, id);
#ifdef RADSTATS
        totloops++;
        thisloops++;
#endif
    }
#ifdef RADSTATS
    if (thisloops < minloops)
        minloops = thisloops;
    if (thisloops > maxloops)
        maxloops = thisloops;
#endif

#ifdef OT_DEBUG
    if (id->Size > 139)
    {
        Debug_Info("unusually large id, maxdel=%.4f, bsized=%.4f, isize=%d\n",
                   maxdel, bsized, id->Size);
    }
#endif
}
static int sort_and_split(BSPHERE_TREE **Root, BSPHERE_TREE ***Elements, int *nElem, int  first, int  last)
{
  int size, i, best_loc;
  DBL *area_left, *area_right;
  DBL best_index, new_index;
  BSPHERE_TREE *cd;

  Axis = find_axis(*Elements, first, last);

  size = last - first;

  if (size <= 0)
  {
    return (1);
  }

  Do_Cooperate(1);

  /*
   * Actually, we could do this faster in several ways. We could use a
   * logn algorithm to find the median along the given axis, and then a
   * linear algorithm to partition along the axis. Oh well.
   */

  QSORT((void *)(*Elements + first), size, sizeof(BSPHERE_TREE *), comp_elements);

  /*
   * area_left[] and area_right[] hold the surface areas of the bounding
   * boxes to the left and right of any given point. E.g. area_left[i] holds
   * the surface area of the bounding box containing Elements 0 through i and
   * area_right[i] holds the surface area of the box containing Elements
   * i through size-1.
   */

  area_left  = (DBL *)POV_MALLOC(size * sizeof(DBL), "blob bounding hierarchy");
  area_right = (DBL *)POV_MALLOC(size * sizeof(DBL), "blob bounding hierarchy");

  /* Precalculate the areas for speed. */

  build_area_table(*Elements, first, last - 1, area_left);
  build_area_table(*Elements, last - 1, first, area_right);

  best_index = area_right[0] * (size - 3.0);

  best_loc = - 1;

  /*
   * Find the most effective point to split. The best location will be
   * the one that minimizes the function N1*A1 + N2*A2 where N1 and N2
   * are the number of objects in the two groups and A1 and A2 are the
   * surface areas of the bounding boxes of the two groups.
   */

  for (i = 0; i < size - 1; i++)
  {
    new_index = (i + 1) * area_left[i] + (size - 1 - i) * area_right[i + 1];

    if (new_index < best_index)
    {
      best_index = new_index;
      best_loc = i + first;
    }
  }

  POV_FREE(area_left);
  POV_FREE(area_right);

  /*
   * Stop splitting if the BRANCHING_FACTOR is reached or
   * if splitting stops being effective.
   */

  if ((size <= BRANCHING_FACTOR) || (best_loc < 0))
  {
    cd = (BSPHERE_TREE *)POV_MALLOC(sizeof(BSPHERE_TREE), "blob bounding hierarchy");

    cd->Entries = (short)size;

    cd->Node = (BSPHERE_TREE **)POV_MALLOC(size*sizeof(BSPHERE_TREE *), "blob bounding hierarchy");

    for (i = 0; i < size; i++)
    {
      cd->Node[i] = (*Elements)[first+i];
    }

    recompute_bound(cd);

    *Root = cd;

    if (*nElem >= maxelements)
    {
      /* Prim array overrun, increase array by 50%. */

      maxelements = 1.5 * maxelements;

      /* For debugging only. */

      Debug_Info("Reallocing elements to %d\n", maxelements);

      *Elements = (BSPHERE_TREE **)POV_REALLOC(*Elements, maxelements * sizeof(BSPHERE_TREE *), "bounding slabs");
    }

    (*Elements)[*nElem] = cd;

    (*nElem)++;

    return (1);
  }
  else
  {
    sort_and_split(Root, Elements, nElem, first, best_loc + 1);

    sort_and_split(Root, Elements, nElem, best_loc + 1, last);

    return (0);
  }
}
static int sort_and_split(BBOX_TREE **Root, BBOX_TREE **&Finite, long *numOfFiniteObjects, long  first, long  last)
{
  BBOX_TREE *cd;
  long size, i, best_loc;
  DBL *area_left, *area_right;
  DBL best_index, new_index;

  Axis = find_axis(Finite, first, last);

  size = last - first;

  if (size <= 0)
  {
    return (1);
  }

  Do_Cooperate(1);

  /*
   * Actually, we could do this faster in several ways. We could use a
   * logn algorithm to find the median along the given axis, and then a
   * linear algorithm to partition along the axis. Oh well.
   */

  QSORT((void *)(&Finite[first]), (unsigned long)size, sizeof(BBOX_TREE *), compboxes);

  /*
   * area_left[] and area_right[] hold the surface areas of the bounding
   * boxes to the left and right of any given point. E.g. area_left[i] holds
   * the surface area of the bounding box containing Finite 0 through i and
   * area_right[i] holds the surface area of the box containing Finite
   * i through size-1.
   */

  area_left = (DBL *)POV_MALLOC(size * sizeof(DBL), "bounding boxes");
  area_right = (DBL *)POV_MALLOC(size * sizeof(DBL), "bounding boxes");

  /* Precalculate the areas for speed. */

  build_area_table(Finite, first, last - 1, area_left);
  build_area_table(Finite, last - 1, first, area_right);

  best_index = area_right[0] * (size - 3.0);

  best_loc = -1;

  /*
   * Find the most effective point to split. The best location will be
   * the one that minimizes the function N1*A1 + N2*A2 where N1 and N2
   * are the number of objects in the two groups and A1 and A2 are the
   * surface areas of the bounding boxes of the two groups.
   */

  for (i = 0; i < size - 1; i++)
  {
    new_index = (i + 1) * area_left[i] + (size - 1 - i) * area_right[i + 1];

    if (new_index < best_index)
    {
      best_index = new_index;
      best_loc = i + first;
    }
  }

  POV_FREE(area_left);
  POV_FREE(area_right);

  /*
   * Stop splitting if the BUNCHING_FACTOR is reached or
   * if splitting stops being effective.
   */

  if ((size <= BUNCHING_FACTOR) || (best_loc < 0))
  {
    cd = create_bbox_node(size);
      
    for (i = 0; i < size; i++)
    {
      cd->Node[i] = Finite[first+i];
    }

    calc_bbox(&(cd->BBox), Finite, first, last);

    *Root = (BBOX_TREE *)cd;

    if (*numOfFiniteObjects > maxfinitecount)
    {
      /* Prim array overrun, increase array by 50%. */

      maxfinitecount = 1.5 * maxfinitecount;

      /* For debugging only. */

      Debug_Info("Reallocing Finite to %d\n", maxfinitecount);

      Finite = (BBOX_TREE **)POV_REALLOC(Finite, maxfinitecount * sizeof(BBOX_TREE *), "bounding boxes");
    }

    Finite[*numOfFiniteObjects] = cd;

    (*numOfFiniteObjects)++;

    return (1);
  }
  else
  {
    sort_and_split(Root, Finite, numOfFiniteObjects, first, best_loc + 1);

    sort_and_split(Root, Finite, numOfFiniteObjects, best_loc + 1, last);

    return (0);
  }
}