Exemple #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;
}
Exemple #2
0
int free_view_struct(
  ThreeDViewStruct	*view_struct)
{
  WlzErrorNum		errNum=WLZ_ERR_NONE;

  errNum = WlzFree3DViewStruct(view_struct->wlzViewStr);

  if( errNum == WLZ_ERR_NONE ){
    view_struct->ximage->data = NULL;
    XDestroyImage(view_struct->ximage);

    glDeleteLists(view_struct->display_list, 1);
    MAOpenGLDrawScene( globals.canvas );
  }

  /* check the view, painted and masked objects */
  if( (errNum == WLZ_ERR_NONE) && (view_struct->view_object != NULL) )
  {
    errNum = WlzFreeObj( view_struct->view_object );
    view_struct->view_object = NULL;
  }

  if( (errNum == WLZ_ERR_NONE) && (view_struct->painted_object != NULL) )
  {
    errNum = WlzFreeObj( view_struct->painted_object );
    view_struct->painted_object = NULL;
  } 
 
  if( (errNum == WLZ_ERR_NONE) && (view_struct->masked_object != NULL) )
  {
    errNum = WlzFreeObj( view_struct->masked_object );
    view_struct->masked_object = NULL;
  }  

  if( (errNum == WLZ_ERR_NONE) && (view_struct->prev_view_obj != NULL) )
  {
    errNum = WlzFreeObj( view_struct->prev_view_obj );
    view_struct->prev_view_obj = NULL;
  }  

  if( errNum != WLZ_ERR_NONE ){
    MAPaintReportWlzError(globals.topl, "reset_view_struct", errNum);
    return 1;
  }
  return( 0 );
}
Exemple #3
0
/*! 
* \return       Woolz error code.
* \ingroup      WlzAllocation
* \brief        Free a domain structure of any type. All domain
*		structures must have a type and linkcount. Most
*		also have a freeptr by which, if set, all the space
*		allocated can be freed, however there are some special
*		cases.
* \param    domain			Domain to be freed.
*/
WlzErrorNum WlzFreeDomain(WlzDomain domain)
{
  WlzErrorNum	errNum = WLZ_ERR_NONE;
  AlcErrno	alcErrNum = ALC_ER_NONE;

  if(domain.core != NULL)
  {
    if(WlzUnlink(&(domain.core->linkcount), &errNum))
    {
      switch(domain.core->type)
      {
	case WLZ_CMESH_2D:
	  errNum = WlzCMeshFree2D(domain.cm2);
	  break;
	case WLZ_CMESH_3D:
	  errNum = WlzCMeshFree3D(domain.cm3);
	  break;
	case WLZ_3D_VIEW_STRUCT:
	  errNum = WlzFree3DViewStruct(domain.vs3d);
	  break;
	default:
	  /* Most domains are are freed in the same way. */
	  if(domain.core->freeptr != NULL)
	  {
	    alcErrNum = AlcFreeStackFree(domain.core->freeptr);
	  }
	  AlcFree((void *)domain.core);
	  if(alcErrNum != ALC_ER_NONE)
	  {
	    errNum = WLZ_ERR_MEM_FREE;
	  }
	  break;
      }
    }
  }
  return(errNum);
}
Exemple #4
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;
}
Exemple #5
0
int             main(int argc, char **argv)
{
  int		option,
		ok = 1,
		usage = 0,
      		nVx = 0,
		inputWlz = 0,
		testFlg = 0;
  WlzVertexP	vxp;
  WlzDVertex3	up,
  		nrm,
		pip;
  WlzObject	*outObj = NULL;
  WlzVertexType vtxType = WLZ_VERTEX_D3;
  WlzObjectType	outObjType = WLZ_NULL;
  WlzDomain	outDomain;
  WlzValues	outValues;
  WlzErrorNum	errNum = WLZ_ERR_NONE;
  WlzFitPlaneAlg alg = WLZ_FITPLANE_ALG_SVD;
  WlzFitPlaneOut out = WLZ_FITPLANE_OUT_SECTION;
  char		*inFileStr = NULL,
		*outFileStr = NULL;
  const char	*errMsg;
  static char	optList[] = "ahstTwA:o:u:",
		fileStrDef[] = "-";

  /* These vertices correspond to a plane in EMA27 with
   * fp=0,0,0, dist=123, pitch=123, yaw=45 which should give
   * the following text output:
   * -0.593865 -0.592398 0.544417 211.6 137.7 154.4 57.0152 224.929
   */
  const int	     testVxCount = 10;
  static WlzDVertex3 testVx[10] =
  {
    {181,62,39},
    {105,192,97},
    {281,185,282},
    {342,81,235},
    {118,139,54},
    {221,146,173},
    {312,147,274},
    {225,69,94},
    {190,148,142},
    {141,208,154}
  };

  opterr = 0;
  vxp.v = NULL;
  up.vtX = 0.0;
  up.vtY = 0.0;
  up.vtZ = 0.0;
  outDomain.core = NULL;
  outValues.core = NULL;
  inFileStr = fileStrDef;
  outFileStr = fileStrDef;
  while(ok && ((option = getopt(argc, argv, optList)) != -1))
  {
    switch(option)
    {
      case 'A':
	if(WlzStringMatchValue((int *)&alg, optarg,
			       "SVD",  WLZ_FITPLANE_ALG_SVD,
			       NULL) == 0)
	{
	  usage = 1;
	  ok = 0;
	}
        break;
      case 'a':
        out = WLZ_FITPLANE_OUT_AFFINE;
	break;
      case 'o':
        outFileStr = optarg;
	break;
      case 's':
        out = WLZ_FITPLANE_OUT_SECTION;
	break;
      case 't':
        out = WLZ_FITPLANE_OUT_TEXT;
	break;
      case 'T':
        testFlg = 1;
	break;
      case 'u':
        if(sscanf(optarg, "%lg,%lg,%lg", &(up.vtX), &(up.vtY), &(up.vtZ)) < 3)
	{
	  usage = 1;
	  ok = 0;
	}
	break;
      case 'w':
        inputWlz = 1;
	break;
      case 'h':
      default:
        usage = 1;
	ok = 0;
	break;
    }
  }
  if(ok && (optind < argc))
  {
    if((optind + 1) != argc)
    {
      usage = 1;
      ok = 0;
    }
    else
    {
      inFileStr = *(argv + optind);
    }
  }
  if(ok)
  {
    if(testFlg)
    {
      nVx = testVxCount;
      vxp.d3 = testVx;
    }
    else
    {
      FILE	*fP = NULL;

      if((*inFileStr == '\0') ||
	 ((fP = (strcmp(inFileStr, "-")?
		fopen(inFileStr, "r"): stdin)) == NULL))
      {
	ok = 0;
	errNum = WLZ_ERR_READ_EOF;
      }
      else
      {
        if(inputWlz)
	{
	  WlzObject *inObj = NULL;

	  if((inObj = WlzReadObj(fP, &errNum)) != NULL)
	  {
	    WlzVertexP inVxP;
	    WlzVertexType inVxType;

	    inVxP = WlzVerticesFromObj(inObj, NULL, &nVx, &inVxType, &errNum);
	    if(errNum == WLZ_ERR_NONE)
	    {
	      switch(inVxType)
	      {
	        case WLZ_VERTEX_I3: /* FALLTHROUGH */
		case WLZ_VERTEX_F3: /* FALLTHROUGH */
		case WLZ_VERTEX_D3:
		  vtxType = inVxType;
		  vxp.v = inVxP.v;
		  inVxP.v = NULL;
		  break;
	        default:
		  errNum = WLZ_ERR_OBJECT_TYPE;
		  break;
	      }
	      AlcFree(inVxP.v);
	    }
	    (void )WlzFreeObj(inObj);
	  }
	}
	else
	{
	  size_t nM = 0,
		 nN = 0;
	  double **inData = NULL;

	  if((AlcDouble2ReadAsci(fP, &inData, &nM, &nN) != ALC_ER_NONE) ||
	     (nM < 1) || (nN != 3))
	  {
	    ok = 0;
	    errNum = WLZ_ERR_PARAM_DATA;
	  }
	  (void )fclose(fP);
	  if(ok)
	  {
	    nVx = nM;
	    if((vxp.d3 = (WlzDVertex3 *)
			 AlcMalloc(nVx * sizeof(WlzDVertex3))) == NULL)
	    {
	      ok = 0;
	      errNum = WLZ_ERR_MEM_ALLOC;
	    }
	  }
	  if(ok)
	  {
	    int	idx;

	    for(idx = 0; idx < nVx; ++idx)
	    {
	      vxp.d3[idx].vtX = inData[idx][0];
	      vxp.d3[idx].vtY = inData[idx][1];
	      vxp.d3[idx].vtZ = inData[idx][2];
	    }
	  }
	  (void )AlcDouble2Free(inData);
	}
	if(strcmp(inFileStr, "-"))
	{
	  (void )fclose(fP);
	}
      }
      if(!ok)
      {
        (void )WlzStringFromErrorNum(errNum, &errMsg);
	(void )fprintf(stderr,
	               "%s: failed to input vertices from file %s (%s).\n",
		       *argv, inFileStr, errMsg);
      }
    }
  }
  if(ok)
  {
    switch(alg)
    {
      case WLZ_FITPLANE_ALG_SVD:
	errNum = WlzFitPlaneSVD(vtxType, nVx, vxp, &pip, &nrm);
	if(errNum == WLZ_ERR_NONE)
	{
	  outDomain.vs3d = Wlz3DViewStructFromNormal(nrm, pip, up, &errNum);
	}
	break;
      default:
	errNum = WLZ_ERR_PARAM_TYPE;
        break;
    }
    if(errNum == WLZ_ERR_NONE)
    {
      switch(out)
      {
        case WLZ_FITPLANE_OUT_AFFINE:
	  outObjType = WLZ_AFFINE_TRANS;
	  {
	    WlzAffineTransform *tr = NULL;

	    errNum = WlzInit3DViewStructAffineTransform(outDomain.vs3d);
	    if(errNum == WLZ_ERR_NONE)
	    {
	      tr = WlzAffineTransformCopy(outDomain.vs3d->trans, &errNum);
	      (void )WlzFree3DViewStruct(outDomain.vs3d);
	      outDomain.t = tr;
	    }
	  }
	  break;
        case WLZ_FITPLANE_OUT_SECTION:
	  outObjType = WLZ_3D_VIEW_STRUCT;
	  break;
	case WLZ_FITPLANE_OUT_TEXT:
	  outObjType = WLZ_NULL;
	  break;
        default:
	  errNum = WLZ_ERR_PARAM_TYPE;
	  break;
      }
    }
    if(errNum != WLZ_ERR_NONE)
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
      		     "%s: failed to compute best fit plane (%s).\n",
		     *argv, errMsg);
    }
  }
  if((testFlg == 0) && (vxp.v != NULL))
  {
    AlcFree(vxp.v);
  }
  if(ok && (outObjType != WLZ_NULL))
  {
    outObj = WlzMakeMain(outObjType, outDomain, outValues,
    		        NULL, NULL, &errNum);
    if(errNum != WLZ_ERR_NONE)
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
      		     "%s: failed to make output object (%s).\n",
		     *argv, errMsg);
    }
  }
  if(ok)
  {
    FILE	*fP = NULL;

    errNum = WLZ_ERR_WRITE_EOF;
    if((fP = (strcmp(outFileStr, "-")?
             fopen(outFileStr, "w"): stdout)) != NULL)
    {
      if(outObjType == WLZ_NULL)
      {
	double	theta,
		phi;

	theta = outDomain.vs3d->theta * 180.0 / ALG_M_PI;
	phi =   outDomain.vs3d->phi   * 180.0 / ALG_M_PI;
	while(theta < 0.0)
	{
	  theta += 360.0;
	}
	while(phi < 0.0)
	{
	  phi += 360.0;
	}

        if(fprintf(fP, "%g %g %g %g %g %g %g %g\n",
	           nrm.vtX, nrm.vtY, nrm.vtZ,
		   pip.vtX, pip.vtY, pip.vtZ,
		   phi,
		   theta) > 16)
        {
	  errNum = WLZ_ERR_NONE;
	}
      }
      else
      {
        errNum = WlzWriteObj(fP, outObj);
      }
    }
    if(errNum != WLZ_ERR_NONE)
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
      		     "%s: failed to write output object "
		     "to file %s (%s).\n",
		     *argv, outFileStr, errMsg);
    }
    if(fP && strcmp(outFileStr, "-"))
    {
      (void )fclose(fP);
    }
  }
  if(outObj)
  {
    WlzFreeObj(outObj);
  }
  if(usage)
  {
    (void )fprintf(stderr,
    "Usage: %s%s%s%s",
    *argv,
    " [-a] [-A <alg>] [-o <output file>] [-h]\n"
    "\t\t[-s] [-t] [-T] [-u<x>,<y>,<z>] [<input file>]\n"
    "Version: ",
    WlzVersion(),
    "\n"
    "Options:\n"
    "  -A  Force the algorithm selection, valid algorithms are:\n"
    "        SVD  Singular Value Decomposition based least squares\n"
    "             (the default).\n"
    "  -a  Output is an affine transform.\n"
    "  -h  Help, prints this usage message.\n"
    "  -o  Output file name.\n"
    "  -s  Output is a 3D view struct (default).\n"
    "  -t  Output is a text description of the plane.\n"
    "  -T  Use test data, probably only useful for debugging.\n"
    "  -u  Up vector, the default is (0, 0, 0) which implies that\n"
    "      the up vector is not explicitly set.\n"
    "  -w  Input is a Woolz object rather than ascii vertices.\n"
    "Calculates the best (least squares) plane through the given input\n"
    "vertices or object.\n"
    "Text output is of the form:\n"
    "  <nx> <ny> <nz> <cx> <cy> <cz> <pitch> <yaw>\n"
    "where these are the normal components, centroid location in the plane\n"
    "and the Euler angles (in degrees).\n"
    "The input vertices are read from an ascii file with the format:\n"
    "  <vtx x> <vtx y> <vtx z>\n"
    "The input data are read from stdin and the output object is written\n"
    "to stdout unless the filenames are given.\n");
  }
  return(!ok);
}
int main(int	argc,
	 char	**argv)
{

  FILE	       *inFile = NULL;   /* used to read Woolz object */ 
  FILE	       *outFile = NULL;   /* used to read Woolz object */
  int           i,j,k=0, m; /* , l1, label[3], individual[4] */
  int		option;
  int            TotalN; /* numChar, numChar1, */
  
  /* int           outputAutoMeshVTK        = 0,
                outputAutoMeshWLZ        = 0,
                outputTransformedMeshWLZ = 0,
    outputCutPlaneAndCorrepSurfaceVTK        = 0;
  */
    /*		WARP                     = 1 */
  /* int                  basisFnPolyOrder = 3; */
  int                  Inumber, num;
  int                  globalCycle;
  /* int                  binObjFlag; */
  int                  centorOfMass = 1;
  int                  numOf2DWlzFiles = 0, numOfSampleBibFiles = 0;
  /* int                  initialn0, endNum0,initialn1, endNum1; */
  int           BibFileIndex[50];
  /* double	zConst                   = 0.; */
  /* double        mass = 0.0; */
  /* char          under ='_'; */
  /* char                ctemp; */
  char                *inFileStr, *inFileStr1,  *outFileStr; /* *inFileStr3, */
  char                *inFileStrw, *outputBibFilesDir; /* , inFileStrSec[100]; */
  char                TwoDImageFilesNameList[1000][120];
  char                TwoDImagePureFilesNameList[1000][70];
  char                PureBibFilesNameList[700][70];
  char                SampleBibFilesNameList[100][120];
  char                SampleBibPureFilesName[100][70];
  char                SampleBibFilesDir[100];
  char                TwoDImageFilesDir[100];
  char                *List2DImageFilesStr, *SampleBibFilesStr;
  /* char                *cstr; */
  /* const char	      *errMsg; */
  /* WlzDVertex2          cMass, cMassS; */
  WlzErrorNum	       errNum = WLZ_ERR_NONE;
  /* WlzInterpolationType interp = WLZ_INTERPOLATION_NEAREST;  Use the nearest neighbour */
  WlzThreeDViewStruct *wlzViewStr, *wlzViewStr1, *wlzViewStrInter;
  /* AlcErrno             alcErr = ALC_ER_NONE; */
  WlzObject           *WObjS;/*, *WObj2DS, *WObj2D;*/ 
  /* WlzObjectType        wtp = WLZ_3D_DOMAINOBJ; */

  /* read the argument list and check for an input file */
  static char	optList[] = "i:I:f:w:o:d:z:M:m:n:r:R:L:B:h",

  opterr = 0;
 
   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':
	    SampleBibFilesStr = optarg;
	    break;
        case 'w':
	    inFileStrw = optarg;
	    break;
        case 'n':
	 if(sscanf(optarg, "%d", &num) != 1)
	    {
	      printf("read error");
	      exit(1);
	    }
	    break;
        case 'o':
	    outFileStr = optarg;
	    break;
        case 'd':
	    outputBibFilesDir = optarg;
	    break;
        default:
              return(0);
      }
   }


  /* 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];
         PureBibFilesNameList[m][j-k]       = TwoDImageFilesNameList[m][j];
       }
       TwoDImagePureFilesNameList[m][j-k] = (char ) NULL;
       PureBibFilesNameList[m][j-k]       = (char ) NULL;
       PureBibFilesNameList[m][j-k-3]     = 'b';
       PureBibFilesNameList[m][j-k-2]     = 'i';
       PureBibFilesNameList[m][j-k-1]     = 'b';
         
       /* 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]);   
    }

    /* changeToBibFileNamse */

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


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

    for(m=0; m<numOfSampleBibFiles; m++)
    {
       for(i=0; i<sizeof(SampleBibFilesNameList[m]); i++){
          if( SampleBibFilesNameList[m][i] == (char ) NULL )
           break; 
          if( SampleBibFilesNameList[m][i] == '/' )
            k = i; 	   
       }
       if(k != 0)
       k++;
       for(j=k; j<i; j++)
       {
         SampleBibPureFilesName[m][j-k] = SampleBibFilesNameList[m][j];
       }
        SampleBibPureFilesName[m][j-k] = (char ) NULL;
       /* extract directory */
       if(m == 0)
       {
          for(j=0; j<k; j++)
	  {
	     SampleBibFilesDir[j] = SampleBibFilesNameList[m][j];
	  }
	     SampleBibFilesDir[j] = (char) NULL;
	     printf("B_DIR  %s\n",SampleBibFilesDir);
       }

       printf("%s\n", SampleBibPureFilesName[m]);   
    }


    /*---------- extract the bib File number ----------- */
    for(i=0; i<numOfSampleBibFiles; i++)
    {
       BibFileIndex[i] = -1;
       for(m=0; m<numOf2DWlzFiles; m++)
       {
          /* printf("%s  %s\n", PureBibFilesNameList[m], SampleBibPureFilesName[i] ); */
          if(strcmp(PureBibFilesNameList[m], SampleBibPureFilesName[i] ) == 0)
          {
	     BibFileIndex[i] = m;
             break;
          }
       }

       printf("m = %d\n",BibFileIndex[i]);
     }


   centorOfMass = 0;
   if(centorOfMass)
   {
      /* 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;
    }
    /* read Section viewer parameters */
    
     centorOfMass = 1;

   if(centorOfMass)
   {
      wlzViewStr      = WlzMake3DViewStruct(WLZ_3D_VIEW_STRUCT, NULL);
      wlzViewStr1     = WlzMake3DViewStruct(WLZ_3D_VIEW_STRUCT, NULL);
      wlzViewStrInter = WlzMake3DViewStruct(WLZ_3D_VIEW_STRUCT, NULL);
   }
   /* interpolation */
 
   globalCycle = 0;
   while(globalCycle < numOfSampleBibFiles - 1)
   {
      printf("%d\n",globalCycle );
      errNum = ReadBibFile(inFile, SampleBibFilesNameList[globalCycle],   wlzViewStr  );
      errNum = ReadBibFile(inFile, SampleBibFilesNameList[globalCycle+1], wlzViewStr1 );
      errNum = ReadBibFile(inFile, SampleBibFilesNameList[globalCycle],   wlzViewStrInter  );
      TotalN = BibFileIndex[globalCycle+1] - BibFileIndex[globalCycle];


      /* cycle through between sample bib file */
      j = BibFileIndex[globalCycle] + 1;
      k = BibFileIndex[globalCycle+1];
      printf("NNNN:  %d %d\n",j,k );
      i=j;
      while ( i < k )
      {
          Inumber = i - BibFileIndex[globalCycle];
	  
	  /* linear interpolations */
	  errNum = LinearInterpolations(wlzViewStr, wlzViewStr1, wlzViewStrInter, Inumber, TotalN);

	  /* change the fixed point to (0 0 0)  */
          errNum = ChangeFixedPoint(wlzViewStrInter, 0., 0., 0.);
         
	  /* write Section viewer parameters */
	  printf("%s\n", PureBibFilesNameList[i]);
	  errNum = WriteBibFile(outFile, PureBibFilesNameList[i], inFileStrw,  TwoDImageFilesNameList[i], wlzViewStrInter);
	  i++;
      }
      globalCycle++;
   }

    /* Now cover the orginal input bib files with new  */
 
   globalCycle = 0;
   while(globalCycle < numOfSampleBibFiles)
   {
     i = BibFileIndex[globalCycle];
      errNum = ReadBibFile(inFile, SampleBibFilesNameList[globalCycle],   wlzViewStr  );
      errNum = ReadBibFile(inFile, SampleBibFilesNameList[globalCycle],   wlzViewStr1 );
      errNum = ReadBibFile(inFile, SampleBibFilesNameList[globalCycle],   wlzViewStrInter  );
      errNum = LinearInterpolations(wlzViewStr, wlzViewStr, wlzViewStrInter, 1, 1);
      /* change the fixed point to (0 0 0)  */
      errNum = ChangeFixedPoint(wlzViewStrInter, 0., 0., 0.);

      errNum = WriteBibFile(outFile, PureBibFilesNameList[i], inFileStrw,  TwoDImageFilesNameList[i], wlzViewStrInter);
      globalCycle++;
   } 

    /*  */
    centorOfMass = 0;

   if(centorOfMass)
   {
       WlzFreeObj(WObjS);
   }
   centorOfMass = 1;

   if(centorOfMass)
   {
       WlzFree3DViewStruct(wlzViewStr);
       WlzFree3DViewStruct(wlzViewStr1);
       WlzFree3DViewStruct(wlzViewStrInter);
   }  
     

  return ( 0 );
}
Exemple #7
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);
}
Exemple #8
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);
}
Exemple #9
0
int		main(int argc, char *argv[])
{
  int		ok,
		idx,
		option,
		nMsk = 0,
		nTr = 0,
		nPart = 1,
  		usage = 0;
  char		*inFileName,
		*outFileName,
  		*prjFileName,
		*secFileName;
  char		**mskFileNames = NULL,
  		**trFileNames = NULL;
  WlzObject	*inObj = NULL,
  		*outObj= NULL;
  WlzObject	**mskObjs = NULL,
  		**trObjs = NULL;
  WlzThreeDViewStruct *prjView = NULL,
  		*secView = NULL;
  WlzErrorNum	errNum = WLZ_ERR_NONE;
  const char	*errMsg;
  static char	optList[] = "ho:p:s:n:m:t:",
  		defFileName[] = "-";

  opterr = 0;
  inFileName = defFileName;
  outFileName = defFileName;
  prjFileName = defFileName;
  secFileName = defFileName;
  while((usage == 0) && ((option = getopt(argc, argv, optList)) != -1))
  {
    switch(option)
    {
      case 'o':
        outFileName = optarg;
	break;
      case 'p':
        prjFileName = optarg;
	break;
      case 's':
        secFileName = optarg;
	break;
      case 'n':
        if((sscanf(optarg, "%d\n", &nPart) != 1) || (nPart < 1))
	{
	  usage = 1;
	}
        break;
      case 'm':
	if((nMsk = WlzProjDomParseNameList(&mskFileNames, optarg, nPart)) < 1)
	{
	  usage = 1;
	}
        break;
      case 't':
	if((nTr = WlzProjDomParseNameList(&trFileNames, optarg, nPart)) < 1)
	{
	  usage = 1;
	}
        break;
      case 'h': /* FALLTHROUGH */
      default:
        usage = 1;
	break;
    }
  }
  if(nMsk != nTr)
  {
    usage = 0;
  }
  if((usage == 0) && (optind < argc))
  {
    if((optind + 1) != argc)
    {
      usage = 1;
    }
    else
    {
      inFileName = *(argv + optind);
    }
  }
  ok = (usage == 0);
  if(ok)
  {
    if(((prjView = WlzAssign3DViewStruct(
                   WlzProjDomReadViewFromNamedFile(prjFileName, &errNum),
	           NULL)) == NULL) ||
       ((secView = WlzAssign3DViewStruct(
                   WlzProjDomReadViewFromNamedFile(secFileName, &errNum),
	           NULL)) == NULL) ||
       ((inObj = WlzAssignObject(
                 WlzProjDomReadObjFromNamedFile(inFileName, &errNum),
		 NULL)) == NULL))
    {
      ok = 0;
    }
    if(ok)
    {
      if(((trObjs = (WlzObject **)
                    AlcCalloc(nPart, sizeof(WlzObject *))) == NULL) ||
         ((mskObjs = (WlzObject **)
                     AlcCalloc(nPart, sizeof(WlzObject *))) == NULL))
      {
        ok = 0;
      }
    }
    if(ok)
    {
      for(idx = 0; idx < nPart; ++idx)
      {
        if(strcmp(trFileNames[idx], "null"))
	{
	  if((trObjs[idx] = WlzAssignObject(
	               WlzProjDomReadObjFromNamedFile(trFileNames[idx],
		                                      &errNum), NULL)) == NULL)
	  {
	    ok = 0;
	    break;
	  }
	}
      }
    }
    if(ok)
    {
      for(idx = 0; idx < nPart; ++idx)
      {
        if(strcmp(mskFileNames[idx], "null"))
	{
	  if((mskObjs[idx] = WlzAssignObject(
	               WlzProjDomReadObjFromNamedFile(mskFileNames[idx],
		                                      &errNum), NULL)) == NULL)
	  {
	    ok = 0;
	    break;
	  }
	}
      }
    }
    if(ok == 0)
    {
      (void )fprintf(stderr,
                     "%s: Failed to read input view or object.\n",
		     *argv);
    }
  }
  AlcFree(trFileNames);
  AlcFree(mskFileNames);
  if(ok)
  {
    outObj = WlzProj3DToSection(inObj, nPart, mskObjs, prjView, nPart, trObjs,
                                secView, &errNum);
    if(errNum != WLZ_ERR_NONE)
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
      "%s: Failed to create projected section (%s).\n",
      *argv, errMsg);
    }
  }
  if(ok)
  {
    FILE 	*fP = NULL;

    errNum = WLZ_ERR_WRITE_EOF;
    if(((fP = (strcmp(outFileName, "-")?
              fopen(outFileName, "w"): stdout)) == NULL) ||
       ((errNum = WlzWriteObj(fP, outObj)) != WLZ_ERR_NONE))
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
                     "%s: Failed to write output object (%s).\n",
                     *argv, errMsg);
    }
    if(fP && strcmp(outFileName, "-"))
    {
      (void )fclose(fP);
    }
  }
  (void )WlzFree3DViewStruct(prjView);
  (void )WlzFree3DViewStruct(secView);
  (void )WlzFreeObj(inObj);
  (void )WlzFreeObj(outObj);
  if(trObjs)
  {
    for(idx = 0; idx < nPart; ++idx)
    {
      WlzFreeObj(trObjs[idx]);
    }
    AlcFree(trObjs);
  }
  if(mskObjs)
  {
    for(idx = 0; idx < nPart; ++idx)
    {
      WlzFreeObj(mskObjs[idx]);
    }
    AlcFree(mskObjs);
  }
  if(usage)
  {
    (void )fprintf(stderr,
    	"Usage: %s%s%s%s%s%s\n",
	*argv,
	" [-h] [-o<out object>] [-p<proj>] [-s[<sec>]\n"
	"        [-n#] [-m<mask1>[,<mask2>,...,<maskn>]]\n"
	"        [-t<tr1>[,<tr2>,...,<trn>]] <input object>\n"
	"Projects the given input 3D (spatial domain) object into a section,\n"
	"as used for EMAGE wholemount views.\n"
	"The input domain may be projected and transformed in parts to allow\n"
	"the separation of regions that may otherwise be obscured in a\n"
	"projected view.\n"
	"Options are:\n"
	"  -h    Help - prints this usage message\n"
	"  -o    Output file for the projected section view.\n"
	"  -p    Projection from the 3D space of the input object and mask\n"
	"        domains onto a plane. This must be defined by a bibfile (as\n"
	"        saved by MAPaint).\n"
	"  -s    Section transform which maps the plane back into a 3D space.\n"
	"        This must be defined by a bibfile (as saved by MAPaint).\n"
	"  -n    The number of parts to be used for the projection.\n"
	"        If the number of parts is one (which is the default) then\n"
	"        no mask is required. In this case the default in-plane\n"
	"        transform is the identity transform.\n"
	"  -m    Mask domains for each of the parts. If the mask is to cover\n"
	"        the whole of the input object's domain then the string\n"
	"        \"null\" (without the quotes) may be used.\n"
	"  -t    Transforms withing the plane for each part. If the identity\n"
	"        transform is required then the string \"null\" (without\n"
	"        the quotes) may be used.\n"
	"The list of masks and in-plane transforms should be comma separated\n"
	"and a missing string represents either the universal domain or an\n"
	"identity transform.\n"
	"Examples:\n",
	*argv,
	" -o out.wlz -p prj.bib -s sec.bib -n 2 \\\n"
	"        -m body-msk.wlz,tail-msk.wlz \\\n"
	"        -t body-tr.wlz,tail-tr.wlz domain.wlz\n"
	"The 3D domain in the file domain.wlz is masked using the 3D domains\n"
	"read from the files body-msk.wlz and tail-msk.wlz. The resulting\n"
	"domains are projected onto a plane using the projection defined in\n"
	"the bibfile  prj.bib. Each of these projected domains is then\n"
	"transformed independently using the transforms read from the files\n"
	"body-tr.wlz and tail-tr.wlz. The union of these transformed 2D\n"
	"domains is then made a section defined by the section transform\n"
	"read from the bibfile sec.bib.\n",
        *argv,
	" -o out.wlz -p prj.bib -s sec.bib domain.wlz\n"
	"The 3D domain in the file domain.wlz is projected onto a plane\n"
	"using the projecttion transform defined in the bibfile prj.bib\n"
	"this is then made a section defined by the section transform\n"
	"read from the bibfile sec.bib.\n");
  }
  exit(!ok);
}
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 );
}
Exemple #11
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;
}
/*! 
* \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;
}
/*! 
* \return       New object with the rojection.
* \ingroup      WlzTransform
* \brief        Use the view transform to define a projection from
*		3D to 2D and then project the object onto this plane.
*		The object supplied to this function must be a 3D
*		spatial domain object (WLZ_3D_DOMAINOBJ) with either
*		no values or for integration WLZ_GREY_UBYTE values.
*		Integration will assign each output pixel the sum of
*		all input voxels mapped via either the domain density
*		or the voxel density.
*		The integration is controled by the integrate parameter
*		with valid values:
*		WLZ_PROJECT_INT_MODE_NONE - a "shadow domain" without values
*               is computed,
*		WLZ_PROJECT_INT_MODE_DOMAIN - the voxels of the domain are
*		integrated using
*		\f[
		p = \frac{1}{255} n d
                \f]
*		WLZ_PROJECT_INT_MODE_VALUES - the voxel values are integrated
*		using
*		\f[
		p = \frac{1}{255} \sum{l\left[v\right]}.
		\f]
*		Where
*		  \f$p\f$ is the projected image value,
*		  \f$n\f$ is the number of voxels projected for \f$p\f$,
*		  \f$d\f$ is the density of domain voxels,
*		  \f$l\f$ is the voxel value density look up table and
*		  \f$v\f$ is a voxel value.
* \param	obj			The given object.
* \param	vStr			Given view structure defining the
* 					projection plane.
* \param	intMod			This may take three values:
* 					WLZ_PROJECT_INT_MODE_NONE,
* 					WLZ_PROJECT_INT_MODE_DOMAIN or
* 					WLZ_PROJECT_INT_MODE_VALUES.
* \param	denDom			Density of domain voxels this value
* 					is not used unless the integration
* 					mode is WLZ_PROJECT_INT_MODE_DOMAIN.
* \param	denVal			Density look up table for object
* 					voxel density values which must be
* 					an array of 256 values. This may be
* 					NULL if the integration mode is not
* 					WLZ_PROJECT_INT_MODE_VALUES.
* \param	depth			If greater than zero, the projection
* 					depth perpendicular to the viewing
* 					plane.
* \param	dstErr			Destination error pointer, may be NULL.
*/
WlzObject 	*WlzProjectObjToPlane(WlzObject *obj,
  				WlzThreeDViewStruct *vStr,
  				WlzProjectIntMode intMod,
				WlzUByte denDom, WlzUByte *denVal,
				double depth, WlzErrorNum *dstErr)
{
  int		nThr = 1,
		itvVal = 0;
  WlzIVertex2	prjSz;
  WlzIBox2	prjBox = {0};
  double	pln[4];
  WlzObject	*bufObj = NULL,
  		*prjObj = NULL;
  WlzThreeDViewStruct *vStr1 = NULL;
  double	**vMat = NULL;
  WlzValues	nullVal;
  WlzErrorNum	errNum = WLZ_ERR_NONE;
  WlzAffineTransform *rescaleTr = NULL;
  WlzGreyValueWSpace **gVWSp = NULL;
  void		***prjAry = NULL;
  const double	eps = 0.000001;
#ifdef WLZ_DEBUG_PROJECT3D_TIME
struct timeval	times[3];
#endif /* WLZ_DEBUG_PROJECT3D_TIME */

  nullVal.core = NULL;
  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;
  }
  else if(vStr == NULL)
  {
    errNum = WLZ_ERR_TRANSFORM_NULL;
  }
  else if((intMod == WLZ_PROJECT_INT_MODE_VALUES) &&
          (obj->values.core == NULL))
  {
    errNum = WLZ_ERR_VALUES_NULL;
  }
#ifdef WLZ_DEBUG_PROJECT3D_TIME
  gettimeofday(times + 0, NULL);
#endif /* WLZ_DEBUG_PROJECT3D_TIME */
  /* Create new view transform without voxel scaling. The voxel scaling
   * is done after the projection. */
  if(errNum == WLZ_ERR_NONE)
  {
    if((vStr1 = WlzMake3DViewStruct(WLZ_3D_VIEW_STRUCT, &errNum)) != NULL)
    {
      vStr1->fixed = vStr->fixed;
      vStr1->theta = vStr->theta;
      vStr1->phi = vStr->phi;
      vStr1->zeta = vStr->zeta;
      vStr1->dist = vStr->dist;
      vStr1->scale = vStr->scale;
      vStr1->voxelSize[0] = 1.0;
      vStr1->voxelSize[1] = 1.0;
      vStr1->voxelSize[2] = 1.0;
      vStr1->voxelRescaleFlg = 0;
      vStr1->interp = vStr->interp;
      vStr1->view_mode = vStr->view_mode;
      vStr1->up = vStr->up;
      vStr1->initialised = WLZ_3DVIEWSTRUCT_INIT_NONE;
      vMat = vStr1->trans->mat;
      errNum = WlzInit3DViewStructAffineTransform(vStr1);
      if(errNum == WLZ_ERR_NONE)
      {
        errNum = Wlz3DViewStructTransformBB(obj, vStr1);
      }
      if(errNum != WLZ_ERR_NONE)
      {
	WlzFree3DViewStruct(vStr1);
	vStr1 = NULL;
      }
    }
  }
  /* Compute bounding box of the projection. */
  if(errNum == WLZ_ERR_NONE)
  {
    prjBox.xMin = WLZ_NINT(vStr1->minvals.vtX);
    prjBox.yMin = WLZ_NINT(vStr1->minvals.vtY);
    prjBox.xMax = WLZ_NINT(vStr1->maxvals.vtX);
    prjBox.yMax = WLZ_NINT(vStr1->maxvals.vtY);
    prjSz.vtX = prjBox.xMax - prjBox.xMin + 1;
    prjSz.vtY = prjBox.yMax - prjBox.yMin + 1;
  }
  /* Compute post projection scaling. */
  if((errNum == WLZ_ERR_NONE) && (vStr->voxelRescaleFlg != 0))
  {
    WlzIBox2	sBox;
    WlzIVertex2 sSz;
    WlzThreeDViewStruct *vStr2;

    vStr2 = WlzMake3DViewStruct(WLZ_3D_VIEW_STRUCT, &errNum);
    if(errNum == WLZ_ERR_NONE)
    {
      vStr2->fixed = vStr->fixed;
      vStr2->theta = vStr->theta;
      vStr2->phi = vStr->phi;
      vStr2->zeta = vStr->zeta;
      vStr2->dist = vStr->dist;
      vStr2->scale = vStr->scale;
      vStr2->voxelSize[0] = vStr->voxelSize[0];
      vStr2->voxelSize[1] = vStr->voxelSize[1];
      vStr2->voxelSize[2] = vStr->voxelSize[2];
      vStr2->voxelRescaleFlg = vStr->voxelRescaleFlg;
      vStr2->interp = vStr->interp;
      vStr2->view_mode = vStr->view_mode;
      vStr2->up = vStr->up;
      vStr2->initialised = WLZ_3DVIEWSTRUCT_INIT_NONE;
      errNum = WlzInit3DViewStructAffineTransform(vStr2);
      if(errNum == WLZ_ERR_NONE)
      {
        errNum = Wlz3DViewStructTransformBB(obj, vStr2);
      }
      if(errNum == WLZ_ERR_NONE)
      {
	sBox.xMin = WLZ_NINT(vStr2->minvals.vtX);
	sBox.yMin = WLZ_NINT(vStr2->minvals.vtY);
	sBox.xMax = WLZ_NINT(vStr2->maxvals.vtX);
	sBox.yMax = WLZ_NINT(vStr2->maxvals.vtY);
	sSz.vtX = sBox.xMax - sBox.xMin + 1;
	sSz.vtY = sBox.yMax - sBox.yMin + 1;
        rescaleTr = WlzMakeAffineTransform(WLZ_TRANSFORM_2D_AFFINE, &errNum);
      }
      if(errNum == WLZ_ERR_NONE)
      {
        double	**m;

	m = rescaleTr->mat;
	m[0][0] = (sSz.vtX * eps) / (prjSz.vtX * eps);
	m[1][1] = (sSz.vtY * eps) / (prjSz.vtY * eps);
	m[0][2] = sBox.xMin - WLZ_NINT(m[0][0] * prjBox.xMin);
	m[1][2] = sBox.yMin - WLZ_NINT(m[1][1] * prjBox.yMin);
      }
      (void )WlzFree3DViewStruct(vStr2);
    }
  }
  /* Compute plane equation, used to clip intervals if depth was given. */
  if((errNum == WLZ_ERR_NONE) && (depth > eps))
  {
    Wlz3DViewGetPlaneEqn(vStr1, pln + 0, pln + 1, pln + 2, pln + 3);
  }
  /* Create rectangular projection array buffers, one for each thread,
   * also if integrating values create a grey value workspace per thread. */
  if(errNum == WLZ_ERR_NONE)
  {
    int		idB;

#ifdef _OPENMP
#pragma omp parallel
    {
#pragma omp master
      {
        nThr = omp_get_num_threads();
      }
    }
#endif
    if((prjAry = (void ***)AlcCalloc(nThr, sizeof(void **))) == NULL)
    {
      errNum = WLZ_ERR_MEM_ALLOC;
    }
    else
    {
      if(intMod == WLZ_PROJECT_INT_MODE_NONE)
      {
	for(idB = 0; idB < nThr; ++idB)
	{
	  if(AlcUnchar2Calloc((WlzUByte ***)&(prjAry[idB]),
			      prjSz.vtY, prjSz.vtX) != ALC_ER_NONE)
	  {
	    errNum = WLZ_ERR_MEM_ALLOC;
	    break;
	  }
	}
      }
      else
      {
	for(idB = 0; idB < nThr; ++idB)
	{
	  if(AlcInt2Calloc((int ***)&(prjAry[idB]),
			   prjSz.vtY, prjSz.vtX) != ALC_ER_NONE)
	  {
	    errNum = WLZ_ERR_MEM_ALLOC;
	    break;
	  }
	}
      }
    }
    if((errNum == WLZ_ERR_NONE) &&
       (intMod == WLZ_PROJECT_INT_MODE_VALUES))
    {
      itvVal = (WlzGreyTableIsTiled(obj->values.core->type) == 0);
      if(itvVal == 0)
      {
	if((gVWSp = AlcCalloc(nThr, sizeof(WlzGreyValueWSpace *))) == NULL)
	{
	  errNum = WLZ_ERR_MEM_ALLOC;
	}
	else
	{
	  for(idB = 0; idB < nThr; ++idB) 
	  {
	    gVWSp[idB] = WlzGreyValueMakeWSp(obj, &errNum);
	    if(gVWSp[idB]->gType != WLZ_GREY_UBYTE)
	    {
	      errNum = WLZ_ERR_GREY_TYPE;
	      break;
	    }
	  }
	}
      }
    }
  }
  /* Scan through the 3D domain setting value in the projection array. */
  if(errNum == WLZ_ERR_NONE)
  {
    int		pIdx,
    		pCnt;
    WlzDomain	*doms;
    WlzValues	*vals = NULL;

    doms = obj->domain.p->domains;
    if(itvVal)
    {
      vals = obj->values.vox->values;
    }
    pCnt = obj->domain.p->lastpl - obj->domain.p->plane1 + 1;
#ifdef _OPENMP
#pragma omp parallel for
#endif
    for(pIdx =  0; pIdx < pCnt; ++pIdx)
    {
      int	thrId = 0;

      if((errNum == WLZ_ERR_NONE) && (doms[pIdx].core != NULL))
      {
	WlzObject   *obj2;
	WlzGreyWSpace gWSp;
	WlzIntervalWSpace iWSp;
	WlzErrorNum errNum2 = WLZ_ERR_NONE;

#ifdef _OPENMP
	thrId = omp_get_thread_num();
#endif
        obj2 = WlzMakeMain(WLZ_2D_DOMAINOBJ, doms[pIdx],
	                   (vals)? vals[pIdx]: nullVal,
	                   NULL, NULL, &errNum2);
        if(errNum2 == WLZ_ERR_NONE)
	{
	  if(itvVal)
	  {
	    errNum2 = WlzInitGreyScan(obj2, &iWSp, &gWSp);
	  }
	  else
	  {
	    errNum2 = WlzInitRasterScan(obj2, &iWSp, WLZ_RASTERDIR_ILIC);
	  }
	}
        if(errNum2 == WLZ_ERR_NONE)
	{
	  double      plnZ,
	  	      vMZX,
	  	      vMZY;
	  WlzIVertex3 p0,
	    	      p1;

	  p0.vtZ = p1.vtZ = obj->domain.p->plane1 + pIdx;
	  vMZX = (vMat[0][2] * p0.vtZ) + vMat[0][3] - prjBox.xMin;
	  vMZY = (vMat[1][2] * p0.vtZ) + vMat[1][3] - prjBox.yMin;
	  plnZ = (pln[2] * p0.vtZ) + pln[3];
	  while(((itvVal == 0) &&
	        ((errNum2 = WlzNextInterval(&iWSp)) == WLZ_ERR_NONE)) ||
	        ((itvVal != 0) &&
	        ((errNum2 = WlzNextGreyInterval(&iWSp)) == WLZ_ERR_NONE)))
	  {
	    int		skip = 0;
	    WlzDVertex2 q0,
	    		q1;

            p0.vtX = iWSp.lftpos;
	    p1.vtX = iWSp.rgtpos;
	    p0.vtY = p1.vtY = iWSp.linpos;
	    if(depth > eps)
	    {
	      int	c;
	      double	d0,
	      		d1,
			plnYZ;

	      /* Clip the 3D line segment p0,p1 using the plane equation. */
	      plnYZ = (pln[1] * p0.vtY) + plnZ;
	      d0 = (pln[0] * p0.vtX) + plnYZ;
	      d1 = (pln[0] * p1.vtX) + plnYZ;
	      c = ((d1 >  depth) << 3) | ((d0 >  depth) << 2) |
		  ((d1 < -depth) << 1) |  (d0 < -depth);
	      if(c)
	      {
		if((c == 3) || (c == 12)) /* 00-- or ++00 */
		{
		  /* Both out of range, so don't render. */
		  skip = 1;
		}
		else
		{
		  if(fabs(pln[0]) > eps)
		  {
		    double	plnX;

		    plnX = -1.0 / pln[0];
		    if((c &  1) != 0)      /* x0x- */
		    {
		      p0.vtX = plnX * (plnYZ + depth);
		    }
		    else if((c &  4) != 0) /* x+x0 */
		    {
		      p0.vtX = plnX * (plnYZ - depth);
		    }
		    if((c &  2) != 0)      /* 0x-x */
		    {
		      p1.vtX = plnX * (plnYZ + depth);
		    }
		    else if((c &  8) != 0) /* +x0x */
		    {
		      p1.vtX = plnX * (plnYZ - depth);
		    }
		  }
		}
	      }
	    }
	    if(skip == 0)
	    {
	      q0.vtX = (vMat[0][0] * p0.vtX) + (vMat[0][1] * p0.vtY) + vMZX;
	      q0.vtY = (vMat[1][0] * p0.vtX) + (vMat[1][1] * p0.vtY) + vMZY;
	      q1.vtX = (vMat[0][0] * p1.vtX) + (vMat[0][1] * p1.vtY) + vMZX;
	      q1.vtY = (vMat[1][0] * p1.vtX) + (vMat[1][1] * p1.vtY) + vMZY;
	      switch(intMod)
	      {
		case WLZ_PROJECT_INT_MODE_NONE:
		  {
		    WlzIVertex2 u0,
				u1;

		    WLZ_VTX_2_NINT(u0, q0);
		    WLZ_VTX_2_NINT(u1, q1);
		    WlzProjectObjLine((WlzUByte **)(prjAry[thrId]), u0, u1);
		  }
		  break;
		case WLZ_PROJECT_INT_MODE_DOMAIN:
		  {
		    int	        np,
				nq;
		    WlzDVertex3 dq;
		    WlzIVertex2 u0,
				u1;

		    WLZ_VTX_2_NINT(u0, q0);
		    WLZ_VTX_2_NINT(u1, q1);
		    WLZ_VTX_2_SUB(dq, q0, q1);
		    np = denDom * (iWSp.rgtpos - iWSp.lftpos + 1);
		    nq = (int )ceil(WLZ_VTX_2_LENGTH(dq) + eps);
		    WlzProjectObjLineDom((int **)(prjAry[thrId]), np / nq,
					 u0, u1);
		  }
		  break;
		case WLZ_PROJECT_INT_MODE_VALUES:
		  if(itvVal)
		  {
		    WlzProjectObjLineVal((int **)(prjAry[thrId]), denVal,
					 gWSp.u_grintptr.ubp, NULL,
					 vMat, vMZX, vMZY, p0, p1);
		  }
		  else
		  {
		    WlzProjectObjLineVal((int **)(prjAry[thrId]), denVal,
					 NULL, gVWSp[thrId],
					 vMat, vMZX, vMZY, p0, p1);
		  }
		  break;
	      }
	    }
	  }
	  (void )WlzEndGreyScan(&iWSp, &gWSp);
	  if(errNum2 == WLZ_ERR_EOO)
	  {
	    errNum2 = WLZ_ERR_NONE;
	  }
	}
	(void )WlzFreeObj(obj2);
	if(errNum2 != WLZ_ERR_NONE)
	{
#ifdef _OPENMP
#pragma omp critical
	  {
#endif
	    if(errNum == WLZ_ERR_NONE)
	    {
	      errNum = errNum2;
	    }
#ifdef _OPENMP
	  }
#endif
	}
      }
    }
  }
  /* Free grey value workspaces if they were created. */
  if(gVWSp)
  {
    int		idB;

    for(idB = 0; idB < nThr; ++idB) 
    {
      WlzGreyValueFreeWSp(gVWSp[idB]);
    }
    AlcFree(gVWSp);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    int		idB;
    size_t	idC,
    		bufSz;
    WlzGreyP	buf0,
      		buf1;
    WlzIVertex2	prjOrg;

    prjOrg.vtX = prjBox.xMin;
    prjOrg.vtY = prjBox.yMin;
    bufSz = prjSz.vtX * prjSz.vtY;
    for(idB = 1; idB < nThr; ++idB)
    {
      if(intMod == WLZ_PROJECT_INT_MODE_NONE)
      {
        buf0.ubp = ((WlzUByte ***)(prjAry))[0][0],
	buf1.ubp = ((WlzUByte ***)(prjAry))[idB][0];
	for(idC = 0; idC < bufSz; ++idC)
	{
	  buf0.ubp[idC] += buf1.ubp[idC];
	}
      }
      else
      {
        buf0.inp = ((int ***)(prjAry))[0][0],
	buf1.inp = ((int ***)(prjAry))[idB][0];
	for(idC = 0; idC < bufSz; ++idC)
	{
	  buf0.inp[idC] += buf1.inp[idC];
	}
      }
    }
    switch(intMod != WLZ_PROJECT_INT_MODE_NONE)
    {
      buf0.inp = ((int ***)(prjAry))[0][0];
      for(idC = 0; idC < bufSz; ++idC)
      {
	buf0.inp[idC] /= 256;
      }
    }
    if(intMod == WLZ_PROJECT_INT_MODE_NONE)
    {
      bufObj = WlzAssignObject(
	       WlzFromArray2D((void **)(prjAry[0]), prjSz, prjOrg,
			      WLZ_GREY_UBYTE, WLZ_GREY_UBYTE,
			      0.0, 1.0, 1, 0, &errNum), NULL);
    }
    else
    {
      bufObj = WlzAssignObject(
	       WlzFromArray2D((void **)(prjAry[0]), prjSz, prjOrg,
			      WLZ_GREY_INT, WLZ_GREY_INT,
			      0.0, 1.0, 1, 0, &errNum), NULL);
    }
  }
  /* Free the projection array(s). */
  if(prjAry)
  {
    int		idB;

    for(idB = 0; idB < nThr; ++idB)
    {
      (void )Alc2Free((prjAry[idB]));
    }
    AlcFree(prjAry);
  }
  /* Make return object using threshold. */
  if(errNum == WLZ_ERR_NONE)
  {
    WlzPixelV	tV;
    WlzObject	*tObj = NULL;

    tV.type = WLZ_GREY_UBYTE;
    tV.v.ubv = 1;
    tObj = WlzAssignObject(
	   WlzThreshold(bufObj, tV, WLZ_THRESH_HIGH, &errNum), NULL);
    if(tObj)
    {
      if(intMod == WLZ_PROJECT_INT_MODE_NONE)
      {
	prjObj = WlzMakeMain(tObj->type, tObj->domain, nullVal,
			     NULL, NULL, &errNum);
      }
      else
      {
	prjObj = WlzMakeMain(tObj->type, tObj->domain, tObj->values,
			     NULL, NULL, &errNum);
      }
    }
    (void )WlzFreeObj(tObj);
  }
  (void )WlzFreeObj(bufObj);
  (void )WlzFree3DViewStruct(vStr1);
  /* Scale image. */
  if(rescaleTr != NULL)
  {
    if(errNum == WLZ_ERR_NONE)
    {
      WlzObject	*tObj = NULL;

      tObj = WlzAffineTransformObj(prjObj, rescaleTr, 
				   WLZ_INTERPOLATION_NEAREST, &errNum);
      
      (void )WlzFreeObj(prjObj);
      prjObj = tObj;
    }
    (void )WlzFreeAffineTransform(rescaleTr);
  }
#ifdef WLZ_DEBUG_PROJECT3D_TIME
  gettimeofday(times + 1, NULL);
  ALC_TIMERSUB(times + 1, times + 0, times + 2);
  (void )fprintf(stderr, "WlzGetProjectionFromObject: Elapsed time = %g\n",
                 times[2].tv_sec + (0.000001 * times[2].tv_usec));
#endif /* WLZ_DEBUG_PROJECT3D_TIME */
  if(dstErr)
  {
    *dstErr = errNum;
  }
  return(prjObj);
}
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);
}