source: branches/blt4/packages/vizservers/vtkvis/RpVtkRenderServer.cpp @ 2409

Last change on this file since 2409 was 2409, checked in by gah, 13 years ago

update from branch

File size: 5.6 KB
Line 
1/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2/*
3 * Copyright (C) 2011, Purdue Research Foundation
4 *
5 * Author: Leif Delgass <ldelgass@purdue.edu>
6 */
7
8#include <cstdio>
9#include <cstring>
10#include <cstdlib>
11#include <string>
12#include <sstream>
13#include <unistd.h>
14#include <signal.h>
15
16#ifdef WANT_TRACE
17#include <sys/time.h>
18#endif
19
20#include "Trace.h"
21#include "RpVtkRenderServer.h"
22#include "RpVtkRendererCmd.h"
23#include "RpVtkRenderer.h"
24#include "PPMWriter.h"
25#include "TGAWriter.h"
26
27using namespace Rappture::VtkVis;
28
29int Rappture::VtkVis::g_fdIn = STDIN_FILENO; ///< Input file descriptor
30int Rappture::VtkVis::g_fdOut = STDOUT_FILENO; ///< Output file descriptor
31FILE *Rappture::VtkVis::g_fIn = stdin; ///< Input file handle
32FILE *Rappture::VtkVis::g_fOut = stdout; ///< Output file handle
33FILE *Rappture::VtkVis::g_fLog = NULL; ///< Trace logging file handle
34Renderer *Rappture::VtkVis::g_renderer = NULL; ///< Main render worker
35
36#define ELAPSED_TIME(t1, t2) \
37    ((t1).tv_sec == (t2).tv_sec ? (((t2).tv_usec - (t1).tv_usec)/1.0e+3f) : \
38     (((t2).tv_sec - (t1).tv_sec))*1.0e+3f + (float)((t2).tv_usec - (t1).tv_usec)/1.0e+3f)
39
40static void
41writeFrame(int fd, vtkUnsignedCharArray *imgData)
42{
43#ifdef DEBUG
44    if (g_renderer->getCameraMode() == Renderer::IMAGE) {
45        double xywh[4];
46        g_renderer->getScreenWorldCoords(xywh);
47        TRACE("Image bbox: %g %g %g %g",
48              xywh[0],
49              (xywh[1] + xywh[3]),
50              (xywh[0] + xywh[2]),
51              xywh[1]);
52    }
53
54#ifdef RENDER_TARGA
55    writeTGAFile("/tmp/frame.tga",
56                 imgData->GetPointer(0),
57                 g_renderer->getWindowWidth(),
58                 g_renderer->getWindowHeight(),
59                 TARGA_BYTES_PER_PIXEL);
60#else
61    writeTGAFile("/tmp/frame.tga",
62                 imgData->GetPointer(0),
63                 g_renderer->getWindowWidth(),
64                 g_renderer->getWindowHeight(),
65                 TARGA_BYTES_PER_PIXEL,
66                 true);
67#endif
68
69#else
70    if (g_renderer->getCameraMode() == Renderer::IMAGE) {
71        double xywh[4];
72        g_renderer->getScreenWorldCoords(xywh);
73        std::ostringstream oss;
74        oss.precision(12);
75        // Send upper left and lower right corners as bbox
76        oss << "nv>image -type image -bbox {"
77            << std::scientific
78            << xywh[0] << " "
79            << (xywh[1] + xywh[3]) << " "
80            << (xywh[0] + xywh[2]) << " "
81            << xywh[1] << "} -bytes";
82
83#ifdef RENDER_TARGA
84        writeTGA(fd, oss.str().c_str(),
85                 imgData->GetPointer(0),
86                 g_renderer->getWindowWidth(),
87                 g_renderer->getWindowHeight(),
88                 TARGA_BYTES_PER_PIXEL);
89#else
90        writePPM(fd, oss.str().c_str(),
91                 imgData->GetPointer(0),
92                 g_renderer->getWindowWidth(),
93                 g_renderer->getWindowHeight());
94#endif
95    } else {
96#ifdef RENDER_TARGA
97        writeTGA(fd, "nv>image -type image -bytes",
98                 imgData->GetPointer(0),
99                 g_renderer->getWindowWidth(),
100                 g_renderer->getWindowHeight(),
101                 TARGA_BYTES_PER_PIXEL);
102#else
103        writePPM(fd, "nv>image -type image -bytes",
104                 imgData->GetPointer(0),
105                 g_renderer->getWindowWidth(),
106                 g_renderer->getWindowHeight());
107#endif
108    }
109#endif
110}
111
112static void
113initService()
114{
115    const char *user = getenv("USER");
116    char *logName = NULL;
117    int logNameLen = 0;
118
119    if (user == NULL) {
120        logNameLen = 19+1;
121        logName = (char *)calloc(logNameLen, sizeof(char));
122        strncpy(logName, "/tmp/vtkvis_log.txt", logNameLen);
123    }
124    else {
125        logNameLen = 16+strlen(user)+4+1;
126        logName = (char *)calloc(logNameLen, sizeof(char));
127        strncpy(logName, "/tmp/vtkvis_log_", logNameLen);
128        strncat(logName, user, strlen(user));
129        strncat(logName, ".txt", 4);
130    }
131
132    // open log and map stderr to log file
133    g_fLog = fopen(logName, "w");
134    close(STDERR_FILENO);
135    dup2(fileno(g_fLog), STDERR_FILENO);
136    // flush junk
137    fflush(stderr);
138
139    // clean up malloc'd memory
140    if (logName != NULL) {
141        free(logName);
142    }
143}
144
145static void
146exitService()
147{
148    // close log file
149    if (g_fLog != NULL) {
150        fclose(g_fLog);
151        g_fLog = NULL;
152    }
153}
154
155int
156main(int argc, char *argv[])
157{
158    // Ignore SIGPIPE.  **Is this needed? **
159    signal(SIGPIPE, SIG_IGN);
160    initService();
161    InitLog();
162
163    TRACE("Starting VTKVis Server");
164
165    g_fIn = stdin;
166    g_fOut = stdout;
167    g_fdIn = fileno(stdin);
168    g_fdOut = fileno(stdout);
169
170    /* This synchronizes the client with the server, so that the client
171     * doesn't start writing commands before the server is ready. It could
172     * also be used to supply information about the server (version, memory
173     * size, etc). */
174    fprintf(stdout, "VtkVis 1.0\n");
175    fflush(stdout);
176
177    g_renderer = new Renderer();
178    vtkSmartPointer<vtkUnsignedCharArray> imgData =
179        vtkSmartPointer<vtkUnsignedCharArray>::New();
180
181    Tcl_Interp *interp = initTcl();
182
183    int ret = 0;
184
185    while (1) {
186        ret = processCommands(interp, g_fIn, g_fOut);
187        if (ret < 0)
188            break;
189
190        if (g_renderer->render()) {
191            TRACE("Rendering new frame");
192            g_renderer->getRenderedFrame(imgData);
193            writeFrame(g_fdOut, imgData);
194        } else {
195            TRACE("No render required");
196        }
197
198        if (feof(g_fIn))
199            break;
200    }
201
202    exitTcl(interp);
203    interp = NULL;
204
205    delete g_renderer;
206    g_renderer = NULL;
207
208    TRACE("Exiting VTKVis Server");
209
210    CloseLog();
211    exitService();
212
213    return ret;
214}
215
Note: See TracBrowser for help on using the repository browser.