Exemple #1
0
/*!
* \return	New BasisFn transform.
* \ingroup	WlzTransform
* \brief	Computes a basis function transform for the given object and a
*		set of control points using both an affine and a basis
*		function transform.
* \param	obj			Given object.
* \param	basisFnType		Required basis function type.
* \param	polyOrder		Order of polynomial, only used for
*					WLZ_FN_BASIS_2DPOLY.
* \param	nSPts			Number of source control points.
* \param	sPts			Source control points.
* \param	nDPts			Number of destination control points.
* \param	dPts			Destination control points.
* \param	dstErr			Destination error pointer, may be
*					NULL.
*/
static WlzBasisFnTransform *WlzAffineBasisFnTransformFromCPtsT(WlzObject *obj,
				WlzFnType basisFnType, int polyOrder,
				int nSPts, WlzDVertex2 *sPts,
				int nDPts, WlzDVertex2 *dPts,
				WlzErrorNum *dstErr)
{
  int		idx;
  WlzDVertex2	*dPtsT = NULL;
  WlzAffineTransform *aTr = NULL,
  		*aTrI = NULL;
  WlzBasisFnTransform *bTr = NULL;
  WlzErrorNum	errNum = WLZ_ERR_NONE;

  if(obj == NULL)
  {
    errNum = WLZ_ERR_OBJECT_NULL;
  }
  else if((nDPts <= 0) || (nDPts != nSPts))
  {
    errNum = WLZ_ERR_PARAM_DATA;
  }
  else if((dPts == NULL) || (sPts == NULL))
  {
    errNum = WLZ_ERR_PARAM_NULL;
  }
  /* Compute least squares affine transform from the tie points. */
  if(errNum == WLZ_ERR_NONE)
  {
    aTr = WlzAffineTransformLSq2D(nSPts, sPts, nSPts, dPts, 0, NULL,
				  WLZ_TRANSFORM_2D_AFFINE, &errNum);
  }

  if(errNum == WLZ_ERR_NONE)
  {
    if(nSPts >= 4)
    {
      /* Create a new array of destination vertices which have the original
       * destination transformed by the inverse affine transform. */
      if((dPtsT = (WlzDVertex2 *)AlcMalloc(sizeof(WlzDVertex2) *
	      				   nSPts)) == NULL)
      {
	errNum = WLZ_ERR_MEM_ALLOC;
      }
      if(errNum == WLZ_ERR_NONE)
      {
        aTrI = WlzAffineTransformInverse(aTr, &errNum);
      }
      if(errNum == WLZ_ERR_NONE)
      {
        for(idx = 0; idx < nDPts; ++idx)
	{
          dPtsT[idx] = WlzAffineTransformVertexD2(aTrI, dPts[idx], NULL);
	}
        bTr = WlzBasisFnTrFromCPts2D(basisFnType, polyOrder,
			  	   nSPts, sPts, nSPts, dPtsT, NULL, &errNum);
      }
    }
  }
  AlcFree(dPtsT);
  (void )WlzFreeAffineTransform(aTr);
  (void )WlzFreeAffineTransform(aTrI);
  if(errNum != WLZ_ERR_NONE)
  {
      (void )WlzBasisFnFreeTransform(bTr);
  }
  if(dstErr)
  {
    *dstErr = errNum;
  }
  return(bTr);
}
Exemple #2
0
int             main(int argc, char **argv)
{
  int		option,
  		nTiePP = 0,
		dim = 0,                /* Dimension will be set by objects. */
		cdt = 0,
		cMesh = 0,
		basisFnPolyOrder = 3,
		dbgFlg = 0, 		  /* Bit wise debug flags see usage. */
		noTrObj = 0,
		outBasisTrFlag = 0,
		outMeshTrFlag = 0,
		restrictToBasisFn = 0,
		ok = 1,
		usage = 0;
  double	meshMinDist = 20.0,
  		meshMaxDist = 40.0;
  WlzVertexP	vxA0,
  		vxA1;
  WlzObject	*inObj = NULL,
		*outObj = NULL,
		*dilObj = NULL,
           	*tmpObj = NULL;
  WlzCMeshP	tarMesh;
  WlzTransform  meshTr;
  WlzMeshGenMethod meshGenMth = WLZ_MESH_GENMETHOD_GRADIENT;
  WlzBasisFnTransform *basisTr = NULL;
  WlzFnType basisFnType = WLZ_FN_BASIS_2DMQ;
  WlzInterpolationType interp = WLZ_INTERPOLATION_NEAREST;
  FILE		*fP = NULL;
  WlzErrorNum	errNum = WLZ_ERR_NONE;
  char 		*inObjFileStr,
		*basisFnTrFileStr = NULL,
		*tarMeshFileStr = NULL,
		*tiePtFileStr = NULL,
  		*outObjFileStr;
  const int	delOut = 1;
  const char    *errMsg;
  static char	optList[] = "b:m:o:p:t:D:M:Y:cdghqsyBCGLNQRTU",
  		inObjFileStrDef[] = "-",
		outObjFileStrDef[] = "-";

  opterr = 0;
  vxA0.v = NULL;
  vxA1.v = NULL;
  tarMesh.v = NULL;
  meshTr.core = NULL;
  outObjFileStr = outObjFileStrDef;
  inObjFileStr = inObjFileStrDef;
  while((usage == 0) && ((option = getopt(argc, argv, optList)) != -1))
  {
    switch(option)
    {
      case 'o':
        outObjFileStr = optarg;
	break;
      case 'b':
        basisFnTrFileStr = optarg;
        break;
      case 'B':
        meshGenMth = WLZ_MESH_GENMETHOD_BLOCK;
	break;
      case 'C':
	meshGenMth = WLZ_MESH_GENMETHOD_CONFORM;
	break;
      case 'D':
	if(1 != sscanf(optarg, "%d", &dbgFlg))
	{
	  usage = 1;
	}
	break;
      case 'c':
        basisFnType = WLZ_FN_BASIS_2DCONF_POLY;
	break;
      case 'd':
        cdt = 1;
	break;
      case 'g':
        basisFnType = WLZ_FN_BASIS_2DGAUSS;
	break;
      case 'G':
        meshGenMth = WLZ_MESH_GENMETHOD_GRADIENT;
	break;
      case 'L':
        interp = WLZ_INTERPOLATION_LINEAR;
	break;
      case 'm':
	if(sscanf(optarg, "%lg", &meshMinDist) != 1)
	{
	  usage = 1;
	}
	break;
      case 'M':
	if(sscanf(optarg, "%lg", &meshMaxDist) != 1)
	{
	  usage = 1;
	}
	break;
      case 'N':
        noTrObj = 1;
	break;
      case 'p':
        tiePtFileStr = optarg;
	break;
      case 'q':
        basisFnType = WLZ_FN_BASIS_2DMQ;
	break;
      case 'Q':
        basisFnType = WLZ_FN_BASIS_2DIMQ;
	break;
      case 'R':
        restrictToBasisFn = 1;
	break;
      case 's':
        basisFnType = WLZ_FN_BASIS_2DTPS;
	break;
      case 't':
        tarMeshFileStr = optarg;
	break;
      case 'T':
        outBasisTrFlag = 1;
	break;
      case 'y':
        basisFnType = WLZ_FN_BASIS_2DPOLY;
	break;
      case 'U':
        outMeshTrFlag = 1;
	break;
      case 'Y':
        if(sscanf(optarg, "%d", &basisFnPolyOrder) != 1)
	{
	  usage = 1;
	}
	break;
      case 'h':
      default:
        usage = 1;
	break;
    }
  }
  if(usage == 0)
  {
    if(cdt)
    {
      cMesh = 1;
      restrictToBasisFn = 1;
      meshGenMth = WLZ_MESH_GENMETHOD_CONFORM;
    }
    if((tarMeshFileStr != NULL) && (cMesh == 0))
    {
      usage = 1;
    }
  }
  if(usage == 0)
  {
    if((inObjFileStr == NULL) || (*inObjFileStr == '\0') ||
       (((tiePtFileStr == NULL) || (*tiePtFileStr == '\0')) &&
	((basisFnTrFileStr == NULL) || (*basisFnTrFileStr == '\0'))) ||
       (outObjFileStr == NULL) || (*outObjFileStr == '\0'))
    {
      usage = 1;
    }
  }
  if((usage == 0) && (optind < argc))
  {
    if((optind + 1) != argc)
    {
      usage = 1;
    }
    else
    {
      inObjFileStr = *(argv + optind);
    }
  }
  ok = (usage == 0);
  /* Read input object that's to be transformed. */
  if(ok)
  {
    errNum = WLZ_ERR_READ_EOF;
    if((inObjFileStr == NULL) ||
	(*inObjFileStr == '\0') ||
	((fP = (strcmp(inObjFileStr, "-")?
		fopen(inObjFileStr, "r"): stdin)) == NULL) ||
	((inObj = WlzAssignObject(WlzReadObj(fP, &errNum), NULL)) == NULL) ||
	(errNum != WLZ_ERR_NONE))
    {
      ok = 0;
    }
    if(fP)
    {
      if(strcmp(inObjFileStr, "-"))
      {
	fclose(fP);
      }
      fP = NULL;
    }
    if(ok)
    {
      switch(inObj->type)
      {
        case WLZ_2D_DOMAINOBJ:
	  dim = 2;
	  break;
	case WLZ_3D_DOMAINOBJ:
	  dim = 3;
	  break;
        default:
	  errNum = WLZ_ERR_OBJECT_TYPE;
	  break;
      }
      if(errNum != WLZ_ERR_NONE)
      {
        ok = 0;
      }
    }
    if(ok == 0)
    {
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
		     "%s: Failed to read object from file %s (%s)\n",
		     *argv, inObjFileStr, errMsg);
    }
  }
  /* Read target mesh if required. */
  if(ok)
  {
    if(tarMeshFileStr != NULL)
    {
      errNum = WLZ_ERR_READ_EOF;
      if((tarMeshFileStr == NULL) ||
	  (*tarMeshFileStr == '\0') ||
	  ((fP = (strcmp(tarMeshFileStr, "-")?
		  fopen(tarMeshFileStr, "r"): stdin)) == NULL) ||
	  ((tmpObj = WlzAssignObject(WlzReadObj(fP,
	                                        &errNum), NULL)) == NULL) ||
	  (errNum != WLZ_ERR_NONE))
      {
	ok = 0;
      }
      else
      {
        switch(tmpObj->type)
	{
	  case WLZ_CMESH_2D:
	    if(dim == 0)
	    {
	      dim = 2;
	    }
	    if(dim != 2)
	    {
	      errNum = WLZ_ERR_OBJECT_TYPE;
	    }
	    else
	    {
	      if(tmpObj->domain.core == NULL)
	      {
		errNum = WLZ_ERR_DOMAIN_NULL;
	      }
	      else if(tmpObj->domain.cm2->type != WLZ_CMESH_2D)
	      {
		errNum = WLZ_ERR_DOMAIN_DATA;
	      }
	      else
	      {
		tarMesh.m2 = tmpObj->domain.cm2;
		tmpObj->domain.cm2 = NULL;
	      }
	    }
	    break;
	  case WLZ_CMESH_3D:
	    if(dim == 0)
	    {
	      dim = 3;
	    }
	    if(dim != 3)
	    {
	      errNum = WLZ_ERR_OBJECT_TYPE;
	    }
	    else
	    {
	      if(tmpObj->domain.core == NULL)
	      {
		errNum = WLZ_ERR_DOMAIN_NULL;
	      }
	      else if(tmpObj->domain.cm3->type != WLZ_CMESH_3D)
	      {
		errNum = WLZ_ERR_DOMAIN_DATA;
	      }
	      else
	      {
		tarMesh.m3 = tmpObj->domain.cm3;
		tmpObj->domain.cm3 = NULL;
	      }
	    }
	    break;
	  default:
	    errNum = WLZ_ERR_OBJECT_TYPE;
	    break;
	}
        if(errNum != WLZ_ERR_NONE)
	{
	  ok = 0;
	}
      }
      (void )WlzFreeObj(tmpObj);
      tmpObj = NULL;
      if(ok == 0)
      {
	(void )WlzStringFromErrorNum(errNum, &errMsg);
	(void )fprintf(stderr,
		 "%s: Failed to read target mesh object from file %s (%s).\n",
		       *argv, tarMeshFileStr, errMsg);
      }
    }
  }
  /* Either read the basis function transform from a file or compute it
   * from a set of tie points. */
  if(ok)
  {
    if(basisFnTrFileStr)
    {
      errNum = WLZ_ERR_UNSPECIFIED;
      ok = 0;
      (void )fprintf(stderr,
      		     "%s: Reading basis function transforms has not been\n"
		     "implemented yet\n",
		     *argv);
    }
    else if(tiePtFileStr)
    {
      if((fP = (strcmp(tiePtFileStr, "-")?
                fopen(tiePtFileStr, "r"): stdin)) == NULL)
      {
        ok = 0;
	errNum = WLZ_ERR_READ_EOF;
	(void )WlzStringFromErrorNum(errNum, &errMsg);
	(void )fprintf(stderr,
		       "%s: Failed to open tie points file %s (%s).\n",
		       *argv, tiePtFileStr, errMsg);
      }
      else
      {
        if(dim == 2)
	{
	  errNum = WlzBFTOGetVertices2D(&nTiePP, &(vxA0.d2), &(vxA1.d2),
	  				fP, tarMesh.m2, argv[0], tiePtFileStr);
	}
	else /* dim == 3 */
	{
	  errNum = WlzBFTOGetVertices3D(&nTiePP, &(vxA0.d3), &(vxA1.d3),
	  				fP, tarMesh.m3, argv[0], tiePtFileStr);
	}
	if(errNum != WLZ_ERR_NONE)
	{
	  ok = 0;
	}
      }
      if(fP && strcmp(tiePtFileStr, "-"))
      {
	fclose(fP);
      }
      fP = NULL;
    }
  }
  if(ok)
  {
    if(dim == 3)
    {
      /* Promote basis function type from 2D to 3D. */
      switch(basisFnType)
      {
        case WLZ_FN_BASIS_2DIMQ:
          basisFnType = WLZ_FN_BASIS_3DIMQ;
	  break;
        case WLZ_FN_BASIS_2DMQ:
          basisFnType = WLZ_FN_BASIS_3DMQ;
	  break;
        default:
	  errNum = WLZ_ERR_DOMAIN_TYPE;
	  ok = 0;
	  (void )WlzStringFromErrorNum(errNum, &errMsg);
	  (void )fprintf(stderr,
	                 "%s: invalid basis function type for 3D (%s).\n",
			 *argv, errMsg);
      }
    }
  }
  if(ok)
  {
    if(restrictToBasisFn)
    {
      if(cMesh)
      {
	if(tarMesh.v == NULL)
	{
	  meshTr.obj = WlzCMeshTransformFromObj(inObj,
				meshGenMth, meshMinDist, meshMaxDist,
				&dilObj, delOut, &errNum);
        }
      }
      else
      {
	meshTr.mesh = WlzMeshFromObj(inObj,
			      meshGenMth, meshMinDist, meshMaxDist,
			      &errNum);

      }
      if(errNum != WLZ_ERR_NONE)
      {
	ok = 0;
	(void )WlzStringFromErrorNum(errNum, &errMsg);
	(void )fprintf(stderr,
		       "%s: Failed to compute a mesh for the object (%s).\n",
		       *argv, errMsg);
      }
      if(errNum == WLZ_ERR_NONE)
      {
	if(tarMesh.v == NULL)
	{
	  if(dim == 2)
	  {
	    basisTr = WlzBasisFnTrFromCPts2D(basisFnType, basisFnPolyOrder,
					   nTiePP, vxA0.d2, nTiePP, vxA1.d2,
					   (cdt)? meshTr.obj->domain.cm2: NULL,
					   &errNum);
	  }
	  else /* dim == 3 */
	  {
	    basisTr = WlzBasisFnTrFromCPts3D(basisFnType, basisFnPolyOrder,
					   nTiePP, vxA0.d3, nTiePP, vxA1.d3,
					   (cdt)? meshTr.obj->domain.cm3: NULL,
					   &errNum);
	  }
	}
	else
	{
	  if(dim == 2)
	  {
	    basisTr = WlzBasisFnTrFromCPts2D(basisFnType, basisFnPolyOrder,
	    				     nTiePP, vxA1.d2, nTiePP, vxA0.d2,
					     tarMesh.m2, &errNum);
	  }
	  else /* dim == 3 */
	  {
	    basisTr = WlzBasisFnTrFromCPts3D(basisFnType, basisFnPolyOrder,
	    				     nTiePP, vxA1.d3, nTiePP, vxA0.d3,
					     tarMesh.m3, &errNum);
	  }
	}
	if(errNum != WLZ_ERR_NONE)
	{
	  ok = 0;
	  (void )WlzStringFromErrorNum(errNum, &errMsg);
	  (void )fprintf(stderr,
		   "%s: Failed to compute basis function transform (%s).\n",
		       *argv, errMsg);
	}
      }
    }
    else /* Use affine and basis functions to define mesh. */
    {
      meshTr.mesh = WlzMeshTransformFromCPts(inObj,
      				basisFnType, basisFnPolyOrder,
      				nTiePP, vxA0.d2, nTiePP, vxA1.d2,
				meshGenMth, meshMinDist, meshMaxDist,
				&errNum);
    }
  }
  if(ok)
  {
    if(outBasisTrFlag)
    {
      errNum = WLZ_ERR_UNIMPLEMENTED;
      ok = 0;
      (void )fprintf(stderr,
      		     "%s: Writing basis function transforms has not been\n"
		     "implemented yet\n",
		     *argv);
    }
    else /* Transform the object and then write it out. */
    {
      if(restrictToBasisFn)
      {
	if(errNum == WLZ_ERR_NONE)
	{
	  if(cMesh)
	  {
	    if(tarMesh.v == NULL)
	    {
	      errNum = WlzBasisFnSetCMesh(meshTr.obj, basisTr);
	    }
	    else
	    {
	       meshTr.obj = WlzBasisFnInvertMakeCMeshTr(basisTr, tarMesh,
	       				&errNum);
	    }
	  }
	  else
	  {
	    errNum = WlzBasisFnSetMesh(meshTr.mesh, basisTr);
	  }
	  if(errNum != WLZ_ERR_NONE)
	  {
	    ok = 0;
	    (void )WlzStringFromErrorNum(errNum, &errMsg);
	    (void )fprintf(stderr,
			   "%s: Failed to set the mesh displacements (%s).\n",
			   *argv, errMsg);
	  }
	}
      }
      if(errNum == WLZ_ERR_NONE)
      {
	if(outMeshTrFlag)
	{
	  if(cMesh)
	  {
	    errNum = WLZ_ERR_WRITE_EOF;
	    if(((fP = (strcmp(outObjFileStr, "-")?
		      fopen(outObjFileStr, "w"):
		      stdout)) == NULL) ||
	       ((errNum = WlzWriteObj(fP, meshTr.obj)) != WLZ_ERR_NONE))
	    {
	      ok = 0;
	      (void )WlzStringFromErrorNum(errNum, &errMsg);
	      (void )fprintf(stderr,
			     "%s: Failed to write CMesh object (%s).\n",
			     *argv, errMsg);
	    }
	    if(fP && strcmp(outObjFileStr, "-"))
	    {
	      fclose(fP);
	    }
	  }
	  else
	  {
	    errNum = WLZ_ERR_UNIMPLEMENTED;
	    ok = 0;
	    (void )fprintf(stderr,
			   "%s: Writing mesh transforms has not been\n"
			   "implemented yet\n",
			   *argv);
	  }
	}
	else
	{
	  if(noTrObj == 0)
	  {
	    if(cMesh)
	    {
	      outObj = WlzCMeshTransformObj(inObj, meshTr.obj, interp,
					    &errNum);
	    }
	    else
	    {
	      outObj = WlzMeshTransformObj(inObj, meshTr.mesh, interp,
					   &errNum);
	    }
	  }
	}
      }
      if(errNum == WLZ_ERR_NONE)
      {
	if(dbgFlg & 1)
	{
	  if(cMesh)
	  {
	    WlzCMeshOutputPS(meshTr.obj, inObj, dilObj, outObj);
	  }
	  else
	  {
	    WlzMeshOutputPS(meshTr.mesh);
	  }
	}
      }
      if(errNum != WLZ_ERR_NONE)
      {
	ok = 0;
	(void )WlzStringFromErrorNum(errNum, &errMsg);
	(void )fprintf(stderr,
		       "%s: Failed to transform object (%s).\n",
		       *argv, errMsg);
      }
      if((errNum == WLZ_ERR_NONE) && (noTrObj == 0) &&
         (outBasisTrFlag == 0) && (outMeshTrFlag == 0))
      {
	errNum = WLZ_ERR_WRITE_EOF;
	if(((fP = (strcmp(outObjFileStr, "-")?
		  fopen(outObjFileStr, "w"):
		  stdout)) == NULL) ||
	   ((errNum = WlzWriteObj(fP, outObj)) != WLZ_ERR_NONE))
	{
	  ok = 0;
	  (void )WlzStringFromErrorNum(errNum, &errMsg);
	  (void )fprintf(stderr,
			 "%s: Failed to write output object (%s).\n",
			 *argv, errMsg);
	}
	if(fP && strcmp(outObjFileStr, "-"))
	{
	  fclose(fP);
	}
      }
    }
  }
  AlcFree(vxA0.v);
  AlcFree(vxA1.v);
  (void )WlzCMeshFree(tarMesh);
  if(cMesh)
  {
    (void )WlzFreeObj(meshTr.obj);
  }
  else
  {
    (void )WlzMeshFreeTransform(meshTr.mesh);
  }
  (void )WlzBasisFnFreeTransform(basisTr);
  (void )WlzFreeObj(inObj);
  (void )WlzFreeObj(outObj);
  (void )WlzFreeObj(dilObj);
  if(usage != 0)
  {
    (void )fprintf(stderr,
    "Usage: %s%sExample: %s%s",
    *argv,
    " [-o<out object>] [-p<tie points file>]\n"
    "                  [-m<min mesh dist>] [-M<max mesh dist>]\n"
    "                  [-b<basis fn transform>] [-Y<order of polynomial>]\n"
    "                  [-D<flags>]\n"
    "                  [-d] [-g] [-h] [-q] [-s] [-t] [-y]\n"
    "                  [-B] [-C] [-G] [-L] [-N] [-T]\n"
    "                  [<in object>]\n"
    "Options:\n"
    "  -b  Basis function transform object.\n"
    "  -B  Block mesh generation method (default).\n"
    "  -C  Use conforming mesh.\n"
    "  -D  Debug flags:\n"
    "        1  Output the mesh as postscript to standard error output.\n"
    "        2  Output basis function distance maps to standard error\n"
    "           output.\n"
    "      These debug flags are only intended for use when debuging and\n"
    "      they may be combined by an or operation (eg 11 = 1 | 2 | 8).\n"
    "  -G  Gradient mesh generation method.\n"
    "  -L  Use linear interpolation instead of nearest neighbour.\n"
    "  -m  Minimum mesh node separation distance (default 10.0)\n"
    "  -M  Maximum mesh node separation distance (default 100.0)\n"
    "  -N  Don't transform the object (useful for testing)\n"
    "  -R  Restrict the transformation to only a basis function transform\n"
    "      instead of the default which uses a least squares affine and\n"
    "      basis function transform.\n"
    "  -o  Output object file name.\n"
    "  -p  Tie point file.\n"
    "  -c  Use conformal polynomial basis function if tie points are given.\n"
    "  -d  Compute transform using conforming distance transforms, also\n"
    "      sets the mesh generation to produce a conforming mesh and\n"
    "      restricts the transformation to a basis function transform\n"
    "      only (ie no least squares affine).\n"
    "  -g  Use Gaussian basis function if tie points are given.\n"
    "  -h  Help, prints this usage message.\n"
    "  -q  Use multi-quadric basis function if tie points are given.\n"
    "  -Q  Use inverse-multi-quadric basis function if tie points are given.\n"
    "  -s  Use thin plate spline basis function (default) if tie points\n"
    "      are given.\n"
    "  -t  Target mesh. Only valid for conforming meshes. If given then the\n"
    "      target mesh is used to compute a target-to-source radial basis\n"
    "      function, with distances computed in the target mesh. This is\n"
    "      then inverted as a mesh transform is created.\n"
    "  -T  Output a basis function transform instead of a transformed\n"
    "      object.\n"
    "  -U  Output a mesh transform instead of a transformed object.\n"
    "  -y  Use polynomial basis function if tie points are given.\n"
    "  -Y  Polynomial order for polynomial basis function (default 3).\n"
    "Computes and applies Woolz basis function transforms.\n"
    "Tie points may be read from an ascii file with the 2D format:\n"
    "  <x> <y> <displacement x> <displacement y>\n"
    "and the 3D format:\n"
    "  <x> <y> <z> <displacement x> <displacement y> <displacement z>\n"
    "Objects are read from stdin and written to stdout unless the filenames\n"
    "are given.\n",
    *argv,
    " -o tied.wlz -p points.tie myobj.wlz\n"
    "A thin plate spline basis function transform is computed from the\n"
    "tie points read from the file points.tie. This transform is then\n"
    "applied to the object is read from myobj.wlz. The resulting object\n"
    "is then written to tied.wlz.\n");
  }
  return(!ok);
}
Exemple #3
0
void conformalCalculateMeshCb(
  Widget	w,
  XtPointer	client_data,
  XtPointer	call_data)
{
  WlzBasisFnTransform	*basis;
  WlzFVertex2		*fvtxs, fvtx;
  WlzDVertex2		*dPts, *sPts;
  int			nPts;
  int			i, j;
  double		dist, length;
  WlzErrorNum		wlzErr;

  /* check for polygon */
  if( confPoly == NULL ){
    return;
  }

  /* calculate the source and destination polylines hence
     the conformal transformation */
  nPts = confPoly->nvertices;
  dPts = (WlzDVertex2 *) AlcMalloc(sizeof(WlzDVertex2) * nPts);
  sPts = (WlzDVertex2 *) AlcMalloc(sizeof(WlzDVertex2) * nPts);
  length = 0.0;
  fvtxs = (WlzFVertex2 *) confPoly->vtx;
  dPts[0].vtX = fvtxs[0].vtX;
  dPts[0].vtY = fvtxs[0].vtY;
  sPts[0].vtX = length;
  sPts[0].vtY = 0.0;
  for(i=1; i < nPts; i++){
    dist = (fvtxs[i].vtX - fvtxs[i-1].vtX)*(fvtxs[i].vtX - fvtxs[i-1].vtX);
    dist += (fvtxs[i].vtY - fvtxs[i-1].vtY)*(fvtxs[i].vtY - fvtxs[i-1].vtY);
    dist = sqrt(dist);
    length += dist;
    dPts[i].vtX = fvtxs[i].vtX;
    dPts[i].vtY = fvtxs[i].vtY;
    sPts[i].vtX = length;
    sPts[i].vtY = 0.0;
  }
  /* normalise the transformation */
  for(i=0; i < nPts; i++){
/*    sPts[i].vtX /= length;*/
    sPts[i].vtX *= 2.0 * WLZ_M_PI / length;
  }
  nPts /= 4;
  for(i=0; i < nPts; i++){
    sPts[i] = sPts[i*4];
    sPts[i].vtX = cos(sPts[i].vtX);
    sPts[i].vtY = sin(sPts[i].vtX);
    dPts[i] = dPts[i*4];
  }
/*  basis = WlzConfPolyFromCPts(WLZ_BASISFN_CONF_POLY, 6,
			       nPts, dPts, nPts, sPts,
			       &wlzErr);*/
  basis = WlzBasisFnTrFromCPts2D(WLZ_FN_BASIS_2DCONF_POLY, 2,
				 nPts, sPts, nPts, dPts,
				 NULL, &wlzErr);

  /* calculate the mesh polylines */
  numMeshPolys = 20;
/*  for(i=0; i < 20; i++){
    meshPolys[i] = WlzMakePolyDmn(WLZ_POLYGON_FLOAT,
				  NULL, 0, 41, 1, NULL);
    fvtxs = (WlzFVertex2 *) meshPolys[i]->vtx;
    fvtx.vtX = ((float) i) / 19.0;
    for(j=0; j < 41; j++){
      fvtx.vtY = ((float) j - 20) / 160.0;
      fvtxs[j] = WlzConfPolyTransformVertexF(basis, fvtx, &wlzErr);
    }
    meshPolys[i]->nvertices = 40;
  }
  for(; i < 40; i++){
    meshPolys[i] = WlzMakePolyDmn(WLZ_POLYGON_FLOAT,
				  NULL, 0, 41, 1, NULL);
    fvtxs = (WlzFVertex2 *) meshPolys[i]->vtx;
    fvtx.vtY = ((float) i - 30.0) / 80.0;
    for(j=0; j < 41; j++){
      fvtx.vtX = ((float) j) / 39.0;
      fvtxs[j] = WlzConfPolyTransformVertexF(basis, fvtx, &wlzErr);
    }
    meshPolys[i]->nvertices = 40;
    }*/
  for(i=0; i < 20; i++){
    double	theta, radius;
    meshPolys[i] = WlzMakePolygonDomain(WLZ_POLYGON_FLOAT, 0,
					NULL, 41, 1, NULL);
    fvtxs = (WlzFVertex2 *) meshPolys[i]->vtx;
    theta = (double) i * 2.0 * WLZ_M_PI / 20.0;
    for(j=0; j < 41; j++){
      radius = (double) j / 20.0;
      fvtx.vtX = radius * cos(theta);
      fvtx.vtY = radius * sin(theta);
      fvtxs[j] = WlzBasisFnTransformVertexF(basis, fvtx, &wlzErr);
    }
    meshPolys[i]->nvertices = 40;
  }
/*  for(; i < 40; i++){
    meshPolys[i] = WlzMakePolyDmn(WLZ_POLYGON_FLOAT,
				  NULL, 0, 41, 1, NULL);
    fvtxs = (WlzFVertex2 *) meshPolys[i]->vtx;
    fvtx.vtY = ((float) i - 30.0) / 80.0;
    for(j=0; j < 41; j++){
      fvtx.vtX = ((float) j) / 39.0;
      fvtxs[j] = WlzConfPolyTransformVertexF(basis, fvtx, &wlzErr);
    }
    meshPolys[i]->nvertices = 40;
    }*/

  AlcFree((void *) dPts);
  AlcFree((void *) sPts);
  if( wlzErr != WLZ_ERR_NONE ){
    MAPaintReportWlzError(globals.topl, "conformalCalculateMeshCb", wlzErr);
  }
  return;
}