示例#1
0
/*! 
* \ingroup      WlzBoundary
* \brief        Return a domain object corresponding to the input boundary
object.
*
* \return       Domain object corresponding to the input boundary, NULL on error.
* \param    boundary	Input boundary object.
* \param    fillMode	Fill mode for the individual polyline boundaries.
 If the input object is a genuine boundary object then there will be no
 self-intersecting polylines and <tt> fillMode = WLZ_SIMPLE_FILL </tt>
 is appropriate. See WlzPolyToObj().
 * \param    dstErr	Error return
* \par      Source:
*                WlzBoundToObj.c
*/
WlzObject *WlzBoundaryToObj(
  WlzObject		*boundary,
  WlzPolyFillMode	fillMode,
  WlzErrorNum		*dstErr)
{
  WlzObject	*rtnObj=NULL, *tmpObj;
  WlzDomain	domain, *domains, *bnddmns;
  WlzValues	values;
  int		p;
  WlzErrorNum	errNum=WLZ_ERR_NONE;

  /* check object */
  if( boundary == NULL ){
    errNum = WLZ_ERR_OBJECT_NULL;
  }
  else {
    switch( boundary->type ){
    case WLZ_3D_DOMAINOBJ:
      /* check plane domain */
      if( boundary->domain.p == NULL ){
	errNum = WLZ_ERR_DOMAIN_NULL;
      }
      else {
	switch( boundary->domain.p->type ){
	case WLZ_PLANEDOMAIN_BOUNDLIST:
	  if((domain.p = WlzMakePlaneDomain(WLZ_PLANEDOMAIN_DOMAIN,
					    boundary->domain.p->plane1,
					    boundary->domain.p->lastpl,
					    boundary->domain.p->line1,
					    boundary->domain.p->lastln,
					    boundary->domain.p->kol1,
					    boundary->domain.p->lastkl,
					    &errNum)) != NULL){
	    domain.p->voxel_size[0] = boundary->domain.p->voxel_size[0];
	    domain.p->voxel_size[1] = boundary->domain.p->voxel_size[1];
	    domain.p->voxel_size[2] = boundary->domain.p->voxel_size[2];
	    domains = domain.p->domains;
	    bnddmns = boundary->domain.p->domains;
	    for(p=domain.p->plane1; p <= domain.p->lastpl;
		p++, domains++, bnddmns++){
	      if( (*bnddmns).poly ){
		if((tmpObj = WlzBoundToObj((*bnddmns).b, fillMode,
					   &errNum)) != NULL){
		  *domains = WlzAssignDomain(tmpObj->domain, NULL);
		  WlzFreeObj(tmpObj);
		}
		else {
		  WlzFreePlaneDomain(domain.p);
		  domain.p = NULL;
		  break;
		}
	      }
	    }
	    if( domain.p ){
	      values.core = NULL;
	      if( (rtnObj = WlzMakeMain(WLZ_3D_DOMAINOBJ, domain, values,
					NULL, NULL, &errNum)) == NULL ){
		WlzFreePlaneDomain(domain.p);
	      }
	    }
	  }
	  break;
	  
	case WLZ_EMPTY_DOMAIN:
	  return WlzMakeEmpty(dstErr);

	default:
	  errNum = WLZ_ERR_DOMAIN_TYPE;
	  break;
	}
      }
      break;

    case WLZ_BOUNDLIST:
      return WlzBoundToObj(boundary->domain.b, fillMode, dstErr);

    case WLZ_TRANS_OBJ:
      if((values.obj = WlzBoundaryToObj(boundary->values.obj, fillMode,
				       &errNum)) != NULL){
	return WlzMakeMain(WLZ_TRANS_OBJ, boundary->domain, values,
			   NULL, NULL, dstErr);
      }
      break;

    case WLZ_EMPTY_OBJ:
      return WlzMakeEmpty(dstErr);

    default:
      errNum = WLZ_ERR_OBJECT_TYPE;
      break;
    }
  }

  if( dstErr ){
    *dstErr = errNum;
  }
  return rtnObj;
}
示例#2
0
/*! 
* \ingroup      WlzBoundary
* \brief        Convert the input boundary list to a domain object.
 Use WlzBoundaryToObj if conversion of a 3D stack of boundary list is required
 or if the boundary is available as a first class object.
*
* \return       Domain object corresponding to the input boundary domain,
 NULL on error.
* \param    bound	Input boundary list domain.
* \param    fillMode	Polyline fill mode, see WlzPolyToObj().
* \param    dstNum	Error return.
* \par      Source:
*                WlzBoundToObj.c
*/
WlzObject *WlzBoundToObj(
  WlzBoundList		*bound,
  WlzPolyFillMode	fillMode,
  WlzErrorNum		*dstNum)
{
  WlzObject *obj, *selfobj = NULL, *nextobj, *downobj;
  WlzErrorNum	errNum=WLZ_ERR_NONE;

  /* check input */
  if( bound == NULL ){
    errNum = WLZ_ERR_OBJECT_NULL;
  }

  /* find object corresponding to the current boundary */
  if( errNum == WLZ_ERR_NONE ){
    if( bound->poly != NULL ){
      selfobj = WlzPolyToObj(bound->poly, fillMode, &errNum);
    }
    else {
      selfobj = NULL;
    }
  }
  if( (errNum == WLZ_ERR_NONE) && (selfobj != NULL)
     && (bound->type != WLZ_BOUNDLIST_PIECE)
     && (fillMode != WLZ_VERTEX_FILL) ){
    obj = WlzErosion(selfobj, WLZ_4_CONNECTED, &errNum);
    WlzFreeObj(selfobj);
    selfobj = obj;
  }

  /* add object corresponding to next */
  if( (errNum == WLZ_ERR_NONE) && bound->next ){
    nextobj = WlzBoundToObj(bound->next, fillMode, &errNum);
    if( selfobj == NULL ){
      selfobj = nextobj;
    }
    else {
      if( (errNum == WLZ_ERR_NONE) && (nextobj != NULL) ){
	obj = WlzUnion2(selfobj, nextobj, &errNum);
	WlzFreeObj(nextobj);
	WlzFreeObj(selfobj);
	selfobj = obj;
      }
    }
  }

  /* remove object corresponding to down */
  if( (errNum == WLZ_ERR_NONE) && bound->down ){
    downobj = WlzBoundToObj(bound->down, fillMode, &errNum);
    if( downobj != NULL ){
      if( selfobj != NULL ){
	if( fillMode != WLZ_VERTEX_FILL ){
	  obj = WlzDiffDomain(selfobj, downobj, &errNum);
	}
	else {
	  obj = WlzUnion2(selfobj, downobj, &errNum);
	}
	WlzFreeObj(selfobj);
	selfobj = obj;
      }
      WlzFreeObj(downobj);
    }
  }

  /* return object */
  if( dstNum ){
    *dstNum = errNum;
  }
  return(selfobj);
}
示例#3
0
/*!
* \return	New Woolz object without holes or NULL on error.
* \ingroup	WlzDomainOps
* \brief	Fills the holes in the given object's domain (which are by
* 		definition not connected to the outside). When the given
* 		object's domain has more than one component part, the
* 		object should first be labeled, this function should then be
* 		called for each of the labeled parts and then the union of
* 		the filled domains should be formed.
* \param	srcObj			Given 3D domain object.
* \param	dstErr			Destination error pointer, may be NULL.
*/
WlzObject 			*WlzDomainFill3D(
  				  WlzObject *srcObj,
    				  WlzErrorNum *dstErr)
{
  int		nPln = 0;
  WlzObject	*bndObj = NULL,
  		*filObj = NULL,
  		*gvnObj = NULL,
		*sedObj = NULL,
		*shlObj = NULL;
  WlzPixelV	zeroV;
  WlzValues 	nullVal;
  WlzErrorNum	errNum = WLZ_ERR_NONE;

  nullVal.core = NULL;
  zeroV.type = WLZ_GREY_UBYTE;
  zeroV.v.ubv = 0;
  if(srcObj == NULL)
  {
    errNum = WLZ_ERR_OBJECT_NULL;
  }
  else if(srcObj->type != WLZ_3D_DOMAINOBJ)
  {
    errNum = WLZ_ERR_OBJECT_TYPE;
  }
  else if(srcObj->domain.core == NULL)
  {
    errNum = WLZ_ERR_DOMAIN_NULL;
  }
  else
  {
    gvnObj = WlzMakeMain(srcObj->type, srcObj->domain, nullVal,
    		         NULL, NULL, &errNum);
  }
  /* Create a then shell 1 voxel thick just inside the given objects's
   * domain. */
  if(errNum == WLZ_ERR_NONE)
  {
    WlzObject	*difObj = NULL;

    difObj = WlzAssignObject(
	     WlzBoundaryDomain(gvnObj, &errNum), NULL);
    if(errNum == WLZ_ERR_NONE)
    {
      WlzIBox3	clipBox;

      /* Clip the dilated shell domain to make sure it stays within the
       * bounding box of the given object then all planes will align. */
      clipBox.xMin = gvnObj->domain.p->kol1;
      clipBox.yMin = gvnObj->domain.p->line1;
      clipBox.zMin = gvnObj->domain.p->plane1;
      clipBox.xMax = gvnObj->domain.p->lastkl;
      clipBox.yMax = gvnObj->domain.p->lastln;
      clipBox.zMax = gvnObj->domain.p->lastpl;
      shlObj = WlzAssignObject(
	       WlzClipObjToBox3D(difObj, clipBox, &errNum), NULL);
    }
    (void )WlzFreeObj(difObj);
  }
  /* Make sure that the bounding box of the thin shell domain fits it and
   * that it's first and last planes have interrvals. */
  if(errNum == WLZ_ERR_NONE)
  {
    errNum = WlzStandardPlaneDomain(shlObj->domain.p, NULL);
  }
  /* Create a value table for the shell object with values set to zero. */
  if(errNum == WLZ_ERR_NONE)
  {
    WlzValues	val;
    WlzObjectType tType;

    tType = WlzGreyTableType(WLZ_GREY_TAB_INTL, WLZ_GREY_UBYTE, NULL);
    val.vox = WlzMakeVoxelValueTb(WLZ_VOXELVALUETABLE_GREY,
				  shlObj->domain.p->plane1,
				  shlObj->domain.p->lastpl,
				  zeroV, NULL, &errNum);
    if(errNum == WLZ_ERR_NONE)
    {
      int	p;

      nPln = shlObj->domain.p->lastpl - shlObj->domain.p->plane1 + 1;
      shlObj->values = WlzAssignValues(val, NULL);
#ifdef _OPENMP
#pragma omp parallel for shared(shlObj)
#endif
      for(p = 0; p < nPln; ++p)
      {
	if(errNum == WLZ_ERR_NONE)
	{
	  WlzDomain dom2;
	  WlzErrorNum errNum2;

	  dom2 = shlObj->domain.p->domains[p];
	  if(dom2.core)
	  {
	    WlzValues val2;
	    WlzObject *shlObj2;
	    shlObj2 = WlzMakeMain(WLZ_2D_DOMAINOBJ, dom2, nullVal, NULL, NULL,
				&errNum2);
	    if(errNum2 == WLZ_ERR_NONE)
	    {
	      val2.i = WlzMakeIntervalValues(tType, shlObj2, zeroV, &errNum2);
	      /* WlzMakeIntervalValues() sets all values to zero. */
	    }
	    if(errNum2 == WLZ_ERR_NONE)                          
	    {
	      shlObj->values.vox->values[p] = WlzAssignValues(val2, NULL);
	    }
	    (void )WlzFreeObj(shlObj2);
	    if(errNum2 == WLZ_ERR_NONE)
	    {
#ifdef _OPENMP
#pragma omp critical
	      {
#endif
		if((errNum == WLZ_ERR_NONE) && (errNum2 != WLZ_ERR_NONE))
		{
		  errNum = errNum2;
		}
#ifdef _OPENMP
	      }
#endif
	    }
	  }
	}
      }
    }
  }
  /* Compute the (plane-wise) boundary list for the given object. */
  if(errNum == WLZ_ERR_NONE)
  {
    bndObj = WlzObjToBoundary(gvnObj, 0, &errNum);
  }
  /* Sweep down through the boundary object setting the values of
   * those voxels in the shell object to a non zero value when they
   * correspond to top level boundaries. */
  if(errNum == WLZ_ERR_NONE)
  {
    int		p;

#ifdef _OPENMP
#pragma omp parallel for shared(bndObj,shlObj)
#endif
    for(p = 0; p < nPln; ++p)
    {
      if(errNum == WLZ_ERR_NONE)
      {
	WlzDomain bDom2;

	bDom2 = bndObj->domain.p->domains[p];
	if(bDom2.core)
	{
	  WlzDomain iDom2;
	  WlzValues iVal2;
	  WlzObject *iObj2 = NULL;
	  WlzGreyValueWSpace *gVWSp = NULL;
	  WlzErrorNum errNum2 = WLZ_ERR_NONE;

	  iDom2 = shlObj->domain.p->domains[p];
	  iVal2 = shlObj->values.vox->values[p];
	  iObj2 = WlzMakeMain(WLZ_2D_DOMAINOBJ, iDom2, iVal2, NULL, NULL,
			      &errNum2);
	  if(errNum == WLZ_ERR_NONE)
	  {
	    gVWSp = WlzGreyValueMakeWSp(iObj2, &errNum2);
	  }
	  if(errNum2 == WLZ_ERR_NONE)
	  {
	    WlzBoundList *bnd,
			 *bnd2;

	    bnd2 = bDom2.b;
	    for(bnd = bnd2; bnd != NULL; bnd = bnd->next)
	    {
	      if(bnd->poly != NULL)
	      {
		WlzPolygonDomain *ply;

		ply = bnd->poly;
		if(ply)
		{
		  int	i;
		  WlzIVertex2 *vtx;

		  vtx = ply->vtx;
		  for(i = 0; i < ply->nvertices; ++i)
		  {
		    WlzGreyValueGet(gVWSp, 0, vtx[i].vtY, vtx[i].vtX);
		    *(gVWSp->gPtr[0].ubp) = 255;
		  }
		}
	      }
	    }
	  }
	  else
	  {
#ifdef _OPENMP
#pragma omp critical
	    {
#endif
	      if(errNum == WLZ_ERR_NONE)
	      {
		errNum = errNum2;
	      }
#ifdef _OPENMP
	    }
#endif
	  }
	  (void )WlzFreeObj(iObj2);
	  WlzGreyValueFreeWSp(gVWSp);
	}
      }
    }
  }
  /* Threshold the shell object, throwing away all but where the voxels
   * are set to create a seed domain. Then remove the value table from
   * the shell object and free it as it's no longer needed. */
  if(errNum == WLZ_ERR_NONE)
  {
    WlzObject	*tObj = NULL;
    WlzPixelV	tV;

    tV.type = WLZ_GREY_UBYTE;
    tV.v.ubv = 1;
    tObj = WlzAssignObject(
    	   WlzThreshold(shlObj, tV, WLZ_THRESH_HIGH, &errNum), NULL);
    if(errNum == WLZ_ERR_NONE)
    {
      sedObj = WlzAssignObject(
      	       WlzMakeMain(tObj->type, tObj->domain, nullVal,
			   NULL, NULL, &errNum), NULL);
    }
    (void )WlzFreeObj(tObj); tObj = NULL;
    if(errNum == WLZ_ERR_NONE)
    {
      tObj = WlzAssignObject(
             WlzMakeMain(shlObj->type, shlObj->domain, nullVal,
			 NULL, NULL, &errNum), NULL);
    }
    (void )WlzFreeObj(shlObj); shlObj = NULL;
    if(errNum == WLZ_ERR_NONE)
    {
      shlObj = tObj;
      tObj = NULL;
    }
    (void )WlzFreeObj(tObj);
#ifdef WLZ_DOMOMAINFILL3D_DEBUG
    {
      FILE	*fP;
      fP = fopen("debug-shlObj-00.wlz", "w");
      (void )WlzWriteObj(fP, shlObj);
      (void )fclose(fP);
    }
#endif
  }
  /* Label the shell domain using 26-connectivity in 3D and then
   * keep only those component objects which intersect the seed domain.
   * Then free the shell and seed domains replacing the shell domain
   * with the union of the intersecting labeled component objects.
   * Finaly free the intersecting component objects, keeping only the
   * new shell domain. */
  if(errNum == WLZ_ERR_NONE)
  {
    int		i,
		j,
    		nCSObj = 0;
    WlzIBox3	bBox;
    WlzObject	**csObj = NULL;

    bBox = WlzBoundingBox3I(shlObj, &errNum);
    if(errNum == WLZ_ERR_NONE)      
    {
      int	maxCSObj;

      maxCSObj = ((bBox.xMax - bBox.xMin + 1) *
      		  (bBox.yMax - bBox.yMin + 1) *
      		  (bBox.zMax - bBox.zMin + 1)) / 8;
      if(maxCSObj < 8)
      {
        maxCSObj = 8;
      }
      errNum = WlzLabel(shlObj, &nCSObj, &csObj, maxCSObj, 0,
			WLZ_26_CONNECTED);
    }
    if(errNum == WLZ_ERR_NONE)
    {
      for(i = 0; i < nCSObj; ++i)
      {
        if(!WlzHasIntersection(csObj[i], sedObj, &errNum))
	{
	  (void )WlzFreeObj(csObj[i]);
	  csObj[i] = NULL;
	}
      }
    }
    if(errNum == WLZ_ERR_NONE)
    {
      /* Squeeze out any NULL objects reseting their number.*/
      for(i = 0, j = 0; i < nCSObj; ++i)
      {
        if(csObj[i])
	{
	  csObj[j++] = csObj[i];
	}
      }
      nCSObj = j;
    }
    if(errNum == WLZ_ERR_NONE)
    {
      WlzObject	*iObj = NULL,
      		*uObj = NULL;

      uObj = WlzAssignObject(
      	     WlzUnionN(nCSObj, csObj, 0, &errNum), NULL);
      iObj = WlzAssignObject(
               WlzIntersect2(uObj, shlObj, &errNum),  NULL);
      (void )WlzFreeObj(uObj);
      (void )WlzFreeObj(shlObj);
      shlObj = iObj;
#ifdef WLZ_DOMOMAINFILL3D_DEBUG
      {
	FILE	*fP;
	fP = fopen("debug-shlObj-01.wlz", "w");
	(void )WlzWriteObj(fP, shlObj);
	(void )fclose(fP);
      }
#endif
    }
    if(csObj)
    {
      for(i = 0; i < nCSObj; ++i)
      {
        (void )WlzFreeObj(csObj[i]);
      }
      (void )AlcFree(csObj);
    }
  }
  /* Sweep down through the boundary lists again creating new boundary lists
   * which do not have boundaries that do not intersect the new shell domain.
   * Then create a new filled object from these boundary lists. */
  if(errNum == WLZ_ERR_NONE)
  {
    int		p,
    		nPlnFil;
    WlzDomain	filDom;

    nPlnFil = shlObj->domain.p->lastpl - shlObj->domain.p->plane1 + 1;
    filDom.p = WlzMakePlaneDomain(WLZ_PLANEDOMAIN_DOMAIN, 
		shlObj->domain.p->plane1, shlObj->domain.p->lastpl,
                shlObj->domain.p->line1, shlObj->domain.p->lastln,
                shlObj->domain.p->kol1, shlObj->domain.p->lastkl,
		&errNum);
#ifdef _OPENMP
#pragma omp parallel for shared(bndObj,shlObj)
#endif
    for(p = 0; p < nPlnFil; ++p)
    {
      if(errNum == WLZ_ERR_NONE)
      {
	WlzDomain bDom2;
	
	bDom2 = bndObj->domain.p->domains[p];
	if(bDom2.core)
	{
	  WlzDomain 	sDom2;
	  WlzObject	*fObj2 = NULL;
	  WlzBoundList  *newBnd = NULL;
	  WlzErrorNum	errNum2 = WLZ_ERR_NONE;

	  sDom2 = shlObj->domain.p->domains[p];
	  if(sDom2.core)
	  {
	    newBnd = WlzDomFill3DDoBound2D(bDom2.b, sDom2, &errNum2);
	    if(newBnd != NULL)
	    {
	      fObj2 = WlzBoundToObj(newBnd, WLZ_SIMPLE_FILL, &errNum2);
	      (void )WlzFreeBoundList(newBnd);
	    }
	    if(errNum2 == WLZ_ERR_NONE)
	    {
	      if(fObj2)
	      {
		filDom.p->domains[p] = WlzAssignDomain(fObj2->domain, NULL);
	      }
	    }
	    else
	    {
#ifdef _OPENMP
#pragma omp critical
	      {
#endif
		if(errNum == WLZ_ERR_NONE)
		{
		  errNum = errNum2;
		}
#ifdef _OPENMP
	      }
#endif
	    }
	    (void )WlzFreeObj(fObj2);
	  }
	}
      }
    }
    if(errNum == WLZ_ERR_NONE)
    {
      errNum = WlzStandardPlaneDomain(filDom.p, NULL);
    }
    if(errNum == WLZ_ERR_NONE)
    {
      WlzObject	*tObj0 = NULL,
      		*tObj1 = NULL;

      /* Put back any isolated voxels this function has removed. */
      tObj0 = WlzAssignObject(
              WlzMakeMain(srcObj->type, filDom, nullVal,
      			  NULL, NULL, &errNum), NULL);
      if(errNum == WLZ_ERR_NONE)
      {
        tObj1 = WlzUnion2(gvnObj, tObj0, &errNum);
      }
      if(errNum == WLZ_ERR_NONE)
      {
	filObj = WlzMakeMain(tObj1->type, tObj1->domain, nullVal,
			     NULL, NULL, &errNum);
      }
      (void )WlzFreeObj(tObj0);
      (void )WlzFreeObj(tObj1);
    }
  }
  (void )WlzFreeObj(bndObj);
  (void )WlzFreeObj(gvnObj);
  (void )WlzFreeObj(shlObj);
  (void )WlzFreeObj(sedObj);
  if((errNum != WLZ_ERR_NONE) && (filObj != NULL))
  {
    (void )WlzFreeObj(filObj);
    filObj = NULL;
  }
  if(dstErr)
  {
    *dstErr = errNum;
  }
  return(filObj);
}
示例#4
0
文件: WlzGreyMask.c 项目: dscho/Woolz
/*! 
* \ingroup      WlzValuesUtils
* \brief        Set the value maskVal within the domain given by the	
*		mask object. The mask object can be a 2D, 3D, polygon	
*		or boundary object. A 3D mask with a 2D object is an	
*		error. A 2D mask with a 3D object will be applied to	
*		each plane in turn.			
*
* \return       New object with the same domain as the input object but
 with values in the intersection with the mask domain set to the mask
 value. NULL on error.
 * \param    obj	Input object
 * \param    mask	Mask object.
 * \param    maskVal	mask value.
 * \param    dstErr	Error return.
* \par      Source:
*                WlzGreyMask.c
*/
WlzObject *WlzGreyMask(
  WlzObject	*obj,
  WlzObject	*mask,
  WlzPixelV	maskVal,
  WlzErrorNum	*dstErr)
{
  WlzObject	*rtnObj=NULL;
  WlzObject	*tmpMask, *obj1;
  WlzValues	values;
  WlzPixelV	tmpMaskval;
  WlzIntervalWSpace	iwsp;
  WlzGreyWSpace		gwsp;
  WlzGreyP		gptr;
  int			i;
  WlzErrorNum	errNum=WLZ_ERR_NONE;

  /* check obj */
  if( obj == NULL ){
    errNum = WLZ_ERR_OBJECT_NULL;
  }
  else {
    switch( obj->type ){
    case WLZ_2D_DOMAINOBJ:
      if( obj->values.core == NULL ){
	errNum = WLZ_ERR_VALUES_NULL;
      }
      break;

    case WLZ_3D_DOMAINOBJ:
      return WlzGreyMask3d(obj, mask, maskVal, dstErr);

    case WLZ_TRANS_OBJ:
      if((values.obj = WlzGreyMask(obj->values.obj, mask, maskVal,
      				   &errNum)) != NULL){
	return WlzMakeMain(WLZ_TRANS_OBJ, obj->domain, values,
			   NULL, NULL, dstErr);
      }
      break;

    case WLZ_EMPTY_OBJ:
      return WlzMakeEmpty(dstErr);

    default:
      errNum = WLZ_ERR_OBJECT_TYPE;
      break;
    }
  }

  /* check the mask */
  if( errNum == WLZ_ERR_NONE ){
    if( mask == NULL ){
      errNum = WLZ_ERR_OBJECT_NULL;
    }
    else {
      values.core = NULL;
      switch( mask->type ){
      case WLZ_2D_DOMAINOBJ:
	tmpMask = WlzMakeMain(WLZ_2D_DOMAINOBJ, mask->domain, values,
			      NULL, NULL, &errNum);
	break;

      case WLZ_TRANS_OBJ:
	tmpMask = WlzMakeMain(WLZ_2D_DOMAINOBJ, mask->values.obj->domain,
			      values, NULL, NULL, &errNum);
	break;

      case WLZ_EMPTY_OBJ:
	return WlzMakeMain(WLZ_2D_DOMAINOBJ, obj->domain, obj->values,
			   NULL, NULL, dstErr);

      case WLZ_2D_POLYGON:
	tmpMask = WlzPolyToObj(mask->domain.poly, WLZ_SIMPLE_FILL, &errNum);
	break;

      case WLZ_BOUNDLIST:
	tmpMask = WlzBoundToObj(mask->domain.b, WLZ_SIMPLE_FILL, &errNum);
	break;

      default:
	errNum = WLZ_ERR_OBJECT_TYPE;
	break;
      }
      if( errNum == WLZ_ERR_NONE ){
	tmpMask = WlzAssignObject(tmpMask, NULL);
      }
    }
  }

  /* copy input obj and setvalues in the intersection */
  if(errNum == WLZ_ERR_NONE){
    if((rtnObj = WlzNewGrey(obj, &errNum)) != NULL){
      if((obj1 = WlzIntersect2(obj, tmpMask, &errNum)) != NULL){
	obj1->values = WlzAssignValues(rtnObj->values, NULL);
	errNum = WlzInitGreyScan(obj1, &iwsp, &gwsp);
	WlzValueConvertPixel(&tmpMaskval, maskVal, gwsp.pixeltype);
	while((errNum == WLZ_ERR_NONE) &&
	      ((errNum = WlzNextGreyInterval(&iwsp)) == WLZ_ERR_NONE)){
	  gptr = gwsp.u_grintptr;
	  switch( gwsp.pixeltype ){
	  case WLZ_GREY_INT:
	    for(i=0; i<iwsp.colrmn; i++, gptr.inp++){
	      *gptr.inp = tmpMaskval.v.inv;
	    }
	    break;
	  case WLZ_GREY_SHORT:
	    for(i=0; i<iwsp.colrmn; i++, gptr.shp++){
	      *gptr.shp = tmpMaskval.v.shv;
	    }
	    break;
	  case WLZ_GREY_UBYTE:
	    for(i=0; i<iwsp.colrmn; i++, gptr.ubp++){
	      *gptr.ubp = tmpMaskval.v.ubv;
	    }
	    break;
	  case WLZ_GREY_FLOAT:
	    for(i=0; i<iwsp.colrmn; i++, gptr.flp++){
	      *gptr.flp = tmpMaskval.v.flv;
	    }
	    break;
	  case WLZ_GREY_DOUBLE:
	    for(i=0; i<iwsp.colrmn; i++, gptr.dbp++){
	      *gptr.dbp = tmpMaskval.v.dbv;
	    }
	    break;
	  case WLZ_GREY_RGBA:
	    for(i=0; i<iwsp.colrmn; i++, gptr.rgbp++){
	      *gptr.rgbp = tmpMaskval.v.rgbv;
	    }
	    break;
	  default:
	    errNum = WLZ_ERR_GREY_TYPE;
	    break;
	  }
	}
	if( errNum == WLZ_ERR_EOO ){
	  errNum = WLZ_ERR_NONE;
	}
	WlzFreeObj(obj1);
      }
      else {
	WlzFreeObj(rtnObj);
	rtnObj = NULL;
      }
    }
    WlzFreeObj(tmpMask);
  }

  if( dstErr ){
    *dstErr = errNum;
  }
  return rtnObj;
}
示例#5
0
/*! 
* \ingroup      WlzValuesUtils
* \brief        
*
* \return       New object with the same domain <tt>tmpl</tt> but
 values in the intersection with <tt>obj</tt> set to those of the object.
 Returns NULL on error.
* \param    obj	Input object to which the template is applied
* \param    tmpl	Template object
* \param    tmplVal	Template value for regions in the template
 not in the original object
* \param    dstErr	Error return.
* \par      Source:
*                WlzGreyTemplate.c
*/
WlzObject *WlzGreyTemplate(
  WlzObject	*obj,
  WlzObject	*tmpl,
  WlzPixelV	tmplVal,
  WlzErrorNum	*dstErr)
{
  WlzObject	*rtnObj=NULL;
  WlzObject	*obj1, *obj2;
  WlzValues	values;
  WlzPixelV	bckgrnd;
  WlzObjectType	type;
  WlzGreyType	gtype=WLZ_GREY_UBYTE;
  WlzIntervalWSpace	iwsp1, iwsp2;
  WlzGreyWSpace		gwsp1, gwsp2;
  int			size;
  WlzErrorNum	errNum = WLZ_ERR_NONE;

  /* check obj */
  if( obj == NULL ){
    errNum = WLZ_ERR_OBJECT_NULL;
  }
  else {
    switch( obj->type ){
    case WLZ_2D_DOMAINOBJ:
      if( obj->values.core == NULL ){
	errNum = WLZ_ERR_VALUES_NULL;
      }
      else if( WlzGreyTableIsTiled(obj->values.core->type) ){
	errNum = WLZ_ERR_VALUES_TYPE;
      } else {
        bckgrnd = WlzGetBackground(obj, &errNum);
      }
      if(errNum == WLZ_ERR_NONE) {
        gtype = WlzGreyTableTypeToGreyType(obj->values.core->type, NULL);
      }
      break;

    case WLZ_3D_DOMAINOBJ:
      return WlzGreyTemplate3d(obj, tmpl, tmplVal, dstErr);

    case WLZ_TRANS_OBJ:
      if((values.obj = WlzGreyTemplate(obj->values.obj, tmpl,
				       tmplVal, &errNum)) != NULL){
	return WlzMakeMain(WLZ_TRANS_OBJ, obj->domain, values,
			   NULL, NULL, dstErr);
      }
      break;

    case WLZ_EMPTY_OBJ:
      bckgrnd.type = WLZ_GREY_UBYTE;
      bckgrnd.v.ubv = 0;
      break;

    default:
      errNum = WLZ_ERR_OBJECT_TYPE;
      break;
    }
  }

  /* check the template */
  if( errNum == WLZ_ERR_NONE ){
    if( tmpl == NULL ){
      errNum = WLZ_ERR_OBJECT_NULL;
    }
    else {
      values.core = NULL;
      switch( tmpl->type ){
      case WLZ_2D_DOMAINOBJ:
	rtnObj = WlzMakeMain(WLZ_2D_DOMAINOBJ, tmpl->domain, values,
			      NULL, NULL, &errNum);
	break;

      case WLZ_TRANS_OBJ:
	rtnObj = WlzMakeMain(WLZ_2D_DOMAINOBJ, tmpl->values.obj->domain,
			      values, NULL, NULL, &errNum);
	break;

      case WLZ_EMPTY_OBJ:
	return WlzMakeEmpty(dstErr);

      case WLZ_2D_POLYGON:
	rtnObj = WlzPolyToObj(tmpl->domain.poly, WLZ_SIMPLE_FILL, &errNum);
	break;

      case WLZ_BOUNDLIST:
	rtnObj = WlzBoundToObj(tmpl->domain.b, WLZ_SIMPLE_FILL, &errNum);
	break;

      default:
	errNum = WLZ_ERR_OBJECT_TYPE;
	break;
      }
    }
  }

  /* attach a value table to the template and set to the template value,
     note the background is set to the input object or zero if empty */
  if( errNum == WLZ_ERR_NONE ){
    type = WlzGreyTableType(WLZ_GREY_TAB_RAGR, gtype, NULL);
    if((values.v = WlzNewValueTb(rtnObj, type, bckgrnd, &errNum)) != NULL){
      rtnObj->values = WlzAssignValues(values, NULL);
      errNum = WlzGreySetValue(rtnObj, tmplVal);
    }
  }

  /* copy input obj values within the intersection */
  if( errNum == WLZ_ERR_NONE ){
    if((obj->type != WLZ_EMPTY_OBJ) ){
      if( (obj1 = WlzIntersect2(obj, rtnObj, &errNum)) ){
	obj1->values = WlzAssignValues(rtnObj->values, NULL);
	obj2 = WlzMakeMain(obj1->type, obj1->domain, obj->values,
			   NULL, NULL, NULL);

	errNum = WlzInitGreyScan(obj1, &iwsp1, &gwsp1);
	errNum = WlzInitGreyScan(obj2, &iwsp2, &gwsp2);
	switch( gwsp1.pixeltype ){
	case WLZ_GREY_INT:
	  size = sizeof(int);
	  break;
	case WLZ_GREY_SHORT:
	  size = sizeof(short);
	  break;
	case WLZ_GREY_UBYTE:
	  size = sizeof(WlzUByte);
	  break;
	case WLZ_GREY_FLOAT:
	  size = sizeof(float);
	  break;
	case WLZ_GREY_DOUBLE:
	  size = sizeof(double);
	  break;
	case WLZ_GREY_RGBA:
	  size = sizeof(WlzUInt);
	  break;
	default:
	  errNum = WLZ_ERR_GREY_TYPE;
	  break;
	}

	while((errNum == WLZ_ERR_NONE) &&
	      ((errNum = WlzNextGreyInterval(&iwsp1)) == WLZ_ERR_NONE)){
	  (void) WlzNextGreyInterval(&iwsp2);
	  memcpy((void *) gwsp1.u_grintptr.inp,
		 (const void *) gwsp2.u_grintptr.inp,
		 size * iwsp1.colrmn);
	}
	if( errNum == WLZ_ERR_EOO ){
	  errNum = WLZ_ERR_NONE;
	}
	WlzFreeObj(obj2);
	WlzFreeObj(obj1);
      }
      else {
	WlzFreeObj(rtnObj);
	rtnObj = NULL;
      }
    }
  }

  if( dstErr ){
    *dstErr = errNum;
  }
  return rtnObj;
}
示例#6
0
static WlzObject *WlzGreyTemplate3d(
  WlzObject	*obj,
  WlzObject	*tmpl,
  WlzPixelV	tmplVal,
  WlzErrorNum	*dstErr)
{
  WlzObject	*rtnObj=NULL;
  WlzObject	*tmpObj = NULL, *obj1 = NULL, *obj2 = NULL;
  WlzDomain	domain, *domains;
  WlzValues	values, *valuess;
  WlzPlaneDomain	*pdom;
  int		p;
  WlzErrorNum	errNum=WLZ_ERR_NONE;

  /* check the object - it is non-NULL and 3D but the
     domain needs checking */
  if( obj->domain.p == NULL ){
    errNum = WLZ_ERR_DOMAIN_NULL;
  }
  else {
    switch( obj->domain.p->type ){
    case WLZ_2D_DOMAINOBJ:
      /* check there is a valuetable */
      if( obj->values.core == NULL ){
	errNum = WLZ_ERR_VALUES_NULL;
      } else if( WlzGreyTableIsTiled(obj->values.core->type) ){
	errNum = WLZ_ERR_VALUES_TYPE;
      }
      break;

    default:
      errNum = WLZ_ERR_DOMAIN_TYPE;
      break;
    }
  }

  /* check the template and create the return object */
  if( errNum == WLZ_ERR_NONE ){
    if( tmpl == NULL ){
      errNum = WLZ_ERR_OBJECT_NULL;
    }
    else {
      values.core = NULL;
      switch( tmpl->type ){
      case WLZ_2D_DOMAINOBJ:
	pdom = obj->domain.p;
	if((domain.p = WlzMakePlaneDomain(WLZ_PLANEDOMAIN_DOMAIN,
					  pdom->plane1, pdom->lastpl,
					  pdom->line1, pdom->lastpl,
					  pdom->kol1, pdom->lastkl,
					  &errNum)) != NULL){
	  domain.p->voxel_size[0] = pdom->voxel_size[0];
	  domain.p->voxel_size[1] = pdom->voxel_size[1];
	  domain.p->voxel_size[2] = pdom->voxel_size[2];
	  for(p=pdom->plane1; p <= pdom->lastpl; p++){
	    domain.p->domains[p - pdom->plane1] = WlzAssignDomain(tmpl->domain,
								  NULL);
	  }
	  rtnObj = WlzMakeMain(WLZ_3D_DOMAINOBJ, domain, values,
			       NULL, NULL, &errNum);
	}
	break;

      case WLZ_2D_POLYGON:
	pdom = obj->domain.p;
	if((domain.p = WlzMakePlaneDomain(WLZ_PLANEDOMAIN_DOMAIN,
					  pdom->plane1, pdom->lastpl,
					  pdom->line1, pdom->lastpl,
					  pdom->kol1, pdom->lastkl,
					  &errNum)) != NULL){
	  domain.p->voxel_size[0] = pdom->voxel_size[0];
	  domain.p->voxel_size[1] = pdom->voxel_size[1];
	  domain.p->voxel_size[2] = pdom->voxel_size[2];
	  obj1 = WlzPolyToObj(tmpl->domain.poly, WLZ_SIMPLE_FILL, &errNum);
	  for(p=pdom->plane1; p <= pdom->lastpl; p++){
	    domain.p->domains[p - pdom->plane1] = WlzAssignDomain(obj1->domain,
								  NULL);
	  }
	  WlzFreeObj(obj1);
	  rtnObj = WlzMakeMain(WLZ_3D_DOMAINOBJ, domain, values,
			       NULL, NULL, &errNum);
	}
	break;

      case WLZ_BOUNDLIST:
	pdom = obj->domain.p;
	if((domain.p = WlzMakePlaneDomain(WLZ_PLANEDOMAIN_DOMAIN,
					  pdom->plane1, pdom->lastpl,
					  pdom->line1, pdom->lastpl,
					  pdom->kol1, pdom->lastkl,
					  &errNum)) != NULL){
	  domain.p->voxel_size[0] = pdom->voxel_size[0];
	  domain.p->voxel_size[1] = pdom->voxel_size[1];
	  domain.p->voxel_size[2] = pdom->voxel_size[2];
	  obj1 = WlzBoundToObj(tmpl->domain.b, WLZ_SIMPLE_FILL, &errNum);
	  for(p=pdom->plane1; p <= pdom->lastpl; p++){
	    domain.p->domains[p - pdom->plane1] = WlzAssignDomain(obj1->domain,
								  NULL);
	  }
	  WlzFreeObj(obj1);
	  rtnObj = WlzMakeMain(WLZ_3D_DOMAINOBJ, domain, values,
			       NULL, NULL, &errNum);
	}
	break;

      case WLZ_3D_DOMAINOBJ:
	if( tmpl->domain.p ){
	  switch( tmpl->domain.p->type ){
	  case WLZ_2D_DOMAINOBJ:
	    domain.p = tmpl->domain.p;
	    break;

	  case WLZ_PLANEDOMAIN_POLYGON:
	  case WLZ_PLANEDOMAIN_CONV_HULL:
	    pdom = tmpl->domain.p;
	    if((domain.p = WlzMakePlaneDomain(WLZ_PLANEDOMAIN_DOMAIN,
					      pdom->plane1, pdom->lastpl,
					      pdom->line1, pdom->lastpl,
					      pdom->kol1, pdom->lastkl,
					      &errNum)) != NULL){
	      domain.p->voxel_size[0] = pdom->voxel_size[0];
	      domain.p->voxel_size[1] = pdom->voxel_size[1];
	      domain.p->voxel_size[2] = pdom->voxel_size[2];
	      for(p=pdom->plane1; p <= pdom->lastpl; p++){
		if( pdom->domains[p-pdom->plane1].core ){
		  obj1 = WlzPolyToObj(pdom->domains[p-pdom->plane1].poly,
				      WLZ_SIMPLE_FILL, &errNum);
		  domain.p->domains[p - pdom->plane1] =
		    WlzAssignDomain(obj1->domain, NULL);
		}
		WlzFreeObj(obj1);
	      }
	      values.core = NULL;
	      rtnObj = WlzMakeMain(WLZ_3D_DOMAINOBJ, domain, values,
				   NULL, NULL, &errNum);
	    }
	    break;

	  case WLZ_PLANEDOMAIN_BOUNDLIST:
	    pdom = tmpl->domain.p;
	    if((domain.p = WlzMakePlaneDomain(WLZ_PLANEDOMAIN_DOMAIN,
					      pdom->plane1, pdom->lastpl,
					      pdom->line1, pdom->lastpl,
					      pdom->kol1, pdom->lastkl,
					      &errNum)) != NULL){
	      domain.p->voxel_size[0] = pdom->voxel_size[0];
	      domain.p->voxel_size[1] = pdom->voxel_size[1];
	      domain.p->voxel_size[2] = pdom->voxel_size[2];
	      for(p=pdom->plane1; p <= pdom->lastpl; p++){
		if( pdom->domains[p-pdom->plane1].core ){
		  obj1 = WlzBoundToObj(pdom->domains[p-pdom->plane1].b,
				      WLZ_SIMPLE_FILL, &errNum);
		  domain.p->domains[p - pdom->plane1] =
		    WlzAssignDomain(obj1->domain, NULL);
		}
		WlzFreeObj(obj1);
	      }
	      values.core = NULL;
	      rtnObj = WlzMakeMain(WLZ_3D_DOMAINOBJ, domain, values,
				   NULL, NULL, &errNum);
	    }
	    break;

	  default:
	    errNum = WLZ_ERR_DOMAIN_TYPE;
	    break;
	  }
	  if( errNum == WLZ_ERR_NONE ){
	    rtnObj = WlzMakeMain(WLZ_3D_DOMAINOBJ, domain, values,
				 NULL, NULL, &errNum);
	  }
	}
	else {
	  errNum = WLZ_ERR_DOMAIN_NULL;
	}
	break;

      case WLZ_EMPTY_OBJ:
	return WlzMakeEmpty(dstErr);

      default:
	errNum = WLZ_ERR_OBJECT_TYPE;
	break;
      }
    }
  }

  /* now we have a 3D obj and 3D template so run through the template
     and map values as required, note we must check that all the valuetables
     have the same type ie switch to obj type if necessary */
  if( errNum == WLZ_ERR_NONE ){
    WlzDomain	*objDoms;
    WlzValues	*objVals;
    WlzGreyType	gtype=WLZ_GREY_UBYTE;

    /* attach a voxel table with empty values list */
    values.vox = WlzMakeVoxelValueTb(obj->values.vox->type,
				     rtnObj->domain.p->plane1,
				     rtnObj->domain.p->lastpl,
				     obj->values.vox->bckgrnd,
				     NULL, NULL);
    rtnObj->values = WlzAssignValues(values, NULL);

    /* set some local variables */
    pdom = rtnObj->domain.p;
    domains = rtnObj->domain.p->domains;
    valuess = rtnObj->values.vox->values;
    objDoms = obj->domain.p->domains;
    objVals = obj->values.vox->values;

    /* calculate the new valuetables */
    for(p=pdom->plane1; p <= pdom->lastpl; p++, domains++, valuess++){
      if(((*domains).core)){
	if((p >= obj->domain.p->plane1) &&
	   (p <= obj->domain.p->lastpl) &&
	   (objDoms[p - obj->domain.p->plane1].core) ){
	  tmpObj = WlzMakeMain(WLZ_2D_DOMAINOBJ,
				objDoms[p - obj->domain.p->plane1],
				objVals[p - obj->domain.p->plane1],
				NULL, NULL, NULL);
	  gtype = WlzGreyTableTypeToGreyType(tmpObj->values.core->type, NULL);
	}
	else {
	  tmpObj = WlzMakeEmpty(NULL);
	}
	tmpObj = WlzAssignObject(tmpObj, NULL);
	values.core = NULL;
	obj1 = WlzAssignObject(
	  WlzMakeMain(WLZ_2D_DOMAINOBJ, *domains, values,
		      NULL, NULL, NULL), NULL);
	if((obj2 = WlzGreyTemplate(tmpObj, obj1, tmplVal, &errNum)) != NULL){
	  *valuess = WlzAssignValues(obj2->values, NULL);
	  WlzFreeObj(obj2);
	}
	WlzFreeObj(obj1);
	WlzFreeObj(tmpObj);
      }
    }

    /* now check all valuetables have the same grey type */
    domains = rtnObj->domain.p->domains;
    valuess = rtnObj->values.vox->values;
    for(p=pdom->plane1; p <= pdom->lastpl; p++, domains++, valuess++){
      if((*domains).core &&
	 (WlzGreyTableTypeToGreyType((*valuess).core->type, NULL) != gtype)){
	obj1 = WlzAssignObject(
	  WlzMakeMain(WLZ_2D_DOMAINOBJ, *domains, *valuess,
		      NULL, NULL, NULL), NULL);
	if((obj2 = WlzConvertPix(obj1, gtype, &errNum)) != NULL){
	  /* substitute the valuetable in the voxel table array */
	  WlzFreeValues(*valuess);
	  *valuess = WlzAssignValues(obj2->values, NULL);
	  WlzFreeObj(obj2);
	}
	WlzFreeObj(obj1);
      }
    }
  }

  if( dstErr ){
    *dstErr = errNum;
  }
  return rtnObj;
}