/*! * - Function: outputTheWarpedWlz * - Returns: WlzVetex * - Purpose: Track vertex through neighbour layer. * - Parameters: * * -# vsp: input WlzVertex. * -# vtp: input WlzVertex. * -# wlzViewStri: WlzThreeDViewStruct for layer i; * -# wlzViewStrip1: WlzThreeDViewStruct for the next layer i+-1; * -# UpOrDown: > 0 Up; <= 0 down; * - Author: J. Rao, R. Baldock */ static WlzErrorNum outputTheWarpedWlz( WlzVertex vsp, WlzVertex vtp, WlzVertex vfp, WlzDVertex2 *vtxVec1, char *souce2DWlzStr, char *out2DWlzStr ) { WlzAffineTransform *trans=NULL; WlzTransformType tType = WLZ_TRANSFORM_2D_AFFINE; WlzDVertex2 *vtxVec0; WlzDVertex2 sv, tv; WlzObject *sObj=NULL, *tObj=NULL; FILE *inFile; WlzErrorNum errNum = WLZ_ERR_NONE; WlzInterpolationType interp = WLZ_INTERPOLATION_LINEAR; /* Use the nearest neighbour */ /*------- allocate memory --------*/ if ( ((vtxVec0 = (WlzDVertex2 *)AlcCalloc(sizeof(WlzDVertex2), 3)) == NULL) ) { errNum = WLZ_ERR_MEM_ALLOC; } if( errNum == WLZ_ERR_NONE ) { (vtxVec0)->vtX = vsp.d3.vtX; (vtxVec0)->vtY = vsp.d3.vtY; (vtxVec0 + 1)->vtX = vtp.d3.vtX; (vtxVec0 + 1)->vtY = vtp.d3.vtY; (vtxVec0 + 2)->vtX = vfp.d3.vtX; (vtxVec0 + 2)->vtY = vfp.d3.vtY; trans = WlzAffineTransformLSq2D(3, vtxVec1, 3, vtxVec0, 0, NULL, tType, &errNum); /* trans = WlzAffineTransformLSq2D(3, vtxVec0, 3, vtxVec1, 0, NULL, tType, &errNum); */ } if( errNum == WLZ_ERR_NONE ) { /* check whether it is right or not */ sv.vtX = (vtxVec0)->vtX; sv.vtY = (vtxVec0)->vtY; printf("compare\n"); printf("first one\n"); printf("source: %lg %lg\n", sv.vtX, sv.vtY ); tv = WlzAffineTransformVertexD2(trans, sv, &errNum); printf("target: %lg %lg\n", (vtxVec1)->vtX, (vtxVec1)->vtY ); printf("source trans to target : %lg %lg\n", tv.vtX, tv.vtY); sv.vtX = (vtxVec0 + 1)->vtX; sv.vtY = (vtxVec0 + 1)->vtY; printf("second one\n"); printf("source: %lg %lg\n", sv.vtX, sv.vtY ); tv = WlzAffineTransformVertexD2(trans, sv, &errNum); printf("target: %lg %lg\n", (vtxVec1 + 1)->vtX, (vtxVec1 + 1)->vtY ); printf("source trans to target : %lg %lg\n", tv.vtX, tv.vtY); sv.vtX = (vtxVec0 + 2)->vtX; sv.vtY = (vtxVec0 + 2)->vtY; printf("third one\n"); printf("source: %lg %lg\n", sv.vtX, sv.vtY ); tv = WlzAffineTransformVertexD2(trans, sv, &errNum); printf("target: %lg %lg\n", (vtxVec1 + 2)->vtX, (vtxVec1 + 2)->vtY ); printf("source trans to target : %lg %lg\n", tv.vtX, tv.vtY); } if( errNum == WLZ_ERR_NONE ) { /* read Woolz object */ if((inFile = fopen(souce2DWlzStr, "r")) == NULL ) { printf("cannot open the input woolz file.\n"); exit(1); } if( !( sObj = WlzReadObj(inFile, &errNum) ) ) { printf("input Woolz Object Error.\n"); fclose(inFile); exit(1); } fclose(inFile); inFile = NULL; } if( errNum == WLZ_ERR_NONE ) { tObj = WlzAffineTransformObj(sObj, trans, interp, &errNum ); } if( errNum == WLZ_ERR_NONE ) { /* write Woolz object */ if((inFile = fopen(out2DWlzStr, "w")) == NULL ) { printf("cannot open the output woolz file.\n"); exit(1); } errNum = WlzWriteObj(inFile, tObj); if( errNum != WLZ_ERR_NONE ) { printf("input Woolz Object Error.\n"); fclose(inFile); exit(1); } fclose(inFile); inFile = NULL; } WlzFreeObj(sObj); WlzFreeObj(tObj); AlcFree(vtxVec0 ); AlcFree(trans); return errNum; }
/*! * \return New BasisFn transform. * \ingroup WlzTransform * \brief Computes a basis function transform for the given object and a * set of control points using both an affine and a basis * function transform. * \param obj Given object. * \param basisFnType Required basis function type. * \param polyOrder Order of polynomial, only used for * WLZ_FN_BASIS_2DPOLY. * \param nSPts Number of source control points. * \param sPts Source control points. * \param nDPts Number of destination control points. * \param dPts Destination control points. * \param dstErr Destination error pointer, may be * NULL. */ static WlzBasisFnTransform *WlzAffineBasisFnTransformFromCPtsT(WlzObject *obj, WlzFnType basisFnType, int polyOrder, int nSPts, WlzDVertex2 *sPts, int nDPts, WlzDVertex2 *dPts, WlzErrorNum *dstErr) { int idx; WlzDVertex2 *dPtsT = NULL; WlzAffineTransform *aTr = NULL, *aTrI = NULL; WlzBasisFnTransform *bTr = NULL; WlzErrorNum errNum = WLZ_ERR_NONE; if(obj == NULL) { errNum = WLZ_ERR_OBJECT_NULL; } else if((nDPts <= 0) || (nDPts != nSPts)) { errNum = WLZ_ERR_PARAM_DATA; } else if((dPts == NULL) || (sPts == NULL)) { errNum = WLZ_ERR_PARAM_NULL; } /* Compute least squares affine transform from the tie points. */ if(errNum == WLZ_ERR_NONE) { aTr = WlzAffineTransformLSq2D(nSPts, sPts, nSPts, dPts, 0, NULL, WLZ_TRANSFORM_2D_AFFINE, &errNum); } if(errNum == WLZ_ERR_NONE) { if(nSPts >= 4) { /* Create a new array of destination vertices which have the original * destination transformed by the inverse affine transform. */ if((dPtsT = (WlzDVertex2 *)AlcMalloc(sizeof(WlzDVertex2) * nSPts)) == NULL) { errNum = WLZ_ERR_MEM_ALLOC; } if(errNum == WLZ_ERR_NONE) { aTrI = WlzAffineTransformInverse(aTr, &errNum); } if(errNum == WLZ_ERR_NONE) { for(idx = 0; idx < nDPts; ++idx) { dPtsT[idx] = WlzAffineTransformVertexD2(aTrI, dPts[idx], NULL); } bTr = WlzBasisFnTrFromCPts2D(basisFnType, polyOrder, nSPts, sPts, nSPts, dPtsT, NULL, &errNum); } } } AlcFree(dPtsT); (void )WlzFreeAffineTransform(aTr); (void )WlzFreeAffineTransform(aTrI); if(errNum != WLZ_ERR_NONE) { (void )WlzBasisFnFreeTransform(bTr); } if(dstErr) { *dstErr = errNum; } return(bTr); }
void MAPaintTabletInit( ThreeDViewStruct *view_struct) { TabletEvent event; int quitFlag; Widget dialog; XmString text, title; WlzDVertex2 tabVtxs[2], wlzVtxs[2]; Widget slider; WlzAffineTransform *trans; /* ignore if already open */ if( tablet ){ return; } /* open the tablet */ if( (tablet = TabletOpen(WACOM_IV_TABLET_TYPE, "/dev/term/b", NULL)) == NULL ){ HGU_XmUserError(globals.topl, "Open Wacom Tablet:\n" " Failed to open the tablet, please check\n" " the tablet is connected to serial line b\n" " and switched on, then try again.", XmDIALOG_FULL_APPLICATION_MODAL); return; } /* set tilt mode and start the tablet */ TabletSetMode(tablet, TABLET_TILTMODE_MASK); tablet->cntrlMode2 |= TABLET_CORRECT_TILT_MASK; tablet->cntrlMode2 |= TABLET_TRANSFORM_MASK; TabletStart(tablet); /* if the tablet needs the coordinates set then do so here */ if( !view_struct->tablet_initialised ){ /* get first coordinate */ /* put up an application modal dialog to request first coordinate */ dialog = XmCreateMessageDialog(view_struct->canvas, "MAPaint Message", NULL, 0); XtUnmanageChild(XmMessageBoxGetChild(dialog, XmDIALOG_CANCEL_BUTTON)); XtUnmanageChild(XmMessageBoxGetChild(dialog, XmDIALOG_OK_BUTTON)); XtSetSensitive(XmMessageBoxGetChild(dialog, XmDIALOG_HELP_BUTTON), False); text = XmStringCreateLtoR("Input tablet reference point 1 please", XmSTRING_DEFAULT_CHARSET); title = XmStringCreateSimple("MAPaint Tablet Message"); XtVaSetValues(dialog, XmNmessageString, text, XmNdialogTitle, title, XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL, NULL); XmStringFree( text ); XmStringFree( title ); /* popup widget and process events */ XtManageChild( dialog ); XSync(XtDisplay(view_struct->canvas), False); quitFlag = 0; while( quitFlag < 100 ){ if((XtAppPending(globals.app_con) > 0) ){ XtAppProcessEvent(globals.app_con, XtIMAll); } else { XSync(XtDisplay(view_struct->canvas), False); usleep(1000); quitFlag++; } } quitFlag = 0; while( !quitFlag ){ if( TabletNextEvent(tablet, &event) == TABLET_ERR_NONE ){ if(event.buttonPressed && ((event.buttons == 1) || (event.buttons == 3))){ tabVtxs[0].vtX = event.x; tabVtxs[0].vtY = event.y; quitFlag = 1; XBell(XtDisplay(view_struct->canvas), 100); XFlush(XtDisplay(view_struct->canvas)); } } else { TabletClose(tablet); tablet = NULL; XtDestroyWidget(dialog); return; } } /* get second coordinate */ text = XmStringCreateLtoR("Input tablet reference point 2 please", XmSTRING_DEFAULT_CHARSET); XtVaSetValues(dialog, XmNmessageString, text, NULL); XmStringFree( text ); /* popup widget and process events */ XtManageChild( dialog ); XSync(XtDisplay(view_struct->canvas), False); while( (XtAppPending(globals.app_con) > 0) ){ XtAppProcessEvent(globals.app_con, XtIMAll); XSync(XtDisplay(view_struct->canvas), False); } quitFlag = 0; sleep(1); TabletClearEvents(tablet); while( !quitFlag ){ if( TabletNextEvent(tablet, &event) == TABLET_ERR_NONE ){ if(event.buttonPressed && ((event.buttons == 1) || (event.buttons == 3))){ tabVtxs[1].vtX = event.x; tabVtxs[1].vtY = event.y; quitFlag = 1; XBell(XtDisplay(view_struct->canvas), 100); XFlush(XtDisplay(view_struct->canvas)); } } else { TabletClose(tablet); XtDestroyWidget(dialog); tablet = NULL; return; } } TabletStop(tablet); XtDestroyWidget(dialog); usleep(10000); TabletClearEvents(tablet); /* set the reference coordinates */ view_struct->ref1.vtX = tabVtxs[0].vtX; view_struct->ref1.vtY = tabVtxs[0].vtY; view_struct->ref2.vtX = tabVtxs[1].vtX; view_struct->ref2.vtY = tabVtxs[1].vtY; } else { tabVtxs[0].vtX = view_struct->ref1.vtX; tabVtxs[0].vtY = view_struct->ref1.vtY; tabVtxs[1].vtX = view_struct->ref2.vtX; tabVtxs[1].vtY = view_struct->ref2.vtY; } /* set tablet transform parameters */ if((slider = XtNameToWidget(tablet_controls, "*.x1")) ) { wlzVtxs[0].vtX = HGU_XmGetSliderValue(slider); } if((slider = XtNameToWidget(tablet_controls, "*.y1")) ) { wlzVtxs[0].vtY = HGU_XmGetSliderValue(slider); } if((slider = XtNameToWidget(tablet_controls, "*.x2")) ) { wlzVtxs[1].vtX = HGU_XmGetSliderValue(slider); } if( (slider = XtNameToWidget(tablet_controls, "*.y2"))) { wlzVtxs[1].vtY = HGU_XmGetSliderValue(slider); } trans = WlzAffineTransformLSq2D(2, tabVtxs, 2, wlzVtxs, 0, NULL, WLZ_TRANSFORM_2D_NOSHEAR, NULL); tablet->xTrans[0] = trans->mat[0][0]; tablet->xTrans[1] = trans->mat[0][1]; tablet->xTrans[2] = trans->mat[0][2]; tablet->yTrans[0] = trans->mat[1][0]; tablet->yTrans[1] = trans->mat[1][1]; tablet->yTrans[2] = trans->mat[1][2]; WlzFreeAffineTransform(trans); view_struct->tablet_initialised = 1; /* initialise the globals */ modifiers = 0; tabletDrawingFlag = 0; quitDrawingTrigger = 0; if( tabletPoly ){ WlzFreePolyDmn(tabletPoly); tabletPoly = NULL; } /* now add the tablet stream as an event input source */ TabletStart(tablet); TabletClearEvents(tablet); tabletInputId = XtAppAddInput(globals.app_con, tablet->fd, (XtPointer) XtInputReadMask, tabletInputProc, (XtPointer) view_struct); return; }