コード例 #1
0
ファイル: WlzGeoModelCut.c プロジェクト: dscho/Woolz
/*!
* \return	Woolz error code.
* \ingroup	WlzGeoModel
* \brief	Copies elements from the given model to the cut model on
* 		the condition that the elements do not intersects any
* 		elements of the knide model.
* 		All models are assumed to be valid 3D models.
* \param	given			Given model.
* \param	knife			Knife model.
* \param	dstErr			Destination error pointer, may be NULL.
*/
static WlzErrorNum WlzGMModelCut3D(WlzGMModel *cut, WlzGMModel *given,
				   WlzGMModel *knife)
{
  WlzGMGridWSp3D *kGrid = NULL;
  WlzErrorNum   errNum = WLZ_ERR_NONE;

  if((cut == NULL) || (knife == NULL) || (given == NULL))
  {
    errNum = WLZ_ERR_DOMAIN_NULL;
  }
  else
  {
    int cutDim,
    	givenDim,
    	knifeDim;

    cutDim = WlzGMModelGetDimension(cut, NULL);
    givenDim = WlzGMModelGetDimension(given, NULL);
    knifeDim = WlzGMModelGetDimension(knife, NULL);
    if((cutDim != 3) || (givenDim != 3) || (knifeDim != 3))
    {
      errNum = WLZ_ERR_DOMAIN_TYPE;
    }
  }
  /* Create a cell grid workspace for the knife model. */
  if(errNum == WLZ_ERR_NONE)
  {
    kGrid = WlzGeoModelGridWSpNew3D(knife, WLZ_GMELM_FACE, &errNum);
  }
  /* For each face of the given model, if it does not intersect a face of
   * the knife model then add it to the new cut model. */
  if(errNum == WLZ_ERR_NONE)
  {
    int idF,
        idX,
	idY,
	idZ,
    	gMaxF;
    AlcVector *gFVec;

    gMaxF = given->res.face.numIdx;
    gFVec = given->res.face.vec;
    for(idF = 0; idF < gMaxF; ++idF)
    {
      WlzGMFace *gFace;

      gFace = (WlzGMFace *)AlcVectorItemGet(gFVec, idF);
      if(gFace->idx >= 0)
      {
        int	add = 1;
	WlzDVertex3 gVtx[3];
	WlzIBox3 cBox;
	WlzDBox3 fBox;

	(void )WlzGMFaceGetG3D(gFace, gVtx + 0, gVtx + 1, gVtx + 2);
	fBox = WlzBoundingBoxVtx3D(3, gVtx, NULL);
	cBox = WlzGeoModelGridCellsInDBox(kGrid, fBox);
	/* For each cell that the bonding box intersects. */
        for(idZ = cBox.zMin; idZ <= cBox.zMax; ++idZ)
        {
          WlzDVertex3 kCellMin,
                      kCellMax;

          kCellMin.vtZ = kGrid->org.vtZ + kGrid->cellSz * idZ;
          kCellMax.vtZ = kGrid->org.vtZ + kGrid->cellSz * (idZ + 1);
          for(idY = cBox.yMin; idY <= cBox.yMax; ++idY)
          {
            kCellMin.vtY = kGrid->org.vtY + kGrid->cellSz * idY;
            kCellMax.vtY = kGrid->org.vtY + kGrid->cellSz * (idY + 1);
            for(idX = cBox.xMin; idX <= cBox.xMax; ++idX)
            {
	      WlzDVertex3 kVtx[3];
	      WlzGMGridWSpCell3D *kCell;

              kCellMin.vtX = kGrid->org.vtX + kGrid->cellSz * idX;
              kCellMax.vtX = kGrid->org.vtX + kGrid->cellSz * (idX + 1);
              /* Test if the face of the given model intersects the faces
	       * of the knife grid cells. */
	      kCell = *(*(*(kGrid->cells + idZ) + idY) + idX);
	      while(kCell != NULL)
	      {
		WlzGMFace *kFace;

		kFace = kCell->elem.face;
		(void )WlzGMFaceGetG3D(kFace, kVtx + 0, kVtx + 1, kVtx + 2);
		if(WlzGeomTriangleTriangleIntersect3D(
		                  gVtx[0], gVtx[1], gVtx[2],
		                  kVtx[0], kVtx[1], kVtx[2]) != 0)
		{
		  add = 0;
		  idX = cBox.xMax + 1;            /* Break from these loops. */
		  idY = cBox.yMax + 1;
		  idZ = cBox.zMax + 1;
		  break;
		}
		if(errNum != WLZ_ERR_NONE)
		{
		  goto RETURN;
		}
	        kCell = kCell->next;
	      }
            }
	  }
	}
	if(add)
	{
	  /* Given model face does not intersect the knife model face
	   * so just add it to the cut model. */
	  errNum = WlzGMModelConstructSimplex3D(cut, gVtx);
	}
      }
    }
  }
RETURN:
  if(kGrid)
  {
    (void )WlzGeoModelGridFree3D(kGrid);
  }
  return(errNum);
}
コード例 #2
0
ファイル: WlzExtFFAffineTrFitBox.c プロジェクト: omsai/Woolz
/*!
* \return	Dimension of the given object:
* \ingroup	WlzFeatures
* \brief	Returns the dimension of the given object.
* \param	obj			Given object.
* \param	dstErr			Destination error pointer, may be NULL.
*/
int		WlzObjectDimension(WlzObject *obj, WlzErrorNum *dstErr)
{
  int		dim = 0;
  WlzErrorNum	errNum = WLZ_ERR_NONE;

  if(obj == NULL)
  {
    errNum = WLZ_ERR_OBJECT_NULL;
  }
  else
  {
    switch(obj->type)
    {
      /* Objects which don't have a dimension. */
      case WLZ_CONVOLVE_FLOAT: /* FALLTHROUGH */
      case WLZ_CONVOLVE_INT:   /* FALLTHROUGH */
      case WLZ_EMPTY_OBJ:      /* FALLTHROUGH */
      case WLZ_HISTOGRAM:      /* FALLTHROUGH */
      case WLZ_LUT:            /* FALLTHROUGH */
      case WLZ_PROPERTY_OBJ:   /* FALLTHROUGH */
      case WLZ_TEXT:
        dim = 0;
	break;
      /* Objects which are clearly 2D. */
      case WLZ_2D_DOMAINOBJ: /* FALLTHROUGH */
      case WLZ_2D_POLYGON:   /* FALLTHROUGH */
      case WLZ_BOUNDLIST:    /* FALLTHROUGH */
      case WLZ_CMESH_2D:     /* FALLTHROUGH */
      case WLZ_RECTANGLE:
        dim = 2;
	break;
      /* Objects which are clearly 3D. */
      case WLZ_3D_DOMAINOBJ:  /* FALLTHROUGH */
      case WLZ_3D_POLYGON:    /* FALLTHROUGH */
      case WLZ_3D_WARP_TRANS: /* FALLTHROUGH */
      case WLZ_CMESH_2D5:     /* FALLTHROUGH */
      case WLZ_CMESH_3D:
        dim = 3;
	break;
      /* Objects which need to have their domain checked. */
      case WLZ_TRANS_OBJ:
	if(obj->domain.core == NULL)
	{
	  errNum = WLZ_ERR_DOMAIN_NULL;
	}
	else
	{
	  dim = WlzAffineTransformDimension(obj->domain.t, &errNum);
	}
        break;
      case WLZ_CONV_HULL:
	if(obj->domain.core == NULL)
	{
	  errNum = WLZ_ERR_DOMAIN_NULL;
	}
	else
	{
	  switch(obj->domain.core->type)
	  {
	    case WLZ_CONVHULL_DOMAIN_2D:
	      dim = 2;
	      break;
	    case WLZ_CONVHULL_DOMAIN_3D:
	      dim = 3;
	      break;
	    default:
	      errNum = WLZ_ERR_DOMAIN_TYPE;
	      break;
	  }
	}
        break;
      case WLZ_CONTOUR:
        if((obj->domain.core == NULL) || (obj->domain.ctr->model == NULL))
	{
	  errNum = WLZ_ERR_DOMAIN_NULL;
	}
	else
	{
	  dim = WlzGMModelGetDimension(obj->domain.ctr->model, &errNum);
	}
	break;
      case WLZ_POINTS:
        if(obj->domain.core == NULL)
	{
	  errNum = WLZ_ERR_DOMAIN_NULL;
	}
	else
	{
	  switch(obj->domain.pts->type)
	  {
	    case WLZ_POINTS_2I: /* FALLTHROUGH */
	    case WLZ_POINTS_2D:
	      dim = 2;
	      break;
	    case WLZ_POINTS_3I: /* FALLTHROUGH */
	    case WLZ_POINTS_3D:
	      dim = 3;
	      break;
	    default:
	      errNum = WLZ_ERR_DOMAIN_TYPE;
	      break;


	  }
	}
	break;
      case WLZ_AFFINE_TRANS:
	if(obj->domain.core == NULL)
	{
	  errNum = WLZ_ERR_DOMAIN_NULL;
	}
	else
	{
	  dim = WlzAffineTransformDimension(obj->domain.t, &errNum);
	}
        break;
      case WLZ_COMPOUND_ARR_1: /* FALLTHROUGH */
      case WLZ_COMPOUND_ARR_2:
	{
	  int		idx;
	  WlzCompoundArray *ca;

	  ca = (WlzCompoundArray *)obj;
	  if(ca->n < 0)
	  {
	    errNum = WLZ_ERR_OBJECT_NULL;
	  }
	  else
	  {
	    dim = WlzObjectDimension(ca->o[0], &errNum);
	    for(idx = 1; (errNum == WLZ_ERR_NONE) && (idx < ca->n); ++idx)
	    {
	      int	d;

	      d = WlzObjectDimension(ca->o[idx], &errNum);
	      if((errNum == WLZ_ERR_NONE) && (d != dim))
	      {
		errNum = WLZ_ERR_OBJECT_TYPE;
	      }
	    }
	  }
	}
	break;
      case WLZ_MESH_TRANS:
	if(obj->domain.core == NULL)
	{
	  errNum = WLZ_ERR_DOMAIN_NULL;
	}
	else
	{
	  switch(obj->domain.core->type)
	  {
	    case WLZ_TRANSFORM_2D_MESH:
	      dim = 2;
	      break;
	    case WLZ_TRANSFORM_2D5_MESH: /* FALLTHROUGH */
	    case WLZ_TRANSFORM_3D_MESH:
	      dim = 3;
	      break;
	    default:
	      errNum = WLZ_ERR_DOMAIN_TYPE;
	      break;
	  }
	}
        break;
      case WLZ_CMESH_TRANS:
	if(obj->domain.core == NULL)
	{
	  errNum = WLZ_ERR_DOMAIN_NULL;
	}
	else
	{
	  switch(obj->domain.core->type)
	  {
	    case WLZ_TRANSFORM_2D_CMESH:
	      dim = 2;
	      break;
	    case WLZ_TRANSFORM_2D5_CMESH: /* FALLTHROUGH */
	    case WLZ_TRANSFORM_3D_CMESH:
	      dim = 3;
	      break;
	    default:
	      errNum = WLZ_ERR_DOMAIN_TYPE;
	      break;
	  }
	}
        break;
	/* Objects which aren't supported. */
      case WLZ_COMPOUND_LIST_1: /* FALLTHROUGH */
      case WLZ_COMPOUND_LIST_2: /* FALLTHROUGH */
      case WLZ_FMATCHOBJ:       /* FALLTHROUGH */
      case WLZ_WARP_TRANS:      /* FALLTHROUGH */
      default:
        errNum = WLZ_ERR_OBJECT_TYPE;
	break;
    }
  }
  if(dstErr)
  {
    *dstErr = errNum;
  }
  return(dim);
}