/*! * \return New vertex array. * \brief Reads an array of vertices (2D or 3D) from the given file. * \param fP File pointer. * \param dim Dimension which MUST be either 2 or 3. * \param dstNVtx Destination pointer for the number of * vertices read, MUST not be NULL. * \param dstErr Used to return Woolz error code, * MUST not be NULL. */ static WlzVertexP WlzCFPReadVtxArray(FILE *fP, int dim, int *dstNVtx, WlzErrorNum *dstErr) { int datCnt = 0, datMax = 0; char lnBuf[WLZ_CFP_READLN_LEN]; WlzVertex datV; WlzVertexP datVP; WlzErrorNum errNum = WLZ_ERR_NONE; datVP.v = NULL; while((errNum == WLZ_ERR_NONE) && (fgets(lnBuf, WLZ_CFP_READLN_LEN, fP) != NULL)) { lnBuf[WLZ_CFP_READLN_LEN - 1] = '\0'; switch(dim) { case 2: errNum = WLZ_ERR_UNIMPLEMENTED; break; case 3: if(sscanf(lnBuf, "%lg %lg %lg", &(datV.d3.vtX), &(datV.d3.vtY), &(datV.d3.vtZ)) != 3) { errNum = WLZ_ERR_READ_INCOMPLETE; } else { if(datCnt >= datMax) { datMax = (datMax + 1024) * 2; if((datVP.v = AlcRealloc(datVP.v, sizeof(WlzDVertex3) * datMax)) == NULL) { errNum = WLZ_ERR_MEM_ALLOC; } } } if(errNum == WLZ_ERR_NONE) { *(datVP.d3 + datCnt++) = datV.d3; } break; } } *dstErr = errNum; *dstNVtx = datCnt; return(datVP); }
/*! * \return Number of file names in given string or NULL on error. * \ingroup BinWlzApp * \brief Tries to parse file names from the given comma separated * list. It's an error if there are insufficient file names. * \param fNames Source and destination pointer for * the array of file names. * \param fList Comma separated list of file names. * \param newCnt Number of file names expected. */ static int WlzProjDomParseNameList(char ***fNames, char *fList, int newCnt) { if((fNames == NULL) || (newCnt < 1)) { newCnt = 0; } else { if((*fNames = AlcRealloc(*fNames, sizeof(char *) * newCnt)) == NULL) { newCnt = 0; } } if(newCnt > 0) { int idx; char *tok; tok = strtok(fList, ","); for(idx = 0; (tok != NULL) && (idx < newCnt); ++idx) { if(WlzProjDomStripSpaces(tok) < 1) { tok = NULL; } else { (*fNames)[idx] = tok; tok = strtok(NULL, ","); } } if(idx != newCnt) { newCnt = 0; } } return(newCnt); }
/*! * \return New vertex array. * \brief Reads an array of vertices (2D or 3D) from the given file. * \param fP File pointer. * \param dim Dimension which MUST be either 2 or 3. * \param dstNVtx Destination pointer for the number of * vertices read, MUST not be NULL. * \param dstVType Destination pointer for the vertex * type, MUST not be NULL. * \param dstErr Used to return Woolz error code, * MUST not be NULL. */ static WlzVertexP WlzMTDReadVtxArray(FILE *fP, int dim, int *dstNVtx, WlzVertexType *dstVType, WlzErrorNum *dstErr) { int datCnt = 0, datMax = 0; char lnBuf[WLZ_CFP_READLN_LEN]; WlzVertex datV; WlzVertexP datVP; WlzVertexType vType; WlzErrorNum errNum = WLZ_ERR_NONE; datVP.v = NULL; while((errNum == WLZ_ERR_NONE) && (fgets(lnBuf, WLZ_CFP_READLN_LEN, fP) != NULL)) { lnBuf[WLZ_CFP_READLN_LEN - 1] = '\0'; switch(dim) { case 2: vType = WLZ_VERTEX_I2; if(sscanf(lnBuf, "%lg %lg", &(datV.d2.vtX), &(datV.d2.vtY)) != 2) { errNum = WLZ_ERR_READ_INCOMPLETE; } else { if(datCnt >= datMax) { datMax = (datMax + 1024) * 2; if((datVP.v = AlcRealloc(datVP.v, sizeof(WlzIVertex2) * datMax)) == NULL) { errNum = WLZ_ERR_MEM_ALLOC; } } } if(errNum == WLZ_ERR_NONE) { (datVP.i2 + datCnt)->vtX = ALG_NINT(datV.d2.vtX); (datVP.i2 + datCnt)->vtY = ALG_NINT(datV.d2.vtY); ++datCnt; } break; case 3: vType = WLZ_VERTEX_I3; if(sscanf(lnBuf, "%lg %lg %lg", &(datV.d3.vtX), &(datV.d3.vtY), &(datV.d3.vtZ)) != 3) { errNum = WLZ_ERR_READ_INCOMPLETE; } else { if(datCnt >= datMax) { datMax = (datMax + 1024) * 2; if((datVP.v = AlcRealloc(datVP.v, sizeof(WlzIVertex3) * datMax)) == NULL) { errNum = WLZ_ERR_MEM_ALLOC; } } } if(errNum == WLZ_ERR_NONE) { (datVP.i3 + datCnt)->vtX = ALG_NINT(datV.d3.vtX); (datVP.i3 + datCnt)->vtY = ALG_NINT(datV.d3.vtY); (datVP.i3 + datCnt)->vtZ = ALG_NINT(datV.d3.vtZ); ++datCnt; } break; default: errNum = WLZ_ERR_PARAM_DATA; break; } } *dstErr = errNum; *dstVType = vType; *dstNVtx = datCnt; return(datVP); }
WlzPolygonDomain *HGU_XGetPolyDomain( Display *dpy, Window win, int mode, HGU_XInteractCallbacks *callbacks, WlzPolygonDomain *start) { XEvent event; GC gc; XWindowAttributes win_att; WlzFVertex2 *vtxs=NULL, vtx, vtxp; int nvtxs=0, max_nvtxs=0; int finished = 0; HGU_XGetVtxsCallbackStruct cb_struct; int i; int dx, dy; WlzPolygonDomain *return_polydmn; /* initialise vertex */ vtxp.vtX = 0; vtxp.vtY = 0; /* set up the callback struct */ cb_struct.event = &event; /* get interact gc */ gc = HGU_XGetGC( dpy, win, HGU_XGC_INTERACT ); /* copy the given polygon */ if( (start != NULL) && (start->nvertices > 0) ){ for(i=0; i < start->nvertices; i++){ switch( start->type ){ case WLZ_POLYGON_INT: vtx.vtX = start->vtx[i].vtX; vtx.vtY = start->vtx[i].vtY; break; case WLZ_POLYGON_FLOAT: vtx.vtX = ((WlzFVertex2 *) start->vtx)[i].vtX; vtx.vtY = ((WlzFVertex2 *) start->vtx)[i].vtY; break; case WLZ_POLYGON_DOUBLE: vtx.vtX = ((WlzDVertex2 *) start->vtx)[i].vtX; vtx.vtY = ((WlzDVertex2 *) start->vtx)[i].vtY; break; default: vtx.vtX = 0; vtx.vtY = 0; break; } NEW_VTX((&vtx)); } /* warp pointer */ XWarpPointer(dpy,None,win,0,0,0,0,(int) (vtx.vtX), (int) (vtx.vtY)); } /* select input */ if( XGetWindowAttributes(dpy, win, &win_att) == 0 ){ HGU_XError(dpy, win, "HGU_XGetPolydmn", "failed to get window attributes", 0); return( NULL ); } XSelectInput(dpy, win, win_att.your_event_mask | KeyPressMask | KeyReleaseMask | EnterWindowMask | LeaveWindowMask ); if( QueryInWindow( dpy, win ) ){ HGU_XGrabPointer(dpy, win, mode&HGU_XConfineMask); } /* get the polyline */ while( !finished ){ XNextEvent(dpy, &event); if( event.xany.window != win ){ finished = HGU_XInteractNonwindowEvent(dpy, win, mode, callbacks, &event); continue; } switch( event.type ){ case ButtonPress: switch( event.xbutton.button ){ case Button1: /* new vertex or select */ case Button2: vtx.vtX = event.xbutton.x; vtx.vtY = event.xbutton.y; NEW_VTX((&vtx)); break; case Button3: finished = 1; break; default: break; } break; case ButtonRelease: switch( event.xbutton.button ){ case Button1: /* */ case Button2: /* CHECK NOCONFIRM */ break; case Button3: default: break; } break; case KeyPress: switch( XLookupKeysym(&event.xkey, 0) ){ case XK_Delete: case XK_BackSpace: vtx.vtX = event.xkey.x; vtx.vtY = event.xkey.y; REMOVE_VTX((&vtx)); break; case XK_Right: MOVE_POINTER(1,0,event.xkey.state&ControlMask); break; case XK_Left: MOVE_POINTER(-1,0,event.xkey.state&ControlMask); break; case XK_Up: MOVE_POINTER(0,-1,event.xkey.state&ControlMask); break; case XK_Down: MOVE_POINTER(0,1,event.xkey.state&ControlMask); break; case XK_space: vtx.vtX = event.xkey.x; vtx.vtY = event.xkey.y; NEW_VTX((&vtx)); break; case XK_Return: finished = 1; break; case XK_Help: break; default: break; } break; case KeyRelease: switch( XLookupKeysym(&event.xkey, 0) ){ case XK_Delete: case XK_BackSpace: finished = mode & HGU_XNoConfirmMask; break; default: break; } break; case MotionNotify: /* check button masks */ vtx.vtX = event.xmotion.x; vtx.vtY = event.xmotion.y; if( event.xmotion.state & (Button1Mask|Button2Mask) ){ NEW_VTX((&vtx)); } else { MOVE_VTX((&vtx)); } cb_struct.x = event.xmotion.x; cb_struct.y = event.xmotion.y; cb_struct.vtxs = vtxs; cb_struct.nvtxs = nvtxs; finished = HGU_XInteractWindowEvent(dpy, win, mode, callbacks, (caddr_t) &cb_struct); break; case EnterNotify: HGU_XGrabPointer(dpy, win, mode&HGU_XConfineMask); break; case LeaveNotify: HGU_XUngrabPointer(dpy, win); break; default: cb_struct.vtxs = vtxs; cb_struct.nvtxs = nvtxs; finished = HGU_XInteractWindowEvent(dpy, win, mode, callbacks, (caddr_t) &cb_struct); break; } } /* remove the line */ for(i=1; i < nvtxs; i++) MyDrawLine(dpy, win, gc, &vtxs[i-1], &vtxs[i]); if( nvtxs ) MyDrawLine(dpy, win, gc, &vtxs[nvtxs-1], &vtxp); /* ungrab the pointer */ HGU_XUngrabPointer(dpy, win); /* reset input mask */ XSelectInput(dpy, win, win_att.your_event_mask ); /* check for defined points */ if( nvtxs == 0 ){ if( vtxs != NULL ) AlcFree( (void *) vtxs ); return( NULL ); } /* make a polygondomain to return values */ vtxs = (WlzFVertex2 *) AlcRealloc(vtxs, sizeof(WlzFVertex2)*(nvtxs+2)); vtxs[nvtxs] = vtxp; vtxs[nvtxs+1] = vtxs[0]; /* return the new polygon */ return_polydmn = WlzMakePolygonDomain(WLZ_POLYGON_FLOAT, nvtxs+1, (WlzIVertex2 *) vtxs, nvtxs+2, 1, NULL); AlcFree( (void *) vtxs ); return return_polydmn; }
/*! * \return Woolz error code. * \brief Reads 2D tie points from the file and checks that they * are within the mesh if the mesh is given. * \param dstNVx Destination pointer for number of * tie point pairs, must not be NULL. * \param dstVx0 Destination pointer for source * vertices, must not be NULL. * \param dstVx1 Destination pointer for displacement * vertices, must not be NULL. * \param fP Input file. * \param tMesh Target mesh, may be NULL. * \param prog Program name for error output, must * not be NULL. * \param fStr input file name for error output, must * not be NULL. */ static WlzErrorNum WlzBFTOGetVertices2D(int *dstNVx, WlzDVertex2 **dstVx0, WlzDVertex2 **dstVx1, FILE *fP, WlzCMesh2D *tMesh, const char *prog, const char *fStr) { int vxCount = 0, vxLimit = 0; char *rec; WlzDVertex2 *vx0, *vx1, *vxA0 = NULL, *vxA1 = NULL; const char *errMsg; WlzErrorNum errNum = WLZ_ERR_NONE; char inRecord[IN_RECORD_MAX]; while((errNum == WLZ_ERR_NONE) && (fgets(inRecord, IN_RECORD_MAX - 1, fP) != NULL)) { inRecord[IN_RECORD_MAX - 1] = '\0'; rec = inRecord; while(*rec && isspace(*rec)) { ++rec; } if(*rec && (*rec != '#')) { if(vxCount >= vxLimit) { vxLimit += 4096; if(((vxA0 = (WlzDVertex2 *) AlcRealloc(vxA0, vxLimit * sizeof(WlzDVertex2))) == NULL) || ((vxA1 = (WlzDVertex2 *) AlcRealloc(vxA1, vxLimit * sizeof(WlzDVertex2))) == NULL)) { errNum = WLZ_ERR_MEM_ALLOC; } else { vx0 = vxA0 + vxCount; vx1 = vxA1 + vxCount; } } if(errNum == WLZ_ERR_NONE) { if(sscanf(rec, "%lg %lg %lg %lg", &(vx0->vtX), &(vx0->vtY), &(vx1->vtX), &(vx1->vtY)) != 4) { errNum = WLZ_ERR_READ_INCOMPLETE; } else { vx1->vtX += vx0->vtX; vx1->vtY += vx0->vtY; } } if((errNum == WLZ_ERR_NONE) && (tMesh != NULL)) { if(WlzCMeshElmEnclosingPos2D(tMesh, -1, vx1->vtX, vx1->vtY, 0, NULL) < 0) { errNum = WLZ_ERR_DOMAIN_DATA; (void )WlzStringFromErrorNum(errNum, &errMsg); (void )fprintf(stderr, "%s: tie points line %d not in target mesh (%s).\n", prog, vxCount, errMsg); } } if(errNum == WLZ_ERR_NONE) { ++vx0; ++vx1; ++vxCount; } } } if(errNum == WLZ_ERR_NONE) { *dstNVx = vxCount; *dstVx0 = vxA0; *dstVx1 = vxA1; } else { (void )WlzStringFromErrorNum(errNum, &errMsg); (void )fprintf(stderr, "%s: Failed to read tie points file %s (%s).\n", prog, fStr, errMsg); } return(errNum); }
int main(int argc, char **argv) { WlzObject *inObj, *outObj; WlzDomain domain; WlzValues values; FILE *inFP, *outFP, *bibFP; char *outFile, *bibFile; char optList[] = "b:f:o:hv"; int option; WlzErrorNum errNum=WLZ_ERR_NONE; BibFileRecord *bibfileRecord; BibFileError bibFileErr; int verboseFlg=0; WlzMeshTransform *meshTr = NULL; WlzFnType wlzFnType; WlzMeshGenMethod meshMthd; int basisFnPolyOrder = 3; int meshMinDst; int meshMaxDst; WlzTransformType affineType; WlzDVertex2 *srcVtxs, *dstVtxs; int relFlg=0; int numVtxs, maxNumVtxs; char *errMsg; /* additional defaults */ outFile = "-"; bibFile = NULL; numVtxs = 0; maxNumVtxs = 0; srcVtxs = NULL; dstVtxs = NULL; /* read the argument list and check for an input file */ opterr = 0; while( (option = getopt(argc, argv, optList)) != EOF ){ switch( option ){ case 'b': bibFile = optarg; break; case 'o': outFile = optarg; break; case 'h': default: usage(argv[0]); return 0; case 'v': verboseFlg = 1; break; } } /* check input file/stream */ inFP = stdin; if( optind < argc ){ if( (inFP = fopen(*(argv+optind), "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(strcmp(outFile, "-")) { if((outFP = fopen(outFile, "w")) == NULL) { errNum = WLZ_ERR_WRITE_EOF; } } else { outFP = stdout; } /* check bibfile - get warp function parameters and tie-points */ if((errNum == WLZ_ERR_NONE) && (bibFile != NULL)){ if((bibFP = fopen(bibFile, "r")) != NULL){ bibFileErr = BibFileRecordRead(&bibfileRecord, &errMsg, bibFP); while( bibFileErr == BIBFILE_ER_NONE ){ /* test for warp function and mesh parameters */ if( !strncmp(bibfileRecord->name, "WlzWarpTransformParams", 22) ){ WlzEffBibParseWarpTransformParamsRecord(bibfileRecord, &wlzFnType, &affineType, &meshMthd, &meshMinDst, &meshMaxDst); } /* test for tie points */ if( !strncmp(bibfileRecord->name, "WlzTiePointVtxs", 15) ){ int index; WlzDVertex3 dstVtx; WlzDVertex3 srcVtx; WlzEffBibParseTiePointVtxsRecord(bibfileRecord, &index, &dstVtx, &srcVtx, &relFlg); if( relFlg ){ fprintf(stderr, "%s: warning, relative vertex positions, probably an error\n", argv[0]); } if( numVtxs >= maxNumVtxs ){ maxNumVtxs += 512; srcVtxs = (WlzDVertex2 *) AlcRealloc(srcVtxs, sizeof(WlzDVertex2)*maxNumVtxs); dstVtxs = (WlzDVertex2 *) AlcRealloc(dstVtxs, sizeof(WlzDVertex2)*maxNumVtxs); } srcVtxs[numVtxs].vtX = srcVtx.vtX; srcVtxs[numVtxs].vtY = srcVtx.vtY; dstVtxs[numVtxs].vtX = dstVtx.vtX; dstVtxs[numVtxs].vtY = dstVtx.vtY; numVtxs++; } BibFileRecordFree(&bibfileRecord); bibFileErr = BibFileRecordRead(&bibfileRecord, &errMsg, bibFP); } fclose( bibFP ); if( bibFileErr == BIBFILE_ER_EOF ){ bibFileErr = BIBFILE_ER_NONE; } if( bibFileErr != BIBFILE_ER_NONE ){ fprintf(stderr, "%s: error reading bibfile\n", argv[0]); return 1; } } else { fprintf(stderr, "%s: can't open parameter bibfile %s\n", argv[0], bibFile); return 1; } } else { fprintf(stderr, "%s: warp parameters and tie-points bibfile required\n", argv[0]); usage(argv[0]); return 1; } /* read objects and section if possible */ while((errNum == WLZ_ERR_NONE) && ((inObj = WlzReadObj(inFP, &errNum)) != NULL)) { switch( inObj->type ) { case WLZ_2D_DOMAINOBJ: /* now create the mesh transform */ if((meshTr = WlzMeshTransformFromCPts(inObj, wlzFnType, basisFnPolyOrder, numVtxs, srcVtxs, numVtxs, dstVtxs, meshMthd, meshMinDst, meshMaxDst, &errNum)) != NULL){ /* write out transform and free */ domain.mt = meshTr; values.core = NULL; outObj = WlzMakeMain(WLZ_MESH_TRANS, domain, values, NULL, NULL, &errNum); WlzWriteObj(outFP, outObj); WlzFreeObj(outObj); } else { /* something wrong */ fprintf(stderr, "%s: failed to generate a mesh transform, error code: %d\n", argv[0], errNum); } break; default: fprintf(stderr, "%s: 2D input object required\n", argv[0]); usage(argv[0]); return 1; } WlzFreeObj(inObj); } if(errNum == WLZ_ERR_READ_EOF) { errNum = WLZ_ERR_NONE; } return errNum; }
int main(int argc, char *argv[]) { int idC, idO, idP, option, ok = 1, usage = 0, mean = 0, stddev = 0, nObjs = 0, maxObjs = 0; FILE *fP = NULL; char *fStr, *outObjFileStr; const char *errMsgStr; WlzObject *inObj = NULL, *outObj = NULL; WlzObject **objs = NULL; WlzErrorNum errNum = WLZ_ERR_NONE; static char optList[] = "hmso:"; const char fileStrDef[] = "-"; const int stepObjs = 1024; opterr = 0; outObjFileStr = (char *)fileStrDef; while(ok && ((option = getopt(argc, argv, optList)) != EOF)) { switch(option) { case 'o': outObjFileStr = optarg; break; case 'm': mean = 1; break; case 's': stddev = 1; break; case 'h': default: usage = 1; break; } } ok = !usage; if(ok) { if((outObjFileStr == NULL) || (*outObjFileStr == '\0')) { ok = 0; usage = 1; } } if(ok) { maxObjs += stepObjs; if((objs = AlcMalloc(maxObjs * sizeof(WlzObject *))) == NULL) { ok = 0; errNum = WLZ_ERR_MEM_ALLOC; } } /* Read objects from the command line. */ if(ok) { int nFiles; idO = 0; nFiles = argc - optind; while((errNum == WLZ_ERR_NONE) && (idO < nFiles)) { if(nObjs >= maxObjs) { maxObjs += stepObjs; if((objs = AlcRealloc(objs, stepObjs * sizeof(WlzObject *))) == NULL) { ok = 0; errNum = WLZ_ERR_MEM_ALLOC; break; } } if(ok) { fStr = *(argv + optind + idO); if((fP = (strcmp(fStr, "-")? fopen(fStr, "rb"): stdin)) == NULL) { errNum = WLZ_ERR_READ_EOF; } else { objs[nObjs] = WlzAssignObject( WlzReadObj(fP, &errNum), NULL); if(errNum == WLZ_ERR_NONE) { ++nObjs; } if(strcmp(fStr, "-")) { (void )fclose(fP); } } } ++idO; } if(errNum != WLZ_ERR_NONE) { ok = 0; (void )WlzStringFromErrorNum(errNum, &errMsgStr); (void )fprintf(stderr, "%s: failed to read input objects from command line (%s).\n", *argv, errMsgStr); } } /* Create a single compound object from the input objects. */ if(ok) { int oCnt = 0, oType = 0; for(idO = 0; idO < nObjs; ++idO) { if(objs[idO]) { switch(objs[idO]->type) { case WLZ_2D_DOMAINOBJ: ++oCnt; if(oType == 0) { oType = 2; } else if(oType != 2) { errNum = WLZ_ERR_OBJECT_TYPE; } break; case WLZ_3D_DOMAINOBJ: ++oCnt; if(oType == 0) { oType = 3; } else if(oType != 3) { errNum = WLZ_ERR_OBJECT_TYPE; } break; case WLZ_COMPOUND_ARR_1: /* FALLTHOUGH */ case WLZ_COMPOUND_ARR_2: oCnt += ((WlzCompoundArray *)(objs[idO]))->n; break; default: errNum = WLZ_ERR_OBJECT_TYPE; break; } if(errNum != WLZ_ERR_NONE) { break; } } } if(errNum == WLZ_ERR_NONE) { inObj = (WlzObject *)WlzMakeCompoundArray(WLZ_COMPOUND_ARR_1, 1, oCnt, NULL, WLZ_NULL, &errNum); } if(errNum == WLZ_ERR_NONE) { idC = 0; for(idO = 0; idO < nObjs; ++idO) { if(objs[idO]) { switch(objs[idO]->type) { case WLZ_2D_DOMAINOBJ: /* FALLTHOUGH */ case WLZ_3D_DOMAINOBJ: ((WlzCompoundArray *)inObj)->o[idC++] = WlzAssignObject(objs[idO], NULL); break; case WLZ_COMPOUND_ARR_1: /* FALLTHOUGH */ case WLZ_COMPOUND_ARR_2: for(idP = 0; idP < ((WlzCompoundArray *)(objs[idO]))->n; ++idP) { ((WlzCompoundArray *)inObj)->o[idC++] = WlzAssignObject(((WlzCompoundArray *)(objs[idO]))->o[idP], NULL); } break; default: break; } } } ((WlzCompoundArray *)(inObj))->n = idC; if((((WlzCompoundArray *)(inObj))->n < 1) || (((WlzCompoundArray *)(inObj))->o[0] == NULL)) { errNum = WLZ_ERR_OBJECT_NULL; } else { ((WlzCompoundArray *)(inObj))->otype = ((WlzCompoundArray *) (inObj))->o[0]->type; } } if(errNum != WLZ_ERR_NONE) { ok = 0; (void )WlzStringFromErrorNum(errNum, &errMsgStr); (void )fprintf(stderr, "%s: Failed to create compound object of input object (%s).\n", *argv, errMsgStr); } } if(objs) { for(idO = 0; idO < nObjs; ++idO) { (void )WlzFreeObj(objs[idO]); } AlcFree(objs); objs = NULL; } /* Create compound object for collecting thye statistics. */ if(ok) { outObj = (WlzObject *)WlzMakeCompoundArray(WLZ_COMPOUND_ARR_1, 1, 4, NULL, ((WlzCompoundArray *)(inObj))->otype, &errNum); if(errNum != WLZ_ERR_NONE) { ok = 0; (void )WlzStringFromErrorNum(errNum, &errMsgStr); (void )fprintf(stderr, "%s: Failed to allocate compound object for output object (%s).\n", *argv, errMsgStr); } } /* Compute the cross object statistics. */ if(ok) { errNum = WlzNObjGreyStats(inObj, mean, stddev, NULL, &(((WlzCompoundArray *)outObj)->o[0]), &(((WlzCompoundArray *)outObj)->o[1]), &(((WlzCompoundArray *)outObj)->o[2]), &(((WlzCompoundArray *)outObj)->o[3])); if(errNum == WLZ_ERR_NONE) { for(idO = 0; idO < 4; ++idO) { (void )WlzAssignObject(((WlzCompoundArray *)outObj)->o[idO], NULL); } } else { ok = 0; (void )WlzStringFromErrorNum(errNum, &errMsgStr); (void )fprintf(stderr, "%s: Failed to compute cross object statistics (%s).\n", *argv, errMsgStr); } } /* Output cross object statistics compound object. */ if(ok) { if((fP = (strcmp(outObjFileStr, "-")? fopen(outObjFileStr, "w"): stdout)) == NULL) { ok = 0; (void )fprintf(stderr, "%s: Failed to open output file %s.\n", argv[0], outObjFileStr); } } if(ok) { errNum = WlzWriteObj(fP, outObj); if(strcmp(outObjFileStr, "-")) { (void )fclose(fP); } if(errNum != WLZ_ERR_NONE) { ok = 0; (void )WlzStringFromErrorNum(errNum, &errMsgStr); (void )fprintf(stderr, "%s: Failed to write output object, %s.\n", argv[0], errMsgStr); } } (void )WlzFreeObj(inObj); (void )WlzFreeObj(outObj); /* Report usage. */ if(usage) { (void )fprintf(stderr, "Usage: %s [-h] [-m] [-s] [-o<output file>] [<input objects>]\n" "Version: %s\n" "Options:\n" " -h Output this usage message.\n" " -o Output file name, default is the standard output.\n" " -m Output mean instead of sum of values.\n" " -s Output standard deviation instead of sum of squares of values.\n" "Reads objects (including compound objects) from the given files in\n" "turn: First from the files specified on the commandline and then from\n" "the standard input. The output objects are written to a single compound\n" "object. Each object of the compound object will have the same domain\n" "(which is the intersection of the input object domains) and values for\n" "the simple statistics. The statistics generated are min value, max\n" "value, sum of values and sum of squares of values.\n" "Example:\n" " cat obj1.wlz obj2.wlz obj3.wlz | %s -s -m obj4.wlz >out.wlz\n" "Creates a compound object with four component objects, the domains of\n" "which are all the intersection of the domains of the input objects\n" "(obj[1-4].wlz) and the values are the minimum, maximum, mean and\n" "standard deviation of the input object values across the objects within\n" "the intersection domain.\n", argv[0], WlzVersion(), argv[0]); } return(!ok); }
int WlzEdgeVertices( WlzObject *obj, WlzDVertex3 **vtxs, WlzErrorNum *dstErr) { int numVtxs = 0, n; WlzDVertex3 *rtnVtxs=NULL, *tmpVtxs; WlzErrorNum errNum=WLZ_ERR_NONE; WlzObject *obj1, *obj2; int i, j; WlzValues values; WlzPlaneDomain *planedmn; /* check object */ if( obj == NULL ){ errNum = WLZ_ERR_OBJECT_NULL; } else { switch( obj->type ){ case WLZ_2D_DOMAINOBJ: if((obj1 = WlzObjToBoundary(obj, 1, &errNum)) != NULL){ numVtxs = WlzEdgeVerticesBound(obj1->domain.b, &rtnVtxs, 0, &errNum); WlzFreeObj(obj1); } break; case WLZ_3D_DOMAINOBJ: if( obj->domain.core == NULL){ errNum = WLZ_ERR_DOMAIN_NULL; } else { switch( obj->domain.core->type ){ case WLZ_PLANEDOMAIN_DOMAIN: planedmn = obj->domain.p; values.core = NULL; for(i=planedmn->plane1; i <= planedmn->lastpl; i++){ if( planedmn->domains[i-planedmn->plane1].core ){ obj2 = WlzMakeMain(WLZ_2D_DOMAINOBJ, planedmn->domains[i-planedmn->plane1], values, NULL, NULL, NULL); if( (n = WlzEdgeVertices(obj2, &tmpVtxs, &errNum)) > 0){ if( numVtxs > 0 ){ rtnVtxs = AlcRealloc(rtnVtxs, sizeof(WlzDVertex3)*(numVtxs+n)); } else { rtnVtxs = AlcMalloc(sizeof(WlzDVertex3)*n); } for(j=0; j < n; j++){ tmpVtxs[j].vtZ = i; rtnVtxs[numVtxs+j] = tmpVtxs[j]; } AlcFree(tmpVtxs); numVtxs += n; } WlzFreeObj(obj2); } } break; case WLZ_PLANEDOMAIN_POLYGON: case WLZ_PLANEDOMAIN_BOUNDLIST: break; case WLZ_EMPTY_DOMAIN: if( dstErr ){ *dstErr = errNum; } return numVtxs; default: errNum = WLZ_ERR_DOMAIN_TYPE; } } break; case WLZ_2D_POLYGON: numVtxs = WlzEdgeVerticesPoly(obj->domain.poly, &rtnVtxs, 0, &errNum); break; case WLZ_BOUNDLIST: numVtxs = WlzEdgeVerticesBound(obj->domain.b, &rtnVtxs, 0, &errNum); break; case WLZ_EMPTY_OBJ: if( dstErr ){ *dstErr = errNum; } return numVtxs; default: errNum = WLZ_ERR_OBJECT_TYPE; } } if( dstErr ){ *dstErr = errNum; } *vtxs = rtnVtxs; return numVtxs; }
int WlzEdgeVerticesPoly( WlzPolygonDomain *poly, WlzDVertex3 **vtxs, int numVtxs, WlzErrorNum *dstErr) { int nVtxs=0; WlzErrorNum errNum=WLZ_ERR_NONE; WlzObject *polyObj; int i; /* convert to an 8-connected polyline */ if( poly ){ if((polyObj = WlzPolyTo8Polygon(poly, 1, &errNum)) != NULL){ nVtxs = polyObj->domain.poly->nvertices; if( numVtxs > 0 ){ *vtxs = AlcRealloc(*vtxs, sizeof(WlzDVertex3)* (numVtxs + nVtxs)); } else { numVtxs = 0; *vtxs = AlcMalloc(sizeof(WlzDVertex3)*nVtxs); } switch( polyObj->domain.poly->type ){ case WLZ_POLYGON_INT: for(i=0; i < nVtxs; i++){ (*vtxs)[numVtxs+i].vtX = polyObj->domain.poly->vtx[i].vtX; (*vtxs)[numVtxs+i].vtY = polyObj->domain.poly->vtx[i].vtY; (*vtxs)[numVtxs+i].vtZ = 0.0; } break; case WLZ_POLYGON_FLOAT: for(i=0; i < nVtxs; i++){ (*vtxs)[numVtxs+i].vtX = ((WlzFVertex2 *) polyObj->domain.poly->vtx)[i].vtX; (*vtxs)[numVtxs+i].vtY = ((WlzFVertex2 *) polyObj->domain.poly->vtx)[i].vtY; (*vtxs)[numVtxs+i].vtZ = 0.0; } break; case WLZ_POLYGON_DOUBLE: for(i=0; i < nVtxs; i++){ (*vtxs)[numVtxs+i].vtX = ((WlzDVertex2 *) polyObj->domain.poly->vtx)[i].vtX; (*vtxs)[numVtxs+i].vtY = ((WlzDVertex2 *) polyObj->domain.poly->vtx)[i].vtY; (*vtxs)[numVtxs+i].vtZ = 0.0; } break; default: errNum = WLZ_ERR_POLYGON_TYPE; break; } WlzFreeObj(polyObj); } } if( dstErr ){ *dstErr = errNum; } nVtxs += numVtxs; return nVtxs; }
int main(int argc, char **argv) { int nTiePP, option, vxCount = 0, vxLimit = 0, basisFnPolyOrder = 3, index, relFlag, meshMinDist, meshMaxDist; char *srcFileStr, *bibFileStr = NULL, *outFileStr, *bibErrMsg; const char *errMsg; FILE *inFile = NULL, *outFile = NULL; WlzDVertex2 *sVtx2 = NULL, *dVtx2 = NULL, *srcVtx2 = NULL, *dstVtx2 = NULL; WlzDVertex3 *dVtx = NULL, *sVtx = NULL, *srcVtx = NULL, *dstVtx = NULL; WlzObject *inObj = NULL; WlzCompoundArray *outObj = NULL; WlzBasisFnTransform *basisTr; WlzTransformType trType; WlzFnType basisFnType; WlzMeshGenMethod genMethod; WlzErrorNum errNum = WLZ_ERR_NONE; BibFileRecord *bibfileRecord; BibFileError bibFileErr; /* read the argument list and check for an input file */ static char optList[] = "s:b:t:h"; while( (option = getopt(argc, argv, optList)) != EOF ) { switch( option ) { case 'h': usage(argv[0]); return(0); case 'b': bibFileStr = optarg; break; case 's': srcFileStr = optarg; break; case 't': outFileStr = optarg; break; default: return(0); } } if((inFile = fopen(bibFileStr, "r")) == NULL ) { printf("cannot open the input bib file.\n"); exit(1); } /* read the bibfile until we get the WlzWarptransformParams part */ while( !feof(inFile) ){ bibFileErr = BibFileRecordRead(&bibfileRecord, &bibErrMsg, inFile); if(bibFileErr != BIBFILE_ER_EOF) { bibFileErr = WlzEffBibParseWarpTransformParamsRecord( bibfileRecord, &basisFnType, &trType, &genMethod, &meshMinDist, &meshMaxDist); if (bibFileErr == BIBFILE_ER_NONE) break; } else break; } /* read the bibfile until we get the TiePointVtxs part */ if( bibFileErr == BIBFILE_ER_NONE ) { while( !feof(inFile) ){ bibFileErr = BibFileRecordRead(&bibfileRecord, &bibErrMsg, inFile); if(bibFileErr != BIBFILE_ER_EOF) { if(vxCount >= vxLimit) { vxLimit = (vxLimit + 1024) * 2; if(((srcVtx = (WlzDVertex3 *)AlcRealloc(srcVtx, vxLimit * sizeof(WlzDVertex3))) == NULL) || ((dstVtx = (WlzDVertex3 *)AlcRealloc(dstVtx, vxLimit * sizeof(WlzDVertex3))) == NULL)) { errNum = WLZ_ERR_MEM_ALLOC; } else { sVtx = srcVtx + vxCount; dVtx = dstVtx + vxCount; } } if(errNum == WLZ_ERR_NONE) { bibFileErr = WlzEffBibParseTiePointVtxsRecord( bibfileRecord, &index, dVtx, sVtx, &relFlag); if (bibFileErr == BIBFILE_ER_NONE) { ++sVtx; ++dVtx; ++vxCount; } } } else break; } } nTiePP = vxCount; BibFileRecordFree(&bibfileRecord); fclose(inFile); if( bibFileErr == BIBFILE_ER_EOF ) { errNum = WLZ_ERR_NONE; } else { printf("Read bib file error.\n"); exit(1); } /* copy 3D verices to 2D vertices - cast won't work */ if(((srcVtx2 = (WlzDVertex2 *)AlcRealloc(srcVtx2, vxCount * sizeof(WlzDVertex2))) == NULL) || ((dstVtx2 = (WlzDVertex2 *)AlcRealloc(dstVtx2, vxCount * sizeof(WlzDVertex2))) == NULL)) { errNum = WLZ_ERR_MEM_ALLOC; } else { sVtx = srcVtx; dVtx = dstVtx; sVtx2 = srcVtx2; dVtx2 = dstVtx2; for (vxCount = 0; vxCount < nTiePP; vxCount++) { sVtx2->vtX = sVtx->vtX; sVtx2->vtY = sVtx->vtY; dVtx2->vtX = dVtx->vtX; dVtx2->vtY = dVtx->vtY; ++sVtx2; ++dVtx2; ++sVtx; ++dVtx; } } errNum = WLZ_ERR_READ_EOF; if((srcFileStr == NULL) || (*srcFileStr == '\0') || ((inFile = (strcmp(srcFileStr, "-")? fopen(srcFileStr, "r"): stdin)) == NULL) || ((inObj= WlzAssignObject(WlzReadObj(inFile, &errNum), NULL)) == NULL) || (errNum != WLZ_ERR_NONE)) { (void )fprintf(stderr, "%s: failed to read object from file %s\n", *argv, srcFileStr); } if(inFile) { if(strcmp(srcFileStr, "-")) { fclose(inFile); } inFile = NULL; } if(errNum == WLZ_ERR_NONE) { basisTr = WlzAffineBasisFnTransformFromCPtsT(inObj, basisFnType, basisFnPolyOrder, nTiePP, srcVtx2, nTiePP, dstVtx2, &errNum); } /* Calculate tensor components and then write them out. */ if(errNum == WLZ_ERR_NONE) { outObj = WlzBasisFnTensorTransformObjPrv(inObj, basisTr, &errNum); } if(errNum != WLZ_ERR_NONE) { (void )WlzStringFromErrorNum(errNum, &errMsg); (void )fprintf(stderr, "%s: failed to transform object (%s).\n", *argv, errMsg); } if(errNum == WLZ_ERR_NONE) { errNum = WLZ_ERR_WRITE_EOF; if(((outFile = (strcmp(outFileStr, "-")? fopen(outFileStr, "w"): stdout)) == NULL) || ((errNum = WlzWriteObj(outFile, (WlzObject *)outObj)) != WLZ_ERR_NONE)) { (void )WlzStringFromErrorNum(errNum, &errMsg); (void )fprintf(stderr, "%s: failed to write output compound array (%s).\n", *argv, errMsg); } if(outFile && strcmp(outFileStr, "-")) { fclose(outFile); } } /* free memory */ AlcFree(srcVtx); AlcFree(dstVtx); AlcFree(srcVtx2); AlcFree(dstVtx2); WlzBasisFnFreeTransform(basisTr); return(errNum); }
int main(int argc, char *argv[]) { int option, ok = 1, idx = 0, usage = 0, fileList = 0, gTrans = 0, nObj, nObjMax, nFiles, plane1 = 0, sTrans = 0; FILE *fP; char *fStr, *fLstStr = NULL, *outFileStr = NULL; const char *errMsgStr; WlzEffFormat outFmt = WLZEFF_FORMAT_WLZ; WlzDVertex3 voxSz; WlzObject *obj = NULL; WlzObject **objs = NULL; WlzErrorNum errNum = WLZ_ERR_NONE; char fStrBuf[WLZEFFCON_BUF_LEN]; static char optList[] = "fho:p:s:ST"; const char outFileStrDef[] = "-"; opterr = 0; fStr = ""; voxSz.vtX = voxSz.vtY = voxSz.vtZ = 1.0; outFileStr = (char *)outFileStrDef; while(ok && ((option = getopt(argc, argv, optList)) != EOF)) { switch(option) { case 'f': fileList = 1; break; case 'o': outFileStr = optarg; break; case 'p': if(sscanf(optarg, "%d", &plane1) != 1) { usage = 1; } break; case 's': if(sscanf(optarg, "%lg,%lg,%lg", &(voxSz.vtX), &(voxSz.vtY), &(voxSz.vtZ)) != 3) { usage = 1; } break; case 'G': gTrans = 1; break; case 'S': sTrans = 1; break; case 'h': default: usage = 1; break; } } ok = !usage; if(ok) { if((outFileStr == NULL) || (*outFileStr == '\0')) { ok = 0; usage = 1; } } if(ok) { if(((nFiles = argc - optind) <= 0) || ((fileList != 0) && (nFiles != 1))) { ok = 0; usage = 1; } } if(ok) { nObj = 0; nObjMax = (fileList)? WLZEFFCON_FILE_STEP: nFiles; if((objs = (WlzObject **)AlcMalloc(nObjMax * sizeof(WlzObject *))) == NULL) { ok = 0; (void )fprintf(stderr, "%s: failed to allocate object list.\n", *argv); } } /* Read the 2D image files. */ if(ok) { if(fileList == 0) { idx = 0; while((errNum == WLZ_ERR_NONE) && (idx < nFiles)) { fStr = *(argv + optind + idx); errNum = WlzEFFConAddImg(objs + idx, fStr, sTrans, gTrans); ++idx; } nObj = idx; } else /* fileList != 0 */ { fLstStr = *(argv + optind); if((fP = (strcmp(fLstStr, "-")? fopen(fLstStr, "r"): stdin)) == NULL) { ok = 0; (void )fprintf(stderr, "%s: failed to open file list in file %s.\n", *argv, fStr); } else { idx = 0; nObj = 0; while((errNum == WLZ_ERR_NONE) && (fgets(fStrBuf, WLZEFFCON_BUF_LEN, fP) != NULL)) { if((idx + 1) > nObjMax) { nObjMax += WLZEFFCON_FILE_STEP; if((objs = (WlzObject **) AlcRealloc(objs, nObjMax * sizeof(WlzObject *))) == NULL) { errNum = WLZ_ERR_MEM_ALLOC; } } if(errNum == WLZ_ERR_NONE) { if(((fStr = strtok(fStrBuf, " \t\n")) != NULL) && (*fStr != '#')) { errNum = WlzEFFConAddImg(objs + idx, fStr, sTrans, gTrans); ++idx; } } } nObj = idx; } if(fP && (strcmp(fLstStr, "-"))) { (void )fclose(fP); } } if(errNum != WLZ_ERR_NONE) { ok = 0; (void )fprintf(stderr, "%s: failed to read images at image %d\n", *argv, idx); } } /* Construct the 3D object. */ if(ok) { obj = WlzConstruct3DObjFromObj(nObj, objs, plane1, voxSz.vtX, voxSz.vtY, voxSz.vtZ, &errNum); if(errNum != WLZ_ERR_NONE) { ok = 0; (void )WlzStringFromErrorNum(errNum, &errMsgStr); (void )fprintf(stderr, "%s: Failed to construct 3D object (%s).\n", argv[0], errMsgStr); } } /* Write out the 3D object. */ if(ok) { if(strcmp(outFileStr, "-") == 0) { fP = stdout; outFileStr = NULL; outFmt = WLZEFF_FORMAT_WLZ; } else { fP = NULL; outFmt = WlzEffStringFormatFromFileName(outFileStr); } if(outFmt == WLZEFF_FORMAT_NONE) { ok = 0; (void )fprintf(stderr, "%s: Unrecognized file format for output file %s.\n", argv[0], outFileStr); } } if(ok) { errNum = WlzEffWriteObj(NULL, outFileStr, obj, outFmt); if(errNum != WLZ_ERR_NONE) { ok = 0; (void )WlzStringFromErrorNum(errNum, &errMsgStr); (void )fprintf(stderr, "%s: Failed to write output object, %s.\n", argv[0], errMsgStr); } } if(obj) { (void )WlzFreeObj(obj); } if(objs) { for(idx = 0; idx < nObj; ++idx) { (void )WlzFreeObj(*(objs + idx)); } AlcFree(objs); } if(usage) { (void )fprintf(stderr, "Usage: %s [-h] [-f] [-o<output file>] [-p #] [-s #,#,#]\n" " [-G] [-S] [<file>|<input file list>]\n" "Version: %s\n" "Options:\n" " -h Output this usage message.\n" " -f Input file is a list of image files.\n" " -o Output file name, default is the standard output.\n" " -p Coordinate of the first plane.\n" " -s Voxel size (x,y,z).\n" " -G Apply grey value transforms.\n" " -S Use spatial transforms to create WLZ_TRANS_OBJ objects\n" " (by default just offsets are applied).\n" "Given a set of 2D image files, these are read in turn and used\n" "to build a 3D image. The 2D image files can either be given on\n" "the command line or in a file.\n" "Alignment of the 2D images is assumed to be perfect and is not\n" "addressed.\n" "If a file is used to give the 2D image file names then there\n" "should be one image file name per line, although lines which\n" "start with a '#' character will be treated as comments and\n" "ignored.\n" "File formats are specified using the file 'extension' (.bmp,\n" ".jpg, .wlz, etc) in the file name. The dash character ('-')\n" "can be used to specify the standard input and standard output,\n" "in which case the Woolz object format is used." "The word 'NULL' may be used to specify an empty section.\n" "Example:\n" "%s img00.bmp img01.bmp NULL img03.bmp img04.bmp >out.wlz\n" "Constructs a 3D woolz object from the 2D BMP image files\n" "img0X.bmp, with an empty 3rd section.\n", argv[0], WlzVersion(), argv[0]); } return(!ok); }