📄 pik.c
字号:
/*====================================================================*\ pik list subroutines This code is complicated by the extensive use of global variables. Note that these routines are distinct from the pick routines whjich appear to be used for annotation of the frame positions. Reginald H. Beardsley rhb@acm.org\*====================================================================*/#include <string.h>#include <stdlib.h>#include <stdio.h>#include "su.h"#include "main.h"#include "axis.h"#include "color.h"#include "draw.h"#include "data.h"#include "map.h"#include "render.h"#include "view.h"#include "plane.h"#include "pick.h"#include "pik.h"#include "ui_window.h"#include "ui_menu.h"/* main pik object */PikList pik = 0;PikList pikSet[NFILES];static cwp_String pikfile[NFILES];int nfiles = 0;/*--------------------------------------------------------------------*\ Initialize startup pik objects specified by pick=file1,file2. There is no default pickfile. \*--------------------------------------------------------------------*/void PikInit(void){ int i; if ((nfiles = countparval("pick")) != 0) { getparstringarray("pick", pikfile); } for (i = 0; i < nfiles; i++) { { extern int _alloc; pikSet[i] = (PikList) malloc((1) * sizeof(pikSet[i][0])); _alloc += (1) * sizeof(pikSet[i][0]); if (pikSet[i] == 0) err ("cant allocate %d bytes for pikSet[i]; %d already allocated", (1) * sizeof(pikSet[i][0]), _alloc); if (memwatch) (void) printf("malloc %s=%d\n", " pikSet[i]", (1) * sizeof(pikSet[i][0])); }; pik = pikSet[i]; strcpy(pik->file, pikfile[i]); pik->npik = 0; pik->size = PIK_SIZE; pik->changed = 0; getparint("picksize", &pik->size); pik->nmax = NPIK; getparint("npick", &pik->nmax); { extern int _alloc; pik->pik = (Pik *) malloc((pik->nmax) * sizeof(pik->pik[0])); _alloc += (pik->nmax) * sizeof(pik->pik[0]); if (pik->pik == 0) err ("cant allocate %d bytes for pik->pik; %d already allocated", (pik->nmax) * sizeof(pik->pik[0]), _alloc); if (memwatch) (void) printf("malloc %s=%d\n", " pik->pik", (pik->nmax) * sizeof(pik->pik[0])); }; pik->range = PIK_RANGE; getparint("pickrange", &pik->range); PikRead(); } if (!nfiles) { nfiles++; { extern int _alloc; pikSet[0] = (PikList) malloc((1) * sizeof(pikSet[0][0])); _alloc += (1) * sizeof(pikSet[0][0]); if (pikSet[0] == 0) err ("cant allocate %d bytes for pikSet[0]; %d already allocated", (1) * sizeof(pikSet[0][0]), _alloc); if (memwatch) (void) printf("malloc %s=%d\n", " pikSet[0]", (1) * sizeof(pikSet[0][0])); }; pik = pikSet[0]; memset(pik->file, 0, sizeof(pik->file)); pik->npik = 0; pik->size = PIK_SIZE; pik->changed = 0; getparint("picksize", &pik->size); pik->nmax = NPIK; getparint("npick", &pik->nmax); { extern int _alloc; pik->pik = (Pik *) malloc((pik->nmax) * sizeof(pik->pik[0])); _alloc += (pik->nmax) * sizeof(pik->pik[0]); if (pik->pik == 0) err ("cant allocate %d bytes for pik->pik; %d already allocated", (pik->nmax) * sizeof(pik->pik[0]), _alloc); if (memwatch) (void) printf("malloc %s=%d\n", " pik->pik", (pik->nmax) * sizeof(pik->pik[0])); }; pik->range = PIK_RANGE; getparint("pickrange", &pik->range); } PikDraw(NO_INDEX, DRAW);}/*--------------------------------------------------------------------*\ Clear all items in the current pik list (pik) and redraw the screen.\*--------------------------------------------------------------------*/void PikClear(void){ PikDraw(NO_INDEX, ERASE); pik->npik = 0; pik->changed = 0; PikDraw(NO_INDEX, DRAW);}/*--------------------------------------------------------------------*\ Read one pick file. \*--------------------------------------------------------------------*/void PikRead(void){ int iaxis; int ipik; FILE *fd; float value[DATA_NAXIS+1]; char line[256]; char* ptr; int cnt; int i; extern Data data; Message message; if (!pik) { return; } if ((fd = fopen(pik->file, "r")) == NULL) { sprintf(message, "can't open pick=%s file for reading", pik->file); UIMessage(message); return; }/*--------------------------------------------------------------------*\ The format being parsed here is a bit odd. The input consists of a line "n1 n2 n3 n4 n5 val" however the data is stored in the value array in the order: val n1 n2 n3 n4 n5. The intent here is to allow 3 to 6 column input with the last column being the data value. The value is optional.\*--------------------------------------------------------------------*/ while (pik->npik < pik->nmax && !feof(fd) ){ memset( value ,0 ,sizeof(value) ); memset( line ,0 ,sizeof(line) ); if( fgets( line ,sizeof(line) ,fd ) && line[0] != '#' ){ ptr = line; cnt = 0; i = 1; while( *ptr ){ strtok( ptr ," \t\n" ); if( ptr && strspn( ptr ," \t\n") != strlen( ptr ) ){ sscanf( ptr ,"%f" ,&value[i] ); cnt++; } ptr += strlen(ptr) + 1; i++; } if( cnt > 2 ){ for (iaxis = 1; iaxis < DATA_NAXIS; iaxis++) { pik->pik[pik->npik][iaxis] = AxisIndex(DataAxis(data, iaxis), value[iaxis]); } }/*--------------------------------------------------------------------*\ Allow specifying coordinates w/o the field value to facilitate data import from other sources.\*--------------------------------------------------------------------*/ if( cnt > 3 ){ pik->pik[pik->npik][0] = AxisIndex(DataAxis(data, 0), value[cnt] ); }else{ pik->pik[pik->npik][0] = 0; } pik->npik++; } } fclose(fd); sprintf(message, "%d picks read from file %s", pik->npik, pik->file); UIMessage(message);/*--------------------------------------------------------------------*\ Note: this cruft belongs in a class constructor, not here. Since we're not really using C++, the overhead has to be tolerated.\*--------------------------------------------------------------------*/ for (ipik = pik->npik; ipik < pik->nmax; ipik++) { pik->pik[ipik][0] = NO_INDEX; }}/*--------------------------------------------------------------------*\ write the current pick file\*--------------------------------------------------------------------*/void PikWrite(char *filename, FILE * fd){ int ipik, count = 0; extern Data data; Message message; if (!pik || !pik->npik) { return; } strcpy(pik->file, filename); for (ipik = 0, count = 0; ipik < pik->npik; ipik++) { if (pik->pik[ipik][0] != NO_INDEX) { count++; fprintf(fd, "%10g %10g %10g %10g %10g %10g\n", AxisValue(DataAxis(data, 1), pik->pik[ipik][1]), AxisValue(DataAxis(data, 2), pik->pik[ipik][2]), AxisValue(DataAxis(data, 3), pik->pik[ipik][3]), AxisValue(DataAxis(data, 4), pik->pik[ipik][4]), AxisValue(DataAxis(data, 5), pik->pik[ipik][5]), AxisValue(DataAxis(data, 0), pik->pik[ipik][0])); } } fclose(fd); sprintf(message, "%d picks written to %s", count, pik->file); UIMessage(message);}/*--------------------------------------------------------------------*\ draw pick pik0 or all picks ( pik0 = NO_INDEX ) on all planes. Note that the current pick list selected must be saved and restored after the draw operation. This is ugly, but done as a defensive measure since the scope of "pik" is large and unknown.\*--------------------------------------------------------------------*/void PikDraw(int pik0, int draw){ Plane plane; extern Data data; extern Plane planelist; int dir; int frame; int hskew; int ipik; int pik1; int pik2; int range1; int range2; int vskew; int x0; int x; int y0; int y; int i; PikList currentPik; currentPik = pik; for (i = 0; i < nfiles; i++) { if (pik0 == NO_INDEX) { pik = pikSet[i]; } if (!pik ){ return; }else if (!pik->npik) { continue; } if (pik0 < pik->npik) {/*--------------------------------------------------------------------*\ Loop over all the planes currently shown on the screen. This varies from one to three depending on the display mode being used. Picks are displayed as X's on the frame on which they were picked and as small boxes on adjacent frames. The range field specifies the number of frames in which a box is shown.\*--------------------------------------------------------------------*/ for (plane = planelist; plane < planelist + NPLANE && plane->attr->orient != NO_INDEX; plane++) { dir = PlaneDir(plane); frame = PlaneFrame(plane); range1 = frame - pik->range; range2 = frame + pik->range; range1 = range1 > 0 ? range1 : 0; range2 = range2 < AxisSize(DataAxis(data, dir)) - 1 ? range2 : AxisSize(DataAxis(data, dir)) - 1;/*--------------------------------------------------------------------*\ Set bounds for the pick display loop. This may be either a single pick or all the picks in a picklist. For each pick, check to see if the current frame and range values are such that the pick should be drawn.\*--------------------------------------------------------------------*/ if (pik0 == NO_INDEX) { pik1 = 0; pik2 = pik->npik - 1; } else { pik1 = pik0; pik2 = pik0; } for (ipik = pik1; ipik <= pik2; ipik++) { if (pik->pik[ipik][0] != NO_INDEX && pik->pik[ipik][dir] >= range1 && pik->pik[ipik][dir] <= range2) {/*--------------------------------------------------------------------*\ Calculate the screen coordinates for the pick from the data coordinates and whether the image is skewed.\*--------------------------------------------------------------------*/ hskew = 0; vskew = 0; if (PlaneType(plane) == RENDER_HORZ) { hskew = PlaneSkew(plane); } else { vskew = PlaneSkew(plane); } x = MapInverse(PlaneHmap(plane) , pik->pik[ipik][AxisDir (MapAxis (PlaneHmap(plane)))]); if (PlaneType(plane) == RENDER_VERT) { x = MapSize(PlaneHmap(plane)) - x; } y = MapInverse(PlaneVmap(plane), pik->pik[ipik][AxisDir (MapAxis (PlaneVmap(plane)))]);/*--------------------------------------------------------------------*\ If the pick is drawable, draw an X or box as appropriate.\*--------------------------------------------------------------------*/ if (x != NO_INDEX && y != NO_INDEX) { x0 = x + PlaneH0(plane) + hskew * (MapSize(PlaneVmap(plane)) - y); y0 = y + PlaneV0(plane) + vskew * (PlaneNH(plane) - x); if (pik->pik[ipik][dir] == frame) { PikDrawEx(x0, y0, draw); } else if (pik->pik[ipik][dir] > frame) { PikDrawBox(x0, y0, pik->range - pik->pik[ipik][dir] + frame, draw); } else { PikDrawBox(x0, y0, pik->range - frame + pik->pik[ipik][dir], draw); } } } } } } } pik = currentPik;}/*--------------------------------------------------------------------*\ draw an "x"\*--------------------------------------------------------------------*/void PikDrawEx(int x, int y, int draw){ if (!pik) { return; } DrawLine(x + pik->size, y + pik->size, x - pik->size, y - pik->size, draw); DrawLine(x - pik->size, y + pik->size, x + pik->size, y - pik->size, draw);}/*--------------------------------------------------------------------*\ draw a box of specified size\*--------------------------------------------------------------------*/void PikDrawBox(int x, int y, int size, int draw){ if (!pik) { return; } DrawLine(x + size, y + size, x - size, y + size, draw); DrawLine(x + size, y - size, x - size, y - size, draw); DrawLine(x + size, y + size, x + size, y - size, draw); DrawLine(x - size, y + size, x - size, y - size, draw);}/*--------------------------------------------------------------------*\ find nearest visible pick on mouse pick plane\*--------------------------------------------------------------------*/int PikNear(int x, int y){ PickPoint_ pick; Plane plane; extern Data data; int dir1; int dir2; int dir; int distance; int frame; int inear; int ipik; int near;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -