/* ui_raytracing.c: user interface raytracing menu */ #include #include #include #include #include "ui.h" #include "uit.h" #include "raytracing.h" #include "canvas.h" #include "camera.h" #include "error.h" #include "statistics.h" #include "render.h" /*************************** RayTracing Menu ******************************/ static int busy_raytracing = FALSE; /**************************************************************************/ static int DoRayTracing(void /* char *filename, FILE *fp, int ispipe, Widget filenamePromptBox */) { /* XtUnmanageChild(filenamePromptBox); */ CanvasPushMode(CANVASMODE_RENDER); /* make sure the dialog box has disappeared and the scene is redrawn * before starting to raytrace */ /* CheckForEvents(); CanvasCancelRedraw(); */ Camera.changed = FALSE; renderopts.render_raytraced_image = TRUE; busy_raytracing = TRUE; RayTrace(NULL, NULL, FALSE/* filename, fp, ispipe */); busy_raytracing = FALSE; CanvasPullMode(); return 0; /* The file selection box has been unmanaged already */ } /**************************************************************************/ static void RayTracingRunStopCallback(Widget w, XtPointer client_data, XtPointer call_data) { #ifdef ASK_FOR_FILENAME Widget filenamePromptBox = (Widget)client_data; #endif if(RayTracing == NULL) { Error(0, "Specify raytracing method first"); } else { if (!busy_raytracing) { #ifdef ASK_FOR_FILENAME XtManageChild(filenamePromptBox); #endif DoRayTracing(); } else { RayTracing->InterruptRayTracing(); } } } /* ++++++++++++++++++++++++ RayTracing Control Dialog ++++++++++++++++++ */ static void RayTracingControlCallback(Widget w, XtPointer client_data, XtPointer call_data) { if (RayTracing) RayTracing->ShowControlPanel(); else Error(NULL, "Specify a raytracing method first"); } /**************************************************************************/ /* format string to be used for printing statistics about the current or last * raytracing run. The format string is the text string assigned to the * raytracingStatsMessage label at startup and is extracted in CreateRayTracingStatsBox() * when creating the interface. */ static char *raytracingStatsFormatString = (char *)NULL; /* XmLabelClass widgets used to display the statstics about the current scene */ static Widget raytracingStatsMessage = (Widget)NULL; /* updates the raytracing statstics */ void UpdateRayTracingStats(void) { char buf[MAX_LABEL_STRING_LENGTH]; if (!raytracingStatsFormatString || !raytracingStatsMessage) return; sprintf(buf, raytracingStatsFormatString, rt_total_time/(float)CLOCKS_PER_SEC, rt_pixcount/(rt_total_time ? (rt_total_time/(float)CLOCKS_PER_SEC) : 1.), rt_raycount/(rt_total_time ? (rt_total_time/(float)CLOCKS_PER_SEC) : 1.)); SetLabelString(raytracingStatsMessage, buf); } /**************************************************************************/ /* called when the Update button on a stats dialog box is clicked: pops down the * statistics dialog box. */ static void UpdateRayTracingStatsCallback(Widget statsBox, XtPointer client_data, XtPointer call_data) { UpdateRayTracingStats(); } /**************************************************************************/ /* 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 CreateRayTracingStatsBox(Widget parent, char *name) { Widget statsBox = CreateDialog(parent, name); /* create a label widget inside the statsBox */ raytracingStatsMessage = CreateLabel(statsBox, "raytracingStatsMessage"); /* at startup, the text defined for the raytracingStatsMessage label widget is nothing * else than the printf format string to be used for printing the statistics. */ raytracingStatsFormatString = GetLabelString(raytracingStatsMessage); /* fill in the statstics for the current scene */ UpdateRayTracingStats(); XtAddCallback(statsBox, XmNokCallback, UpdateRayTracingStatsCallback, (XtPointer)NULL); XtAddCallback(statsBox, XmNcancelCallback, DismissStatsCallback, (XtPointer)NULL); return statsBox; } /**************************************************************************/ /* called when the user presses the 'Statistics' button in the raytracing menu */ static void ShowRayTracingStats(Widget statsButton, XtPointer client_data, XtPointer call_data) { Widget statsBox = (Widget)client_data; UpdateRayTracingStats(); XtManageChild(statsBox); } /**************************************************************************/ static void SetRayTracingMethodCallback(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 */ SetRayTracing((RAYTRACINGMETHOD *)client_data); CanvasPullMode(); } } static void CreateRayTracingMethodMenu(Widget parent) { Widget methodMenu = CreateSubMenu(parent, "raytracingMethodButton", "raytracingMethodMenu"); XtVaSetValues(methodMenu, XmNradioBehavior, True, NULL); CreateToggleButton(methodMenu, "NoRayTracingButton", (!RayTracing ? TRUE : FALSE), SetRayTracingMethodCallback, (XtPointer)NULL); ForAllRayTracingMethods(method) { CreateToggleButton(methodMenu, method->buttonName, (method == RayTracing ? TRUE : FALSE), SetRayTracingMethodCallback, (XtPointer)method); } EndForAll; } /**************************************************************************/ static void CreateRayTracingControlPanels(void *parent_widget) { ForAllRayTracingMethods(method) { method->CreateControlPanel(parent_widget); } EndForAll; } /**************************************************************************/ static void RayTracingRedisplayCallback(Widget w, XtPointer client_data, XtPointer call_data) { /* make sure the dialog box has disappeared and the scene is redrawn * before starting to raytrace */ CanvasPushMode(CANVASMODE_RENDER); /* CheckForEvents(); CanvasRedraw(); */ if (!RayTracing) Warning(NULL, "No ray tracing method active"); else if (!RayTracing->Redisplay || !RayTracing->Redisplay()) Warning(NULL, "No previous %s image available", RayTracing->fullName); else { /* redisplay was succesful */ Camera.changed = FALSE; renderopts.render_raytraced_image = TRUE; } CanvasPullMode(); } static void RayTracingReprojectCallback(Widget w, XtPointer client_data, XtPointer call_data) { /* make sure the dialog box has disappeared and the scene is redrawn * before starting to raytrace */ CanvasPushMode(CANVASMODE_RENDER); /* CheckForEvents(); CanvasRedraw(); */ if (!RayTracing) Warning(NULL, "No ray tracing method active"); else if (!RayTracing->Reproject || !RayTracing->Reproject()) Warning(NULL, "No previous %s image available", RayTracing->fullName); else { /* reproject was succesful */ Camera.changed = FALSE; renderopts.render_raytraced_image = TRUE; } CanvasPullMode(); } static int RayTracingSaveImage(char *fname, FILE *fp, int ispipe, Widget fsbox) { ImageOutputHandle *img = NULL; if (fp) { img = CreateRadianceImageOutputHandle(fname, fp, ispipe, Camera.hres, Camera.vres, reference_luminance/179.); if (!img) return 0; } if (!RayTracing) Warning(NULL, "No ray tracing method active"); else if (!RayTracing->SaveImage || !RayTracing->SaveImage(img)) Warning(NULL, "No previous %s image available", RayTracing->fullName); if (img) DeleteImageOutputHandle(img); return 1; /* unmanage the file section dialog */ } static Widget CreateSaveImageDialog(Widget parent, char *name) { return CreateFileSelectionDialog(parent, name, RayTracingSaveImage, "w"); } /**************************************************************************/ void CreateRayTracingMenu(Widget menuBar) { Widget raytracingMenu, raytracingControlButton; #ifdef ASK_FOR_FILENAME Widget filenamePromptBox; #endif raytracingMenu = CreateSubMenu(menuBar, "raytracingButton", "raytracingMenu"); CreateRayTracingMethodMenu(raytracingMenu); raytracingControlButton = CreatePushButton(raytracingMenu, "raytracingControlButton", RayTracingControlCallback, (XtPointer)NULL); CreateRayTracingControlPanels(raytracingControlButton); CreateSeparator(raytracingMenu, "raytracingSeparator"); #ifdef ASK_FOR_FILENAME /* dialog asking for a filename etc... */ filenamePromptBox = CreateFileSelectionDialog(raytracingMenu, "filenamePromptBox", DoRayTracing, "w"); #endif CreatePushButton(raytracingMenu, "raytracingRunStopButton", RayTracingRunStopCallback, (XtPointer)NULL /* filenamePromptBox */); busy_raytracing = FALSE; CreateSeparator(raytracingMenu, "raytracingSeparator"); /* redisplay last image button */ CreatePushButton(raytracingMenu, "raytracingRedisplayButton", RayTracingRedisplayCallback, NULL); #ifdef RT_REPROJECT_BUTTON CreatePushButton(raytracingMenu, "raytracingReprojectButton", RayTracingReprojectCallback, NULL); #endif /* save last image */ CreateCascadeDialog(raytracingMenu, "raytracingSaveImageButton", CreateSaveImageDialog, "filenamePromptBox", NULL, NULL); CreateSeparator(raytracingMenu, "raytracingSeparator"); CreateCascadeDialog(raytracingMenu, "statsButton", CreateRayTracingStatsBox, "statsBox", ShowRayTracingStats, NULL); }