Exemplo n.º 1
0
// Create a bounding box hierarchy from a given list of finite and
// infinite elements. Each element consists of
//
// - an infinite flag
// - a bounding box enclosing the element
// - a pointer to the structure representing the element (e.g an object)
void Build_BBox_Tree(BBOX_TREE **Root, size_t numOfFiniteObjects, BBOX_TREE **&Finite, size_t numOfInfiniteObjects, BBOX_TREE **Infinite, size_t& maxfinitecount)
{
    ptrdiff_t low, high;
    BBOX_TREE *cd, *root;

    // This is a resonable guess at the number of finites needed.
    // This array will be reallocated as needed if it isn't.
    maxfinitecount = 2 * numOfFiniteObjects;

    // Now do a sort on the objects, with the end result being
    // a tree of objects sorted along the x, y, and z axes.
    if(numOfFiniteObjects > 0)
    {
        low = 0;
        high = numOfFiniteObjects;

        while(sort_and_split(Root, Finite, &numOfFiniteObjects, low, high, maxfinitecount) == 0)
        {
            low = high;
            high = numOfFiniteObjects;
        }

        // Move infinite objects in the first leaf of Root.
        if(numOfInfiniteObjects > 0)
        {
            root = *Root;
            root->Node = reinterpret_cast<BBOX_TREE **>(POV_REALLOC(root->Node, (root->Entries + 1) * sizeof(BBOX_TREE *), "composite"));
            POV_MEMMOVE(&(root->Node[1]), &(root->Node[0]), root->Entries * sizeof(BBOX_TREE *));
            root->Entries++;
            cd = create_bbox_node(numOfInfiniteObjects);
            for(size_t i = 0; i < numOfInfiniteObjects; i++)
                cd->Node[i] = Infinite[i];

            calc_bbox(&(cd->BBox), Infinite, 0, numOfInfiniteObjects);
            root->Node[0] = cd;
            calc_bbox(&(root->BBox), root->Node, 0, root->Entries);

            // Root and first node are infinite.
            root->Infinite = true;
            root->Node[0]->Infinite = true;
        }
    }
    else
    {
        // There are no finite objects and no Root was created.
        // Create it now and put all infinite objects into it.

        if(numOfInfiniteObjects > 0)
        {
            cd = create_bbox_node(numOfInfiniteObjects);
            for(size_t i = 0; i < numOfInfiniteObjects; i++)
                cd->Node[i] = Infinite[i];
            calc_bbox(&(cd->BBox), Infinite, 0, numOfInfiniteObjects);
            *Root = cd;
            (*Root)->Infinite = true;
        }
    }
}
Exemplo n.º 2
0
void CFFD::calc_afine_deform(void* pDest, int nStride)
{
	float     fDelX, fDelY, fDelZ, fX, fY, fZ;
	int       nX, nY, nZ;
	CVector   cT, cI1, cI2, cI3, cI4, cI5, cI6;
	CVector*  pTab = m_pVectorTable;
	CVector*  pDeformed = (CVector*)pDest;
	CVector*  pD1;
	CVector*  pD2;

	calc_bbox();

	fDelX = 1.0f/((m_cBMax.fX - m_cBMin.fX)/(float)(m_nDeformResX - 1));
	fDelY = 1.0f/((m_cBMax.fY - m_cBMin.fY)/(float)(m_nDeformResY - 1));
	fDelZ = 1.0f/((m_cBMax.fZ - m_cBMin.fZ)/(float)(m_nDeformResZ - 1));

	for (int nI = 0; nI != m_nElements; nI++)
	{
		cT.fX = (pTab->fX - m_cBMin.fX)*fDelX;
		cT.fY = (pTab->fY - m_cBMin.fY)*fDelY;
		cT.fZ = (pTab->fZ - m_cBMin.fZ)*fDelZ;

		nX = (int)cT.fX;
		nY = (int)cT.fY;
		nZ = (int)cT.fZ;

		fX = cT.fX - (float)nX;
		fY = cT.fY - (float)nY;
		fZ = cT.fZ - (float)nZ;

		pD1 = get_deform_point(nX, nY, nZ);
		pD2 = get_deform_point(nX + 1, nY, nZ);
		afine_interpolate(pD2, pD1, fX, cI1);

		pD1 = get_deform_point(nX, nY + 1, nZ);
		pD2 = get_deform_point(nX + 1, nY + 1, nZ);
		afine_interpolate(pD2, pD1, fX, cI2);

		pD1 = get_deform_point(nX, nY, nZ + 1);
		pD2 = get_deform_point(nX + 1, nY, nZ + 1);
		afine_interpolate(pD2, pD1, fX, cI3);

		pD1 = get_deform_point(nX, nY + 1, nZ + 1);
		pD2 = get_deform_point(nX + 1, nY + 1, nZ + 1);
		afine_interpolate(pD2, pD1, fX, cI4);

		afine_interpolate(&cI2, &cI1, fY, cI5);
		afine_interpolate(&cI4, &cI3, fY, cI6);
		afine_interpolate(&cI6, &cI5, fZ, *pDeformed);

		pTab = (CVector*)((char*)pTab + m_nVectorStride);
		pDeformed = (CVector*)((char*)pDeformed + nStride);
	}
}
Exemplo n.º 3
0
void CFFD::calc_spline_deform(void *pDest, int nStride)
{
	float     fDelX, fDelY, fDelZ, fX, fY, fZ;
	int       nX, nY, nZ, nI, nQ;
	CVector   cT;
	CVector*  pTab = m_pVectorTable;
	CVector*  pDeformed = (CVector*)pDest;

	CVector   aI1[4][4];
	CVector   aI2[4];

	calc_bbox();

	fDelX = 1.0f/((m_cBMax.fX - m_cBMin.fX)/(float)(m_nDeformResX - 1));
	fDelY = 1.0f/((m_cBMax.fY - m_cBMin.fY)/(float)(m_nDeformResY - 1));
	fDelZ = 1.0f/((m_cBMax.fZ - m_cBMin.fZ)/(float)(m_nDeformResZ - 1));

	for (int nS = 0; nS != m_nElements; nS++)
	{
		cT.fX = (pTab->fX - m_cBMin.fX)*fDelX;
		cT.fY = (pTab->fY - m_cBMin.fY)*fDelY;
		cT.fZ = (pTab->fZ - m_cBMin.fZ)*fDelZ;

		nX = (int)cT.fX;
		nY = (int)cT.fY;
		nZ = (int)cT.fZ;

		fX = cT.fX - (float)nX;
		fY = cT.fY - (float)nY;
		fZ = cT.fZ - (float)nZ;

		for (nQ = 0; nQ != 4; nQ++)
		{
			for (nI = 0; nI != 4; nI++)
			{
				spline_interpolate(*get_deform_point(nX - 1, nY - 1 + nI, nZ - 1 + nQ),
				*get_deform_point(nX    , nY - 1 + nI, nZ - 1 + nQ),
				*get_deform_point(nX + 1, nY - 1 + nI, nZ - 1 + nQ),
				*get_deform_point(nX + 2, nY - 1 + nI, nZ - 1 + nQ), fX, aI1[nI][nQ]);
			}
		}

		for (nI = 0; nI != 4; nI++)
		spline_interpolate(aI1[0][nI], aI1[1][nI], aI1[2][nI], aI1[3][nI], fY, aI2[nI]);

		spline_interpolate(aI2[0], aI2[1], aI2[2], aI2[3], fZ, *pDeformed);


		pTab = (CVector*)((char*)pTab + m_nVectorStride);
		pDeformed = (CVector*)((char*)pDeformed + nStride);
	}
}
Exemplo n.º 4
0
/*
  Load a simple database
*/
void load_database(void)
{

    ssgLoaderOptions *loaderopt = new ssgLoaderOptions();
    
    loaderopt->setCreateBranchCallback(hookNode);
    
    Root = ssgLoadAC(InputFileName, loaderopt);

    fprintf(stderr, "%d branches found\n", BrNb);

    calc_bbox();
    calc_coord();
}
Exemplo n.º 5
0
static __inline__ Uint32 sort_and_split(BBOX_TREE* bbox_tree, Uint32 node, Uint32* index, Uint32 first, Uint32 last)
{
	Uint32 size, i, j, axis[3];
	int best_loc;
	float *area_left, *area_right;
	float best_index, new_index;
#ifdef FASTER_MAP_LOAD
	AABBOX bbox;
#endif

	size = last - first;

	if (size < 1) return -1;

#ifdef FASTER_MAP_LOAD
	find_axis_and_bbox(bbox_tree, first, last, axis, &bbox);
#else
	find_axis(bbox_tree, first, last, axis);
#endif

	best_loc = -1;

	if (size > 8)
	{
		area_left = malloc(size * sizeof(float));
		area_right = malloc(size * sizeof(float));

		for (j = 0; j < 3; j++)
		{
			Axis = axis[j];

			qsort(bbox_tree->items + first, size, sizeof(BBOX_ITEM), compboxes);
			build_area_table(bbox_tree, first, last - 1, area_left);
			build_area_table(bbox_tree, last - 1, first, area_right);

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

			/*
			 * 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;
				}
			}
			if (best_loc >= 0) break;
		}

		free(area_left);
		free(area_right);
	}

#ifdef FASTER_MAP_LOAD
	VAssign(bbox_tree->nodes[node].bbox.bbmin, bbox.bbmin);
	VAssign(bbox_tree->nodes[node].bbox.bbmax, bbox.bbmax);
	VAssign(bbox_tree->nodes[node].orig_bbox.bbmin, bbox.bbmin);
	VAssign(bbox_tree->nodes[node].orig_bbox.bbmax, bbox.bbmax);
#else
	calc_bbox(&bbox_tree->nodes[node].bbox, bbox_tree, first, last);
	VAssign(bbox_tree->nodes[node].orig_bbox.bbmin, bbox_tree->nodes[node].bbox.bbmin);
	VAssign(bbox_tree->nodes[node].orig_bbox.bbmax, bbox_tree->nodes[node].bbox.bbmax);
#endif
	bbox_tree->nodes[node].items_index = first;
	bbox_tree->nodes[node].items_count = size;

	bbox_tree->nodes[node].dynamic_objects.size = 0;
	bbox_tree->nodes[node].dynamic_objects.index = 0;
	bbox_tree->nodes[node].dynamic_objects.items = NULL;

	if (best_loc < 0)
	{
		bbox_tree->nodes[node].nodes[0] = NO_INDEX;
		bbox_tree->nodes[node].nodes[1] = NO_INDEX;
		return 1;
	}
	else
	{
		if (*index+2 >= bbox_tree->nodes_count)
		{
			bbox_tree->nodes_count *= 2;
			bbox_tree->nodes = (BBOX_TREE_NODE*)realloc(bbox_tree->nodes, bbox_tree->nodes_count*sizeof(BBOX_TREE_NODE));
		}
		bbox_tree->nodes[node].nodes[0] = (*index)+0;
		bbox_tree->nodes[node].nodes[1] = (*index)+1;
		*index += 2;
		sort_and_split(bbox_tree, bbox_tree->nodes[node].nodes[0], index, first, best_loc + 1);
		sort_and_split(bbox_tree, bbox_tree->nodes[node].nodes[1], index, best_loc + 1, last);
		return 0;
	}
}
Exemplo n.º 6
0
void Build_BBox_Tree(BBOX_TREE **Root, long numOfFiniteObjects, BBOX_TREE **&Finite, long  numOfInfiniteObjects, BBOX_TREE  **Infinite)
{
  short i;
  long low, high;
  BBOX_TREE *cd, *root;

  /*
   * This is a resonable guess at the number of finites needed.
   * This array will be reallocated as needed if it isn't.
   */

  maxfinitecount = 2 * numOfFiniteObjects;

  /*
   * Now do a sort on the objects, with the end result being
   * a tree of objects sorted along the x, y, and z axes.
   */

  if (numOfFiniteObjects > 0)
  {
    low = 0;
    high = numOfFiniteObjects;

    while (sort_and_split(Root, Finite, &numOfFiniteObjects, low, high) == 0)
    {
      low = high;
      high = numOfFiniteObjects;

      Do_Cooperate(0);
    }

    /* Move infinite objects in the first leaf of Root. */

    if (numOfInfiniteObjects > 0)
    {
      root = (BBOX_TREE *)(*Root);

      root->Node = (BBOX_TREE **)POV_REALLOC(root->Node, (root->Entries + 1) * sizeof(BBOX_TREE *), "composite");

      POV_MEMMOVE(&(root->Node[1]), &(root->Node[0]), root->Entries * sizeof(BBOX_TREE *));

      root->Entries++;

      cd = create_bbox_node(numOfInfiniteObjects);

      for (i = 0; i < numOfInfiniteObjects; i++)
      {
        cd->Node[i] = Infinite[i];
      }

      calc_bbox(&(cd->BBox), Infinite, 0, numOfInfiniteObjects);

      root->Node[0] = (BBOX_TREE *)cd;

      calc_bbox(&(root->BBox), root->Node, 0, root->Entries);

      /* Root and first node are infinite. */

      root->Infinite = true;

      root->Node[0]->Infinite = true;
    }
  }
  else
  {
    /*
     * There are no finite objects and no Root was created.
     * Create it now and put all infinite objects into it.
     */

    if (numOfInfiniteObjects > 0)
    {
      cd = create_bbox_node(numOfInfiniteObjects);

      for (i = 0; i < numOfInfiniteObjects; i++)
      {
        cd->Node[i] = Infinite[i];
      }

      calc_bbox(&(cd->BBox), Infinite, 0, numOfInfiniteObjects);

      *Root = (BBOX_TREE *)cd;

      (*Root)->Infinite = true;
    }
  }
}
Exemplo n.º 7
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);
  }
}
Exemplo n.º 8
0
int sort_and_split(BBOX_TREE **Root, BBOX_TREE **&Finite, size_t *numOfFiniteObjects, ptrdiff_t first, ptrdiff_t last, size_t& maxfinitecount)
{
    BBOX_TREE *cd;
    ptrdiff_t size, i, best_loc;
    DBL *area_left, *area_right;
    DBL best_index, new_index;

    int Axis = find_axis(Finite, first, last);
    size = last - first;
    if(size <= 0)
        return (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.

    switch(Axis)
    {
        case X:
            QSORT(reinterpret_cast<void *>(&Finite[first]), size, sizeof(BBOX_TREE *), compboxes<X>);
            break;
        case Y:
            QSORT(reinterpret_cast<void *>(&Finite[first]), size, sizeof(BBOX_TREE *), compboxes<Y>);
            break;
        case Z:
            QSORT(reinterpret_cast<void *>(&Finite[first]), size, sizeof(BBOX_TREE *), compboxes<Z>);
            break;
    }

    // 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  = new DBL[size];
    area_right = new DBL[size];

    // 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;
        }
    }

    delete[] area_left;
    delete[] 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 = cd;
        if(*numOfFiniteObjects >= maxfinitecount)
        {
            // Prim array overrun, increase array by 50%.
            maxfinitecount = 1.5 * maxfinitecount;

            // For debugging only.
            // TODO MESSAGE      Debug_Info("Reallocing Finite to %d\n", maxfinitecount);
            Finite = reinterpret_cast<BBOX_TREE **>(POV_REALLOC(Finite, maxfinitecount * sizeof(BBOX_TREE *), "bounding boxes"));
        }

        Finite[*numOfFiniteObjects] = cd;
        (*numOfFiniteObjects)++;

        return (1);
    }

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

    return (0);
}