Beispiel #1
0
/*!
* \return
* \ingroup	WlzTransform
* \brief	Gets a 3D section through a byte packed bitmap.
* \param	sizeBitData		Number of bytes in bitmap.
* \param	bitData			Bitmap data.
* \param	width			Bitmap width.
* \param	height			Bitmap height.
* \param	x_offset		Horizontal ofset into the bitmap.
* \param	y_offset		Vertical offset into the bitmap.
* \param	x			Fixed point x coordinate.
* \param	y			Fixed point y coordinate.
* \param	z			Fixed point z coordinate.
* \param	theta			Angle of rotation about the z-axis
*					(radians).
* \param	phi			Angle between the viewing direction
*					and the original z-axis (radians).
* \param	distance		Perpendicular distance from the
*					fixed point to the view plane.
* \param	dstErr			Destination error pointer, may be NULL.
*/
WlzObject *Wlz3DViewTransformBitmap(
    int		sizeBitData,
    WlzUByte	*bitData,
    int		width,
    int 		height,
    int 		x_offset,
    int 		y_offset,
    double 	x,
    double 	y,
    double 	z,
    double 	theta,
    double 	phi,
    double 	distance,
    WlzErrorNum	*dstErr)
{
    WlzErrorNum		errNum=WLZ_ERR_NONE;
    WlzObject		*rtnObj=NULL;
    WlzObject		*tmpObj;
    WlzIVertex2 		arraySizeDat;
    WlzIVertex2 		arrayOrigin;
    WlzThreeDViewStruct	*viewStr;

    arraySizeDat.vtX = width;
    arraySizeDat.vtY = height;
    arrayOrigin.vtX = x_offset;
    arrayOrigin.vtY = y_offset;

    if((tmpObj = WlzAssignObject(WlzFromBArray1D(arraySizeDat, bitData,
                                 arrayOrigin, &errNum), NULL)) != NULL) {

        /* make  and initialise WlzThreeDViewStruct */
        if((viewStr = WlzMake3DViewStruct(WLZ_3D_VIEW_STRUCT, &errNum)) != NULL) {
            viewStr->fixed.vtX	= x;
            viewStr->fixed.vtY	= y;
            viewStr->fixed.vtZ	= z;
            viewStr->theta 	= theta * WLZ_M_PI / 180.0;
            viewStr->phi 	= phi * WLZ_M_PI / 180.0;
            viewStr->dist 	= distance;
            viewStr->scale 	= 1.0;
            viewStr->view_mode = WLZ_UP_IS_UP_MODE;
            viewStr->up.vtX 	= 0.0;
            viewStr->up.vtY 	= 0.0;
            viewStr->up.vtZ 	= -1.0;
            WlzInit3DViewStruct(viewStr, tmpObj);

            /* transform the 2D section to 3D */
            rtnObj = Wlz3DViewTransformObj(tmpObj, viewStr, &errNum);

            /* clean up */
            WlzFree3DViewStruct(viewStr);
        }
        WlzFreeObj(tmpObj);
    }

    if( dstErr ) {
        *dstErr = errNum;
    }
    return rtnObj;
}
Beispiel #2
0
void setup_ref_display_list_cb(
Widget	w,
XtPointer	client_data,
XtPointer	call_data)
{

  WlzPlaneDomain	*planedmn;
  WlzThreeDViewStruct	*viewStr;
  WlzErrorNum		errNum=WLZ_ERR_NONE;

  if( globals.obj == NULL || globals.obj->type != WLZ_3D_DOMAINOBJ ||
     globals.ref_display_list == 0){
    return;
  }
  /* create a new display list */
  glDeleteLists(globals.ref_display_list, 1);
  globals.ref_display_list = glGenLists( (GLsizei) 1 );

  planedmn = globals.obj->domain.p;

  /* create the reference object 3D display  DisplayList */
  glNewList( globals.ref_display_list, GL_COMPILE );

  glBegin(GL_LINES);
  glColor3f(1.0, 0.0, 0.0);
  glIndexi( (int) HGU_XGetColorPixel(globals.dpy, globals.cmap, 1.0, 0.0, 0.0) );
  glVertex3i(planedmn->kol1, planedmn->line1, planedmn->plane1);
  glVertex3i(planedmn->lastkl, planedmn->line1, planedmn->plane1);
  glVertex3i(planedmn->kol1, planedmn->line1, planedmn->lastpl);
  glVertex3i(planedmn->lastkl, planedmn->line1, planedmn->lastpl);
  glVertex3i(planedmn->kol1, planedmn->lastln, planedmn->plane1);
  glVertex3i(planedmn->lastkl, planedmn->lastln, planedmn->plane1);
  glVertex3i(planedmn->kol1, planedmn->lastln, planedmn->lastpl);
  glVertex3i(planedmn->lastkl, planedmn->lastln, planedmn->lastpl);

  glColor3f(0.0, 1.0, 0.0);
  glIndexi( (int) HGU_XGetColorPixel(globals.dpy, globals.cmap, 0.0, 1.0, 0.0) );
  glVertex3i(planedmn->kol1, planedmn->line1, planedmn->plane1);
  glVertex3i(planedmn->kol1, planedmn->lastln, planedmn->plane1);
  glVertex3i(planedmn->kol1, planedmn->line1, planedmn->lastpl);
  glVertex3i(planedmn->kol1, planedmn->lastln, planedmn->lastpl);
  glVertex3i(planedmn->lastkl, planedmn->line1, planedmn->plane1);
  glVertex3i(planedmn->lastkl, planedmn->lastln, planedmn->plane1);
  glVertex3i(planedmn->lastkl, planedmn->line1, planedmn->lastpl);
  glVertex3i(planedmn->lastkl, planedmn->lastln, planedmn->lastpl);

  glColor3f(0.0, 0.0, 1.0);
  glIndexi( (int) HGU_XGetColorPixel(globals.dpy, globals.cmap, 0.0, 0.0, 1.0) );
  glVertex3i(planedmn->kol1, planedmn->line1, planedmn->plane1);
  glVertex3i(planedmn->kol1, planedmn->line1, planedmn->lastpl);
  glVertex3i(planedmn->kol1, planedmn->lastln, planedmn->plane1);
  glVertex3i(planedmn->kol1, planedmn->lastln, planedmn->lastpl);
  glVertex3i(planedmn->lastkl, planedmn->line1, planedmn->plane1);
  glVertex3i(planedmn->lastkl, planedmn->line1, planedmn->lastpl);
  glVertex3i(planedmn->lastkl, planedmn->lastln, planedmn->plane1);
  glVertex3i(planedmn->lastkl, planedmn->lastln, planedmn->lastpl);
  glEnd();

  if( globals.fb_obj && (globals.fb_obj->type == WLZ_3D_DOMAINOBJ) ){
    WlzObject		*obj1, *boundobj;
    WlzValues		values;
    int			z, step;

    /* establish the step size */
    planedmn = globals.fb_obj->domain.p;
    step = (planedmn->lastkl - planedmn->kol1) / 6;
    z = (planedmn->lastln - planedmn->line1) / 6;
    step = WLZ_MIN(step, z);
    z = (planedmn->lastpl - planedmn->plane1) / 6;
    step = WLZ_MIN(step, z);

    /* set up const z boundaries */
    glColor3f(1.0, 1.0, 1.0);
    glIndexi((int) HGU_XGetColorPixel(globals.dpy, globals.cmap, 1.0, 1.0, 1.0));
    (void) glLineWidth( (GLfloat) 2.0 );
    for(z=planedmn->plane1+step/2; z <= planedmn->lastpl; z += step)
    {
      values.core = NULL;
      obj1 = WlzMakeMain(WLZ_2D_DOMAINOBJ,
			 planedmn->domains[z - planedmn->plane1],
			 values, NULL, NULL, NULL);
      if( obj1->domain.core != NULL )
      {
	boundobj = WlzObjToBoundary(obj1, 1, &errNum);
	if( boundobj != NULL )
	{
	  MAOpenGLDisplayBoundList(boundobj->domain.b, (float) z );
	  WlzFreeObj( boundobj );
	}
	if( errNum != WLZ_ERR_NONE ){
	  break;
	}
      }
      WlzFreeObj( obj1 );
    }
    (void) glLineWidth( (GLfloat) 1.0 );

    /* set up const y boundaries */
    if( errNum == WLZ_ERR_NONE ){
      glColor3f(1.0, 1.0, 0.0);
      glIndexi((int) HGU_XGetColorPixel(globals.dpy, globals.cmap, 1.0, 1.0, 0.0));
      if((viewStr = WlzMake3DViewStruct(WLZ_3D_VIEW_STRUCT, &errNum))){
	viewStr->theta = WLZ_M_PI / 2.0;
	viewStr->phi = WLZ_M_PI / 2.0;
	viewStr->dist = planedmn->line1 - step/2;
	errNum = WlzInit3DViewStruct(viewStr, globals.fb_obj);
	for(z=viewStr->dist+step; (errNum == WLZ_ERR_NONE) && (z <= planedmn->lastln);
	    z += step)
	{
	  Wlz3DSectionIncrementDistance(viewStr, (double) step);
	  if((obj1 = WlzGetSectionFromObject(globals.fb_obj, viewStr,
					     WLZ_INTERPOLATION_NEAREST,
					     &errNum))){
	    obj1 = WlzAssignObject(obj1, NULL);
	    boundobj = WlzObjToBoundary(obj1, 1, &errNum);
	    if( boundobj != NULL )
	    {
	      /* convert boundary coordinates to voxel coordinates */
	      Wlz3DSectionTransformYBound(boundobj->domain.b, viewStr);
	      MAOpenGLDisplayYBoundList(boundobj->domain.b, (float) z);
	      WlzFreeObj( boundobj );
	    }
	    WlzFreeObj( obj1 );
	  }
	}
	WlzFree3DViewStruct(viewStr);
      }
    }

    /* set up const x boundaries */
    if( errNum == WLZ_ERR_NONE ){
      glIndexi((int) HGU_XGetColorPixel(globals.dpy, globals.cmap, 1.0, 1.0, 0.0));
      glColor3f(1.0, 1.0, 0.0);
      if((viewStr = WlzMake3DViewStruct(WLZ_3D_VIEW_STRUCT, &errNum))){
	viewStr->theta = 0.0;
	viewStr->phi = WLZ_M_PI / 2.0;
	viewStr->dist = planedmn->kol1 - step/2;
	errNum = WlzInit3DViewStruct(viewStr, globals.fb_obj);
	for(z=viewStr->dist+step; (errNum == WLZ_ERR_NONE) && (z <= planedmn->lastkl);
	    z += step)
	{
	  Wlz3DSectionIncrementDistance(viewStr, (double) step);
	  if((obj1 = WlzGetSectionFromObject(globals.fb_obj, viewStr,
					     WLZ_INTERPOLATION_NEAREST,
					     &errNum))){
	    obj1 = WlzAssignObject(obj1, NULL);
	    boundobj = WlzObjToBoundary(obj1, 1, &errNum);
	    if( boundobj != NULL )
	    {
	      /* convert boundary coordinates to voxel coordinates */
	      Wlz3DSectionTransformXBound(boundobj->domain.b, viewStr);
	      MAOpenGLDisplayXBoundList(boundobj->domain.b, (float) z);
	      WlzFreeObj( boundobj );
	    }
	    WlzFreeObj( obj1 );
	  }
	}
	WlzFree3DViewStruct(viewStr);
      }
    }
  }

  if( errNum == WLZ_ERR_NONE ){
    glIndexi( (int) HGU_XGetColorPixel(globals.dpy, globals.cmap, 1.0, 1.0, 1.0) );
    glColor3f(1.0, 1.0, 1.0);
    glEndList();

    WLZ_VTX_3_SET(globals.bbox_vtx, planedmn->kol1 - 2.0,
		  planedmn->line1 - 2.0, planedmn->plane1 - 2.0);
    WLZ_VTX_3_SET(globals.bbox_size,
		  planedmn->lastkl - planedmn->kol1 + 4.0,
		  planedmn->lastln - planedmn->line1 + 4.0,
		  planedmn->lastpl - planedmn->plane1 + 4.0);
    glFogf(GL_FOG_DENSITY, 0.25/globals.bbox_size.vtX);
    MAOpenGLDrawScene( globals.canvas );
  }
  else {
    MAPaintReportWlzError(globals.topl, "setup_ref_display_list_cb", errNum);
  }

  return;
}
Beispiel #3
0
int		main(int argc, char *argv[])
{
  int		option,
  		ok = 1,
		usage = 0,
		dim = 2,
		section = 0,
		timer = 0;
  double	yaw = 0.0,
  		pitch = 0.0,
		roll =  0.0,
		dist = 0.0,
		scale = 1.0;
  WlzPixelV	bgdV;
  WlzGreyType	gType;
  WlzDVertex3	up,
  		fixed;
  WlzInterpolationType interp = WLZ_INTERPOLATION_NEAREST;
  WlzThreeDViewMode mode = WLZ_UP_IS_UP_MODE;
  WlzErrorNum	errNum = WLZ_ERR_NONE;
  FILE		*fP = NULL;
  WlzObject	*inObj = NULL,
  		*tlObj = NULL;
  char		*inFileStr,
		*outFileStr,
  		*secFileStr;
  struct timeval times[3];
  const char	*errMsg;
  const size_t	tlSz = 4096;
  static char	optList[] = "hsto:S:",
  		inFileStrDef[] = "-";

  opterr = 0;
  outFileStr = NULL;
  inFileStr = inFileStrDef;
  secFileStr = inFileStrDef;
  gType = WLZ_GREY_UBYTE;
  bgdV.type = WLZ_GREY_UBYTE;
  bgdV.v.ubv = 0;
  up.vtX = up.vtY = 0.0; up.vtZ = -1.0;
  fixed.vtX = fixed.vtY = fixed.vtZ = 0.0;
  while(ok && ((option = getopt(argc, argv, optList)) != -1))
  {
    switch(option)
    {
      case 'o':
        outFileStr = optarg;
	break;
      case 's':
        section = 1;
	break;
      case 'S':
        secFileStr = optarg;
	break;
      case 't':
        timer = 1;
	break;
      case 'h': /* FALLTHROUGH */
      default:
	usage = 1;
	break;
    }
  }
  if((usage == 0) && (optind < argc))
  {
    if((optind + 1) != argc)
    {
      usage = 1;
    }
    else
    {
      inFileStr = *(argv + optind);
    }
  }
  ok = !usage;
  if(ok)
  {
    fP = NULL;
    errNum = WLZ_ERR_READ_EOF;
    if(((fP = (strcmp(inFileStr, "-")? fopen(inFileStr, "r"):
                                       stdin)) == NULL) ||
       ((inObj= WlzAssignObject(WlzReadObj(fP, &errNum), NULL)) == NULL))
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
                     "%s: Failed to read object from file %s (%s).\n",
		     *argv, inFileStr, errMsg);
    }
    if(fP && strcmp(inFileStr, "-"))
    {
      (void )fclose(fP);
    }
  }
  if(ok)
  {
    if(inObj == NULL)
    {
      errNum = WLZ_ERR_OBJECT_NULL;
    }
    else if(inObj->domain.core == NULL)
    {
      errNum = WLZ_ERR_DOMAIN_NULL;
    }
    else
    {
      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;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
                     "%s: invalid object read from file %s (%s).\n",
		     *argv, inFileStr, errMsg);
    }
  }
  if(ok)
  {
    if(timer)
    {
      gettimeofday(times + 0, NULL); 
    }
    tlObj = WlzMakeTiledValuesFromObj(inObj, tlSz, 1, gType, bgdV, &errNum);
    if(timer)
    {
      gettimeofday(times + 1, NULL); 
      timersub(times + 1, times + 0, times + 2);
      (void )fprintf(stderr,
                     "%s: Elapsed time for WlzMakeTiledValuesFromObj() %gs\n",
                     *argv,
		     times[2].tv_sec + (0.000001 * times[2].tv_usec));

    }
    if(errNum != WLZ_ERR_NONE)
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
                     "%s: Failed to create object with tiled values (%s).\n",
		     *argv, errMsg);
    }
  }
  if(ok && (outFileStr != NULL))
  {
    if(((fP = (strcmp(outFileStr, "-")? fopen(outFileStr, "w"):
                                        stdout)) == NULL) ||
       ((errNum = WlzWriteObj(fP, tlObj)) != WLZ_ERR_NONE))
    
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
		     "%s: Failed to write tiled object to file %s (%s).\n",
		     *argv, outFileStr, errMsg);
    }
  }
  if(ok && section && (dim == 3))
  {
    WlzObject 	*secObj = NULL;
    WlzThreeDViewStruct *view = NULL;

    view = WlzMake3DViewStruct(WLZ_3D_VIEW_STRUCT, &errNum);
    if(errNum == WLZ_ERR_NONE)
    {
      view->theta = yaw * WLZ_M_PI / 180.0;
      view->phi = pitch * WLZ_M_PI / 180.0;
      view->zeta = roll * WLZ_M_PI / 180.0;
      view->dist = dist;
      view->fixed = fixed;
      view->up = up;
      view->view_mode = mode;
      view->scale = scale;
      errNum = WlzInit3DViewStruct(view, tlObj);
    }
    if(errNum == WLZ_ERR_NONE)
    {
      if(timer)
      {
	gettimeofday(times + 0, NULL); 
      }
      secObj = WlzGetSubSectionFromObject(tlObj, NULL, view, interp,
      					  NULL, &errNum);
      if(timer)
      {
	gettimeofday(times + 1, NULL); 
	timersub(times + 1, times + 0, times + 2);
	(void )fprintf(stderr,
		     "%s: Elapsed time for WlzGetSubSectionFromObject() %gs\n",
		     *argv,
		     times[2].tv_sec + (0.000001 * times[2].tv_usec));
      }
      fP = NULL;
      errNum = WLZ_ERR_WRITE_EOF;
      if(((fP = (strcmp(secFileStr, "-")? fopen(secFileStr, "w"):
					  stdout)) == NULL) ||
	 ((errNum = WlzWriteObj(fP, secObj)) != WLZ_ERR_NONE))
      {
	ok = 0;
	(void )WlzStringFromErrorNum(errNum, &errMsg);
	(void )fprintf(stderr,
		       "%s: Failed to write section object to file %s (%s).\n",
		       *argv, secFileStr, errMsg);
      }
      if(fP && strcmp(secFileStr, "-"))
      {
	(void )fclose(fP);
      }
    }
    (void )WlzFree3DViewStruct(view);
    (void )WlzFreeObj(secObj);
  }
  (void )WlzFreeObj(tlObj);
  (void )WlzFreeObj(inObj);
  if(usage)
  {
    (void )fprintf(stderr,
    "Usage: %s%s",
    *argv,
    " [-o<output object>] [-h] [-o <file>] [-s] [-S <file>] [-t]\n"
    "                  [<input object>]\n"
    "Copied the input object to an object with tiled values.\n"
    "Options:\n"
    "  -h  Prints this usage information.\n"
    "  -o  Output tiled object.\n"
    "  -s  Cut section from tiled object.\n"
    "  -S  Output file for section object.\n"
    "  -t  Output timing information.\n");
  }
  return(!ok);
}
Beispiel #4
0
int main(int	argc,
	 char	**argv)
{

  WlzObject	*obj, *nobj;
  FILE		*inFP, *outFP, *bibFP;
  char		*outFile, *bibFile;
  char 		optList[] = "a:b:d:f:m:o:s:u:hv";
  int		option;
  int		iVal;
  double	dist=0.0, pitch=0.0, yaw=0.0, roll=0.0;
  double	scale=1.0;
  WlzDVertex3	fixed={0.0,0.0,0.0};
  WlzDVertex3	up={0.0,0.0,-1.0};
  WlzThreeDViewStruct	*viewStr=NULL;
  WlzThreeDViewMode mode=WLZ_UP_IS_UP_MODE;
  WlzErrorNum	errNum=WLZ_ERR_NONE;
  BibFileRecord	*bibfileRecord;
  BibFileError	bibFileErr;
  int		verboseFlg=0;
  char		*errMsg;
    
  /* additional defaults */
  outFile = "-";
  bibFile = NULL;

  /* read the argument list and check for an input file */
  opterr = 0;
  while( (option = getopt(argc, argv, optList)) != EOF ){
    switch( option ){

    case 'a':
      switch( sscanf(optarg, "%lg,%lg,%lg", &pitch, &yaw, &roll) ){
      default:
	usage(argv[0]);
	return 1;
      case 2:
	break;
      case 3:
	mode = WLZ_ZETA_MODE;
	break;
      }
      break;

    case 'b':
      bibFile = optarg;
      break;

    case 'd':
      if( sscanf(optarg, "%lg", &dist) < 1 ){
	usage(argv[0]);
	return 1;
      }
      break;

    case 'f':
      if( sscanf(optarg, "%lg,%lg,%lg", &(fixed.vtX), &(fixed.vtY),
		 &(fixed.vtZ)) < 3 ){
	usage(argv[0]);
	return 1;
      }
      break;

    case 'm':
      if( sscanf(optarg, "%d", &iVal) < 1 ){
	usage(argv[0]);
	return 1;
      }
      else if( mode != WLZ_ZETA_MODE ){
	switch( iVal ){
	default:
	  usage(argv[0]);
	  return 1;
	case 0:
	  mode = WLZ_UP_IS_UP_MODE;
	  break;
	case 1:
	  mode = WLZ_STATUE_MODE;
	  break;
	case 2:
	  mode = WLZ_ZETA_MODE;
	  break;
	}
      }
      break;

    case 'o':
      outFile = optarg;
      break;

    case 's':
      if( sscanf(optarg, "%lg", &scale) < 1 ){
	usage(argv[0]);
	return 1;
      }
      break;

    case 'u':
      if( sscanf(optarg, "%lg,%lg,%lg", &(up.vtX), &(up.vtY),
		 &(up.vtZ)) < 3 ){
	usage(argv[0]);
	return 1;
      }
      break;

    case 'h':
    default:
      usage(argv[0]);
      return 0;

    case 'v':
      verboseFlg = 1;
      break;

    }
  }

  /* check input file/stream */
  inFP = stdin;
  if( optind < argc ){
    if( (inFP = fopen(*(argv+optind), "r")) == NULL ){
      fprintf(stderr, "%s: can't open file %s\n", argv[0], *(argv+optind));
      usage(argv[0]);
      return 1;
    }
  }

  /* check output file/stream */
  if(strcmp(outFile, "-"))
  {
    if((outFP = fopen(outFile, "w")) == NULL)
    {
      errNum = WLZ_ERR_WRITE_EOF;
    }
  }
  else
  {
    outFP = stdout;
  }

  /* create view structure */
  if((viewStr = WlzMake3DViewStruct(WLZ_3D_VIEW_STRUCT, &errNum)) != NULL){
    viewStr->theta = yaw * WLZ_M_PI / 180.0;
    viewStr->phi = pitch * WLZ_M_PI / 180.0;
    viewStr->zeta = roll * WLZ_M_PI / 180.0;
    viewStr->dist = dist;
    viewStr->fixed = fixed;
    viewStr->up = up;
    viewStr->view_mode = mode;
    viewStr->scale = scale;
  }

  /* check bibfile - select first section parameters in the file */
  if((errNum == WLZ_ERR_NONE) && (bibFile != NULL)){
    if((bibFP = fopen(bibFile, "r")) != NULL){
      bibFileErr = BibFileRecordRead(&bibfileRecord, &errMsg, bibFP);
      while((bibFileErr == BIBFILE_ER_NONE) &&
	    (strncmp(bibfileRecord->name, "Wlz3DSectionViewParams", 22))){
	BibFileRecordFree(&bibfileRecord);
	bibFileErr = BibFileRecordRead(&bibfileRecord, &errMsg, bibFP);
      }
      fclose( bibFP );
      if( bibFileErr != BIBFILE_ER_NONE ){
	fprintf(stderr, "%s: error reading bibfile: %s\n", argv[0], errMsg);
	AlcFree((void *) errMsg);
	return 1;
      }
      WlzEffBibParse3DSectionViewParamsRecord(bibfileRecord, viewStr);
      BibFileRecordFree(&bibfileRecord);
    }
    else {
      fprintf(stderr, "%s: can't open parameter bibfile %s\n", argv[0],
	      bibFile);
      return 1;
    }
  }
  

  /* read objects and section if possible */
  while((errNum == WLZ_ERR_NONE) &&
        ((obj = WlzReadObj(inFP, &errNum)) != NULL))
  {
    switch( obj->type )
    {
    case WLZ_3D_DOMAINOBJ:
      WlzInit3DViewStruct(viewStr, obj);
      nobj = WlzGetProjectionFromObject(obj, viewStr, NULL, NULL, &errNum);
      if( nobj != NULL){
	WlzWriteObj(outFP, nobj);
      }
      else {
	return errNum;
      }
      WlzFreeObj(nobj);
      break;

    default:
	WlzWriteObj(outFP, obj);
	break;
    }

    WlzFreeObj(obj);
  }
  if(errNum == WLZ_ERR_READ_EOF)
  {
    errNum = WLZ_ERR_NONE;
  }

  return errNum;
}
int main(int	argc,
	 char	**argv)
{

  FILE	       *inFile = NULL;   /* used to read Woolz object */ 
  int           i,j,k=0, m;
  int		option;
  int           startJ;
  int           cycleI, cycleNext;
  double           ntnm,nfnm,nsnm;
  int           numOf2DWlzFiles = 0, numOfBibFiles = 0;
  int           ok, usage1, idx;
  double        deltaZ;
  double        sx=0,sy=0,sz=0, fx=0,fy=100,fz=0, tx=100,ty=0,tz=0;
  double        Sx=0,Sy=0,Sz=60, Fx=0,Fy=100,Fz=60, Tx=100,Ty=0,Tz=60;
  double        lengthTS;
  char         *inFileStr, *inFileStr1, *outFileStr;
  char         *inFileStrw=NULL, *outputWlzFilesDir=NULL;
  char          TwoDImageFilesNameList[700][120];
  char          TwoDImagePureFilesNameList[700][120];
  char          warpedFilesNameList[700][120];
  char          BibFilesNameList[700][120];

  char          TwoDImageFilesDir[120];
  char         *List2DImageFilesStr= NULL, *ListBibFilesStr= NULL;


  WlzVertex      vs, vt, vf,  vS, vT, vF;
  WlzVertex      vs1, vt1, vf1, vsp, vtp, vfp, vST;

  WlzVertex      vsr, vtr, vfr;
  WlzVertex      ns, nf, nt, nsp, nfp, ntp, nz,nm;
  WlzDVertex2   *vtxVec1;
  WlzErrorNum	 errNum = WLZ_ERR_NONE;
  WlzThreeDViewStruct *wlzViewStr, *wlzViewStr1;
  WlzObject     *WObjS; 
  char		*cutStr[3];
  double        cutVal[3];

  /* read the argument list and check for an input file */
  static char	optList[] = "i:I:w:o:d:s:S:f:F:t:T:M:n:r:R:L:B:h",opterr = 0;
  ok = 1;
 
   while( (option = getopt(argc, argv, optList)) != EOF )
   {
      switch( option )
      {
        case 'h':
             usage(argv[0]);
	     return(0);
        case 'i':
	    inFileStr  = optarg;
	    /*
	    outFileStr = optarg;
	    */
	    break;
        case 'I':
	    inFileStr1 = optarg;
	    break;
        case 'L':
	    List2DImageFilesStr = optarg;
	    break;
        case 'B':
	    ListBibFilesStr = optarg;
	    break;
        case 'w':
	    inFileStrw = optarg;
	    break;
        case 'n':
	 if(sscanf(optarg, "%d", &startJ) != 1)
	    {
	      printf("read error");
	      exit(1);
	    }
	    break;
        case 's':
        case 'f':
        case 't':
        case 'S':
        case 'F':
        case 'T':
	  if(optarg)
	  {
	  	while(*optarg && isspace(*optarg))
	  	{
                    ++optarg;
		}
	 	if(*optarg == ',')
	  	{
	    		cutStr[0] = NULL;
	    		cutStr[1] = strtok(optarg, ",");
	    		cutStr[2] = strtok(optarg, ",");
	  	}
	  	else
	  	{
	    		cutStr[0] = strtok(optarg, ",");
	    		cutStr[1] = strtok(NULL, ",");
		    	cutStr[2] = strtok(NULL, ",");
	  	}
	  	if((cutStr[0] == NULL) && (cutStr[1] == NULL) && (cutStr[2] == NULL)   )
	  	{
	    		usage1 = 1;
	    		ok = 0;
	  	}
	  	else
	  	{
	    		idx = 0;
	    		while(ok && (idx < 3))
	    		{
	      			if(cutStr[idx] && (sscanf(cutStr[idx], "%lg",
					 cutVal + idx) != 1))
	      			{
					usage1 = 1;
					ok = 0;
	      			}
	      			++idx;
	    		}
	  	}
	}
	if(ok)
	{
	  switch(option)
	  {
	    case 's':
		sx = (double) cutVal[0];
		sy = (double) cutVal[1];
		sz = (double) cutVal[2];
		break;
	    case 'f':
		fx = (double) cutVal[0];
		fy = (double) cutVal[1];
		fz = (double) cutVal[2];
		break;
	    case 't':
		tx = (double) cutVal[0];
		ty = (double) cutVal[1];
		tz = (double) cutVal[2];
		break;
	    case 'S':
		Sx = (double) cutVal[0];
		Sy = (double) cutVal[1];
		Sz = (double) cutVal[2];
		break;
	    case 'F':
		Fx = (double) cutVal[0];
		Fy = (double) cutVal[1];
		Fz = (double) cutVal[2];
		break;
	    case 'T':
		Tx = (double) cutVal[0];
		Ty = (double) cutVal[1];
		Tz = (double) cutVal[2];
		break;
	  }	

	}
	break;
        case 'o':
	    outFileStr = optarg;
	    break;
        case 'd':
	    outputWlzFilesDir = optarg;
	    break;
        default:
              return(0);
      }
   }

      printf("t: %f %f %f\n",tx,ty, tz );
      printf("T: %f %f %f\n",Tx,Ty, Tz );

    /*------- allocate memory --------*/
    if (
         ((vtxVec1 = (WlzDVertex2 *)AlcCalloc(sizeof(WlzDVertex2), 3))  == NULL) 
      )
    {
       errNum = WLZ_ERR_MEM_ALLOC;
    }

    /* ------Read 2D Wlz files List------- */
     printf("Read 2D Wlz file list\n");
    if((inFile = fopen(List2DImageFilesStr, "r")) == NULL )
    {
        printf("cannot open the 2D image files list file.\n");
        exit(1);
    }
    
    i=0;
    /* get the number of files */
    while(!feof(inFile)){

        fscanf(inFile, "%s", *(TwoDImageFilesNameList + i ));
	/*  printf("%s\n", *(TwoDImageFilesNameList + i ) ); */
	i++;
    }
    fclose(inFile); 
    inFile = NULL;

    numOf2DWlzFiles = i-1;
    printf("number of files = %d\n", numOf2DWlzFiles );

    /* extract pure wlz filename without directory */
    printf("extract pure wlz filename without directory\n");

    for(m=0; m<numOf2DWlzFiles; m++)
    {
       for(i=0; i<sizeof(TwoDImageFilesNameList[m]); i++){
          if( TwoDImageFilesNameList[m][i] == (char) NULL )
           break; 
          if( TwoDImageFilesNameList[m][i] == '/' )
            k = i; 	   
       }
       if(k != 0)
       k++;
       for(j=k; j<i; j++)
       {
         TwoDImagePureFilesNameList[m][j-k] = TwoDImageFilesNameList[m][j];
         warpedFilesNameList[m][j-k]        = TwoDImageFilesNameList[m][j];
       }
       TwoDImagePureFilesNameList[m][j-k] = ( char ) NULL;
       warpedFilesNameList[m][j-k]        = ( char ) NULL;
         
       /* extract directory */
       if(m == 0)
       {
          for(j=0; j<k; j++)
	  {
	     TwoDImageFilesDir[j] = TwoDImageFilesNameList[m][j];
	  }
	     TwoDImageFilesDir[j] = ( char ) NULL;
	     printf("I_DIR  %s\n",TwoDImageFilesDir );
       }
       printf("%s\n", TwoDImagePureFilesNameList[m]);   
    }

/*--- Read bib File name list ----*/
    if((inFile = fopen(ListBibFilesStr, "r")) == NULL )
    {
        printf("cannot open the 2D image files list file.\n");
        exit(1);
    }
    i=0;
    while(!feof(inFile)){
        fscanf(inFile, "%s", BibFilesNameList[i]);
	printf("%s\n", BibFilesNameList[i]);
	i++;
    }
      fclose(inFile); 
      inFile = NULL;
    numOfBibFiles = i-1;
    printf("number of files bib files = %d\n", numOfBibFiles );

/* check whether the number of bib files is the same as number of Wlz 2D sections */
    if(numOfBibFiles != numOf2DWlzFiles )
    {
         printf("Number of 2D woolz files and number of bib files are different\n");
	 exit(1);
    }

/* get the output file namelist */
   i =  (int) strlen( (const char *) outputWlzFilesDir);
   printf("%d\n", i);
   for( j = 0; j < numOfBibFiles; j++)
   {
      strcpy( warpedFilesNameList[j], (const char *) outputWlzFilesDir );
      strcat( warpedFilesNameList[j], "/");
      strcat(warpedFilesNameList[j], (const char *) TwoDImagePureFilesNameList[j]);
      printf("%s\n", warpedFilesNameList[j] );   
   }   
   
/* --------read Woolz object--------- */
      if((inFile = fopen(inFileStrw, "r")) == NULL )
      {
        printf("cannot open the input woolz file.\n");
        exit(1);
      }

      if( !(WObjS = WlzReadObj(inFile, &errNum) ) )
      {
        printf("input Woolz Object Error.\n");
        fclose(inFile); 
        exit(1);
      }
      fclose(inFile); 
      inFile = NULL;

/* ------get the fixed S , T and F ready and s, t, f  in OPT space------ */

      vS.d3.vtX = Sx; 
      vS.d3.vtY = Sy;
      vS.d3.vtZ = Sz;
      vT.d3.vtX = Tx; 
      vT.d3.vtY = Ty;
      vT.d3.vtZ = Tz;
      vF.d3.vtX = Fx; 
      vF.d3.vtY = Fy;
      vF.d3.vtZ = Fz;
      
      vs.d3.vtX = sx; 
      vs.d3.vtY = sy;
      vs.d3.vtZ = sz;
      vt.d3.vtX = tx; 
      vt.d3.vtY = ty;
      vt.d3.vtZ = tz;
      vf.d3.vtX = fx; 
      vf.d3.vtY = fy;
      vf.d3.vtZ = fz;
      
      printf("vt: %f %f %f\n",vt.d3.vtX,vt.d3.vtY, vt.d3.vtZ );
      printf("vT: %f %f %f\n",vT.d3.vtX,vT.d3.vtY, vT.d3.vtZ );
/*  -----get the three directions in OPT space------- 
    n = 1/(|r2-r1|) { (x2-x1) i  + (y2-y1) j + (z2-z1) k  }

  */
   
      WLZ_VTX_3_SUB(vST.d3,vS.d3,vs.d3);
      lengthTS  =  WLZ_VTX_3_LENGTH( vST.d3);
      ns.d3.vtX = vST.d3.vtX/ lengthTS;
      ns.d3.vtY = vST.d3.vtY/ lengthTS;
      ns.d3.vtZ = vST.d3.vtZ/ lengthTS;


      WLZ_VTX_3_SUB(vST.d3,vF.d3,vf.d3);
      lengthTS  =  WLZ_VTX_3_LENGTH( vST.d3);
      nf.d3.vtX = vST.d3.vtX/ lengthTS;
      nf.d3.vtY = vST.d3.vtY/ lengthTS;
      nf.d3.vtZ = vST.d3.vtZ/ lengthTS;

      WLZ_VTX_3_SUB(vST.d3,vT.d3,vt.d3);
      printf("vt: %f %f %f\n",vt.d3.vtX,vt.d3.vtY, vt.d3.vtZ );
      printf("vT: %f %f %f\n",vT.d3.vtX,vT.d3.vtY, vT.d3.vtZ );
      lengthTS  =  WLZ_VTX_3_LENGTH( vST.d3);
      printf("Length: %f\n",lengthTS);
      nt.d3.vtX = vST.d3.vtX/ lengthTS;
      nt.d3.vtY = vST.d3.vtY/ lengthTS;
      nt.d3.vtZ = vST.d3.vtZ/ lengthTS;

/* 
  ---- get the three points in the master plane ( startJ plane ) ----

*/

/* allocate memory and give default values for viewer strcuture */
      wlzViewStr      = WlzMake3DViewStruct(WLZ_3D_VIEW_STRUCT, NULL);
      wlzViewStr1     = WlzMake3DViewStruct(WLZ_3D_VIEW_STRUCT, NULL);

/* set up */
   cycleI     = startJ;
   /* read Section viewer parameters */
   errNum = ReadBibFile(inFile, (char *) BibFilesNameList[cycleI],   wlzViewStr  );
   if(errNum != WLZ_ERR_NONE)
   {
         printf("Read or parse bib file err.\n");
         exit(1);
   
   }
   inFile = NULL;

   WlzInit3DViewStruct(wlzViewStr, WObjS);


/* -------- get the corresponding three directions in Main view space -------
    (It is also the stack up space 
    nsp = Tm ns, 
    nfp = Tm nf, 
    ntp = Tm nt;
  */
  errNum = Wlz3DSectionTransformVtxR(wlzViewStr, ns.d3, &nsp.d3 );
  if(errNum != WLZ_ERR_NONE)
   {
         printf("can not get the direction in stack up space for ns err.\n");
	 exit(1);
   }
  errNum = Wlz3DSectionTransformVtxR(wlzViewStr, nf.d3, &nfp.d3 );
  if(errNum != WLZ_ERR_NONE)
   {
         printf("can not get the direction in stack up space for nf err.\n");
	 exit(1);
   }
  errNum = Wlz3DSectionTransformVtxR(wlzViewStr, nt.d3, &ntp.d3 );
  if(errNum != WLZ_ERR_NONE)
   {
         printf("can not get the direction in stack up space for np err.\n");
	 exit(1);
   }
     

  /* --- get the main plane direction in OPT space --- */
  /* it can got by inverse transform from stack up viewer space to
     OPT space */
     /* in stack up space or master plane sapce */
      nz.d3.vtX = 0.0;
      nz.d3.vtY = 0.0;
      nz.d3.vtZ = 1.0;
  
  /*  nm = Tm^-1  nz  (inverse transform used here ) nm is in OPT space */
  errNum = Wlz3DSectionTransformInvVtxR(wlzViewStr, nz.d3, &nm.d3 );
  if(errNum != WLZ_ERR_NONE)
   {
         printf("can not get the main plane direction in OPT space err.\n");
         printf("Which means your three straight line has to be rechosen\n");
	 exit(1);
   }
   /* get the nt dot nm, etc */

  ntnm  =  WLZ_VTX_3_DOT(nt.d3, nm.d3);
  nfnm  =  WLZ_VTX_3_DOT(nf.d3, nm.d3);
  nsnm  =  WLZ_VTX_3_DOT(ns.d3, nm.d3);
  ntnm = nm.d3.vtX * nt.d3.vtX +  nm.d3.vtY * nt.d3.vtY + nm.d3.vtZ * nt.d3.vtZ;


  if(  ( ( ntnm == 0 )  || ( nfnm == 0 ) ) ||( nsnm == 0 ) )
    {
      printf("At least one of your three strait lines are parallel to the main plane err.\n");
      printf("Which means your three straight line has to be rechosen or chose another plane\n");
      printf("as main plane\n");
      exit(1);
    }




  /* get crossed point in this plane p_{i} then project to viewer space */
  errNum = WlzGetCorssPoint(vs,  ns,  &vsr,  wlzViewStr);
  if(errNum != WLZ_ERR_NONE)
    {
      printf("can not find crossed point err.\n");
      exit(1);
    }
  errNum = WlzGetCorssPoint(vt,  nt,  &vtr,  wlzViewStr);
  if(errNum != WLZ_ERR_NONE)
    {
      printf("can not find crossed point err.\n");
      exit(1);
    }

  errNum = WlzGetCorssPoint(vf,  nf,  &vfr,  wlzViewStr);
  if(errNum != WLZ_ERR_NONE)
  {
         printf("can not find crossed point err.\n");
         exit(1);
   
  }

  /* use this 3 point as refernce */
  /* --------Get Tie-points -------- */


   /* get the target points for this plane in stack up space */

   (vtxVec1    )->vtX = vsr.d3.vtX;
   (vtxVec1    )->vtY = vsr.d3.vtY;
   (vtxVec1 + 1)->vtX = vtr.d3.vtX;
   (vtxVec1 + 1)->vtY = vtr.d3.vtY;
   (vtxVec1 + 2)->vtX = vfr.d3.vtX;
   (vtxVec1 + 2)->vtY = vfr.d3.vtY;

  /* get the source point */
   /* get ( sx' sy' sz' )_i  */
   printf("%f  %f\n", sx, sy);
   vsp.d3.vtX = vsr.d3.vtX;
   vsp.d3.vtY = vsr.d3.vtY;
   vsp.d3.vtZ = vsr.d3.vtZ;

   /* get ( tx' ty' tz' )_i  */
   printf("%f  %f\n", tx, ty);
   vtp.d3.vtX = vtr.d3.vtX;
   vtp.d3.vtY = vtr.d3.vtY;
   vtp.d3.vtZ = vtr.d3.vtZ;

   /* get ( fx' fy' fz' )_i  */
   printf("%f  %f\n", fx, fy);
   vfp.d3.vtX =  vfr.d3.vtX;
   vfp.d3.vtY =  vfr.d3.vtY;
   vfp.d3.vtZ =  vfr.d3.vtZ;
 
   /* ------ output the affine transformed Wlz ------*/
   errNum =        outputTheWarpedWlz( vsp, 
                                       vtp,
				       vfp,
                                       vtxVec1,
                                       TwoDImageFilesNameList[cycleI],
				       warpedFilesNameList[cycleI]
				     );

   while(cycleI < numOfBibFiles - 1)
   {

      	cycleNext = cycleI + 1;
	
   	errNum = ReadBibFile(inFile, (char *) BibFilesNameList[cycleNext],   wlzViewStr1  );
   	WlzInit3DViewStruct(wlzViewStr1, WObjS);

  	/* ------ get Tie - points -------*/

 	/* get crossed point in this plane p_{i} then project to viewer space */
   	errNum = WlzGetCorssPoint(vs,  ns,  &vs1,  wlzViewStr1);
  	if(errNum != WLZ_ERR_NONE)
   	{
        	printf("can not find crossed point err.\n");
         	exit(1);
   
  	 }
  	errNum = WlzGetCorssPoint(vt,  nt,  &vt1,  wlzViewStr1);
  	if(errNum != WLZ_ERR_NONE)
   	{
        	printf("can not find crossed point err.\n");
         	exit(1);
   
   	}

  	errNum = WlzGetCorssPoint(vf,  nf,  &vf1,  wlzViewStr1);
  	if(errNum != WLZ_ERR_NONE)
   	{
        	printf("can not find crossed point err.\n");
         	exit(1);
   
   	}


  	/*  get the source points */
   	/* get ( sx' sy' sz' )_i  */
   	/* printf("%f  %f\n", sx, sy); */
   	vsp.d3.vtX = vs1.d3.vtX;
   	vsp.d3.vtY = vs1.d3.vtY;
   	vsp.d3.vtZ = vs1.d3.vtZ;

   	/* get ( tx' ty' tz' )_i  */
   	/* printf("%f  %f\n", tx, ty); */
   	vtp.d3.vtX = vt1.d3.vtX;
   	vtp.d3.vtY = vt1.d3.vtY;
   	vtp.d3.vtZ = vt1.d3.vtZ;

   	/* get ( fx' fy' fz' )_i  */
   	/* printf("%f  %f\n", fx, fy); */
   	vfp.d3.vtX =  vf1.d3.vtX;
   	vfp.d3.vtY =  vf1.d3.vtY;
   	vfp.d3.vtZ =  vf1.d3.vtZ;

  	/*  get the target points */

   	/* find the target points by keep the same direction in
	   stack up space and the OPT space.The following are in stack up space */
        deltaZ = (double) ( cycleNext - startJ );


  	errNum = WlzGetDxDy( nsp,  deltaZ,  &vs1);
  	if(errNum != WLZ_ERR_NONE)
   	{
        	printf("can not get Dx Dy err.\n");
         	exit(1);
   
   	}
  	errNum = WlzGetDxDy( nfp,  deltaZ,  &vf1);
  	if(errNum != WLZ_ERR_NONE)
   	{
        	printf("can not get Dx Dy err.\n");
         	exit(1);
   
   	}
  	errNum = WlzGetDxDy( ntp,  deltaZ,  &vt1);
  	if(errNum != WLZ_ERR_NONE)
   	{
        	printf("can not get Dx Dy err.\n");
         	exit(1);
   
   	}

   	(vtxVec1    )->vtX = vsr.d3.vtX + vs1.d3.vtX;
   	(vtxVec1    )->vtY = vsr.d3.vtY + vs1.d3.vtY;
   	(vtxVec1 + 1)->vtX = vtr.d3.vtX + vt1.d3.vtX;
   	(vtxVec1 + 1)->vtY = vtr.d3.vtY + vt1.d3.vtY;
   	(vtxVec1 + 2)->vtX = vfr.d3.vtX + vf1.d3.vtX;
   	(vtxVec1 + 2)->vtY = vfr.d3.vtY + vf1.d3.vtY;
 
   	/* ------ output the affine transformed Wlz ------*/
	printf("----------- %d\n",cycleI);
	/* out put the source and target for checking */
   	errNum =        outputTheWarpedWlz( vsp, 
                                       vtp,
				       vfp,
                                       vtxVec1,
                                       TwoDImageFilesNameList[cycleNext],
				       warpedFilesNameList[cycleNext]
				     );

   	/* track from s_i' to  s_{i+1}' */
   	/*  scale = |T - S |/|t - s|      */
        
        cycleI++;

   }


   cycleI = startJ;
   while(  cycleI > 0  )
   {
      	cycleNext = cycleI - 1;
	
   	errNum = ReadBibFile(inFile, (char *) BibFilesNameList[cycleNext],   wlzViewStr1  );
   	WlzInit3DViewStruct(wlzViewStr1, WObjS);

  	/* ------ get Tie - points -------*/

 	/* get crossed point in this plane p_{i} then project to viewer space */
   	errNum = WlzGetCorssPoint(vs,  ns,  &vs1,  wlzViewStr1);
  	if(errNum != WLZ_ERR_NONE)
   	{
        	printf("can not find crossed point err.\n");
         	exit(1);
   
  	 }
  	errNum = WlzGetCorssPoint(vt,  nt,  &vt1,  wlzViewStr1);
  	if(errNum != WLZ_ERR_NONE)
   	{
        	printf("can not find crossed point err.\n");
         	exit(1);
   
   	}

  	errNum = WlzGetCorssPoint(vf,  nf,  &vf1,  wlzViewStr1);
  	if(errNum != WLZ_ERR_NONE)
   	{
        	printf("can not find crossed point err.\n");
         	exit(1);
   
   	}


  	/*  get the source points */
   	/* get ( sx' sy' sz' )_i  */
   	printf("%f  %f\n", sx, sy);
   	vsp.d3.vtX = vs1.d3.vtX;
   	vsp.d3.vtY = vs1.d3.vtY;
   	vsp.d3.vtZ = vs1.d3.vtZ;

   	/* get ( tx' ty' tz' )_i  */
   	printf("%f  %f\n", tx, ty);
   	vtp.d3.vtX = vt1.d3.vtX;
   	vtp.d3.vtY = vt1.d3.vtY;
   	vtp.d3.vtZ = vt1.d3.vtZ;

   	/* get ( fx' fy' fz' )_i  */
   	printf("%f  %f\n", fx, fy);
   	vfp.d3.vtX =  vf1.d3.vtX;
   	vfp.d3.vtY =  vf1.d3.vtY;
   	vfp.d3.vtZ =  vf1.d3.vtZ;

  	/*  get the target points */

   	/* find the target points by keep the same direction in
	   stack up space and the OPT space.The following are in stack up space */
        deltaZ = (double) ( cycleNext - startJ );


  	errNum = WlzGetDxDy( nsp,  deltaZ,  &vs1);
  	if(errNum != WLZ_ERR_NONE)
   	{
        	printf("can not get Dx Dy err.\n");
         	exit(1);
   
   	}
  	errNum = WlzGetDxDy( nfp,  deltaZ,  &vf1);
  	if(errNum != WLZ_ERR_NONE)
   	{
        	printf("can not get Dx Dy err.\n");
         	exit(1);
   
   	}
  	errNum = WlzGetDxDy( ntp,  deltaZ,  &vt1);
  	if(errNum != WLZ_ERR_NONE)
   	{
        	printf("can not get Dx Dy err.\n");
         	exit(1);
   
   	}


       /* target points */
   	(vtxVec1    )->vtX = vsr.d3.vtX + vs1.d3.vtX;
   	(vtxVec1    )->vtY = vsr.d3.vtY + vs1.d3.vtY;
   	(vtxVec1 + 1)->vtX = vtr.d3.vtX + vt1.d3.vtX;
   	(vtxVec1 + 1)->vtY = vtr.d3.vtY + vt1.d3.vtY;
   	(vtxVec1 + 2)->vtX = vfr.d3.vtX + vf1.d3.vtX;
   	(vtxVec1 + 2)->vtY = vfr.d3.vtY + vf1.d3.vtY;
 
   	/* ------ output the affine transformed Wlz ------*/
   	errNum =   outputTheWarpedWlz( vsp, 
                                       vtp,
				       vfp,
                                       vtxVec1,
                                       TwoDImageFilesNameList[cycleNext],
				       warpedFilesNameList[cycleNext]
				     );

   	/* track from s_i' to  s_{i+1}' */
   	/*  scale = |T - S |/|t - s|      */
        
        cycleI--;

	}



     AlcFree(vtxVec1 );

   /* */
       WlzFree3DViewStruct(wlzViewStr);
       WlzFree3DViewStruct(wlzViewStr1);

  return ( 0 );
}
Beispiel #6
0
int             main(int argc, char **argv)
{
  int		tI,
		errIdx,
  		option,
		keep2D = 0,
		ok = 1,
		usage = 0;
  WlzDDOVxSzSrc voxSzSrc = WLZDDO_VSS_UNIT;
  WlzDVertex2	org;
  WlzThreeDViewStruct *view = NULL;
  WlzErrorNum	errNum = WLZ_ERR_NONE;
  WlzObject	*dwnObj = NULL,
  		*refObj = NULL;
  FILE		*fP = NULL;
  char 		*errMsg0,
  		*cmdStr = NULL,
		*refFileStr = NULL,
  		*outFileStr,
        	*inFileStr;
  double	voxSz[3];
  const char	*errMsg;
  static char	optList[] = "a:b:d:E:f:g:m:o:r:s:u:2eh",
		outFileStrDef[] = "-",
  		inFileStrDef[] = "-";

  opterr = 0;
  errMsg = errMsg0 = "";
  org.vtX = org.vtY = 0.0;
  inFileStr = inFileStrDef;
  outFileStr = outFileStrDef;
  voxSz[0] = voxSz[1] = voxSz[2] = 1.0;
  if((view = WlzMake3DViewStruct(WLZ_3D_VIEW_STRUCT, &errNum)) == NULL)
  {
    ok = 0;
    (void )WlzStringFromErrorNum(errNum, &errMsg);
    (void )fprintf(stderr,
		   "%s: failed to create view structure (%s)\n",
		   *argv, errMsg);
  }
  if(ok)
  {
    view->dist = 0.0;
    view->scale = 1.0;
    view->ref_obj = NULL;
    view->view_mode = WLZ_UP_IS_UP_MODE;
    view->phi = view->theta = view->zeta = 0.0;
    view->up.vtX = view->up.vtY = 0.0; view->up.vtZ = 1.0;
    view->fixed.vtX = view->fixed.vtY = view->fixed.vtZ = 0.0;
    while((usage == 0) && ((option = getopt(argc, argv, optList)) != -1))
    {
      switch(option)
      {
	case '2':
	  keep2D = 1;
	  break;
	case 'a':
	  usage = WlzDrawDomObjScanTriple(optarg,
	                                  &(view->phi),
					  &(view->theta),
					  &(view->zeta)) < 1;
	  break;
	case 'e':
	  voxSzSrc = WLZDDO_VSS_OBJ;
	  break;
	case 'E':
	  voxSzSrc = WLZDDO_VSS_GVN;
	  usage = WlzDrawDomObjScanTriple(optarg,
	                                  &(voxSz[0]),
					  &(voxSz[1]),
					  &(voxSz[2])) < 1;
	  break;
	case 'f':
	  usage = WlzDrawDomObjScanTriple(optarg,
	                                  &(view->fixed.vtX),
					  &(view->fixed.vtY),
					  &(view->fixed.vtZ)) < 1;
	  break;
	case 'd':
	  usage = sscanf(optarg, "%lg", &(view->dist)) != 1;
	  break;
	case 'b':
	  usage = WlzDrawDomObjReadView(optarg, view,
					&errMsg0) != WLZ_ERR_NONE;
	  if(usage)
	  {
	    (void )fprintf(stderr,
			   "%s: failed to read view parameters from file "
			   "%s (%s)\n",
			   *argv, optarg, errMsg0);
	  }
	  break;
	case 'm':
	  if(WlzStringMatchValue(&tI, optarg,
				 "up-is-up", WLZ_UP_IS_UP_MODE,
				 "statue", WLZ_STATUE_MODE,
				 "absolute", WLZ_ZETA_MODE,
				 NULL))
	  {
	    view->view_mode = (WlzThreeDViewMode )tI;
	  }
	  else
	  {
	    usage = 1;
	  }
	  break;
	case 'u':
	  usage = WlzDrawDomObjScanTriple(optarg,
					  &(view->up.vtX),
					  &(view->up.vtY),
					  &(view->up.vtZ)) < 1;
	  break;
	case 'g':
	  usage = WlzDrawDomObjScanPair(optarg, &(org.vtX), &(org.vtY)) < 1;
	  break;
	case 'o':
	  outFileStr = optarg;
	  break;
	case 'r':
	  refFileStr = optarg;
          errNum = WLZ_ERR_READ_EOF;
	  if((refFileStr == NULL) ||
             (*refFileStr == '\0') ||
	     ((fP = (strcmp(refFileStr, "-")?
		     fopen(refFileStr, "r"): stdin)) == NULL) ||
	     ((refObj = WlzAssignObject(
			WlzReadObj(fP, &errNum), NULL)) == NULL) ||
	     (errNum != WLZ_ERR_NONE))
	  {
	    usage = 1;
            (void )WlzStringFromErrorNum(errNum, &errMsg);
	    (void )fprintf(stderr,
		   "%s: failed to read 3D reference object from %s (%s)\n",
		   *argv, refFileStr, errMsg);
	  }
	  if(fP)
	  {
	    if(strcmp(refFileStr, "-"))
	    {
	      (void )fclose(fP);
	    }
	    fP = NULL;
	  }
	  break;
	case 's':
	  if((cmdStr = AlcStrDup(optarg)) == NULL)
	  {
	    usage = 1;
	    errNum = WLZ_ERR_MEM_ALLOC;
	  }
	  break;
	case 'h':
	default:
	  usage = 1;
	  ok = 0;
	  break;
      }
    }
    if((usage == 0) && (cmdStr == NULL))
    {
      if((optind == argc))
      {
	inFileStr = inFileStrDef;
      }
      else if(optind + 1 == argc )
      {
	inFileStr = *(argv + optind);
      }
      else
      {
	usage = 1;
      }
      if(usage == 0)
      {
	cmdStr = WlzDrawDomObjReadStr(inFileStr, &errNum);
      }
    }
    ok = usage == 0;
  }
  if(ok)
  {
    switch(voxSzSrc)
    {
      case WLZDDO_VSS_UNIT:
	view->voxelRescaleFlg = 0;
	view->voxelSize[0] = 1.0f;
	view->voxelSize[1] = 1.0f;
	view->voxelSize[2] = 1.0f;
	break;
       case WLZDDO_VSS_GVN:
	view->voxelRescaleFlg = 1;
	 view->voxelSize[0] = (float )WLZ_CLAMP(voxSz[0], FLT_MIN, FLT_MAX);
	 view->voxelSize[1] = (float )WLZ_CLAMP(voxSz[1], FLT_MIN, FLT_MAX);
	 view->voxelSize[2] = (float )WLZ_CLAMP(voxSz[2], FLT_MIN, FLT_MAX);
	 break;
      case WLZDDO_VSS_OBJ:
	/* Handled below. */
        break;
    }
  }
  if(ok && refObj)
  {
    WlzObject	*sObj = NULL;
    WlzThreeDViewStruct *v = NULL;

    v = WlzMake3DViewStruct(WLZ_3D_VIEW_STRUCT, &errNum);
    if(errNum == WLZ_ERR_NONE)
    {
      v->type = view->type;
      v->fixed = view->fixed;
      v->theta = view->theta;
      v->phi = view->phi;
      v->zeta = view->zeta;
      v->dist = view->dist;
      v->scale = view->scale;
      if(voxSzSrc == WLZDDO_VSS_OBJ)
      {
	view->voxelRescaleFlg = 1;
	if((refObj->type == WLZ_3D_DOMAINOBJ) &&
	   (refObj->domain.core != NULL) &&
	   (refObj->domain.core->type == WLZ_PLANEDOMAIN_DOMAIN))
	{
	  view->voxelSize[0] = refObj->domain.p->voxel_size[0];
	  view->voxelSize[1] = refObj->domain.p->voxel_size[1];
	  view->voxelSize[2] = refObj->domain.p->voxel_size[2];
	}
      }
      v->voxelRescaleFlg = view->voxelRescaleFlg;
      v->voxelSize[0] = view->voxelSize[0];
      v->voxelSize[1] = view->voxelSize[1];
      v->voxelSize[2] = view->voxelSize[2];
      v->interp = view->interp;
      v->view_mode = view->view_mode;
      v->up = view->up;
      v->fixed_2 = view->fixed_2;
      v->fixed_line_angle = view->fixed_line_angle;
      errNum = WlzInit3DViewStruct(v, refObj);
    }
    if(errNum == WLZ_ERR_NONE)
    {
      sObj = WlzGetSectionFromObject(refObj, v, WLZ_INTERPOLATION_NEAREST,
                                     &errNum);
    }
    if(errNum == WLZ_ERR_NONE)
    {
      if((sObj->type != WLZ_2D_DOMAINOBJ) || (sObj->domain.core == NULL))
      {
        errNum = WLZ_ERR_DOMAIN_DATA;
      }
      else
      {
        org.vtX += sObj->domain.i->kol1;
        org.vtY += sObj->domain.i->line1;
      }
    }
    (void )WlzFree3DViewStruct(v);
    (void )WlzFreeObj(sObj); 
    if(errNum != WLZ_ERR_NONE)
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
                     "%s: failed find offset from reference object (%s).\n",
		     *argv, errMsg);
    }
  }
  if(ok)
  {
    dwnObj = WlzDrawDomainObj(org, view, keep2D, cmdStr, &errIdx, &errNum);
    if(errNum != WLZ_ERR_NONE)
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
                     "%s: failed to draw object in command prior to string\n"
		     "position %d (%s)\n",
		     *argv, errIdx, errMsg);
    }
  }
  if(ok)
  {
    errNum = WLZ_ERR_WRITE_EOF;
    if((fP = (strcmp(outFileStr, "-")? fopen(outFileStr, "w"):
	      			       stdout)) == NULL)
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
		     "%s: failed to open output file (%s).\n",
		     *argv, errMsg);
    }
    else
    {
      if((errNum = WlzWriteObj(fP, dwnObj)) != WLZ_ERR_NONE)
      {
        ok = 0;
	(void )WlzStringFromErrorNum(errNum, &errMsg);
	(void )fprintf(stderr,
	               "%s: Failed to write output object (%s).\n",
		       argv[0], errMsg);
      }
    }
    if(fP && strcmp(outFileStr, "-"))
    {
      fclose(fP);
    }
  }
  AlcFree(cmdStr);
  (void )WlzFreeObj(refObj);
  (void )WlzFree3DViewStruct(view);
  (void )WlzFreeObj(dwnObj);
  if(usage)
  {
    (void )fprintf(stderr,
    "Usage: %s%s%s%sExample: %s%s",
    *argv,
    " [-2] [-a<pitch,yaw,roll>]\n"
    "                 [-f <fx,fy,fz>]\n"
    "                 [-d <dist> [-b <view bib file>]\n"
    "                 [-m <mode>] [-u<ux,uy,uz>]\n"
    "                 [-e] [-E<vx,vy,vz>]\n"
    "                 [-g <ox,oy,oz>] [-h] [-o<output>]\n"
    "                 [-r <ref object>]\n"
    "                 [-s <cmd str>] [<cmd str file>>]\n"
    "Version: ",
    WlzVersion(),
    "\n"
    "Options:\n"
    "  -2  Ignore the view struct and keep as a 2D object.\n"
    "  -a  Viewing angles: pitch (phi), yaw (theta) and roll (zeta),\n"
    "      default 0.0,0.0,0.0.\n"
    "  -f  Fixed point position, default 0.0,0.0,0.0.\n"
    "  -d  Distance parameter, default 0.0.\n"
    "  -b  Bib file with view parameters, e.g. saved from MAPaint.\n"
    "  -m  Viewing mode, one of: up-is-up, statue or absolute, default\n"
    "      is up-is-up.\n"
    "  -u  Up vector, default 0.0,0.0,1.0.\n"
    "  -e  Use object voxel size, default is voxel size 1.0,1.0,1.0.\n"
    "  -E  Use supplied voxel size rather than the object voxel size,\n"
    "      default 1.0,1.0,1.0.\n"
    "  -g  Origin of the drawing with respect to the 2D Woolz object\n"
    "      cut using the view transform, default 0.0,0.0.\n"
    "  -r  Reference object. If given this is must be a 3D spatial domain\n"
    "      object. The object is used to determine an additional offset\n"
    "      for the origin of the 2D plane with respect to the section in 3D\n"
    "      (i.e. it is added to any offset given using the -g option).\n"
    "  -s  Drawing command string.\n"
    "  -h  Help, prints this usage message.\n"
    "  -o  Output file name.\n"
    "Reads drawing commands from either a string given on the command line,\n"
    "a file given on the command line or the standard input (in this order\n"
    "of precidence). The drawing commands are used to create a drawn\n"
    "section which is placed into 3D using the view transform.\n"
    "\n"
    "The command string must have the following syntax:\n"
    "  <command string> = <init command>[<command>]+<end command>\n"
    "  <init command> = <ident>:<version>;\n"
    "  <end command> = END:;\n"
    "  <ident> = WLZ_DRAW_DOMAIN\n"
    "  <version> = 1\n"
    "  <command> = <command name>:[<parameter>[,<parameter>]*];\n"
    "  <command name> = PEN | LINE | CIRCLE\n"
    "In addition to the init and end commands, the following\n"
    "drawing commands are recognised:\n"
    "  CIRCLE:<action>:<radius>,<x>,<y>;\n"
    "  LINE:<action>:<width>,<x>,<y>,<x>,<y>;\n"
    "  PEN:<action>,<width>,<x>,<y>[,<x>,<y>]*;\n"
    "Where:\n"
    " <action> = DRAW | ERASE\n"
    "The circle command draws or erases a filled circle which is specified\n"
    "by it's radius and centre parameters.\n"
    "The line command draws a rectangle using the given width and end\n"
    "coordinates of the mid-line.\n"
    "The pen command draws a polyline which is composed of a series of\n"
    "rectangular segments, with each segment ending in a semi-circular cap.\n"
    "The parameters of the pen command are the width and line segment end\n"
    "point coordinates.\n"
    "All widths, radii and coordinates may be in any floating point format\n"
    "recognised by scanf(3).\n"
    "Other commands may be present provided they have the same syntax\n"
    "described above, but they will be ignored.\n"
    "All white space characters are ignored.\n",
    *argv,
    " -o out.wlz -s 'WLZ_DRAW_DOMAIN:1; CIRCLE:DRAW,100,200,300; END:;'\n"
    "This creates a 3D domain object with a single plane at z = 0\n"
    "which has a domain that is  a single circle (radius = 100,\n"
    "centre = 200,300).\n");
  }
  return(!ok);
}
Beispiel #7
0
int main(int	argc,
	 char	**argv)
{

  WlzObject	*obj = NULL, *nobj = NULL, *subDomain = NULL;
  FILE		*inFP = NULL, *outFP = NULL, *trFP = NULL, *bibFP = NULL;
  char		*outFile = NULL, *trFile = NULL, *bibFile = NULL;
  char 		optList[] = "ACLNTa:b:d:f:m:o:r:s:t:u:R:h";
  int		option;
  int		i,
  		j,
		iVal,
		timer = 0,
		voxRescale = 0,
  		allFlg = 0;
  double	dist=0.0, pitch=0.0, yaw=0.0, roll=0.0;
  double	scale=1.0;
  WlzDVertex3	fixed={0.0,0.0,0.0};
  WlzDVertex3	up={0.0,0.0,-1.0};
  WlzThreeDViewStruct	*viewStr=NULL;
  WlzThreeDViewMode mode=WLZ_UP_IS_UP_MODE;
  WlzInterpolationType interp = WLZ_INTERPOLATION_NEAREST;
  WlzErrorNum	errNum=WLZ_ERR_NONE;
  BibFileRecord	*bibfileRecord;
  BibFileError	bibFileErr;
  struct timeval times[3];
  char		*errMsg;
    
  /* additional defaults */
  outFile = "-";
  bibFile = NULL;
  trFile = NULL;
  subDomain = NULL;

  /* read the argument list and check for an input file */
  opterr = 0;
  while( (option = getopt(argc, argv, optList)) != EOF ){
    switch( option ){

    case 'A':
      allFlg = 1;
      break;

    case 'C':
      interp = WLZ_INTERPOLATION_CLASSIFY_1;
      break;

    case 'L':
      interp = WLZ_INTERPOLATION_LINEAR;
      break;

    case 'N':
      interp = WLZ_INTERPOLATION_NEAREST;
      break;

    case 'a':
      switch( sscanf(optarg, "%lg,%lg,%lg", &pitch, &yaw, &roll) ){
      default:
	usage(argv[0]);
	return 1;
      case 2:
	break;
      case 3:
	mode = WLZ_ZETA_MODE;
	break;
      }
      break;

    case 'b':
      bibFile = optarg;
      break;

    case 'd':
      if( sscanf(optarg, "%lg", &dist) < 1 ){
	usage(argv[0]);
	return 1;
      }
      break;

    case 'f':
      if( sscanf(optarg, "%lg,%lg,%lg", &(fixed.vtX), &(fixed.vtY),
		 &(fixed.vtZ)) < 3 ){
	usage(argv[0]);
	return 1;
      }
      break;

    case 'm':
      if( sscanf(optarg, "%d", &iVal) < 1 ){
	usage(argv[0]);
	return 1;
      }
      else if( mode != WLZ_ZETA_MODE ){
	switch( iVal ){
	default:
	  usage(argv[0]);
	  return 1;
	case 0:
	  mode = WLZ_UP_IS_UP_MODE;
	  break;
	case 1:
	  mode = WLZ_STATUE_MODE;
	  break;
	case 2:
	  mode = WLZ_ZETA_MODE;
	  break;
	}
      }
      break;

    case 'o':
      outFile = optarg;
      break;

    case 'r':
      if( sscanf(optarg, "%d", &voxRescale) < 1 ){
	usage(argv[0]);
	return 1;
      }
      break;

    case 's':
      if( sscanf(optarg, "%lg", &scale) < 1 ){
	usage(argv[0]);
	return 1;
      }
      break;

    case 'u':
      if( sscanf(optarg, "%lg,%lg,%lg", &(up.vtX), &(up.vtY),
		 &(up.vtZ)) < 3 ){
	usage(argv[0]);
	return 1;
      }
      break;

    case 'R':
      if((inFP = fopen(optarg, "rb"))){
	if((subDomain = WlzReadObj(inFP, &errNum)) == NULL){
	  fprintf(stderr, "%s: can't read sub-domain object %s\n", argv[0], optarg);
	  usage(argv[0]);
	  return 1;
	}
	fclose(inFP);
      }
      else {
	fprintf(stderr, "%s: can't open file %s\n", argv[0], optarg);
	usage(argv[0]);
	return 1;
      }
      break;

    case 'T':
      timer = 1;
      break;
    case 't':
      trFile = optarg;
      break;
    case 'h':
    default:
      usage(argv[0]);
      return 0;

    }
  }

  /* check input file/stream */
  inFP = stdin;
  if( optind < argc ){
    if( (inFP = fopen(*(argv+optind), "rb")) == NULL ){
      fprintf(stderr, "%s: can't open file %s\n", argv[0], *(argv+optind));
      usage(argv[0]);
      return 1;
    }
  }

  /* check output file/stream */
  if( allFlg ){
    if(strcmp(outFile, "-"))
    {
      /* strip any file extension */
      for(i=0, j=strlen(outFile); i < strlen(outFile); i++){
	if( outFile[i] == '.' ){
	  j = i;
	}
      }
      outFile[j] = '\0';
  }
    else {
      outFile = "plane";
    }
  }
  else {
    if(strcmp(outFile, "-"))
    {
      if((outFP = fopen(outFile, "wb")) == NULL)
      {
	errNum = WLZ_ERR_WRITE_EOF;
      }
    }
    else
    {
      outFP = stdout;
    }
  }

  /* create view structure */
  if((viewStr = WlzMake3DViewStruct(WLZ_3D_VIEW_STRUCT, &errNum)) != NULL){
    viewStr->theta = yaw * WLZ_M_PI / 180.0;
    viewStr->phi = pitch * WLZ_M_PI / 180.0;
    viewStr->zeta = roll * WLZ_M_PI / 180.0;
    viewStr->dist = dist;
    viewStr->fixed = fixed;
    viewStr->up = up;
    viewStr->view_mode = mode;
    viewStr->scale = scale;
    viewStr->voxelRescaleFlg = voxRescale;
  }

  if((errNum == WLZ_ERR_NONE) && (bibFile != NULL) && (trFile != NULL)) {
    fprintf(stderr, "%s: both bibfile and transform file specified.\n",
            argv[0]);
  }

  /* check bibfile - select first section parameters in the file */
  if((errNum == WLZ_ERR_NONE) && (bibFile != NULL)){
    if((bibFP = fopen(bibFile, "r")) != NULL){
      bibFileErr = BibFileRecordRead(&bibfileRecord, &errMsg, bibFP);
      while((bibFileErr == BIBFILE_ER_NONE) &&
	    (strncmp(bibfileRecord->name, "Wlz3DSectionViewParams", 22))){
	BibFileRecordFree(&bibfileRecord);
	bibFileErr = BibFileRecordRead(&bibfileRecord, &errMsg, bibFP);
      }
      fclose( bibFP );
      if( bibFileErr != BIBFILE_ER_NONE ){
	fprintf(stderr, "%s: error reading bibfile: %s\n", argv[0], errMsg);
	AlcFree((void *) errMsg);
	return 1;
      }
      WlzEffBibParse3DSectionViewParamsRecord(bibfileRecord, viewStr);
      BibFileRecordFree(&bibfileRecord);
    }
    else {
      fprintf(stderr, "%s: can't open parameter bibfile %s\n", argv[0],
	      bibFile);
      return 1;
    }
  }
  
  if((errNum == WLZ_ERR_NONE) && (trFile != NULL)){
    if((trFP = fopen(trFile, "r")) != NULL){
      WlzObject *trObj = NULL;

      if((trObj = WlzReadObj(trFP, &errNum)) != NULL) {
        if(trObj->type != WLZ_3D_VIEW_STRUCT) {
	  errNum = WLZ_ERR_OBJECT_TYPE;
	}
	else if (trObj->domain.core == NULL) {
	  errNum = WLZ_ERR_DOMAIN_NULL;
	}
	else {
	  WlzThreeDViewStruct *fViewStr;

	  fViewStr = trObj->domain.vs3d;
	  viewStr->theta = fViewStr->theta;
	  viewStr->phi = fViewStr->phi;
	  viewStr->zeta = fViewStr->zeta;
	  viewStr->dist = fViewStr->dist;
	  viewStr->fixed = fViewStr->fixed;
	  viewStr->up = fViewStr->up;
	  viewStr->view_mode = fViewStr->view_mode;
	  viewStr->scale = fViewStr->scale;
	  viewStr->voxelRescaleFlg = fViewStr->voxelRescaleFlg;
	}
	(void )WlzFreeObj(trObj);
      }
    }
    if(errNum != WLZ_ERR_NONE) {
      fprintf(stderr,
              "%s: error reading section view transform from %s.\n",
              argv[0], trFile);
      return 1;
    }
  }

  /* read objects and section if possible */
  while((errNum == WLZ_ERR_NONE) &&
        ((obj = WlzReadObj(inFP, &errNum)) != NULL))
  {
    obj = WlzAssignObject(obj, &errNum);
    switch( obj->type )
    {
      case WLZ_CONTOUR:
      case WLZ_3D_DOMAINOBJ:
	if(voxRescale && obj->domain.core)
	{
	  viewStr->voxelSize[0] = obj->domain.p->voxel_size[0];
	  viewStr->voxelSize[1] = obj->domain.p->voxel_size[1];
	  viewStr->voxelSize[2] = obj->domain.p->voxel_size[2];
	}
	WlzInit3DViewStruct(viewStr, obj);
	if(timer)
	{
	  gettimeofday(times + 0, NULL);
	}
	if( allFlg ){
	  /* loop through all possible planes */
	  for(i=WLZ_NINT(viewStr->minvals.vtZ), j=0;
	      i <= WLZ_NINT(viewStr->maxvals.vtZ); i++, j++){
	    viewStr->dist = i;
	    WlzInit3DViewStruct(viewStr, obj);
	    nobj = WlzGetSubSectionFromObject(obj, subDomain, viewStr, interp,
					      NULL, &errNum);
	    if( nobj != NULL){
	      char	fileBuf[256];
	      sprintf(fileBuf, "%s%06d.wlz", outFile, j);
	      if((outFP = fopen(fileBuf, "w")) != NULL){
		 WlzWriteObj(outFP, nobj);
		 fclose(outFP);
	      }
	    }
	    else {
	      return errNum;
	    }
	    WlzFreeObj(nobj);
	  }
	}
	else {
	  nobj = WlzGetSubSectionFromObject(obj, subDomain, viewStr, interp,
					    NULL, &errNum);
	  if( nobj != NULL){
	    WlzWriteObj(outFP, nobj);
	  }
	  else {
	    return errNum;
	  }
	  WlzFreeObj(nobj);
	}
	if(timer)
	{
	  gettimeofday(times + 1, NULL);
	  ALC_TIMERSUB(times + 1, times + 0, times + 2);
	  (void )fprintf(stderr,
	                 "%s: Elapsed time = %g\n",
			 *argv,
			 times[2].tv_sec + (0.000001 * times[2].tv_usec));
	}
	break;

      default:
	WlzWriteObj(outFP, obj);
	break;
    }

    WlzFreeObj(obj);
  }
  if(errNum == WLZ_ERR_READ_EOF)
  {
    errNum = WLZ_ERR_NONE;
  }

  if( viewStr ){
    WlzFree3DViewStruct(viewStr);
  }
  if( subDomain ){
    WlzFreeObj(subDomain);
  }

  return errNum;
}
Beispiel #8
0
int init_view_struct(
  ThreeDViewStruct	*view_struct)
{
  XWindowAttributes	win_att;
  Display		*dpy = XtDisplay(view_struct->canvas);
  Window		win = XtWindow(view_struct->canvas);
  unsigned int		widthp, heightp;
  Dimension		win_width, win_height;
  WlzThreeDViewStruct	*wlzViewStr = view_struct->wlzViewStr;
  float			minz, maxz, z;
  Widget		widget;
  WlzErrorNum		errNum=WLZ_ERR_NONE;

  if( XGetWindowAttributes(dpy, win, &win_att) == 0 )
    return( 1 );

  /* initialise the 3D view structure */
  errNum = WlzInit3DViewStruct(wlzViewStr, globals.obj);
  if( errNum != WLZ_ERR_NONE ){
    MAPaintReportWlzError(globals.topl, "init_view_struct", errNum);
    return 1;
  }

  /* set the limits set the slider values here */
  minz = wlzViewStr->minvals.vtZ;
  maxz = wlzViewStr->maxvals.vtZ;
  if( wlzViewStr->dist < wlzViewStr->minvals.vtZ )
    wlzViewStr->dist = wlzViewStr->minvals.vtZ;
  if( wlzViewStr->dist > wlzViewStr->maxvals.vtZ )
    wlzViewStr->dist = wlzViewStr->maxvals.vtZ;
  z = wlzViewStr->dist;

  HGU_XmSetSliderRange( view_struct->slider, minz, maxz );
  HGU_XmSetSliderValue( view_struct->slider, z );

  /* set the zeta slider */
  if((widget = XtNameToWidget(view_struct->dialog, "*.zeta_slider"))){
    HGU_XmSetSliderValue(widget,
			 view_struct->wlzViewStr->zeta * 180.0 / WLZ_M_PI);
  }

  /* set up the ximage - note the internal ximage is 8 bit but we must honour 
     the bitmap-pad for the display */
  widthp  = wlzViewStr->maxvals.vtX - wlzViewStr->minvals.vtX + 1;
  heightp = wlzViewStr->maxvals.vtY - wlzViewStr->minvals.vtY + 1;
  view_struct->ximage = XCreateImage(dpy, win_att.visual, 8,
				     ZPixmap, 0, NULL, widthp,
				     heightp, BitmapPad(dpy), 0);
  if(view_struct->ximage == NULL) {
    MAPaintReportWlzError(globals.topl, "init_Inview_struct",
    			  WLZ_ERR_PARAM_DATA);
    return 1;
  }
  /* resize the canvas */
  win_width = widthp * wlzViewStr->scale;
  win_height = heightp * wlzViewStr->scale;
  XtVaSetValues(view_struct->canvas,
		XmNwidth, win_width,
		XmNheight, win_height,
		NULL);

  view_struct->display_list = 0;
  return( 0 );
}
Beispiel #9
0
int reset_view_struct(
  ThreeDViewStruct	*view_struct)
{
  unsigned int	widthp, heightp;
  Dimension		win_width, win_height;
  WlzThreeDViewStruct	*wlzViewStr = view_struct->wlzViewStr;
  float		minz, maxz, z;
  WlzErrorNum		errNum=WLZ_ERR_NONE;

  /* initialise the 3D view structure */
  errNum = WlzInit3DViewStruct(wlzViewStr, globals.obj);
  if( errNum != WLZ_ERR_NONE ){
    MAPaintReportWlzError(globals.topl, "reset_view_struct", errNum);
    return 1;
  }

  /* set the limits set the slider values here -
     may need to increment distance */
  minz = wlzViewStr->minvals.vtZ;
  maxz = wlzViewStr->maxvals.vtZ;
  z = wlzViewStr->dist;
  if( wlzViewStr->dist < wlzViewStr->minvals.vtZ ){
    z = wlzViewStr->minvals.vtZ;
  }
  if( wlzViewStr->dist > wlzViewStr->maxvals.vtZ ){
    z = wlzViewStr->maxvals.vtZ;
  }
  if( z != wlzViewStr->dist ){
    Wlz3DSectionIncrementDistance(wlzViewStr, z - wlzViewStr->dist);
    z = wlzViewStr->dist;
  }

  HGU_XmSetSliderRange( view_struct->slider, minz, maxz );
  HGU_XmSetSliderValue( view_struct->slider, z );

  /* resize the canvas */
  widthp  = wlzViewStr->maxvals.vtX - wlzViewStr->minvals.vtX + 1;
  heightp = wlzViewStr->maxvals.vtY - wlzViewStr->minvals.vtY + 1;
  win_width = widthp * wlzViewStr->scale;
  win_height = heightp * wlzViewStr->scale;
  XtVaSetValues(view_struct->canvas,
		XmNwidth, win_width,
		XmNheight, win_height,
		NULL);

  /* reset the dialog title */
  set_view_dialog_title(view_struct->dialog, wlzViewStr->theta,
			wlzViewStr->phi);

  /* reset the ximage */
  view_struct->ximage->width = widthp;
  view_struct->ximage->height = heightp;
  view_struct->ximage->bytes_per_line = widthp;

  /* tablet needs re-initialising if in use */
  view_struct->tablet_initialised = 0;

  /* reset the view object */
  if( (errNum == WLZ_ERR_NONE) && (view_struct->view_object != NULL) )
  {
    errNum = WlzFreeObj( view_struct->view_object );
    view_struct->view_object = NULL;
  }

  /* free the painted and masked objects */
  if( (errNum == WLZ_ERR_NONE) && (view_struct->painted_object != NULL) )
  {
    errNum = WlzFreeObj( view_struct->painted_object );
    view_struct->painted_object = NULL;
    errNum = WlzFreeObj( view_struct->masked_object );
    view_struct->masked_object = NULL;
  }

  if( errNum != WLZ_ERR_NONE ){
    MAPaintReportWlzError(globals.topl, "reset_view_struct", errNum);
    return 1;
  }
  return( 0 );
}
Beispiel #10
0
/*! 
* \return       projection object
* \ingroup      WlzTransform
* \brief        Use the view transform to define a projection from
*		3D to 2D. Currently only the domain is projected as
*		an opaque shadow.
*		This is old code temporarily kept for compatibility.
* \param    obj	source 3D object
* \param    viewStr	view structure defining the projection
* \param    intFunc	grey-value summation function
* \param    intFuncData data to be passed to the integration function
* \param    dstErr	error return
*/
WlzObject *WlzGetProjectionFromObject(
  WlzObject		*obj,
  WlzThreeDViewStruct 	*viewStr,
  Wlz3DProjectionIntFn 	intFunc,
  void			*intFuncData,
  WlzErrorNum		*dstErr)
{
  WlzObject		*rtnObj=NULL,
  			*obj1;
  WlzThreeDViewStruct	*viewStr1=NULL;
  WlzDomain		domain;
  WlzValues		values;
  WlzGreyType		srcGType = WLZ_GREY_UBYTE,
  			dstGType = WLZ_GREY_UBYTE;
  WlzPixelV		pixval;
  WlzPixelP		pixptr;
  WlzIntervalWSpace	iwsp;
  WlzGreyWSpace		gwsp;
  WlzGreyValueWSpace	*gVWSp = NULL;
  WlzDVertex3		vtx, vtx1;
  double		x, y, z;
  double		*s_to_x=NULL;
  double		*s_to_y=NULL;
  double		*s_to_z=NULL;
  int			k, xp, yp, s, sp;
  int			length = 0, size = 0, occupiedFlg;
  WlzErrorNum 	errNum=WLZ_ERR_NONE;

  /* check inputs */
  if( obj == NULL ){
    errNum = WLZ_ERR_OBJECT_NULL;
  }
  else if( obj->type != WLZ_3D_DOMAINOBJ ){
    errNum = WLZ_ERR_OBJECT_TYPE;
  }
  else if( obj->domain.core == NULL ){
    errNum = WLZ_ERR_DOMAIN_NULL;
  }
  else if( obj->domain.core->type != WLZ_PLANEDOMAIN_DOMAIN ){
    errNum = WLZ_ERR_DOMAIN_TYPE;
  }

  if( (errNum == WLZ_ERR_NONE) && (viewStr == NULL) ){
    errNum = WLZ_ERR_OBJECT_NULL;
  }

  /* create new view transform */
  if( errNum == WLZ_ERR_NONE ){
    if((viewStr1 = WlzMake3DViewStruct(WLZ_3D_VIEW_STRUCT, &errNum)) != NULL){
      /* need to worry about fixed line mode here sometime */
      viewStr1->fixed = viewStr->fixed;
      viewStr1->theta = viewStr->theta;
      viewStr1->phi = viewStr->phi;
      viewStr1->zeta = viewStr->zeta;
      viewStr1->dist = viewStr->dist;
      viewStr1->scale = viewStr->scale;
      viewStr1->voxelSize[0] = viewStr->voxelSize[0];
      viewStr1->voxelSize[1] = viewStr->voxelSize[1];
      viewStr1->voxelSize[2] = viewStr->voxelSize[2];
      viewStr1->voxelRescaleFlg = viewStr->voxelRescaleFlg;
      viewStr1->interp = viewStr->interp;
      viewStr1->view_mode = viewStr->view_mode;
      viewStr1->up = viewStr->up;

      /* now intialize it */
      /* could optimise by setting fixed point to object centre */
      if( (errNum = WlzInit3DViewStruct(viewStr1, obj)) != WLZ_ERR_NONE ){
	WlzFree3DViewStruct(viewStr1);
	viewStr1 = NULL;
      }
    }
  }

  /* set up orthogonal line parameters & luts */
  if( errNum == WLZ_ERR_NONE ){
    length = WLZ_NINT(viewStr1->maxvals.vtZ) -
      WLZ_NINT(viewStr1->minvals.vtZ) + 1;
    s_to_x = (double *) AlcMalloc(sizeof(double) * length );
    s_to_y = (double *) AlcMalloc(sizeof(double) * length );
    s_to_z = (double *) AlcMalloc(sizeof(double) * length );

    /* transform a perpendicular vector */
    vtx.vtX = 0.0;
    vtx.vtY = 0.0;
    vtx.vtZ = 1.0;
    Wlz3DSectionTransformInvVtx(&vtx, viewStr1);
    vtx1.vtX = 0.0;
    vtx1.vtY = 0.0;
    vtx1.vtZ = 0.0;
    Wlz3DSectionTransformInvVtx(&vtx1, viewStr1);
    vtx.vtX -= vtx1.vtX;
    vtx.vtY -= vtx1.vtY;
    vtx.vtZ -= vtx1.vtZ;

    /* assign lut values */
    s = (int )(WLZ_NINT(viewStr1->minvals.vtZ) - viewStr1->dist);
    for(sp=0; sp < length; sp++, s++){
      s_to_x[sp] = s * vtx.vtX;
      s_to_y[sp] = s * vtx.vtY;
      s_to_z[sp] = s * vtx.vtZ;
    }
  }

  /* if there is an integration function then allocate space for
     the grey-level array */
  if( (errNum == WLZ_ERR_NONE) && (intFunc) ){
    srcGType = WlzGreyTypeFromObj(obj, &errNum);
    switch( srcGType ){
    case WLZ_GREY_LONG:
      size = sizeof(WlzLong)*length;
      break;
    case WLZ_GREY_INT:
      size = sizeof(int)*length;
      break;
    case WLZ_GREY_SHORT:
      size = sizeof(short)*length;
      break;
    case WLZ_GREY_UBYTE:
      size = sizeof(WlzUByte)*length;
      break;
    case WLZ_GREY_FLOAT:
      size = sizeof(float)*length;
      break;
    case WLZ_GREY_DOUBLE:
      size = sizeof(double)*length;
      break;
    case WLZ_GREY_RGBA:
      size = sizeof(int)*length;
      break;
    default:
      errNum = WLZ_ERR_GREY_TYPE;
      break;
    }
    if( (pixptr.p.inp = (int *) AlcMalloc(size)) == NULL ){
      errNum = WLZ_ERR_MEM_ALLOC;
    }
    pixptr.type = srcGType;

    /* set up the grey-value workspace for random access */
    gVWSp = WlzGreyValueMakeWSp(obj, &errNum);
  }

  /* create rectangular projection image */
  if( errNum == WLZ_ERR_NONE ){
    if((domain.i = WlzMakeIntervalDomain(WLZ_INTERVALDOMAIN_RECT,
				     WLZ_NINT(viewStr1->minvals.vtY),
				     WLZ_NINT(viewStr1->maxvals.vtY),
				     WLZ_NINT(viewStr1->minvals.vtX),
				     WLZ_NINT(viewStr1->maxvals.vtX),
					 &errNum)) != NULL){
      values.core = NULL;
      if((rtnObj = WlzMakeMain(WLZ_2D_DOMAINOBJ, domain, values, NULL, NULL,
			       &errNum)) != NULL){
	/* note the grey-values required are determined by the integration
	   function. Here we use WlzUByte and reset later if needed */
	dstGType = WLZ_GREY_UBYTE;
	pixval.type = WLZ_GREY_UBYTE;
	pixval.v.ubv = (WlzUByte )0;
	if((values.v = WlzNewValueTb(rtnObj,
				     WlzGreyTableType(WLZ_GREY_TAB_RECT,
						      dstGType, NULL),
				     pixval, &errNum)) != NULL){
	  rtnObj->values = WlzAssignValues(values, &errNum);
	}
	else {
	  WlzFreeObj(rtnObj);
	  rtnObj = NULL;
	}
      }
      else {
	WlzFreeDomain(domain);
	domain.core = NULL;
      }
    }
  }

  /* scan image setting values */
  if( errNum == WLZ_ERR_NONE ){
    errNum = WlzInitGreyScan(rtnObj, &iwsp, &gwsp);
  }
  if( errNum == WLZ_ERR_NONE ){
    while( (errNum = WlzNextGreyInterval(&iwsp)) == WLZ_ERR_NONE ){
      yp = iwsp.linpos - WLZ_NINT(viewStr1->minvals.vtY);
      for(k=iwsp.lftpos; k <= iwsp.rgtpos; k++){
	xp = k - WLZ_NINT(viewStr1->minvals.vtX);
	vtx.vtX = viewStr1->xp_to_x[xp] + viewStr1->yp_to_x[yp];
	vtx.vtY = viewStr1->xp_to_y[xp] + viewStr1->yp_to_y[yp];
	vtx.vtZ = viewStr1->xp_to_z[xp] + viewStr1->yp_to_z[yp];

	/* get the projection values */
	/* if no function then just check for occupancy */
	if( intFunc == NULL ){
	  occupiedFlg = 0;
	  sp = (int )(viewStr1->dist - WLZ_NINT(viewStr1->minvals.vtZ));
	  for(; !occupiedFlg && (sp < length); sp++){
	    x = vtx.vtX + s_to_x[sp];
	    y = vtx.vtY + s_to_y[sp];
	    z = vtx.vtZ + s_to_z[sp];
	    if( WlzInsideDomain(obj, z, y, x, &errNum) ){
	      occupiedFlg = 1;
	    }
	  }
	  sp = (int )(viewStr1->dist - WLZ_NINT(viewStr1->minvals.vtZ) - 1);
	  for(; !occupiedFlg && (sp >= 0); sp--){
	    x = vtx.vtX + s_to_x[sp];
	    y = vtx.vtY + s_to_y[sp];
	    z = vtx.vtZ + s_to_z[sp];
	    if( WlzInsideDomain(obj, z, y, x, &errNum) ){
	      occupiedFlg = 1;
	    }
	  }

	  /* set the integrated value - only WlzUByte at the moment */
	  *(gwsp.u_grintptr.ubp) = (WlzUByte )occupiedFlg;
	  gwsp.u_grintptr.ubp++;
	}
	/* use integration function */
	else {
	  /* set array of pixel values */
	  for(sp=0; sp < length; sp++){
	    x = vtx.vtX + s_to_x[sp];
	    y = vtx.vtY + s_to_y[sp];
	    z = vtx.vtZ + s_to_z[sp];
	    WlzGreyValueGet(gVWSp, WLZ_NINT(z), WLZ_NINT(y),
			    WLZ_NINT(x));
	    switch( srcGType ){
	    case WLZ_GREY_LONG:
	      pixptr.p.lnp[sp] = gVWSp->gVal[0].lnv;
	      break;
	    case WLZ_GREY_INT:
	      pixptr.p.inp[sp] = gVWSp->gVal[0].inv;
	      break;
	    case WLZ_GREY_SHORT:
	      pixptr.p.shp[sp] = gVWSp->gVal[0].shv;
	      break;
	    case WLZ_GREY_UBYTE:
	      pixptr.p.ubp[sp] = gVWSp->gVal[0].ubv;
	      break;
	    case WLZ_GREY_FLOAT:
	      pixptr.p.flp[sp] = gVWSp->gVal[0].flv;
	      break;
	    case WLZ_GREY_DOUBLE:
	      pixptr.p.dbp[sp] = gVWSp->gVal[0].dbv;
	      break;
	    case WLZ_GREY_RGBA:
	      pixptr.p.rgbp[sp] = gVWSp->gVal[0].rgbv;
	      break;
	    default:
	      errNum = WLZ_ERR_GREY_TYPE;
	      break;
	    }
	  }
	  /* call integration function and seet value */
	  intFunc(pixptr, length, (int )(viewStr1->dist -
		                         WLZ_NINT(viewStr1->minvals.vtZ)),
		  intFuncData, &errNum);
	}
      }
    }
    (void )WlzEndGreyScan(&iwsp, &gwsp);
    if(errNum == WLZ_ERR_EOO)	   /* Reset error from end of intervals */ 
    {
      errNum = WLZ_ERR_NONE;
    }

    /* if no integration function then threshold - binary only */
    if( intFunc == NULL ){
      pixval.v.ubv = 1;
      rtnObj = WlzAssignObject(rtnObj, NULL);
      if((obj1 = WlzThreshold(rtnObj, pixval, WLZ_THRESH_HIGH,
                              &errNum)) != NULL){
	WlzFreeObj(rtnObj);
	values.core = NULL;
	rtnObj = WlzMakeMain(WLZ_2D_DOMAINOBJ, obj1->domain, values, NULL, NULL,
			     &errNum);
	WlzFreeObj(obj1);
      }
      else {
	WlzFreeObj(rtnObj);
	rtnObj = NULL;
      }
    }
  }

  /* clear space */
  if( viewStr1 ){
    errNum = WlzFree3DViewStruct(viewStr1);
  }
  if( s_to_x ){
    AlcFree( s_to_x );
  }
  if( s_to_y ){
    AlcFree( s_to_y );
  }
  if( s_to_z ){
    AlcFree( s_to_z );
  }

  /* check error and return */
  if( dstErr ){
    *dstErr = errNum;
  }
  return rtnObj;
}
int             main(int argc, char **argv)
{
  int		option,
  		ok = 1,
		debug = 0,
		usage = 0,
		verbose = 0,
		verboseDat = 0,
		idx0,
		index,
		binFlg = 0,
  		nMatch = 0,
		useCOfM = 0,
		maxItr = 200,
		minSpx = 15,
		minSegSpx = 10,
		matchImpNN = 7,
		noMatching = 0,
		decompLimit = INT_MAX,
		removeRefOrg = 1,
		refMedianSz = 0,
		srcMedianSz = 0,
		multipleFiles = 0;
  double	tD0,
  		tD1,
		delta = 0.01,	
  		maxAng = 30 * (ALG_M_PI / 180.0),
  		maxDeform = 0.5,
  		maxDisp = 20.0,
		refCThr = 20.0,
		srcCThr = 20.0,
		refThr = 254.0,
		srcThr = 254.0,
		matchImpThr = 2.5,
		refSmooth = 3.0,
		srcSmooth = 3.0;
  FILE		*vFP,
  		*lFP = NULL,
  		*fP = NULL;
  char		*inFileStr = NULL,
		*inTrFileStr = NULL,
  		*outFileBaseStr = NULL,
		*ctrFileBaseStr = NULL;
  char		secParFile[256];
  char		*refObjFileStr = NULL,
  		*srcObjFileStr = NULL;
  WlzThresholdType thrType = WLZ_THRESH_LOW;
  WlzEffFormat	refObjFileType = WLZEFF_FORMAT_WLZ,
  		srcObjFileType = WLZEFF_FORMAT_WLZ;
  WlzObject	*tObj0 = NULL,
  		*refObj3D = NULL,
		*refObj2D = NULL,
  		*srcObj2D = NULL,
		*refCObj2D = NULL,
  		*srcCObj2D = NULL;
  WlzDVertex2	tDV0,
  		refCOfM,
  		srcCOfM,
		refObj2DOrg;
  WlzAffineTransform *inTr = NULL,
		*inPTr = NULL;
  WlzThreeDViewStruct *view = NULL;
  WlzVertexP	matchRP,
  		matchSP;
  WlzInterpolationType interp = WLZ_INTERPOLATION_NEAREST;
  WlzMatchICPWeightCbData cbData;
  WlzAffineTransformPrim inTrPrim;
  WlzErrorNum	errNum = WLZ_ERR_NONE;
  char		fileNameBuf[FILENAME_MAX];
  const char	*errMsg;
  static char	optList[] =
                "dhvVo:r:Yt:x:y:a:s:efg:k:u:b:B:i:p:A:E:S:F:P:m:n:c:NL";
  const int	nScatter = 5;
  const char	nullStr[] = "<NULL>",
  		inFileStrDef[] = "-",
  	        outFileStrDef[] = "-";

  matchRP.v = matchSP.v = NULL;
  srcCOfM.vtX = srcCOfM.vtY = 0.0;
  inFileStr = (char *)inFileStrDef;
  outFileBaseStr = (char *)outFileStrDef;
  (void )memset(&inTrPrim, 0, sizeof(WlzAffineTransformPrim));
  inTrPrim.scale = 1.0;
  while((usage == 0) && ok &&
        ((option = getopt(argc, argv, optList)) != -1))
  {
    switch(option)
    {
      case 'd':
        debug = 1;
	break;
      case 'h':
        usage = 1;
	break;
      case 'v':
        verbose = 1;
	break;
      case 'V':
        verboseDat = 1;
	break;
      case 'o':
        outFileBaseStr = optarg;
	break;
      case 'r':
        if((refObjFileStr = AlcStrDup(optarg)) == NULL)
	{
	  ok = 0;
	  (void )fprintf(stderr, "%s Failed to allocate enough memory.\n",
	     	         *argv);
	}
        break;
      case 'Y':
        multipleFiles = 1;
	break;
      case 't':
        inTrFileStr = optarg;
	break;
      case 'x':
        if(sscanf(optarg, "%lg", &(inTrPrim.tx)) != 1)
	{
	  usage = 1;
	}
	break;
      case 'y':
        if(sscanf(optarg, "%lg", &(inTrPrim.ty)) != 1)
	{
	  usage = 1;
	}
	break;
      case 'a':
        if(sscanf(optarg, "%lg", &(inTrPrim.theta)) != 1)
	{
	  usage = 1;
	}
	else
	{
	  inTrPrim.theta *= ALG_M_PI / 180.0;
	}
	break;
      case 's':
        if(sscanf(optarg, "%lg", &(inTrPrim.scale)) != 1)
	{
	  usage = 1;
	}
	break;
      case 'e':
        useCOfM = 1;
	break;
      case 'f':
        removeRefOrg = 0;
	break;
      case 'b':
	binFlg = 1;
        thrType = WLZ_THRESH_LOW;
        usage = WlzMatchICPPlaneParseDPair(optarg, &refThr, &srcThr) != 3;
	break;
      case 'B':
	binFlg = 1;
        thrType = WLZ_THRESH_HIGH;
        usage = WlzMatchICPPlaneParseDPair(optarg, &refThr, &srcThr) != 3;
	break;
      case 'g':
        usage = WlzMatchICPPlaneParseDPair(optarg, &refCThr, &srcCThr) != 3;
	break;
      case 'k':
        usage = WlzMatchICPPlaneParseDPair(optarg, &tD0, &tD1) != 3;
	refMedianSz = WLZ_NINT(tD0);
	srcMedianSz = WLZ_NINT(tD1);
	break;
      case 'u':
        usage = WlzMatchICPPlaneParseDPair(optarg,
					   &refSmooth, &srcSmooth) != 3;
	break;
      case 'i':
        if((sscanf(optarg, "%d", &maxItr) != 1) || (maxItr <= 0))
	{
	  usage = 1;
	}
	break;
      case 'p':
        if((sscanf(optarg, "%d", &minSpx) != 1) || (minSpx <= 10))
	{
	  usage = 1;
	}
	break;
      case 'P':
        if(sscanf(optarg, "%d", &minSegSpx) != 1)
	{
	  usage = 1;
	}
	break;
      case 'A':
        if((sscanf(optarg, "%lg", &maxAng) != 1) ||
	   (maxAng < 0.0) || (maxAng > 180.0))
	{
	  usage = 1;
	}
	else
	{
	  maxAng *= ALG_M_PI / 180;
	}
	break;
      case 'E':
        if((sscanf(optarg, "%lg", &delta) != 1) || (delta < 0.0))
	{
	  usage = 1;
	}
      case 'F':
        if((sscanf(optarg, "%lg", &maxDeform) != 1) || (maxDeform < 0.0))
	{
	  usage = 1;
	}
	break;
      case 'S':
        if((sscanf(optarg, "%lg", &maxDisp) != 1) || (maxDisp <= 0.0))
	{
	  usage = 1;
	}
	break;
      case 'm':
        if((sscanf(optarg, "%lg", &matchImpThr) != 1) || (matchImpThr < 0.0))
	{
	  usage = 1;
	}
	break;
      case 'n':
        if((sscanf(optarg, "%d", &matchImpNN) != 1) || (matchImpNN < 1))
	{
	  usage = 1;
	}
	break;
      case 'c':
        ctrFileBaseStr = optarg;
        if(strlen(ctrFileBaseStr) > (FILENAME_MAX - 16))
	{
	  usage = 1;
	}
	break;
      case 'N':
        noMatching = 1;
	break;
      case 'L':
        interp = WLZ_INTERPOLATION_LINEAR;
	break;
      default:
        usage = 1;
	break;
    }
  }
  if(usage)
  {
    ok = 0;
  }
  if(ok)
  {
    if((inFileStr == NULL) || (*inFileStr == '\0') ||
       (outFileBaseStr == NULL) || (*outFileBaseStr == '\0'))
    {
      ok = 0;
      usage = 1;
    }
    if(ok && (optind < argc))
    {
      if((optind + 1) != argc)
      {
        usage = 1;
	ok = 0;
      }
      else
      {
        inFileStr = *(argv + optind);
      }
    }
  }
  if(verbose)
  {
    (void )fprintf(stderr, "Parameter and other internal variable values:\n");
    (void )fprintf(stderr, "  ok = %d\n", ok);
    (void )fprintf(stderr, "  debug = %d\n", debug);
    (void )fprintf(stderr, "  verbose = %d\n", verbose);
    (void )fprintf(stderr, "  verboseDat = %d\n", verboseDat);
    (void )fprintf(stderr, "  outFileBaseStr = %s\n",
		   outFileBaseStr? outFileBaseStr: nullStr);
    (void )fprintf(stderr, "  refObjFileStr = %s\n",
		   refObjFileStr? refObjFileStr: nullStr);
    (void )fprintf(stderr, "  multipleFiles = %d\n", multipleFiles);
    (void )fprintf(stderr, "  inTrFileStr = %s\n",
                   inTrFileStr? inTrFileStr: nullStr);
    (void )fprintf(stderr, "  inTrPrim.tx = %g\n", inTrPrim.tx);
    (void )fprintf(stderr, "  inTrPrim.ty = %g\n", inTrPrim.ty);
    (void )fprintf(stderr, "  inTrPrim.theta = %g (Radians)\n",
    		   inTrPrim.theta);
    (void )fprintf(stderr, "  inTrPrim.scale = %g\n", inTrPrim.scale);
    (void )fprintf(stderr, "  useCOfM = %d\n", useCOfM);
    (void )fprintf(stderr, "  removeRefOrg = %d\n", removeRefOrg);
    (void )fprintf(stderr, "  binFlg = %d\n", binFlg);
    (void )fprintf(stderr, "  thrType = %s\n",
	    (thrType == WLZ_THRESH_LOW)? "WLZ_THRESH_LOW": "WLZ_THRESH_HIGH");
    (void )fprintf(stderr, "  refThr = %g\n", refThr);
    (void )fprintf(stderr, "  srcThr = %g\n", srcThr);
    (void )fprintf(stderr, "  refCThr = %g\n", refCThr);
    (void )fprintf(stderr, "  srcCThr = %g\n", srcCThr);
    (void )fprintf(stderr, "  refMedianSz = %d\n", refMedianSz);
    (void )fprintf(stderr, "  srcMedianSz = %d\n", srcMedianSz);
    (void )fprintf(stderr, "  refSmooth = %g\n", refSmooth);
    (void )fprintf(stderr, "  srcSmooth = %g\n", srcSmooth);
    (void )fprintf(stderr, "  delta = %g\n", delta);
    (void )fprintf(stderr, "  maxItr = %d\n", maxItr);
    (void )fprintf(stderr, "  minSpx = %d\n", minSpx);
    (void )fprintf(stderr, "  maxAng = %g (Radians)\n", maxAng);
    (void )fprintf(stderr, "  maxDeform = %g\n", maxDeform);
    (void )fprintf(stderr, "  maxDisp = %g\n", maxDisp);
    (void )fprintf(stderr, "  matchImpThr = %g\n", matchImpThr);
    (void )fprintf(stderr, "  matchImpNN = %d\n", matchImpNN);
    (void )fprintf(stderr, "  ctrFileBaseStr = %s\n",
		   ctrFileBaseStr? ctrFileBaseStr: nullStr);
    (void )fprintf(stderr, "  noMatching = %d\n", noMatching);
    (void )fprintf(stderr, "  usage = %d\n", usage);
  }
  /* Create the initial affine transform and it's inverse. */
  if(ok)
  {
    if(inTrFileStr)
    {
      tObj0 = NULL;
      if(((fP = fopen(inTrFileStr, "r")) == NULL) ||
         ((tObj0 = WlzReadObj(fP, &errNum)) == NULL) ||
	 (tObj0->type != WLZ_AFFINE_TRANS) ||
	 (tObj0->domain.core == NULL))
      {
        errNum = WLZ_ERR_READ_INCOMPLETE;
      }
      else
      {
        inTr = WlzAffineTransformCopy(tObj0->domain.t, &errNum);
      }
      if(fP)
      {
        (void )fclose(fP);
	fP = NULL;
      }
      if(tObj0)
      {
        WlzFreeObj(tObj0);
	tObj0 = NULL;
      }
    }
    else
    {
      inTr = WlzMakeAffineTransform(WLZ_TRANSFORM_2D_AFFINE, &errNum);
      if(errNum == WLZ_ERR_NONE)
      {
	errNum = WlzAffineTransformPrimSet(inTr, inTrPrim);
      }
    }
    if(errNum == WLZ_ERR_NONE)
    {
      if(verbose)
      {
        (void )fprintf(stderr, "Affine transform inTr = \n");
	(void )AlcDouble2WriteAsci(stderr, inTr->mat, 3, 3);
      }
    }
    if(errNum != WLZ_ERR_NONE)
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
      		     "%s: Failed to set initial affine transform (%s).\n",
		     *argv, errMsg);
    }
  }
  /* If the reference file name was given on the command line then it use it
   * in place of the reference file name in the section parameters bibfile. */
  if(ok && refObjFileStr)
  {
    if(((refObj3D = WlzAssignObject(
		    WlzEffReadObj(NULL, refObjFileStr, refObjFileType,
				  0, 0, 0, &errNum), NULL)) == NULL) ||
       (errNum != WLZ_ERR_NONE))
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
      "%s Failed to read the reference object from file %s (%s).\n",
      *argv, refObjFileStr, errMsg);
    }
  }
  if(ok)
  {
    if((lFP = (strcmp(inFileStr, "-")?
             fopen(inFileStr, "r"): stdin)) == NULL)
    {
      ok = 0;
      (void )fprintf(stderr,
		   "%s Failed to open the input section parameters file %s.\n",
		    *argv, inFileStr);
    }
  }
  /* Get each input section parameters file and process it. */
  index = 0;
  while(ok &&
        ((fP = WlzMatchICPPlaneSecParFile(lFP, multipleFiles, index,
					  secParFile)) != NULL))
  {
    errNum = WlzMatchICPPlaneReadSecParam(fP, &view,
	refObjFileStr? NULL: &refObjFileStr, &refObjFileType,
	refObj3D? NULL: &refObj3D,
	&srcObjFileStr, &srcObjFileType, &srcObj2D);
    /* Note: srcObj2D assigned in WlzMatchICPPlaneReadSecParam(). */
    if(errNum == WLZ_ERR_NONE)
    {
      if(verboseDat)
      {
	if(verbose)
	{
	  (void )fprintf(stderr,
			 "Writing srcObj2D to dbg-srcObj2D.wlz.\n");
	}
	if((vFP = fopen("dbg-srcObj2D.wlz", "w")) != NULL)
	{
	  (void )WlzWriteObj(vFP, srcObj2D);
	  (void )fclose(vFP);
	}
      }
      errNum = WlzInit3DViewStruct(view, refObj3D);
    }
    if(fP)
    {
      fclose(fP);
      fP = NULL;
    }
    if(errNum != WLZ_ERR_NONE)
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
       "%s Failed to read input section parameters from file %s (%s).\n",
       argv[0], secParFile, errMsg);
    }
    /* Create the section object. */
    if(ok)
    {
      refObj2D = WlzAssignObject(
      		 WlzMatchICPPlaneGetSection(refObj3D, view, interp,
		 		            &errNum), NULL);
      if((errNum == WLZ_ERR_NONE) && (refObj2D != NULL) &&
	  (refObj2D->type = WLZ_2D_DOMAINOBJ) && (refObj2D->domain.core))
      {
	refObj2DOrg.vtX = refObj2D->domain.i->kol1;
	refObj2DOrg.vtY = refObj2D->domain.i->line1;
	if(verboseDat)
	{
	  if(verbose)
	  {
	    (void )fprintf(stderr,
			   "Writing refObj2D to dbg-refObj2D.wlz.\n");
	  }
	  if((vFP = fopen("dbg-refObj2D.wlz", "w")) != NULL)
	  {
	    (void )WlzWriteObj(vFP, refObj2D);
	    (void )fclose(vFP);
	  }
	}
      }
      else
      {
	ok = 0;
        (void )WlzStringFromErrorNum(errNum, &errMsg);
	(void )fprintf(stderr,
	"%s Failed to get section from reference object (%s).\n",
	argv[0], errMsg);
      }
    }
    /* Create the contour objects. */
    if(ok)
    {
      refCObj2D = WlzMatchICPPlaneCreateContourObj(refObj2D,
				binFlg, thrType, refThr,
      				refMedianSz, refSmooth,
				refCThr, minSpx, debug,
				verboseDat? "dbg-refObj2D.wlz": NULL,
				&errNum);
      if(errNum == WLZ_ERR_NONE)
      {
	srcCObj2D = WlzMatchICPPlaneCreateContourObj(srcObj2D,
				binFlg, thrType, srcThr,
				srcMedianSz, srcSmooth,
				srcCThr, minSpx, debug,
				verboseDat? "dbg-srcObj2D.wlz": NULL,
				&errNum);
      }
      if(errNum != WLZ_ERR_NONE)
      {
	ok = 0;
        (void )WlzStringFromErrorNum(errNum, &errMsg);
	(void )fprintf(stderr, "%s Failed to compute contours (%s).\n",
		       argv[0], errMsg);
      }
    }
    /* Compute translation using centre of mass if required. Then create
     * modified initial and inverse transforms for this plane. */
    if(ok)
    {
      if(useCOfM)
      {
	if(verbose)
	{
	  (void )fprintf(stderr,
	  "Using centre of mass to refine initial affine transform.\n");
	}
	refCOfM = WlzCentreOfMass2D(refCObj2D, 0, NULL, &errNum);
	tObj0 = NULL;
	if(errNum == WLZ_ERR_NONE)
	{
	  tObj0 = WlzAssignObject(
		  WlzAffineTransformObj(srcCObj2D, inTr,
					WLZ_INTERPOLATION_NEAREST,
					&errNum), NULL);
	}
	if(errNum == WLZ_ERR_NONE)
	{
	  srcCOfM = WlzCentreOfMass2D(tObj0, 0, NULL, &errNum);
	}
	(void )WlzFreeObj(tObj0);
	if(errNum == WLZ_ERR_NONE)
	{
	  if(verbose)
	  {
	    (void )fprintf(stderr,
	    "centres of mass are: refCOfM = {%g,%g}, srcCOfM = {%g,%g}.\n",
	    refCOfM.vtX, refCOfM.vtY, srcCOfM.vtX, srcCOfM.vtY);
	  }
	  inPTr = WlzAffineTransformCopy(inTr, &errNum);
	}
	if(errNum == WLZ_ERR_NONE)
	{
	  WLZ_VTX_2_SUB(tDV0, refCOfM, srcCOfM);
	  inPTr->mat[0][2] += tDV0.vtX;
	  inPTr->mat[1][2] += tDV0.vtY;
	}
	if(errNum != WLZ_ERR_NONE)
	{
	  ok = 0;
	  (void )WlzStringFromErrorNum(errNum, &errMsg);
	  (void )fprintf(stderr,
	  "%s Failed to modify transform using centre of mass (%s).\n",
			 argv[0], errMsg);
	}
      }
      if(errNum == WLZ_ERR_NONE)
      {
	if(verbose)
	{
	  (void )fprintf(stderr, "Affine transform inPTr = ");
	  if(inPTr)
	  {
	    (void )fprintf(stderr, "\n");
	    (void )AlcDouble2WriteAsci(stderr, inPTr->mat, 3, 3);
	  }
	  else
	  {
	    (void )fprintf(stderr, "Identity\n");
	  }
	}
      }
    }
    if(ok && ctrFileBaseStr)
    {
      if(multipleFiles)
      {
        sprintf(fileNameBuf, "%s_%06d_ctr_ref.wlz", ctrFileBaseStr, index);
      }
      else
      {
        sprintf(fileNameBuf, "%s_ctr_ref.wlz", ctrFileBaseStr);
      }
      errNum = WLZ_ERR_FILE_OPEN;
      ok = (fP = fopen(fileNameBuf, "w")) != NULL;
      if(ok)
      {
	ok = (errNum = WlzWriteObj(fP, refCObj2D)) == WLZ_ERR_NONE;
      }
      if(fP)
      {
	(void )fclose(fP);
	fP = NULL;
      }
      if(ok)
      {
	if(multipleFiles)
	{
	  sprintf(fileNameBuf, "%s_%06d_ctr_src.wlz", ctrFileBaseStr, index);
	}
	else
	{
	  sprintf(fileNameBuf, "%s_ctr_src.wlz", ctrFileBaseStr);
	}
	ok = (fP = fopen(fileNameBuf, "w")) != NULL;
      }
      if(ok)
      {
	ok = (errNum = WlzWriteObj(fP, srcCObj2D)) == WLZ_ERR_NONE;
      }
      if(fP)
      {
	(void )fclose(fP);
	fP = NULL;
      }
      tObj0 = NULL;
      if(ok)
      {
        tObj0 = WlzAffineTransformObj(srcCObj2D, inPTr,
				      WLZ_INTERPOLATION_NEAREST, &errNum);
        ok = errNum == WLZ_ERR_NONE;
      }
      if(ok)
      {
        if(multipleFiles)
	{
	  sprintf(fileNameBuf, "%s_%06d_ctr_itrsrc.wlz", ctrFileBaseStr,
	  	  index);
	}
	else
	{
	  sprintf(fileNameBuf, "%s_ctr_itrsrc.wlz", ctrFileBaseStr);
	}
	ok = (fP = fopen(fileNameBuf, "w")) != NULL;
      }
      if(ok)
      {
	ok = (errNum = WlzWriteObj(fP, tObj0)) == WLZ_ERR_NONE;
      }
      (void )WlzFreeObj(tObj0);
      if(fP)
      {
        (void )fclose(fP);
	fP = NULL;
      }
      if(!ok)
      {
	(void )WlzStringFromErrorNum(errNum, &errMsg);
	(void )fprintf(stderr,
		       "%s Failed to write contour to file %s (%s)\n",
		       argv[0], fileNameBuf, errMsg);
      }
    }
    if(ok && (noMatching == 0))
    {
      /* Set up weighting function callback data. */
      cbData.tGM = refCObj2D->domain.ctr->model;
      cbData.sGM = srcCObj2D->domain.ctr->model;
      cbData.maxDisp = maxDisp;
      cbData.nScatter = nScatter;
      errNum = WlzMatchICPCtr(refCObj2D->domain.ctr, srcCObj2D->domain.ctr,
			      inPTr, maxItr, minSpx, minSegSpx,
			      &nMatch, &matchRP, &matchSP, decompLimit,
			      maxDisp, maxAng, maxDeform,
			      matchImpNN, matchImpThr,
			      WlzMatchICPWeightMatches, &cbData,
			      delta);
      if(errNum != WLZ_ERR_NONE)
      {
	ok = 0;
	(void )WlzStringFromErrorNum(errNum, &errMsg);
	(void )fprintf(stderr,
		       "%s Failed to compute tie-points from contours (%s).\n",
		       argv[0], errMsg);
      }
    }
    if(ok && verboseDat)
    {
	if(verbose)
	{
	  (void )fprintf(stderr,
			 "Writing tie points to dbg-tiepoints.num.\n");
	}
	if((vFP = fopen("dbg-tiepoints.num", "w")) != NULL)
	{
	  for(idx0 = 0; idx0 < nMatch; ++ idx0)
	  {
	    (void )fprintf(vFP, "%g %g %g %g\n",
		       (matchSP.d2 + idx0)->vtX,
		       (matchSP.d2 + idx0)->vtY,
		       (matchRP.d2 + idx0)->vtX - (matchSP.d2 + idx0)->vtX,
		       (matchRP.d2 + idx0)->vtY - (matchSP.d2 + idx0)->vtY);
	  }
	  (void )fclose(vFP);
	}
    }
    if(ok && ctrFileBaseStr)
    {
      if(multipleFiles)
      {
	sprintf(fileNameBuf, "%s_%06d_ctr_dcp.wlz", ctrFileBaseStr, index);
      }
      else
      {
	sprintf(fileNameBuf, "%s_ctr_dcp.wlz", ctrFileBaseStr);
      }
      if((fP = fopen(fileNameBuf, "w")) == NULL)
      {
	ok = 0;
	(void )fprintf(stderr, "%s Failed to open contour file %s\n",
		       argv[0], fileNameBuf);
      }
      else
      {
	if((errNum = WlzWriteObj(fP, srcCObj2D)) != WLZ_ERR_NONE)
	{
	  ok = 0;
	  (void )WlzStringFromErrorNum(errNum, &errMsg);
	  (void )fprintf(stderr,
	  		 "%s Failed to write contour to file %s (%s)\n",
			 argv[0], fileNameBuf, errMsg);
	}
	(void )fclose(fP);
	fP = NULL;
      }
    }
    /* Write the new section parameters file together with the computed
     * tie-points. */
    if(ok)
    {
      if(multipleFiles)
      {
        sprintf(fileNameBuf, "%s_%06d.bib", outFileBaseStr, index);
      }
      else
      {
        sprintf(fileNameBuf, "%s.bib", outFileBaseStr);
      }
      if((fP = fopen(fileNameBuf, "w")) == NULL)
      {
	ok = 0;
	(void )fprintf(stderr,
		 "%s Failed to open the output section parameters file %s.\n",
		 *argv, fileNameBuf);
      }
    }
    if(ok)
    {
      if(verbose)
      {
	(void )fprintf(stderr, "Writing section parameters.\n");
      }
      errNum = WlzMatchICPPlaneWriteSecParam(fP, view,
	  refObjFileStr, refObjFileType,
	  srcObjFileStr, srcObjFileType,
	  nMatch, matchRP.d2, matchSP.d2,
	  removeRefOrg? &refObj2DOrg: NULL);
      if(fP && strcmp(outFileBaseStr, "-"))
      {
	fclose(fP);
	fP = NULL;
      }
      if(errNum != WLZ_ERR_NONE)
      {
	ok = 0;
	(void )WlzStringFromErrorNum(errNum, &errMsg);
	(void )fprintf(stderr,
	"%s Failed to write output section parameters to file %s (%s).\n",
	argv[0], fileNameBuf, errMsg);
      }
    }
    WlzFreeAffineTransform(inPTr); inPTr = NULL;
    ++index;
  }
  (void )WlzFree3DViewStruct(view);
  AlcFree(refObjFileStr);
  AlcFree(srcObjFileStr);
  AlcFree(matchRP.v);
  AlcFree(matchSP.v);
  (void )WlzFreeAffineTransform(inTr);
  (void )WlzFreeObj(refObj3D);
  (void )WlzFreeObj(refObj2D);
  (void )WlzFreeObj(srcObj2D);
  (void )WlzFreeObj(refCObj2D);
  (void )WlzFreeObj(srcCObj2D);
  if(usage)
  {
      (void )fprintf(stderr,
      "Usage: %s%s%s%s",
      *argv,
      " [-h] [-d] [-v] [-V]\n"
      "                        [-o<output file base>] [-r <reference file>]\n"
      "                        [-Y] [-t#] [-x#] [-y#] [-a#] [-s#] [-e]\n"
      "                        [-g#,#] [-k#,#] [-u#,#] [-b #] [-B #]\n"
      "                        [-f] [-i#] [-s#] [-A#] [-S#] [-F#] [-m#] [-n#]\n"
      "                        [-c<contour file base>] [-N] [-L]\n"
      "                        [<section parameters file>]\n"
      "Version: ",
      WlzVersion(),
      "\n"
      "Options:\n"
      "  -h  Prints this usage information.\n"
      "  -d  Perform extra tests to aid debuging.\n"
      "  -E  Tolerance in mean registration metric value.\n"
      "  -v  Be verbose, lots of text output to the standard error output!\n"
      "  -V  Be verbose with Woolz objects and data, with file name names\n"
      "      prefixed by dbg-.\n"
      "  -o  Output file base.\n"
      "  -r  Reference file.\n"
      "  -Y  The section parameters file is a list of section parameters\n"
      "      files, one per line.\n"
      "  -e  Use centres of mass of geometric models to compute translation,\n"
      "      with this translaton being applied after the optional initial\n"
      "      affine transform.\n"
      "  -t  Initial affine transform (if given all initial affine\n"
      "      transform primitives are ignored).\n"
      "  -x  Initial horizontal translation.\n"
      "  -y  Initial vertical translation.\n"
      "  -a  Initial angle of rotation (degrees).\n"
      "  -s  Initial scale factor.\n"
      "  -g  Maximal gradient contour thresholds, with the format:\n"
      "      <ref threshold>,<src threshold>, either may be omitted.\n"
      "  -k  Median filter size, with the format:\n"
      "      <ref size>,<src size>, either may be omitted.\n"
      "  -u  Gaussian smoothing factors, with the format:\n"
      "      <ref smooth>,<src smooth>, either may be omitted.\n"
      "  -b  Low threshold values used to produce binary mask images for\n"
      "      matching instead of the grey valued images, with objects\n"
      "      having values at or below the given thresholds.\n"
      "  -B  High threshold values used to produce binary mask images for\n"
      "      matching instead of the grey valued images, with objects\n"
      "      having values above the given thresholds.\n"
      "  -f  Keep the reference offset in the reference tie-points (MAPaint\n"
      "      doesn't do this).\n"
      "  -i  Maximum number of iterations.\n"
      "  -p  Minimum number of simplices per shell.\n"
      "  -P  Minimum number of simplices per matched shell segment, with a\n"
      "      pair of correspondence points possibly being generated per\n"
      "      matched shell segment.\n"
      "  -A  Maximum angle (degrees) from a global transformation.\n"
      "  -S  Maximum displacement from a global transformed position.\n"
      "  -F  Maximum deformation from a global transformation.\n"
      "  -m  Implausibility threshold for rejecting implausible\n"
      "      correspondence points which should be greater than zero,\n"
      "      although the useful range is probably [0.5-5.0]. Higher\n"
      "      values allow more implausible matches to be returned.\n"
      "  -n  Number of match points in neighbourhood when checking the\n"
      "	     plausibility of the correspondence points.\n"
      "  -c  Outputs the computed and decomposed geometric models using\n"
      "	     the given file base.\n"
      "  -N  Don't compute the tie-points.\n"
      "  -L  Use linear interpolation (instead of nearest neighbour) when\n"
      "      cuting sections.\n"
      "  Reads either a 2D or 3D reference object and an MAPaint section\n"
      "parameters file. Computes tie-points and then writes a new MAPaint\n"
      "section parameters file which includes the tie-points.\n"
      "  An initial affine transform is computed from the (optional) initial\n"
      "translation, rotation and scale parameters. A centre of mass can be\n"
      "computed to improve the initial translation estimates. If a centre of\n"
      "mass computation is used then the images must have background with\n"
      "high values and foreground with low values. This initial affine\n"
      "transform is appiled to the source image before computing the\n"
      "tie-points. Once computed, the tie-points are transformed using the\n"
      "inverse of the intial transform, before output.\n"
      "  The tie-points are computed using an ICP based matching algorithm\n"
      "in which geometric models built from the maximal gradient edges\n"
      "extracted from the computed section of the reference object and\n"
      "the source object (refered to in the section parameters file).\n"
      "  To aid rejection of poor tie-points, the tie-points are ranked by\n"
      "plausibility, with the most plausible first.\n");
  }
  return(!ok);
}