#include "interface.h" #include /* Nset_fence_color_cmd -- Command to set appropriate fence color Arguments: one of ABOVE, BELOW, BLEND, GREY, OFF Returns: None Side Effects: Sets appropriate fence color */ int Nset_fence_color_cmd(Nv_data * data, Tcl_Interp * interp, int argc, char **argv) { /* Verify arguments */ if (argc != 2) { sprintf(interp->result, "Usage: Nset_fence_color ABOVE | BELOW | BLEND | GREY | OFF"); return (TCL_ERROR); } /* Otherwise parse the second argument and call the appropriate function */ if (!strncmp(argv[1], "ABOVE", 5)) { GS_set_fencecolor(FC_ABOVE); } else if (!strncmp(argv[1], "BELOW", 5)) { GS_set_fencecolor(FC_BELOW); } else if (!strncmp(argv[1], "BLEND", 5)) { GS_set_fencecolor(FC_BLEND); } else if (!strncmp(argv[1], "GREY", 4)) { GS_set_fencecolor(FC_GREY); } else if (!strncmp(argv[1], "OFF", 3)) { GS_set_fencecolor(FC_OFF); } else { sprintf(interp->result, "Error in Nset_fence_color, second argument must be one of ABOVE, BELOW, BLEND, GREY or OFF."); return (TCL_ERROR); } return (TCL_OK); } /* Nget_fence_color_cmd -- Command to set appropriate fence color Arguments: None Returns: one of ABOVE, BELOW, BLEND, GREY, OFF Side Effects: None */ int Nget_fence_color_cmd(Nv_data * data, Tcl_Interp * interp, int argc, char **argv) { int mode; /* Verify arguments */ if (argc != 1) { Tcl_SetResult(interp, "Usage: Nget_fence_color", TCL_VOLATILE); return (TCL_ERROR); } /* Get the mode and return an appropriate value */ mode = GS_get_fencecolor(); switch (mode) { case FC_ABOVE: Tcl_SetResult(interp, "ABOVE", TCL_VOLATILE); break; case FC_BELOW: Tcl_SetResult(interp, "BELOW", TCL_VOLATILE); break; case FC_BLEND: Tcl_SetResult(interp, "BLEND", TCL_VOLATILE); break; case FC_GREY: Tcl_SetResult(interp, "GREY", TCL_VOLATILE); break; case FC_OFF: Tcl_SetResult(interp, "OFF", TCL_VOLATILE); break; default: Tcl_SetResult(interp, "Internal Error: Unknown mode returned from GS_get_fencecolor", TCL_VOLATILE); return (TCL_ERROR); } return (TCL_OK); } /* Ncutplane_obj_cmd -- Command to intercept commands for cutplane objects. Arguments: one of: draw [surf1 surf2] on off set_rot dx dy dz set_trans dx dy dz get_rot get_trans Returns: get_rot - returns dx dy dz of rotation for current plane get_trans - returns dx dy dz of rotation for current plane Side Effects: draw - draws the given cutplane on - sets the cutplane as active off - deactivates the given cutplane set_rot - sets rotation for the current cutplane set_trans - sets the translation for the current cutplane */ int Ncutplane_obj_cmd(Nv_data * data, Tcl_Interp * interp, /* Current interpreter. */ int argc, /* Number of arguments. */ char **argv /* Argument strings. */ ) { int id; id = get_cp_idnum(argv[0]); if (!strcmp(argv[1], "draw")) return (draw_cp_obj(data, interp, id, argv, argc)); else if (!strcmp(argv[1], "on")) return (on_cp_obj(data, interp, id, argv, argc)); else if (!strcmp(argv[1], "off")) return (off_cp_obj(data, interp, id, argv, argc)); else if (!strcmp(argv[1], "state")) return (state_cp_obj(data, interp, id, argv, argc)); else if (!strcmp(argv[1], "set_rot")) return (cp_set_rot(data, interp, id, argv, argc)); else if (!strcmp(argv[1], "set_trans")) return (cp_set_trans(data, interp, id, argv, argc)); else if (!strcmp(argv[1], "get_rot")) return (cp_get_rot(data, interp, id, argv, argc)); else if (!strcmp(argv[1], "get_trans")) return (cp_get_trans(data, interp, id, argv, argc)); else { sprintf(interp->result, "Usage: %s \tdraw [surf1 surf2]\n\t\ton\n\t\toff\n\t\tset_rot dx dy dz\n\t\tset_trans dx dy dz\n\t\tget_rot\n\t\tget_trans", argv[0]); return (TCL_ERROR); } } /* Nnew_cutplane_obj_cmd -- Creates a cutplane object. Arguments: id - Id number for the new cutplane, should be unique Returns: The name of the command for the new cutplane. Side Effects: Cutplanes are implemented as Tcl commands which communicate with the underlying GSF library. Each time this routine is called a new tcl command is created for the new cutplane. I.e. basically an oops approach. */ int Nnew_cutplane_obj_cmd(Nv_data * data, Tcl_Interp * interp, /* Current interpreter. */ int argc, /* Number of arguments. */ char **argv /* Argument strings. */ ) { /* Pretty simple. Since the number of cutplanes is fixed and we'll create them all ahead of time anyway we just let the user decide on the id for each. */ char id[128]; int num_id; if (argc != 2) { interp->result = "Usage: Nnew_cutplane_obj id_num"; return (TCL_ERROR); } data->NumCplanes++; num_id = atoi(argv[1]); sprintf(id, "Ncutplane%d", num_id); /* Initialize internal attributes for this cutplane */ data->Cp_rot[num_id][Y] = data->Cp_rot[num_id][Z] = 0.0; data->Cp_rot[num_id][X] = 0.0; data->Cp_trans[num_id][X] = data->Cp_trans[num_id][Y] = data->Cp_trans[num_id][Z] = 0.0; data->Cp_on[num_id] = 0; Tcl_CreateCommand(interp, id, (Tcl_CmdProc *) Ncutplane_obj_cmd, data, NULL); Tcl_SetResult(interp, id, TCL_VOLATILE); return (TCL_OK); } /* Nnum_cutplane_obj_cmd -- Return the number of cutplane objects currently allocated. Arguments: None Returns: Number of cutplane objects in existence. Side Effects: None */ int Nnum_cutplane_obj_cmd(Nv_data * data, Tcl_Interp * interp, /* Current interpreter. */ int argc, /* Number of arguments. */ char **argv /* Argument strings. */ ) { char result[20]; sprintf(result, "%d", data->NumCplanes); Tcl_SetResult(interp, result, TCL_VOLATILE); return (TCL_OK); } /* */ int Nset_current_cutplane_cmd(Nv_data * data, Tcl_Interp * interp, /* Current interpreter. */ int argc, /* Number of arguments. */ char **argv /* Argument strings. */ ) { return (TCL_OK); } /* Nget_current_cutplane_cmd -- Get the current active cutplane. Arguments: None Returns: NAME of current cutplane Side Effects: None */ int Nget_current_cutplane_cmd(Nv_data * data, Tcl_Interp * interp, /* Current interpreter. */ int argc, /* Number of arguments. */ char **argv /* Argument strings. */ ) { char curr[128]; if (data->CurCplane == -1) { sprintf(curr, "None"); } else { sprintf(curr, "Ncutplane%d", data->CurCplane); } Tcl_SetResult(interp, curr, TCL_VOLATILE); return (TCL_OK); } /* Nget_map_list type id|name returns list of all map objects of specified type, either by name or id. */ int Nget_cutplane_list_cmd(Nv_data * data, Tcl_Interp * interp, /* Current interpreter. */ int argc, /* Number of arguments. */ char **argv /* Argument strings. */ ) { return (TCL_OK); } /* cp_draw -- Routine to draw all the cutplanes. Arguments: Current active cutplane Data for Nviz application Boundary surfaces (surf1 and surf2), set to -1 to ignore Returns: None Side Effects: Causes all the active cut planes to be drawn */ void cp_draw(int current, Nv_data * data, int surf1, int surf2) { int i, nsurfs; int surf_min=0, surf_max=0, temp; int *surf_list; GS_set_draw(GSD_BACK); GS_clear(data->BGcolor); GS_ready_draw(); /* If surf boundaries present then find them */ surf_list = GS_get_surf_list(&nsurfs); if ((surf1 != -1) && (surf2 != -1)) { for (i = 0; i < nsurfs; i++) { if (surf_list[i] == surf1) surf_min = i; if (surf_list[i] == surf2) surf_max = i; } if (surf_max < surf_min) { temp = surf_min; surf_min = surf_max; surf_max = temp; } surf_max++; } else { surf_min = 0; surf_max = nsurfs; } if (nsurfs > 1) { for (i = 0; i < MAX_CPLANES; i++) { if (data->Cp_on[i]) GS_draw_cplane_fence(surf_list[0], surf_list[1], i); } } for (i = surf_min; i < surf_max; i++) { GS_draw_wire(surf_list[i]); } GS_done_draw(); } /* draw_cp_obj -- Draw the current cutplane. Arguments: [Optional] surf1, surf2 - Only draws between surf1 and surf2 Returns: None Side Effects: None */ int draw_cp_obj(Nv_data * data, Tcl_Interp * interp, int id, char **argv, int argc) { int bound1, bound2; /* Verify arguments */ if ((argc != 2) && (argc != 4)) { sprintf(interp->result, "Usage: %s draw [surf1 surf2]", argv[0]); return (TCL_ERROR); } /* Parse boundary surfaces if necessary (should be surface id's) */ if (argc == 2) { bound1 = bound2 = -1; } else { if (Tcl_GetInt(interp, argv[2], &bound1) != TCL_OK) { sprintf(interp->result, "Error in %s draw %s %s, expected integer argument in surf1 field", argv[0], argv[2], argv[3]); return (TCL_ERROR); } if (Tcl_GetInt(interp, argv[3], &bound2) != TCL_OK) { sprintf(interp->result, "Error in %s draw %s %s, expected integer argument in surf2 field", argv[0], argv[2], argv[3]); return (TCL_ERROR); } } /* Finally make the draw call */ cp_draw(data->CurCplane, data, bound1, bound2); return (TCL_OK); } /* on_cp_obj -- Turn on (make current) the given cutplane. Arguments: None Returns: None Side Effects: Sets the current cutplane as the currently active cutplane in the gsf library. */ int on_cp_obj(Nv_data * data, Tcl_Interp * interp, int id, char **argv, int argc) { /* Verify arguments are correct */ if (argc != 2) { sprintf(interp->result, "Usage: %s on", argv[0]); return (TCL_ERROR); } /* Otherwise make the current cutplane active */ data->CurCplane = id; data->Cp_on[id] = 1; GS_set_cplane(id); return (TCL_OK); } /* off_cp_obj -- Turn off (make inactive) the given cutplane. Arguments: None Returns: None Side Effects: Sets the current cutplane as inactive in the gsf library. */ int off_cp_obj(Nv_data * data, Tcl_Interp * interp, int id, char **argv, int argc) { /* Verify arguments */ if (argc != 2) { sprintf(interp->result, "Usage: %s off", argv[0]); return (TCL_ERROR); } /* Otherwise make the current cutplane inactive */ data->Cp_on[id] = 0; GS_unset_cplane(id); return (TCL_OK); } /* state_cp_obj -- Return the state (on/off) of the given cutplane. Arguments: None Returns: None Side Effects: None */ int state_cp_obj(Nv_data * data, Tcl_Interp * interp, int id, char **argv, int argc) { /* Verify arguments */ if (argc != 2) { sprintf(interp->result, "Usage: %s state", argv[0]); return (TCL_ERROR); } /* Otherwise figure out the state */ if (data->Cp_on[id]) Tcl_SetResult(interp, "on", TCL_VOLATILE); else Tcl_SetResult(interp, "off", TCL_VOLATILE); return (TCL_OK); } /* cp_set_rot -- Set the rotation for the current cutplane. Arguments: dx, dy, dz - components of rotation Returns: None Side Effects: Sets the rotation parameters for the given cutplane. */ int cp_set_rot(Nv_data * data, Tcl_Interp * interp, int id, char **argv, int argc) { double dx, dy, dz; /* Verify arguments */ if (argc != 5) { sprintf(interp->result, "Usage: %s set_rot dx dy dz", argv[0]); return (TCL_ERROR); } /* Extract nummerical arguments */ if (Tcl_GetDouble(interp, argv[2], &dx) != TCL_OK) { sprintf(interp->result, "Error in %s set_rot %s %s %s, expected numerical argument in dx field", argv[0], argv[2], argv[3], argv[4]); return (TCL_ERROR); } if (Tcl_GetDouble(interp, argv[3], &dy) != TCL_OK) { sprintf(interp->result, "Error in %s set_rot %s %s %s, expected numerical argument in dy field", argv[0], argv[2], argv[3], argv[4]); return (TCL_ERROR); } if (Tcl_GetDouble(interp, argv[4], &dz) != TCL_OK) { sprintf(interp->result, "Error in %s set_rot %s %s %s, expected numerical argument in dz field", argv[0], argv[2], argv[3], argv[4]); return (TCL_ERROR); } /* Set internal rotation and call gsf library */ data->Cp_rot[id][X] = (float) dx; data->Cp_rot[id][Y] = (float) dy; data->Cp_rot[id][Z] = (float) dz; GS_set_cplane_rot(id, data->Cp_rot[id][X], data->Cp_rot[id][Y], data->Cp_rot[id][Z]); cp_draw(data->CurCplane, data, -1, -1); return (TCL_OK); } /* cp_set_trans -- Set the translation for the current cutplane. Arguments: dx, dy, dz - values for setting translation Returns: None Side Effects: Sets translation of current cutplane */ int cp_set_trans(Nv_data * data, Tcl_Interp * interp, int id, char **argv, int argc) { double dx, dy, dz; /* Verify arguments */ if (argc != 5) { sprintf(interp->result, "Usage: %s set_trans dx dy dz", argv[0]); return (TCL_ERROR); } /* Extract nummerical arguments */ if (Tcl_GetDouble(interp, argv[2], &dx) != TCL_OK) { sprintf(interp->result, "Error in %s set_trans %s %s %s, expected numerical argument in dx field", argv[0], argv[2], argv[3], argv[4]); return (TCL_ERROR); } if (Tcl_GetDouble(interp, argv[3], &dy) != TCL_OK) { sprintf(interp->result, "Error in %s set_trans %s %s %s, expected numerical argument in dy field", argv[0], argv[2], argv[3], argv[4]); return (TCL_ERROR); } if (Tcl_GetDouble(interp, argv[4], &dz) != TCL_OK) { sprintf(interp->result, "Error in %s set_trans %s %s %s, expected numerical argument in dz field", argv[0], argv[2], argv[3], argv[4]); return (TCL_ERROR); } /* Set internal rotation and call gsf library */ data->Cp_trans[id][X] = (float) dx; data->Cp_trans[id][Y] = (float) dy; data->Cp_trans[id][Z] = (float) dz; GS_set_cplane_trans(id, data->Cp_trans[id][X], data->Cp_trans[id][Y], data->Cp_trans[id][Z]); cp_draw(data->CurCplane, data, -1, -1); return (TCL_OK); } /* cp_get_rot -- Get the rotation values for the current cutplane. */ int cp_get_rot(Nv_data * data, Tcl_Interp * interp, int id, char **argv, int argc) { char x[32], y[32], z[32]; if (argc != 2) { sprintf(interp->result, "Usage: %s get_rot", argv[0]); return (TCL_ERROR); } sprintf(x, "%f", data->Cp_rot[id][X]); sprintf(y, "%f", data->Cp_rot[id][Y]); sprintf(z, "%f", data->Cp_rot[id][Z]); Tcl_AppendElement(interp, x); Tcl_AppendElement(interp, y); Tcl_AppendElement(interp, z); return (TCL_OK); } /* cp_get_trans -- Get the translation values for the current cutplane. */ int cp_get_trans(Nv_data * data, Tcl_Interp * interp, int id, char **argv, int argc) { char x[32], y[32], z[32]; if (argc != 2) { sprintf(interp->result, "Usage: %s get_trans", argv[0]); return (TCL_ERROR); } sprintf(x, "%f", data->Cp_trans[id][X]); sprintf(y, "%f", data->Cp_trans[id][Y]); sprintf(z, "%f", data->Cp_trans[id][Z]); Tcl_AppendElement(interp, x); Tcl_AppendElement(interp, y); Tcl_AppendElement(interp, z); return (TCL_OK); } /* get_cp_idnum -- Strip the id number out of the name of a cutplane object. Arguments: Name of cutplane object Returns: Integer id of cutplane object Side Effects: None */ int get_cp_idnum(char *name) { static char comp[] = "Ncutplane"; /* Strip out "Ncutplane" from name */ return (atoi(&name[strlen(comp)])); }