/* ui_radiance.c: user interface radiance menu */ #include #include "ui.h" #include "uit.h" #include "radiance.h" #include "statistics.h" #include "scene.h" #include "canvas.h" #include "render.h" #include "error.h" /************************** Radiance menu ********************************/ /* ++++++++++++++++++++++++ Radiance Method submenu ++++++++++++++++++ */ static void SetRadianceMethodCallback(Widget w, XtPointer client_data, XtPointer call_data) { int set = ((XmToggleButtonCallbackStruct *)call_data)->set; if (set == XmSET) { CanvasPushMode(CANVASMODE_WORKING); /* it may take a little while */ SetRadianceMethod((RADIANCEMETHOD *)client_data); CanvasPullMode(); RenderNewDisplayList(); RenderScene(); } } static void CreateRadianceMethodMenu(Widget parent) { Widget methodMenu = CreateSubMenu(parent, "radianceMethodButton", "radianceMethodMenu"); XtVaSetValues(methodMenu, XmNradioBehavior, True, NULL); CreateToggleButton(methodMenu, "NoRadianceButton", (!Radiance ? TRUE : FALSE), SetRadianceMethodCallback, (XtPointer)NULL); ForAllRadianceMethods(method) { CreateToggleButton(methodMenu, method->buttonName, (method == Radiance ? TRUE : FALSE), SetRadianceMethodCallback, (XtPointer)method); } EndForAll; } /* ++++++++++++++++++++++++ Radiance Control Panels ++++++++++++++++++ */ static Widget controlPanelParent; /* needed for updating control panels */ static void CreateRadianceControlPanels(Widget parent) { controlPanelParent = parent; ForAllRadianceMethods(method) { method->CreateControlPanel((void *)parent); } EndForAll; } /* ++++++++++++++++++++++++ Radiance Run/Stop button ++++++++++++++++++ */ static int radiance_running; int interrupt_radiance; void UpdateRadianceStats(void); /* Does one step with the current radiance method. Returns TRUE * when the computations need to be interrupted or are converged. */ int DoRadianceOneStep(void) { int done; renderopts.render_raytraced_image = FALSE; if (!World || !Radiance) return TRUE; CanvasPushMode(CANVASMODE_WORKING); done = Radiance->DoStep(); CanvasPullMode(); UpdateRadianceStats(); RenderNewDisplayList(); RenderScene(); return done; } /* invoked when the user presses the run/stop button in the radiance menu */ static void RadianceRunStopCallback(Widget w, XtPointer client_data, XtPointer call_data) { if (radiance_running) /* sometime in future, a Radiance-INterrupt method will be introduced that will * enable computation to be interrupted in the middle of an iteration step. */ interrupt_radiance = TRUE; else { int done; if (!Radiance) Error(NULL, "Specify a radiance method first"); radiance_running = TRUE; interrupt_radiance = FALSE; ProcessWaitingEvents(); done = FALSE; while (!interrupt_radiance && !done) { done = DoRadianceOneStep(); ProcessWaitingEvents(); } radiance_running = FALSE; interrupt_radiance = FALSE; } } static void RadianceOneIterationCallback(Widget w, XtPointer client_data, XtPointer call_data) { if (Radiance) { interrupt_radiance = FALSE; radiance_running = TRUE; DoRadianceOneStep(); interrupt_radiance = FALSE; radiance_running = FALSE; } else Error(NULL, "Specify a radiance method first"); } /* ++++++++++++++++++++++++ Radiance Control Dialog ++++++++++++++++++ */ static void RadianceControlCallback(Widget w, XtPointer client_data, XtPointer call_data) { if (Radiance) { if (Radiance->UpdateControlPanel) Radiance->UpdateControlPanel(controlPanelParent); Radiance->ShowControlPanel(); } else Error(NULL, "Specify a radiance method first"); } /* ++++++++++++++++++++++++ Radiance Statistics Dialog ++++++++++++++++++ */ /* The label widget used to show statistics information */ static Widget radianceStatsMessage = (Widget)NULL; /* updates the radiance statstics */ void UpdateRadianceStats(void) { char *message; if (!Radiance || !(message=Radiance->GetStats())) message = "No statistics information available"; SetLabelString(radianceStatsMessage, message); } /* called when the Update button on a stats dialog box is clicked: pops down the * statistics dialog box. */ static void UpdateRadianceStatsCallback(Widget statsBox, XtPointer client_data, XtPointer call_data) { UpdateRadianceStats(); } /* called when the Dismiss button on a stats dialog box is clicked: pops down the * statistics dialog box. */ static void DismissStatsCallback(Widget statsBox, XtPointer client_data, XtPointer call_data) { XtUnmanageChild(statsBox); } /* Creates a dialog box for showing statistics about the current scene */ static Widget CreateRadianceStatsDialog(Widget parent, char *name) { Widget statsBox = CreateDialog(parent, name); /* create a label widget inside the statsBox to show the statistics information. */ radianceStatsMessage = CreateLabel(statsBox, "radianceStatsMessage"); /* fill in the statstics for the current scene */ UpdateRadianceStats(); /* update and dismiss button are created automatically since a label string * is defined for them in the application resources file. */ XtAddCallback(statsBox, XmNokCallback, UpdateRadianceStatsCallback, (XtPointer)NULL); XtAddCallback(statsBox, XmNcancelCallback, DismissStatsCallback, (XtPointer)NULL); return statsBox; } /* called when the user presses the 'Statistics' button in the radiance menu */ static void ShowRadianceStats(Widget statsButton, XtPointer client_data, XtPointer call_data) { Widget statsBox = (Widget)client_data; UpdateRadianceStats(); XtManageChild(statsBox); } /* ++++++++++++++++++++++++ Radiance Main Menu ++++++++++++++++++ */ void CreateRadianceMenu(Widget menuBar) { Widget radianceMenu, radianceControlButton; radianceMenu = CreateSubMenu(menuBar, "radianceButton", "radianceMenu"); CreateRadianceMethodMenu(radianceMenu); radianceControlButton = CreatePushButton(radianceMenu, "radianceControlButton", RadianceControlCallback, (XtPointer)NULL); CreateRadianceControlPanels(radianceControlButton); CreateSeparator(radianceMenu, "radianceSeparator"); CreatePushButton(radianceMenu, "radianceOneIterationButton", RadianceOneIterationCallback, (XtPointer)NULL); CreatePushButton(radianceMenu, "radianceRunStopButton", RadianceRunStopCallback, (XtPointer)NULL); radiance_running = FALSE; CreateSeparator(radianceMenu, "radianceSeparator"); CreateCascadeDialog(radianceMenu, "statsButton", CreateRadianceStatsDialog, "statsBox", ShowRadianceStats, NULL); }