/* This file is part of the FElt finite element analysis package. Copyright (C) 1993-2000 Jason I. Gobat and Darren C. Atkinson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /************************************************************************ * File: velvet.c * * * * Description: This file contains the routines for the top level of * * the velvet application. * ************************************************************************/ # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include "problem.h" # include "fe.h" # include "error.h" # include "definition.h" # include "Drawing.h" # include "FileDialog.h" # include "OutputDialog.h" # include "ElementList.h" # include "Constraint.h" # include "Element.h" # include "Force.h" # include "Material.h" # include "Load.h" # include "Colors.h" # include "Node.h" # include "Canvas.h" # include "Solution.h" # include "Analysis.h" # include "LoadCase.h" # include "Wireframe.h" # include "Contour.h" # include "dialog.h" # include "procedures.h" # include "globals.h" # include "callbacks.h" # include "panel.h" # include "vfe.h" # include "interface.h" # include "check.xbm" # include "question.xbm" # include "menu16.xbm" # include "popup.xbm" # include "FElt.icon" static String defaults_2d = "\ *shapeStyle: Oval\n\ *control*spacer.height: 119\n\ *control*MenuButton*height: 19\n\ *control*Command*height: 19\n\ *elementDialog*MenuButton*shapeStyle: Rectangle\n\ *nodeDialog*MenuButton*shapeStyle: Rectangle\n\ *elementDialog*help*shapeStyle: Oval\n\ *nodeDialog*help*shapeStyle: Oval\n\ "; static String defaults_3d = "\ *shapeStyle: Rectangle\n\ *control*spacer.height: 43\n\ *control*MenuButton*height: 26\n\ *control*Command*height: 26\n\ "; static char *defaults [ ] = { # include "velvet.ad.h" NULL }; static char *about_message = "\ Velvet v3.02 copyright 1993-2000 by\n\ Jason I. Gobat (jgobat@mit.edu) and\n\ Darren C. Atkinson (atkinson@ucsd.edu)"; /* the global dialogs that we will create in main() or on the fly */ FileDialog dumpd; FileDialog filed; CanvasDialog canvas_d; SolutionDialog solution_d; WireframeDialog wireframe_d; ContourDialog contour_d; ConstraintDialog constraint_d; ForceDialog force_d; LoadDialog load_d; LoadCaseDialog loadcase_d; MaterialDialog material_d; ElementDialog element_d; NodeDialog node_d; ElementList element_l; AnalysisDialog analysis_d; ColorsDialog colors_d; Dialog *info_dialog; PanelId last_command = -1; /************************************************************************ * Function: PanelCallback * * * * Parameters: widget - callback widget (ignored) * * clientData - pointer to panel id * * callData - callback data (ignored) * * * * Return value: none * * * * Calls: ??? * * * * Called by: X11 * * * * Global data: changeflag may be modified * * * * Description: Panelcallback is called when an action is taken on the * * control panel. The client data is a pointer to the * * panel id which indicates what action is to be taken. * ************************************************************************/ void PanelCallback (widget, clientData, callData) Widget widget; XtPointer clientData; XtPointer callData; { if (!edit_mode) { last_command = *(PanelId *) clientData; switch (*(PanelId *) clientData) { case AddNode: EditAddNode (); break; case DeleteNode: EditDeleteNode (); break; case EditNode: EditNodeNumber (); break; case MoveNodeId: MoveNodeNumber (); break; case MassNode: EditNodalMass (); break; case RenumberId: OptimizeNumbering (); break; case RenumberSolveId: ToggleRenumberStatus (); break; case AddElt: EditAddElement (); break; case DeleteElt: EditDeleteElement (); break; case EditElement: EditElementNumber (); break; case SetType: ElementListPopup (element_l); break; case Generate: GenerateElements (); break; case DefMaterial: MaterialDialogPopup (material_d); break; case OpenMaterial: OpenMaterialFile (); break; case SaveMaterial: WriteMaterialFile (); break; case ApplyMaterial: EditApplyMaterial (); break; case ApplyForce: EditApplyForce (); break; case ApplyLoad: EditApplyLoad ( ); break; case ApplyConstraint: EditApplyConstraint (); break; case DefForce: ForceDialogPopup (force_d); break; case DefLoad: LoadDialogPopup (load_d); break; case DefConstraint: ConstraintDialogPopup (constraint_d); break; case ProbAnalysis: AnalysisDialogPopup (analysis_d); break; case LoadCases: LoadCaseDialogPopup (loadcase_d); break; case AnimateId: SetupAnimate ( ); break; case Solve: SetupAndSolve ( ); break; case Output: SolutionDialogPopup (solution_d); break; case Wireframe: WireframeDialogPopup (wireframe_d); break; case Contour: ContourDialogPopup (contour_d); break; case PlotDisplacement: SetupDisplacements (True); break; case PlotStress: SetupStresses (True); break; case PlotStructure: SetupStructure (True); break; case Configure: CanvasDialogPopup (canvas_d); break; case ColorControl: ColorsDialogPopup (colors_d); break; case Recolor: RecolorCanvas ( ); break; case ZoomOut: ZoomAll (); break; case ZoomIn: ZoomStart (); break; case SaveXWD: DumpDrawingArea (drawing, "Save Drawing Area", True); break; case NodeNumbersOnOff: ToggleNodeNumberStatus (); break; case EltNumbersOnOff: ToggleEltNumberStatus (); break; case SnapOnOff: ToggleSnapStatus (); break; case GridOnOff: ToggleGridStatus (); break; case LineTool: ToolsDrawLine (); break; case Circle: ToolsDrawCircle (); break; case Arc: ToolsDrawArc (); break; case Rectangle: ToolsDrawRectangle (); break; case Polygon: ToolsDrawPolygon (); break; case Text: ToolsDrawText (); break; case DeleteTool: ToolsDeleteFigure (); break; case MoveFigure: MoveTool (); break; case NewId: StartNew (); break; case Open: OpenFile (); break; case Save: if (!filename [0]) WriteNamedFile (False); else { if (!WriteVFeltFile (False)) changeflag = False; } break; case SaveAll: WriteNamedFile (True); break; case SaveAs: WriteNamedFile (False); break; case Restore: RestoreOriginal (); break; case Exit: QuitVelvet (); break; case Info: PopupDialog (info_dialog, about_message, NULL, NULL); break; case Quit: case Abort: break; } /* end switch top of control panel */ } /* end if !edit_mode */ else { switch (*(PanelId *) clientData) { case Configure: CanvasDialogPopup (canvas_d); break; case ColorControl: ColorsDialogPopup (colors_d); break; case SnapOnOff: ToggleSnapStatus (); break; case GridOnOff: ToggleGridStatus (); break; case NodeNumbersOnOff: ToggleNodeNumberStatus (); break; case EltNumbersOnOff: ToggleEltNumberStatus (); break; case DefMaterial: MaterialDialogPopup (material_d); break; case DefForce: ForceDialogPopup (force_d); break; case DefLoad: LoadDialogPopup (load_d); break; case DefConstraint: ConstraintDialogPopup (constraint_d); break; case Info: PopupDialog (info_dialog, about_message, NULL, NULL); break; default: XBell (XtDisplay (toplevel), 20); } /* end switch bottom of control panel */ } } /************************************************************************ * Function: SelectCallback ************************************************************************/ void SelectCallback (w, clientData, callData) Widget w; XtPointer clientData; XtPointer callData; { DrawingReport *report; FigureAttributes attributes; Figure figure; Node node; Element element; Drawn drawn; report = (DrawingReport *) callData; if (report -> event -> type != ButtonPress) return; figure = DW_FindFigure (w, report -> unsnapped.x, report -> unsnapped.y); if (figure == NULL) return; DW_GetAttributes (w, figure, &attributes); if (attributes.user_data == NULL) return; node = (Node) attributes.user_data; element = (Element) attributes.user_data; drawn = (Drawn) node -> aux; if (drawn -> type == DrawnNode) { if (report -> event -> xbutton.button == 1) { NodeDialogDisplay (node_d, node); NodeDialogPopup (node_d); } else if (report -> event -> xbutton.button == 2) DoMoveNode (node, True); else if (report -> event -> xbutton.button == 3) { ConstraintDialogDisplay (constraint_d, node -> constraint); ConstraintDialogPopup (constraint_d); if (node -> force) { ForceDialogDisplay (force_d, node -> force); ForceDialogPopup (force_d); } NodeDialogDisplay (node_d, node); NodeDialogPopup (node_d); } } else if (drawn -> type == DrawnElement) { if (report -> event -> xbutton.button == 1) { ElementDialogDisplay (element_d, element); ElementDialogPopup (element_d); } else if (report -> event -> xbutton.button == 3) { ElementDialogDisplay (element_d, element); ElementDialogPopup (element_d); MaterialDialogDisplay (material_d, element -> material); MaterialDialogPopup (material_d); if (element -> numdistributed > 0) { LoadDialogDisplay (load_d, element -> distributed [1]); LoadDialogPopup (load_d); } } } } static XrmOptionDescRec options [ ] = { {"-sensitive", "*sensitiveMenus", XrmoptionNoArg, "True"}, {"+sensitive", "*sensitiveMenus", XrmoptionNoArg, "False"}, {"-numbers", "*numbers", XrmoptionNoArg, "True"}, {"+numbers", "*numbers", XrmoptionNoArg, "False"}, {"-nodeColor", "*nodeColor", XrmoptionSepArg, NULL}, {"-elementColor", "*elementColor", XrmoptionSepArg, NULL}, {"-toolColor", "*toolColor", XrmoptionSepArg, NULL}, {"-labelFont", "*labelFont", XrmoptionSepArg, NULL}, {"-toolFont", "*toolFont", XrmoptionSepArg, NULL}, }; struct resources { Boolean sensitive; Boolean numbers; String nodecolor; String elementcolor; String toolcolor; String labelfont; String toolfont; } appResources; # define offset(field) XtOffsetOf (struct resources, field) static XtResource Resources [ ] = { {"sensitiveMenus", "SensitiveMenus", XtRBoolean, sizeof (Boolean), offset (sensitive), XtRImmediate, (XtPointer) True}, {"numbers", "Numbers", XtRBoolean, sizeof (Boolean), offset (numbers), XtRImmediate, (XtPointer) True}, {"nodeColor", "NodeColor", XtRString, sizeof (String), offset (nodecolor), XtRImmediate, (XtPointer) "blue"}, {"elementColor", "ElementColor", XtRString, sizeof (String), offset (elementcolor), XtRImmediate, (XtPointer) "black"}, {"toolColor", "ToolColor", XtRString, sizeof (String), offset (toolcolor), XtRImmediate, (XtPointer) "red"}, {"labelFont", "LabelFont", XtRString, sizeof (String), offset (labelfont), XtRImmediate, (XtPointer) "5x8"}, {"toolFont", "ToolFont", XtRString, sizeof (String), offset (toolfont), XtRImmediate, (XtPointer) "fg-22"}, }; # undef offset static void GetArgs ( ) { XtGetApplicationResources (toplevel, &appResources, Resources, XtNumber (Resources), NULL, 0); sensitive_menus = appResources.sensitive; canvas -> node_color = appResources.nodecolor; canvas -> element_color = appResources.elementcolor; canvas -> tool_color = appResources.toolcolor; canvas -> label_font = appResources.labelfont; canvas -> tool_font = appResources.toolfont; canvas -> node_numbers = appResources.numbers; canvas -> element_numbers = appResources.numbers; } /************************************************************************ * Function: main * * * * Description: Main is the startup function for the velvet program. * ************************************************************************/ int main (argc, argv) int argc; char *argv [ ]; { int status = 0; int i, j; char string [32]; Arg arglist [14]; Dimension width; Dimension height; float xscale; float yscale; Cardinal count; XtTranslations trans; Window window; Pixmap icon_pixmap; Pixmap question; Pixmap menu16; Pixmap popup; Widget form, control, bottom; Widget coord; Widget dummy; XrmDatabase our_db; XrmDatabase real_db; static String dump_toggles [ ] = {"XWD", "PostScript"}; static String error_buttons [ ] = {"okay"}; static String output_buttons [ ] = {"dismiss", "save"}; static String proceed_buttons [ ] = {"okay", "cancel"}; static String qsave_buttons [ ] = {"yes", "no", "cancel"}; /* Parse the initial command line options */ if (ParseCppOptions (&argc, argv)) { fputs ("Oops", stderr); exit (1); } add_all_definitions ( ); /* Create the top level widgets. */ toplevel = XtAppInitialize (&app_context, "Velvet", options, XtNumber (options), &argc, argv, defaults, NULL, 0); /* Determine if the 2D or 3D defaults should be used and load them. */ width = 0; dummy = XtVaCreateWidget ("dummy", commandWidgetClass, toplevel, NULL); XtVaGetValues (dummy, "shadowWidth", &width, NULL); XtDestroyWidget (dummy); our_db = XrmGetStringDatabase (width != 0 ? defaults_3d : defaults_2d); real_db = XtDatabase (XtDisplay (toplevel)); XrmCombineDatabase (our_db, &real_db, False); /* Create the primary widgets. */ icon_pixmap = XCreateBitmapFromData (XtDisplay (toplevel), RootWindowOfScreen (XtScreen (toplevel)), FElt_bits, FElt_width, FElt_height); XtSetArg (arglist [0], XtNiconPixmap, icon_pixmap); XtSetValues (toplevel, arglist, 1); form = XtCreateManagedWidget ("form", formWidgetClass, toplevel, NULL, 0); control = XtCreateManagedWidget ("control", formWidgetClass, form, NULL, 0); viewport = XtCreateManagedWidget ("viewport", viewportWidgetClass, form, NULL, 0); drawing = XtCreateManagedWidget ("drawing", drawingWidgetClass, viewport, NULL, 0); coord = XtCreateManagedWidget ("coord", labelWidgetClass, form, NULL, 0); bottom = XtCreateManagedWidget ("bottom", formWidgetClass, form, NULL, 0); statusline = XtCreateManagedWidget ("status", labelWidgetClass, bottom, NULL, 0); count = 0; XtSetArg (arglist [count], XtNeditType, XawtextEdit); count ++; entry = XtCreateManagedWidget ("entry", asciiTextWidgetClass, bottom, arglist, count); /* Focus all keyboard input to the text entry widget. */ XtSetKeyboardFocus (form, entry); /* Create the bitmaps. */ window = RootWindowOfScreen (XtScreen (toplevel)); checkmark = XCreateBitmapFromData (XtDisplay(toplevel), window, check_bits, check_width, check_height); question = XCreateBitmapFromData (XtDisplay (toplevel), window, question_bits, question_width, question_height); menu16 = XCreateBitmapFromData (XtDisplay (toplevel), window, menu16_bits, menu16_width, menu16_height); popup = XCreateBitmapFromData (XtDisplay (toplevel), window, popup_bits, popup_width, popup_height); /* Create the control panel menus and buttons. */ for (i = 0; i < XtNumber (panel); i ++) { count = 0; if (panel [i].class == &menuButtonWidgetClass) { XtSetArg (arglist [0], XtNleftBitmap, menu16); count++; } else if (strcmp(panel [i].name,"info") == 0) { XtSetArg (arglist [0], XtNleftBitmap, question); count++; } else if (strcmp(panel [i].name,"materials_d") == 0) { XtSetArg (arglist [0], XtNleftBitmap, popup); count++; } else if (strcmp(panel [i].name,"forces_d") == 0) { XtSetArg (arglist [0], XtNleftBitmap, popup); count++; } else if (strcmp(panel [i].name,"loads_d") == 0) { XtSetArg (arglist [0], XtNleftBitmap, popup); count++; } else if (strcmp(panel [i].name,"constraints_d") == 0) { XtSetArg (arglist [0], XtNleftBitmap, popup); count++; } else if (panel [i].class != &commandWidgetClass) { XtSetArg (arglist [0], XtNlabel, ""); count++; } panel [i].button = XtCreateManagedWidget (panel [i].name, *panel [i].class,control,arglist, count); if (panel [i].class == &menuButtonWidgetClass) { sprintf (string, "%sMenu", panel [i].name); panel [i].menu = XtCreatePopupShell (string, simpleMenuWidgetClass, control, NULL, 0); for (j = 0; j < panel [i].numentries; j ++) { panel [i].menuentry [j].widget = XtCreateManagedWidget (panel [i].menuentry [j].name, smeBSBObjectClass, panel [i].menu, NULL, 0); XtAddCallback (panel [i].menuentry [j].widget, XtNcallback, PanelCallback, &panel [i].menuentry [j].id); } } else if (panel [i].class == &commandWidgetClass) XtAddCallback (panel [i].button, XtNcallback, PanelCallback, &panel [i].menuentry [0].id); } quitbutton = XtCreateManagedWidget ("quit", commandWidgetClass, control, NULL, 0); XtAddCallback (quitbutton, XtNcallback, QuitEdit, NULL); abortbutton = XtCreateManagedWidget ("abort", commandWidgetClass, control, NULL, 0); XtAddCallback (abortbutton, XtNcallback, AbortEdit, NULL); /* Create the canvas configuration so we can do the args */ canvas_d = CanvasDialogCreate (toplevel, drawing, "canvasDialog", "Canvas"); GetArgs ( ); /* Create the dialogs which we cannot simply create at first pop-up. */ info_dialog = CreateDialog (toplevel, "infod", Okay); filed = FileDialogCreate (toplevel, "fileDialog", NULL); dumpd = FileDialogCreate (toplevel, "dumpDialog", dump_toggles); error_dialog = OutputDialogCreate (toplevel, "errorDialog", error_buttons, XtNumber (error_buttons)); proceed_dialog = OutputDialogCreate (toplevel, "proceedDialog", proceed_buttons, XtNumber (proceed_buttons)); qsave_dialog = OutputDialogCreate (toplevel, "qsaveDialog", qsave_buttons, XtNumber (qsave_buttons)); output_dialog = OutputDialogCreate (toplevel, "outputDialog", output_buttons, XtNumber (output_buttons)); XtSetArg (arglist [0], XtNicon, icon_pixmap); XtSetValues (info_dialog -> dialogwidget, arglist, 1); element_l = ElementListCreate (toplevel, "elementList", "Element Type"); solution_d = SolutionDialogCreate (toplevel, "solutionDialog", "Output solution control"); wireframe_d = WireframeDialogCreate (toplevel, "wireframeDialog", "Wireframe Controls"); contour_d = ContourDialogCreate (toplevel, "contourDialog", "Contour Controls"); element_d = ElementDialogCreate (toplevel, "elementDialog", "Elements", ElementDialogChanged, (XtPointer) NULL); node_d = NodeDialogCreate (toplevel, "nodeDialog", "Nodes", NodeDialogChanged, (XtPointer) element_d); material_d = MaterialDialogCreate (toplevel, "materialDialog", "Materials", MaterialDialogChanged, (XtPointer) element_d); force_d = ForceDialogCreate (toplevel, "forceDialog", "Forces", ForceDialogChanged, (XtPointer) node_d); load_d = LoadDialogCreate (toplevel, "loadDialog", "Loads", LoadDialogChanged, (XtPointer) element_d); constraint_d = ConstraintDialogCreate (toplevel, "constraintDialog", "Constraints", ConstraintDialogChanged, (XtPointer) node_d); analysis_d = AnalysisDialogCreate (toplevel, "analysisDialog", "Problem and Analysis"); loadcase_d = LoadCaseDialogCreate (toplevel, "loadcaseDialog", "Load Cases"); colors_d = ColorsDialogCreate (toplevel, "colorsDialog", "Colors"); /* register the action table and set-up the translations */ XtAppAddActions (app_context, actiontable, XtNumber (actiontable)); trans = XtParseTranslationTable (default_translations); XtOverrideTranslations (entry, trans); /* Realize the top level widget */ XtRealizeWidget (toplevel); /* Configure the drawing widget */ count = 0; XtSetArg (arglist [count], XtNheight, &height); count++; XtSetArg (arglist [count], XtNwidth, &width); count++; XtGetValues (drawing, arglist, count); canvas -> xmin = 0.0; canvas -> xmax = 10.0; canvas -> ymin = 0.0; canvas -> ymax = 10.0; canvas -> grid_size = 1.0; canvas -> snap_size = 0.25; canvas -> snap = False; canvas -> grid = False; xscale = (float) width / (canvas -> xmax - canvas -> xmin); yscale = (float) height / (canvas -> ymax - canvas -> ymin); canvas -> scale = xscale; count = 0; XtSetArg (arglist [count], XtNxScale, Float2Arg (xscale)); count++; XtSetArg (arglist [count], XtNyScale, Float2Arg (yscale)); count++; XtSetArg (arglist [count], XtNcoordinates, coord); count++; XtSetValues (drawing, arglist, count); CanvasDialogSet (canvas_d); /* Configure the initial solution parameters */ solution -> eigen = False; solution -> orthonormal = False; solution -> transfer = False; solution -> felt = True; solution -> stress = False; solution -> displacement = False; solution -> structure = False; solution -> plot = False; solution -> mode_shapes = False; solution -> summary = False; solution -> debug = False; solution -> matrices = False; solution -> details = False; solution -> magnify = 100.0; solution -> s_component = 1; solution -> d_component = 1; solution -> zscale = 0.2; solution -> title = NULL; solution -> xrot = 40.0; solution -> yrot = -20.0; solution -> zrot = 0.0; solution -> hlhsr = False; solution -> plot_orig = True; SolutionDialogUpdate (solution_d); WireframeDialogUpdate (wireframe_d); ContourDialogUpdate (contour_d); solution -> renumber = True; ToggleRenumberStatus (); /* check to see if the user started with a filename */ StartNew ( ); if (argc > 1) { if (access (argv[1], F_OK) == 0) { if (access (argv[1], R_OK) != 0) error ("File %s is not accessible, check file permissions.", argv[1]); else { strcpy (filename, argv [1]); status = VelvetReadFeltFile (filename); } } else strcpy (filename, argv [1]); } else filename [0] = 0; if (status == 0) { UpdateFilenameDisplay (); SetNormalMode ( ); canvas -> node_numbers = !canvas -> node_numbers; canvas -> element_numbers = !canvas -> element_numbers; ToggleNodeNumberStatus ( ); ToggleEltNumberStatus ( ); } /* Enter the main event loop */ changeflag = False; XtAppMainLoop (app_context); return 0; /* NOTREACHED */ }