Changeset 2573 for trunk/packages
- Timestamp:
- Sep 22, 2011, 8:13:47 PM (13 years ago)
- Location:
- trunk/packages/vizservers/vtkvis
- Files:
-
- 4 added
- 17 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/packages/vizservers/vtkvis/CmdProc.cpp
r2492 r2573 10 10 11 11 #include "CmdProc.h" 12 13 using namespace Rappture; 12 14 13 15 /** … … 22 24 */ 23 25 static int 24 BinaryOpSearch( Rappture::CmdSpec *specs,26 BinaryOpSearch(CmdSpec *specs, 25 27 int nSpecs, 26 28 char *string) /* Name of minor operation to search for */ … … 35 37 length = strlen(string); 36 38 while (low <= high) { 37 Rappture::CmdSpec *specPtr;39 CmdSpec *specPtr; 38 40 int compare; 39 41 int median; … … 76 78 */ 77 79 static int 78 LinearOpSearch( Rappture::CmdSpec *specs,80 LinearOpSearch(CmdSpec *specs, 79 81 int nSpecs, 80 82 char *string) /* Name of minor operation to search for */ 81 83 { 82 Rappture::CmdSpec *specPtr;84 CmdSpec *specPtr; 83 85 char c; 84 86 size_t length; … … 120 122 */ 121 123 Tcl_ObjCmdProc * 122 Rappture::GetOpFromObj(Tcl_Interp *interp, 123 int nSpecs, 124 Rappture::CmdSpec *specs,/* Op specification array */125 int operPos, 126 127 int objc, 128 129 130 Tcl_Obj *const *objv, 124 Rappture::GetOpFromObj(Tcl_Interp *interp, /* Interpreter to report errors to */ 125 int nSpecs, /* Number of specifications in array */ 126 CmdSpec *specs, /* Op specification array */ 127 int operPos, /* Position of operation in argument 128 * list. */ 129 int objc, /* Number of arguments in the argument 130 * vector. This includes any prefixed 131 * arguments */ 132 Tcl_Obj *const *objv, /* Argument vector */ 131 133 int flags) 132 134 { -
trunk/packages/vizservers/vtkvis/CmdProc.h
r2492 r2573 19 19 * for a function pointer associated with the operation name. 20 20 */ 21 typedef struct{21 struct CmdSpec { 22 22 const char *name; /**< Name of operation */ 23 23 int minChars; /**< Minimum # characters to disambiguate */ … … 26 26 int maxArgs; /**< Maximum # args required */ 27 27 const char *usage; /**< Usage message */ 28 } CmdSpec;28 }; 29 29 30 typedef enum{30 enum CmdSpecIndex { 31 31 CMDSPEC_ARG0, /**< Op is the first argument. */ 32 32 CMDSPEC_ARG1, /**< Op is the second argument. */ … … 34 34 CMDSPEC_ARG3, /**< Op is the fourth argument. */ 35 35 CMDSPEC_ARG4 /**< Op is the fifth argument. */ 36 } CmdSpecIndex;36 }; 37 37 38 38 #define CMDSPEC_LINEAR_SEARCH 1 -
trunk/packages/vizservers/vtkvis/ColorMap.cpp
r2404 r2573 106 106 cp.value = 1.0; 107 107 108 #ifdef DEBUG 108 109 TRACE("New control point: %g = %g %g %g", 109 110 cp.value, cp.color[0], cp.color[1], cp.color[2]); 110 111 #endif 111 112 for (std::list<ControlPoint>::iterator itr = _controlPoints.begin(); 112 113 itr != _controlPoints.end(); ++itr) { … … 136 137 cp.value = 1.0; 137 138 139 #ifdef DEBUG 138 140 TRACE("New opacity control point: %g = %g", 139 141 cp.value, cp.alpha); 140 142 #endif 141 143 for (std::list<OpacityControlPoint>::iterator itr = _opacityControlPoints.begin(); 142 144 itr != _opacityControlPoints.end(); ++itr) { -
trunk/packages/vizservers/vtkvis/Makefile.in
r2533 r2573 24 24 25 25 GL_LIB_SPEC = -lGL -lm 26 PTHREAD_LIB_SPEC= -lpthread 26 27 27 28 TCL_LIB_SPEC = @TCL_LIB_SPEC@ … … 35 36 36 37 LIBS = \ 37 $(GL_LIB_SPEC) \38 38 $(TCL_LIB_SPEC) \ 39 39 $(VTK_LIB_SPEC) \ 40 $(GL_LIB_SPEC) \ 41 $(PTHREAD_LIB_SPEC) \ 40 42 -Wl,-rpath,$(LD_RUN_PATH) 41 43 … … 50 52 USE_GPU_RAYCASTING = yes 51 53 USE_OFFSCREEN_RENDERING = yes 54 USE_THREADS = #yes 52 55 53 56 #vtk uses deprecated strstream header (instead of sstream) … … 70 73 DEFINES += -DUSE_GPU_RAYCAST_MAPPER 71 74 endif 75 ifdef USE_THREADS 76 DEFINES += -DUSE_THREADS 77 endif 72 78 CXX_SWITCHES = $(CXXFLAGS) $(EXTRA_CFLAGS) $(DEFINES) $(INCLUDES) 73 79 … … 76 82 ColorMap.cpp \ 77 83 PPMWriter.cpp \ 84 ReadBuffer.cpp \ 78 85 RpContour2D.cpp \ 79 86 RpContour3D.cpp \ … … 96 103 ifdef USE_CUSTOM_AXES 97 104 SERVER_SRCS+=vtkRpCubeAxesActor2D.cpp 105 endif 106 ifdef USE_THREADS 107 SERVER_SRCS+=ResponseQueue.cpp 98 108 endif 99 109 … … 130 140 CmdProc.o: CmdProc.h 131 141 ColorMap.o: ColorMap.h RpMolecule.h Trace.h 132 PPMWriter.o: PPMWriter.h Trace.h 142 PPMWriter.o: PPMWriter.h ResponseQueue.h Trace.h 143 ReadBuffer.o: ReadBuffer.h Trace.h 144 ResponseQueue.o: ResponseQueue.h Trace.h 133 145 RpContour2D.o: RpContour2D.h RpVtkGraphicsObject.h RpVtkDataSet.h Trace.h 134 146 RpContour3D.o: RpContour3D.h RpVtkGraphicsObject.h RpVtkDataSet.h ColorMap.h Trace.h … … 143 155 RpVolume.o: RpVolume.h RpVtkGraphicsObject.h RpVtkDataSet.h ColorMap.h Trace.h 144 156 RpVtkDataSet.o: RpVtkDataSet.h Trace.h 145 RpVtkRenderer.o: RpVtkRenderer.h vtkRpCubeAxesActor2D.h RpVtkDataSet.h RpContour2D.h RpContour3D.h Rp Glyphs.h RpHeightMap.h RpLIC.h RpMolecule.h RpPolyData.h RpPseudoColor.h RpStreamlines.h RpVolume.h ColorMap.h Trace.h146 RpVtkRendererCmd.o: RpVtkRenderer.h vtkRpCubeAxesActor2D.h RpVtkDataSet.h RpContour2D.h RpContour3D.h Rp Glyphs.h RpHeightMap.h RpLIC.h RpMolecule.h RpPolyData.h RpPseudoColor.h RpStreamlines.h RpVolume.h ColorMap.h Trace.h CmdProc.h PPMWriter.h TGAWriter.h147 RpVtkRenderServer.o: RpVtkRenderServer.h RpVtkRendererCmd.h RpVtkRenderer.h vtkRpCubeAxesActor2D.h Trace.h PPMWriter.h TGAWriter.h157 RpVtkRenderer.o: RpVtkRenderer.h vtkRpCubeAxesActor2D.h RpVtkDataSet.h RpContour2D.h RpContour3D.h RpCutplane.h RpGlyphs.h RpHeightMap.h RpLIC.h RpMolecule.h RpPolyData.h RpPseudoColor.h RpStreamlines.h RpVolume.h ColorMap.h Trace.h 158 RpVtkRendererCmd.o: RpVtkRenderer.h vtkRpCubeAxesActor2D.h RpVtkDataSet.h RpContour2D.h RpContour3D.h RpCutplane.h RpGlyphs.h RpHeightMap.h RpLIC.h RpMolecule.h RpPolyData.h RpPseudoColor.h RpStreamlines.h RpVolume.h ColorMap.h ReadBuffer.h ResponseQueue.h Trace.h CmdProc.h PPMWriter.h TGAWriter.h 159 RpVtkRenderServer.o: RpVtkRenderServer.h RpVtkRendererCmd.h RpVtkRenderer.h vtkRpCubeAxesActor2D.h ReadBuffer.h ResponseQueue.h Trace.h PPMWriter.h TGAWriter.h 148 160 Trace.o: Trace.h 149 TGAWriter.o: TGAWriter.h Trace.h161 TGAWriter.o: TGAWriter.h ResponseQueue.h Trace.h 150 162 vtkRpCubeAxesActor2D.o: vtkRpCubeAxesActor2D.h -
trunk/packages/vizservers/vtkvis/PPMWriter.cpp
r2492 r2573 12 12 #include <sys/uio.h> 13 13 14 #include "Trace.h" 14 15 #include "PPMWriter.h" 15 #include "Trace.h" 16 #ifdef USE_THREADS 17 #include "ResponseQueue.h" 18 #endif 16 19 17 20 using namespace Rappture::VtkVis; 21 22 #ifdef USE_THREADS 23 24 /** 25 * \brief Writes image data as PPM binary data to the client. 26 * 27 * The PPM binary format is very simple. 28 * 29 * P6 w h 255\n 30 * 3-byte RGB pixel data. 31 * 32 * The client (using the TkImg library) will do less work to unpack this 33 * format, as opposed to BMP or PNG. 34 * 35 * Note that currently the image data has bottom to top scanlines. This 36 * routine could be made even simpler (faster) if the image data had top 37 * to bottom scanlines. 38 * 39 * \param[in] queue Pointer to ResponseQueue to write to 40 * \param[in] cmdName Command name to send (byte length will be appended) 41 * \param[in] data Image data 42 * \param[in] width Width of image in pixels 43 * \param[in] height Height of image in pixels 44 */ 45 void 46 Rappture::VtkVis::queuePPM(ResponseQueue *queue, const char *cmdName, 47 const unsigned char *data, int width, int height) 48 { 49 #define PPM_MAXVAL 255 50 char header[200]; 51 52 TRACE("Entering (%dx%d)\n", width, height); 53 // Generate the PPM binary file header 54 snprintf(header, sizeof(header), "P6 %d %d %d\n", width, height, 55 PPM_MAXVAL); 56 57 size_t headerLength = strlen(header); 58 size_t dataLength = width * height * 3; 59 60 char command[200]; 61 snprintf(command, sizeof(command), "%s %lu\n", cmdName, 62 (unsigned long)headerLength + dataLength); 63 64 size_t cmdLength; 65 cmdLength = strlen(command); 66 67 size_t length; 68 unsigned char *mesg; 69 70 length = headerLength + dataLength + cmdLength; 71 mesg = (unsigned char *)malloc(length); 72 if (mesg == NULL) { 73 ERROR("can't allocate %ld bytes for the image message", length); 74 return; 75 } 76 memcpy(mesg, command, cmdLength); 77 memcpy(mesg + cmdLength, header, headerLength); 78 79 size_t bytesPerRow = width * 3; 80 unsigned char *destRowPtr = mesg + length - bytesPerRow; 81 int y; 82 unsigned char *srcRowPtr = const_cast<unsigned char *>(data); 83 for (y = 0; y < height; y++) { 84 memcpy(destRowPtr, srcRowPtr, bytesPerRow); 85 srcRowPtr += bytesPerRow; 86 destRowPtr -= bytesPerRow; 87 } 88 89 Response *response; 90 if (strncmp(cmdName, "nv>legend", 9) == 0) { 91 response = new Response(Response::LEGEND); 92 } else { 93 response = new Response(Response::IMAGE); 94 } 95 response->setMessage(mesg, length, Response::DYNAMIC); 96 queue->enqueue(response); 97 TRACE("Leaving (%dx%d)\n", width, height); 98 } 99 #else 18 100 19 101 /** … … 39 121 */ 40 122 void 41 Rappture::VtkVis::writePPM(int fd, const char *cmdName, const unsigned char *data,42 int width, int height)123 Rappture::VtkVis::writePPM(int fd, const char *cmdName, 124 const unsigned char *data, int width, int height) 43 125 { 44 126 #define PPM_MAXVAL 255 … … 47 129 TRACE("Entering (%dx%d)\n", width, height); 48 130 // Generate the PPM binary file header 49 snprintf(header, sizeof(header), "P6 %d %d %d\n", width, height, PPM_MAXVAL); 131 snprintf(header, sizeof(header), "P6 %d %d %d\n", width, height, 132 PPM_MAXVAL); 50 133 51 134 size_t headerLength = strlen(header); … … 79 162 } 80 163 if (writev(fd, iov, nRecs) < 0) { 81 164 ERROR("write failed: %s\n", strerror(errno)); 82 165 } 83 166 free(iov); … … 85 168 TRACE("Leaving (%dx%d)\n", width, height); 86 169 } 170 171 #endif /*USE_THREADS*/ -
trunk/packages/vizservers/vtkvis/PPMWriter.h
r2492 r2573 9 9 #define __RAPPTURE_VTKVIS_PPMWRITER_H__ 10 10 11 #ifdef USE_THREADS 12 #include "ResponseQueue.h" 13 #endif 14 11 15 namespace Rappture { 12 16 namespace VtkVis { 13 17 #ifdef USE_THREADS 14 18 extern 15 void writePPM(int fd, const char *cmdName, const unsigned char *data, int width, int height); 16 19 void queuePPM(ResponseQueue *queue, const char *cmdName, 20 const unsigned char *data, int width, int height); 21 #else 22 extern 23 void writePPM(int fd, const char *cmdName, 24 const unsigned char *data, int width, int height); 25 #endif 17 26 } 18 27 } 19 20 28 #endif -
trunk/packages/vizservers/vtkvis/RpGlyphs.cpp
r2492 r2573 44 44 Glyphs::~Glyphs() 45 45 { 46 #ifdef WANT_TRACE 47 if (_dataSet != NULL) 48 TRACE("Deleting Glyphs for %s", _dataSet->getName().c_str()); 49 else 50 TRACE("Deleting Glyphs with NULL DataSet"); 51 #endif 46 52 } 47 53 -
trunk/packages/vizservers/vtkvis/RpLIC.cpp
r2514 r2573 36 36 LIC::~LIC() 37 37 { 38 #ifdef WANT_TRACE 39 if (_dataSet != NULL) 40 TRACE("Deleting LIC for %s", _dataSet->getName().c_str()); 41 else 42 TRACE("Deleting LIC with NULL DataSet"); 43 #endif 38 44 } 39 45 -
trunk/packages/vizservers/vtkvis/RpStreamlines.cpp
r2533 r2573 55 55 Streamlines::~Streamlines() 56 56 { 57 #ifdef WANT_TRACE 58 if (_dataSet != NULL) 59 TRACE("Deleting Streamlines for %s", _dataSet->getName().c_str()); 60 else 61 TRACE("Deleting Streamlines with NULL DataSet"); 62 #endif 57 63 } 58 64 … … 189 195 bary[2] = 1.0 - bary[0] - bary[1]; 190 196 191 TRACE("bary %g %g %g", bary[0], bary[1], bary[2]);197 //TRACE("bary %g %g %g", bary[0], bary[1], bary[2]); 192 198 // Convert to cartesian coords 193 199 for (int i = 0; i < 3; i++) { … … 221 227 } 222 228 bary[3] = 1.0 - bary[0] - bary[1] - bary[2]; 223 TRACE("bary %g %g %g %g", bary[0], bary[1], bary[2], bary[3]);229 //TRACE("bary %g %g %g %g", bary[0], bary[1], bary[2], bary[3]); 224 230 // Convert to cartesian coords 225 231 for (int i = 0; i < 3; i++) { -
trunk/packages/vizservers/vtkvis/RpVtkRenderServer.cpp
r2423 r2573 9 9 #include <cstring> 10 10 #include <cstdlib> 11 #include <string> 12 #include <sstream> 11 #include <cerrno> 13 12 #include <unistd.h> 14 13 #include <signal.h> … … 18 17 #endif 19 18 19 #include <string> 20 #include <sstream> 21 20 22 #include "Trace.h" 23 #include "ReadBuffer.h" 21 24 #include "RpVtkRenderServer.h" 22 25 #include "RpVtkRendererCmd.h" … … 24 27 #include "PPMWriter.h" 25 28 #include "TGAWriter.h" 29 #ifdef USE_THREADS 30 #include <pthread.h> 31 #include "ResponseQueue.h" 32 #endif 26 33 27 34 using namespace Rappture::VtkVis; … … 29 36 int Rappture::VtkVis::g_fdIn = STDIN_FILENO; ///< Input file descriptor 30 37 int Rappture::VtkVis::g_fdOut = STDOUT_FILENO; ///< Output file descriptor 31 FILE *Rappture::VtkVis::g_fIn = stdin; ///< Input file handle32 38 FILE *Rappture::VtkVis::g_fOut = stdout; ///< Output file handle 33 39 FILE *Rappture::VtkVis::g_fLog = NULL; ///< Trace logging file handle 34 40 Renderer *Rappture::VtkVis::g_renderer = NULL; ///< Main render worker 41 ReadBuffer *Rappture::VtkVis::g_inBufPtr = NULL; ///< Socket read buffer 35 42 36 43 #define ELAPSED_TIME(t1, t2) \ … … 38 45 (((t2).tv_sec - (t1).tv_sec))*1.0e+3f + (float)((t2).tv_usec - (t1).tv_usec)/1.0e+3f) 39 46 47 #ifdef USE_THREADS 40 48 static void 41 writeFrame(int fd, vtkUnsignedCharArray *imgData)49 queueFrame(ResponseQueue *queue, vtkUnsignedCharArray *imgData) 42 50 { 43 51 #ifdef DEBUG … … 65 73 TARGA_BYTES_PER_PIXEL, 66 74 true); 67 #endif 75 #endif /*RENDER_TARGA*/ 68 76 69 77 #else … … 82 90 83 91 #ifdef RENDER_TARGA 92 queueTGA(queue, oss.str().c_str(), 93 imgData->GetPointer(0), 94 g_renderer->getWindowWidth(), 95 g_renderer->getWindowHeight(), 96 TARGA_BYTES_PER_PIXEL); 97 #else 98 queuePPM(queue, oss.str().c_str(), 99 imgData->GetPointer(0), 100 g_renderer->getWindowWidth(), 101 g_renderer->getWindowHeight()); 102 #endif /*RENDER_TARGA*/ 103 } else { 104 #ifdef RENDER_TARGA 105 queueTGA(queue, "nv>image -type image -bytes", 106 imgData->GetPointer(0), 107 g_renderer->getWindowWidth(), 108 g_renderer->getWindowHeight(), 109 TARGA_BYTES_PER_PIXEL); 110 #else 111 queuePPM(queue, "nv>image -type image -bytes", 112 imgData->GetPointer(0), 113 g_renderer->getWindowWidth(), 114 g_renderer->getWindowHeight()); 115 #endif /*RENDER_TARGA*/ 116 } 117 #endif /*DEBUG*/ 118 } 119 120 #else 121 122 static void 123 writeFrame(int fd, vtkUnsignedCharArray *imgData) 124 { 125 #ifdef DEBUG 126 if (g_renderer->getCameraMode() == Renderer::IMAGE) { 127 double xywh[4]; 128 g_renderer->getScreenWorldCoords(xywh); 129 TRACE("Image bbox: %g %g %g %g", 130 xywh[0], 131 (xywh[1] + xywh[3]), 132 (xywh[0] + xywh[2]), 133 xywh[1]); 134 } 135 136 #ifdef RENDER_TARGA 137 writeTGAFile("/tmp/frame.tga", 138 imgData->GetPointer(0), 139 g_renderer->getWindowWidth(), 140 g_renderer->getWindowHeight(), 141 TARGA_BYTES_PER_PIXEL); 142 #else 143 writeTGAFile("/tmp/frame.tga", 144 imgData->GetPointer(0), 145 g_renderer->getWindowWidth(), 146 g_renderer->getWindowHeight(), 147 TARGA_BYTES_PER_PIXEL, 148 true); 149 #endif /*RENDER_TARGA*/ 150 151 #else 152 if (g_renderer->getCameraMode() == Renderer::IMAGE) { 153 double xywh[4]; 154 g_renderer->getCameraZoomRegion(xywh); 155 std::ostringstream oss; 156 oss.precision(12); 157 // Send upper left and lower right corners as bbox 158 oss << "nv>image -type image -bbox {" 159 << std::scientific 160 << xywh[0] << " " 161 << xywh[1] << " " 162 << xywh[2] << " " 163 << xywh[3] << "} -bytes"; 164 165 #ifdef RENDER_TARGA 84 166 writeTGA(fd, oss.str().c_str(), 85 167 imgData->GetPointer(0), … … 92 174 g_renderer->getWindowWidth(), 93 175 g_renderer->getWindowHeight()); 94 #endif 176 #endif /*RENDER_TARGA*/ 95 177 } else { 96 178 #ifdef RENDER_TARGA … … 105 187 g_renderer->getWindowWidth(), 106 188 g_renderer->getWindowHeight()); 107 #endif 108 } 109 #endif 110 } 189 #endif /*RENDER_TARGA*/ 190 } 191 #endif /*DEBUG*/ 192 } 193 #endif /*USE_THREADS*/ 111 194 112 195 static void … … 153 236 } 154 237 238 #ifdef USE_THREADS 239 static void * 240 readerThread(void *clientData) 241 { 242 ResponseQueue *queue = (ResponseQueue *)clientData; 243 Tcl_Interp *interp; 244 245 TRACE("Starting reader thread"); 246 interp = (Tcl_Interp *)queue->clientData(); 247 vtkSmartPointer<vtkUnsignedCharArray> imgData = 248 vtkSmartPointer<vtkUnsignedCharArray>::New(); 249 for (;;) { 250 if (processCommands(interp, g_inBufPtr, g_fdOut) < 0) 251 break; 252 253 if (g_renderer->render()) { 254 TRACE("Rendering new frame"); 255 g_renderer->getRenderedFrame(imgData); 256 queueFrame(queue, imgData); 257 } else { 258 TRACE("No render required"); 259 } 260 261 if (g_inBufPtr->status() == ReadBuffer::ENDFILE) 262 break; 263 } 264 return NULL; 265 } 266 267 static void * 268 writerThread(void *clientData) 269 { 270 ResponseQueue *queue = (ResponseQueue *)clientData; 271 272 TRACE("Starting writer thread"); 273 for (;;) { 274 Response *response; 275 276 response = queue->dequeue(); 277 if (fwrite(response->message(), sizeof(char), response->length(), 278 g_fOut) != response->length()) { 279 ERROR("short write while trying to write %ld bytes", 280 response->length()); 281 } 282 fflush(g_fOut); 283 delete response; 284 if (feof(g_fOut)) 285 break; 286 } 287 return NULL; 288 } 289 290 #endif /*USE_THREADS*/ 291 155 292 int 156 293 main(int argc, char *argv[]) … … 159 296 signal(SIGPIPE, SIG_IGN); 160 297 initService(); 161 InitLog();298 initLog(); 162 299 163 300 TRACE("Starting VTKVis Server"); 164 165 g_fIn = stdin;166 g_fOut = stdout;167 g_fdIn = fileno(stdin);168 g_fdOut = fileno(stdout);169 301 170 302 /* This synchronizes the client with the server, so that the client … … 172 304 * also be used to supply information about the server (version, memory 173 305 * size, etc). */ 174 fprintf( stdout, "VtkVis 1.0\n");175 fflush( stdout);306 fprintf(g_fOut, "VtkVis 1.0\n"); 307 fflush(g_fOut); 176 308 177 309 g_renderer = new Renderer(); 310 g_inBufPtr = new ReadBuffer(g_fdIn, 1<<12); 311 312 Tcl_Interp *interp = Tcl_CreateInterp(); 313 314 #ifdef USE_THREADS 315 ResponseQueue *queue = new ResponseQueue((void *)interp); 316 initTcl(interp, (ClientData)queue); 317 318 pthread_t readerThreadId, writerThreadId; 319 if (pthread_create(&readerThreadId, NULL, &readerThread, queue) < 0) { 320 ERROR("Can't create reader thread: %s", strerror(errno)); 321 } 322 if (pthread_create(&writerThreadId, NULL, &writerThread, queue) < 0) { 323 ERROR("Can't create writer thread: %s", strerror(errno)); 324 } 325 if (pthread_join(readerThreadId, NULL) < 0) { 326 ERROR("Can't join reader thread: %s", strerror(errno)); 327 } else { 328 TRACE("Reader thread exited"); 329 } 330 // Writer thread is probably blocked on sem_wait, so cancel instead 331 // of joining 332 if (pthread_cancel(writerThreadId) < 0) { 333 ERROR("Can't cancel writer thread: %s", strerror(errno)); 334 } else { 335 TRACE("Cancelled writer thread"); 336 } 337 338 TRACE("Deleting ResponseQueue"); 339 delete queue; 340 queue = NULL; 341 #else 342 initTcl(interp, (ClientData)NULL); 343 178 344 vtkSmartPointer<vtkUnsignedCharArray> imgData = 179 345 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) 346 for (;;) { 347 if (processCommands(interp, g_inBufPtr, g_fdOut) < 0) 188 348 break; 189 349 … … 196 356 } 197 357 198 if (feof(g_fIn)) 199 break; 200 } 201 358 if (g_inBufPtr->status() == ReadBuffer::ENDFILE) 359 break; 360 } 361 #endif 362 363 TRACE("Stopping Tcl interpreter"); 202 364 exitTcl(interp); 203 365 interp = NULL; 204 366 367 TRACE("Deleting ReadBuffer"); 368 delete g_inBufPtr; 369 g_inBufPtr = NULL; 370 371 TRACE("Deleting renderer"); 205 372 delete g_renderer; 206 373 g_renderer = NULL; … … 208 375 TRACE("Exiting VTKVis Server"); 209 376 210 CloseLog();377 closeLog(); 211 378 exitService(); 212 379 213 return ret; 214 } 215 380 return 0; 381 } -
trunk/packages/vizservers/vtkvis/RpVtkRenderServer.h
r2514 r2573 16 16 extern int g_fdIn; 17 17 extern int g_fdOut; 18 extern FILE *g_fIn;19 18 extern FILE *g_fOut; 20 19 extern FILE *g_fLog; 21 20 extern Renderer *g_renderer; 21 extern ReadBuffer *g_inBufPtr; 22 22 23 23 } -
trunk/packages/vizservers/vtkvis/RpVtkRendererCmd.cpp
r2514 r2573 19 19 #include "Trace.h" 20 20 #include "CmdProc.h" 21 #include "ReadBuffer.h" 21 22 #include "RpVtkRendererCmd.h" 22 23 #include "RpVtkRenderServer.h" … … 24 25 #include "PPMWriter.h" 25 26 #include "TGAWriter.h" 27 #ifdef USE_THREADS 28 #include "ResponseQueue.h" 29 #endif 26 30 27 31 using namespace Rappture::VtkVis; 32 33 static int lastCmdStatus; 34 35 #ifdef USE_THREADS 36 static void 37 QueueResponse(ClientData clientData, const void *bytes, size_t len, 38 Response::AllocationType allocType) 39 { 40 ResponseQueue *queue = (ResponseQueue *)clientData; 41 42 Response *response; 43 44 response = new Response(Response::DATA); 45 response->setMessage((unsigned char *)bytes, len, allocType); 46 queue->enqueue(response); 47 } 48 #else 28 49 29 50 static ssize_t … … 43 64 } 44 65 45 static size_t 46 SocketRead(void *bytes, size_t len) 47 { 48 #ifdef notdef 49 size_t ofs = 0; 50 ssize_t bytesRead = 0; 51 while ((bytesRead = read(g_fdIn, bytes + ofs, len - ofs)) > 0) { 52 ofs += bytesRead; 53 if (ofs == len) 54 break; 55 } 56 TRACE("bytesRead: %lu", ofs); 57 return ofs; 58 #else 59 size_t bytesRead = fread(bytes, 1, len, g_fIn); 60 TRACE("bytesRead: %lu", bytesRead); 61 return bytesRead; 62 #endif 66 #endif /*USE_THREADS*/ 67 68 static bool 69 SocketRead(char *bytes, size_t len) 70 { 71 ReadBuffer::BufferStatus status; 72 status = g_inBufPtr->followingData((unsigned char *)bytes, len); 73 TRACE("followingData status: %d", status); 74 return (status == ReadBuffer::OK); 63 75 } 64 76 … … 68 80 int result; 69 81 70 result = Tcl_Eval(interp, Tcl_DStringValue(dsPtr)); 82 TRACE("command: '%s'", Tcl_DStringValue(dsPtr)); 83 lastCmdStatus = TCL_OK; 84 result = Tcl_EvalEx(interp, Tcl_DStringValue(dsPtr), 85 Tcl_DStringLength(dsPtr), 86 TCL_EVAL_DIRECT | TCL_EVAL_GLOBAL); 71 87 Tcl_DStringSetLength(dsPtr, 0); 72 88 if (lastCmdStatus == TCL_BREAK) { 89 return TCL_BREAK; 90 } 91 lastCmdStatus = result; 73 92 return result; 74 93 } … … 380 399 pos[0], pos[1], pos[2], focalPt[0], focalPt[1], focalPt[2], viewUp[0], viewUp[1], viewUp[2]); 381 400 401 #ifdef USE_THREADS 402 QueueResponse(clientData, buf, strlen(buf), Response::VOLATILE); 403 #else 382 404 ssize_t bytesWritten = SocketWrite(buf, strlen(buf)); 383 384 405 if (bytesWritten < 0) { 385 406 return TCL_ERROR; 386 407 } 408 #endif 387 409 return TCL_OK; 388 410 } … … 1656 1678 } 1657 1679 char *data = (char *)malloc(nbytes); 1658 size_t bytesRead = SocketRead(data, nbytes); 1659 if (bytesRead < 0) { 1680 if (!SocketRead(data, nbytes)) { 1660 1681 free(data); 1661 1682 return TCL_ERROR; … … 1698 1719 1699 1720 char buf[256]; 1700 snprintf(buf, sizeof(buf), "nv>dataset scalar pixel %d %d %g %s\n", x, y, value, name); 1701 1702 ssize_t bytesWritten = SocketWrite(buf, strlen(buf)); 1721 int length; 1722 1723 length = snprintf(buf, sizeof(buf), "nv>dataset scalar pixel %d %d %g %s\n", 1724 x, y, value, name); 1725 1726 #ifdef USE_THREADS 1727 QueueResponse(clientData, buf, length, Response::VOLATILE); 1728 #else 1729 ssize_t bytesWritten = SocketWrite(buf, length); 1703 1730 1704 1731 if (bytesWritten < 0) { 1705 1732 return TCL_ERROR; 1706 1733 } 1734 #endif 1707 1735 return TCL_OK; 1708 1736 } … … 1726 1754 1727 1755 char buf[256]; 1728 snprintf(buf, sizeof(buf), "nv>dataset scalar world %g %g %g %g %s\n", x, y, z, value, name); 1729 1730 ssize_t bytesWritten = SocketWrite(buf, strlen(buf)); 1731 1756 int length; 1757 1758 length = snprintf(buf, sizeof(buf), 1759 "nv>dataset scalar world %g %g %g %g %s\n", 1760 x, y, z, value, name); 1761 1762 #ifdef USE_THREADS 1763 QueueResponse(clientData, buf, length, Response::VOLATILE); 1764 #else 1765 ssize_t bytesWritten = SocketWrite(buf, length); 1732 1766 if (bytesWritten < 0) { 1733 1767 return TCL_ERROR; 1734 1768 } 1769 #endif 1735 1770 return TCL_OK; 1736 1771 } … … 1773 1808 1774 1809 char buf[256]; 1775 snprintf(buf, sizeof(buf), "nv>dataset vector pixel %d %d %g %g %g %s\n", x, y, 1776 value[0], value[1], value[2], name); 1777 1778 ssize_t bytesWritten = SocketWrite(buf, strlen(buf)); 1810 int length; 1811 length = snprintf(buf, sizeof(buf), 1812 "nv>dataset vector pixel %d %d %g %g %g %s\n", 1813 x, y, 1814 value[0], value[1], value[2], name); 1815 1816 #ifdef USE_THREADS 1817 QueueResponse(clientData, buf, length, Response::VOLATILE); 1818 #else 1819 ssize_t bytesWritten = SocketWrite(buf, length); 1779 1820 1780 1821 if (bytesWritten < 0) { 1781 1822 return TCL_ERROR; 1782 1823 } 1824 #endif /*USE_THREADS*/ 1783 1825 return TCL_OK; 1784 1826 } … … 1802 1844 1803 1845 char buf[256]; 1804 snprintf(buf, sizeof(buf), "nv>dataset vector world %g %g %g %g %g %g %s\n", x, y, z, 1805 value[0], value[1], value[2], name); 1806 1807 ssize_t bytesWritten = SocketWrite(buf, strlen(buf)); 1846 int length; 1847 length = snprintf(buf, sizeof(buf), 1848 "nv>dataset vector world %g %g %g %g %g %g %s\n", 1849 x, y, z, 1850 value[0], value[1], value[2], name); 1851 #ifdef USE_THREADS 1852 QueueResponse(clientData, buf, length, Response::VOLATILE); 1853 #else 1854 ssize_t bytesWritten = SocketWrite(buf, length); 1808 1855 1809 1856 if (bytesWritten < 0) { 1810 1857 return TCL_ERROR; 1811 1858 } 1859 #endif /*USE_THREADS*/ 1812 1860 return TCL_OK; 1813 1861 } … … 1872 1920 oss << "}\n"; 1873 1921 len += 2; 1874 1875 size_t bytesWritten = SocketWrite(oss.str().c_str(), len); 1922 #ifdef USE_THREADS 1923 QueueResponse(clientData, oss.str().c_str(), len, Response::VOLATILE); 1924 #else 1925 ssize_t bytesWritten = SocketWrite(oss.str().c_str(), len); 1876 1926 1877 1927 if (bytesWritten < 0) { 1878 1928 return TCL_ERROR; 1879 1929 } 1930 #endif /*USE_THREADS*/ 1880 1931 return TCL_OK; 1881 1932 } … … 2921 2972 2922 2973 static int 2974 ImageFlushCmd(ClientData clientData, Tcl_Interp *interp, int objc, 2975 Tcl_Obj *const *objv) 2976 { 2977 lastCmdStatus = TCL_BREAK; 2978 return TCL_OK; 2979 } 2980 2981 static int 2923 2982 LegendCmd(ClientData clientData, Tcl_Interp *interp, int objc, 2924 2983 Tcl_Obj *const *objv) … … 2981 3040 2982 3041 #ifdef DEBUG 3042 # ifdef RENDER_TARGA 2983 3043 writeTGAFile("/tmp/legend.tga", imgData->GetPointer(0), width, height, 2984 3044 TARGA_BYTES_PER_PIXEL); 3045 # else 3046 writeTGAFile("/tmp/legend.tga", imgData->GetPointer(0), width, height, 3047 TARGA_BYTES_PER_PIXEL, true); 3048 # endif 2985 3049 #else 2986 3050 char cmd[256]; 2987 3051 snprintf(cmd, sizeof(cmd), "nv>legend {%s} {%s} %g %g", 2988 3052 colorMapName, title.c_str(), range[0], range[1]); 2989 #ifdef RENDER_TARGA 3053 3054 # ifdef USE_THREADS 3055 # ifdef RENDER_TARGA 3056 ResponseQueue *queue = (ResponseQueue *)clientData; 3057 queueTGA(queue, cmd, imgData->GetPointer(0), width, height, 3058 TARGA_BYTES_PER_PIXEL); 3059 # else 3060 ResponseQueue *queue = (ResponseQueue *)clientData; 3061 queuePPM(queue, cmd, imgData->GetPointer(0), width, height); 3062 # endif 3063 # else 3064 # ifdef RENDER_TARGA 2990 3065 writeTGA(g_fdOut, cmd, imgData->GetPointer(0), width, height, 2991 2992 # else3066 TARGA_BYTES_PER_PIXEL); 3067 # else 2993 3068 writePPM(g_fdOut, cmd, imgData->GetPointer(0), width, height); 2994 # endif2995 # endif2996 3069 # endif 3070 # endif // USE_THREADS 3071 #endif // DEBUG 2997 3072 return TCL_OK; 2998 3073 } … … 4684 4759 } 4685 4760 char *data = (char *)malloc(nbytes); 4686 size_t bytesRead = SocketRead(data, nbytes); 4687 if (bytesRead < 0) { 4761 if (!SocketRead(data, nbytes)) { 4688 4762 free(data); 4689 4763 return TCL_ERROR; … … 4733 4807 } 4734 4808 char *data = (char *)malloc(nbytes); 4735 size_t bytesRead = SocketRead(data, nbytes); 4736 if (bytesRead < 0) { 4809 if (!SocketRead(data, nbytes)) { 4737 4810 free(data); 4738 4811 return TCL_ERROR; … … 4973 5046 4974 5047 static Rappture::CmdSpec streamlinesOps[] = { 4975 {"add", 1, StreamlinesAddOp, 2, 3, "?dataSetName?"},4976 {"ccolor", 1, StreamlinesColorOp, 5, 6, "r g b ?dataSetName?"},4977 {"colormap", 7, StreamlinesColorMapOp, 3, 4, "colorMapName ?dataSetName?"},4978 {"colormode", 7, StreamlinesColorModeOp, 3, 4, "mode ?dataSetNme?"},4979 {"delete", 1, StreamlinesDeleteOp, 2, 3, "?dataSetName?"},5048 {"add", 1, StreamlinesAddOp, 2, 3, "?dataSetName?"}, 5049 {"ccolor", 1, StreamlinesColorOp, 5, 6, "r g b ?dataSetName?"}, 5050 {"colormap", 7, StreamlinesColorMapOp, 3, 4, "colorMapName ?dataSetName?"}, 5051 {"colormode", 7, StreamlinesColorModeOp, 3, 4, "mode ?dataSetNme?"}, 5052 {"delete", 1, StreamlinesDeleteOp, 2, 3, "?dataSetName?"}, 4980 5053 {"edges", 1, StreamlinesEdgeVisibilityOp, 3, 4, "bool ?dataSetName?"}, 4981 {"length", 2, StreamlinesLengthOp, 3, 4, "length ?dataSetName?"},4982 {"lighting", 3, StreamlinesLightingOp, 3, 4, "bool ?dataSetName?"},4983 {"linecolor", 5, StreamlinesLineColorOp, 5, 6, "r g b ?dataSetName?"},4984 {"lines", 5, StreamlinesLinesOp, 2, 3, "?dataSetName?"},4985 {"linewidth", 5, StreamlinesLineWidthOp, 3, 4, "width ?dataSetName?"},4986 {"opacity", 2, StreamlinesOpacityOp, 3, 4, "val ?dataSetName?"},4987 {"orient", 2, StreamlinesOrientOp, 6, 7, "qw qx qy qz ?dataSetName?"},4988 {"pos", 1, StreamlinesPositionOp, 5, 6, "x y z ?dataSetName?"},4989 {"ribbons", 1, StreamlinesRibbonsOp, 4, 5, "width angle ?dataSetName?"},4990 {"scale", 2, StreamlinesScaleOp, 5, 6, "sx sy sz ?dataSetName?"},4991 {"seed", 2, StreamlinesSeedOp, 3, 14, "op params... ?dataSetName?"},4992 {"tubes", 1, StreamlinesTubesOp, 4, 5, "numSides radius ?dataSetName?"},4993 {"visible", 1, StreamlinesVisibleOp, 3, 4, "bool ?dataSetName?"}5054 {"length", 2, StreamlinesLengthOp, 3, 4, "length ?dataSetName?"}, 5055 {"lighting", 3, StreamlinesLightingOp, 3, 4, "bool ?dataSetName?"}, 5056 {"linecolor", 5, StreamlinesLineColorOp, 5, 6, "r g b ?dataSetName?"}, 5057 {"lines", 5, StreamlinesLinesOp, 2, 3, "?dataSetName?"}, 5058 {"linewidth", 5, StreamlinesLineWidthOp, 3, 4, "width ?dataSetName?"}, 5059 {"opacity", 2, StreamlinesOpacityOp, 3, 4, "val ?dataSetName?"}, 5060 {"orient", 2, StreamlinesOrientOp, 6, 7, "qw qx qy qz ?dataSetName?"}, 5061 {"pos", 1, StreamlinesPositionOp, 5, 6, "x y z ?dataSetName?"}, 5062 {"ribbons", 1, StreamlinesRibbonsOp, 4, 5, "width angle ?dataSetName?"}, 5063 {"scale", 2, StreamlinesScaleOp, 5, 6, "sx sy sz ?dataSetName?"}, 5064 {"seed", 2, StreamlinesSeedOp, 3, 14, "op params... ?dataSetName?"}, 5065 {"tubes", 1, StreamlinesTubesOp, 4, 5, "numSides radius ?dataSetName?"}, 5066 {"visible", 1, StreamlinesVisibleOp, 3, 4, "bool ?dataSetName?"} 4994 5067 }; 4995 5068 static int nStreamlinesOps = NumCmdSpecs(streamlinesOps); … … 5203 5276 5204 5277 static Rappture::CmdSpec volumeShadingOps[] = { 5205 {"ambient", 1, VolumeShadingAmbientOp, 4, 5, "coeff ?dataSetName?"},5206 {"diffuse", 1, VolumeShadingDiffuseOp, 4, 5, "coeff ?dataSetName?"},5278 {"ambient", 1, VolumeShadingAmbientOp, 4, 5, "coeff ?dataSetName?"}, 5279 {"diffuse", 1, VolumeShadingDiffuseOp, 4, 5, "coeff ?dataSetName?"}, 5207 5280 {"specular", 1, VolumeShadingSpecularOp, 5, 6, "coeff power ?dataSetName?"} 5208 5281 }; … … 5241 5314 5242 5315 static Rappture::CmdSpec volumeOps[] = { 5243 {"add", 1, VolumeAddOp, 2, 3, "?dataSetName?"},5316 {"add", 1, VolumeAddOp, 2, 3, "?dataSetName?"}, 5244 5317 {"colormap", 1, VolumeColorMapOp, 3, 4, "colorMapName ?dataSetName?"}, 5245 {"delete", 1, VolumeDeleteOp, 2, 3, "?dataSetName?"},5318 {"delete", 1, VolumeDeleteOp, 2, 3, "?dataSetName?"}, 5246 5319 {"lighting", 1, VolumeLightingOp, 3, 4, "bool ?dataSetName?"}, 5247 {"opacity", 2, VolumeOpacityOp, 3, 4, "val ?dataSetName?"},5248 {"orient", 2, VolumeOrientOp, 6, 7, "qw qx qy qz ?dataSetName?"},5320 {"opacity", 2, VolumeOpacityOp, 3, 4, "val ?dataSetName?"}, 5321 {"orient", 2, VolumeOrientOp, 6, 7, "qw qx qy qz ?dataSetName?"}, 5249 5322 {"pos", 1, VolumePositionOp, 5, 6, "x y z ?dataSetName?"}, 5250 {"scale", 2, VolumeScaleOp, 5, 6, "sx sy sz ?dataSetName?"},5251 {"shading", 2, VolumeShadingOp, 4, 6, "oper val ?dataSetName?"},5252 {"visible", 1, VolumeVisibleOp, 3, 4, "bool ?dataSetName?"}5323 {"scale", 2, VolumeScaleOp, 5, 6, "sx sy sz ?dataSetName?"}, 5324 {"shading", 2, VolumeShadingOp, 4, 6, "oper val ?dataSetName?"}, 5325 {"visible", 1, VolumeVisibleOp, 3, 4, "bool ?dataSetName?"} 5253 5326 }; 5254 5327 static int nVolumeOps = NumCmdSpecs(volumeOps); … … 5270 5343 /** 5271 5344 * \brief Execute commands from client in Tcl interpreter 5345 * 5346 * In this threaded model, the select call is for event compression. We 5347 * want to execute render server commands as long as they keep coming. 5348 * This lets us execute a stream of many commands but render once. This 5349 * benefits camera movements, screen resizing, and opacity changes 5350 * (using a slider on the client). The down side is you don't render 5351 * until there's a lull in the command stream. If the client needs an 5352 * image, it can issue an "imgflush" command. That breaks us out of the 5353 * read loop. 5272 5354 */ 5273 5355 int 5274 Rappture::VtkVis::processCommands(Tcl_Interp *interp, FILE *fin, FILE *fout) 5275 { 5276 Tcl_DString cmdbuffer; 5277 Tcl_DStringInit(&cmdbuffer); 5278 5279 int fdIn = fileno(fin); 5280 int fdOut = fileno(fout); 5281 int flags = fcntl(fdIn, F_GETFL, 0); 5282 fcntl(fdIn, F_SETFL, flags & ~O_NONBLOCK); 5283 5356 Rappture::VtkVis::processCommands(Tcl_Interp *interp, ReadBuffer *inBufPtr, 5357 int fdOut) 5358 { 5284 5359 int status = TCL_OK; 5285 int nCommands = 0; 5286 bool isComplete = false; 5287 while ((!feof(fin)) && (status == TCL_OK)) { 5288 while (!feof(fin)) { 5289 int c = fgetc(fin); 5290 if (c <= 0) { 5291 if (errno == EWOULDBLOCK) { 5292 break; 5293 } 5294 if (feof(fin)) 5295 return 1; 5296 else 5297 return c; 5360 5361 Tcl_DString command; 5362 Tcl_DStringInit(&command); 5363 fd_set readFds; 5364 struct timeval tv, *tvPtr; 5365 5366 FD_ZERO(&readFds); 5367 FD_SET(inBufPtr->file(), &readFds); 5368 tvPtr = NULL; /* Wait for the first read. This is so 5369 * that we don't spin when no data is 5370 * available. */ 5371 while (inBufPtr->isLineAvailable() || 5372 (select(1, &readFds, NULL, NULL, tvPtr) > 0)) { 5373 size_t numBytes; 5374 unsigned char *buffer; 5375 5376 /* A short read is treated as an error here because we assume that we 5377 * will always get commands line by line. */ 5378 if (inBufPtr->getLine(&numBytes, &buffer) != ReadBuffer::OK) { 5379 /* Terminate the server if we can't communicate with the client 5380 * anymore. */ 5381 if (inBufPtr->status() == ReadBuffer::ENDFILE) { 5382 TRACE("Exiting server on EOF from client"); 5383 return -1; 5384 } else { 5385 ERROR("Exiting server, failed to read from client: %s", 5386 strerror(errno)); 5387 return -1; 5298 5388 } 5299 char ch = (char)c; 5300 Tcl_DStringAppend(&cmdbuffer, &ch, 1); 5301 if (ch == '\n') { 5302 isComplete = Tcl_CommandComplete(Tcl_DStringValue(&cmdbuffer)); 5303 if (isComplete) { 5304 break; 5305 } 5389 } 5390 Tcl_DStringAppend(&command, (char *)buffer, numBytes); 5391 if (Tcl_CommandComplete(Tcl_DStringValue(&command))) { 5392 status = ExecuteCommand(interp, &command); 5393 if (status == TCL_BREAK) { 5394 return 1; /* This was caused by a "imgflush" 5395 * command. Break out of the read loop 5396 * and allow a new image to be 5397 * rendered. */ 5306 5398 } 5307 5399 } 5308 // no command? then we're done for now 5309 if (Tcl_DStringLength(&cmdbuffer) == 0) { 5310 break; 5311 } 5312 if (isComplete) { 5313 // back to original flags during command evaluation... 5314 fcntl(fdIn, F_SETFL, flags & ~O_NONBLOCK); 5315 TRACE("command: '%s'", Tcl_DStringValue(&cmdbuffer)); 5316 status = ExecuteCommand(interp, &cmdbuffer); 5317 // non-blocking for next read -- we might not get anything 5318 fcntl(fdIn, F_SETFL, flags | O_NONBLOCK); 5319 isComplete = false; 5320 nCommands++; 5321 } 5322 } 5323 fcntl(fdIn, F_SETFL, flags); 5400 tv.tv_sec = tv.tv_usec = 0L; /* On successive reads, we break out 5401 * if no data is available. */ 5402 FD_SET(inBufPtr->file(), &readFds); 5403 tvPtr = &tv; 5404 } 5324 5405 5325 5406 if (status != TCL_OK) { … … 5328 5409 5329 5410 string = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY); 5330 TRACE(" ERROR errorInfo=(%s)", string);5331 5411 TRACE("%s: status=%d ERROR errorInfo=(%s)", Tcl_DStringValue(&command), 5412 status, string); 5332 5413 nBytes = strlen(string); 5333 5414 struct iovec iov[3]; … … 5339 5420 iov[2].iov_len = strlen((char *)iov[2].iov_base); 5340 5421 if (writev(fdOut, iov, 3) < 0) { 5341 ERROR("write failed: %s", strerror(errno)); 5422 ERROR("write failed: %s", strerror(errno)); 5423 return -1; 5342 5424 } 5343 5425 return 0; … … 5352 5434 * \return The initialized Tcl interpreter 5353 5435 */ 5354 Tcl_Interp * 5355 Rappture::VtkVis::initTcl() 5356 { 5357 Tcl_Interp *interp; 5358 interp = Tcl_CreateInterp(); 5359 5436 void 5437 Rappture::VtkVis::initTcl(Tcl_Interp *interp, ClientData clientData) 5438 { 5360 5439 Tcl_MakeSafe(interp); 5361 5362 Tcl_CreateObjCommand(interp, "axis", AxisCmd, NULL, NULL); 5363 Tcl_CreateObjCommand(interp, "camera", CameraCmd, NULL, NULL); 5364 Tcl_CreateObjCommand(interp, "colormap", ColorMapCmd, NULL, NULL); 5365 Tcl_CreateObjCommand(interp, "contour2d", Contour2DCmd, NULL, NULL); 5366 Tcl_CreateObjCommand(interp, "contour3d", Contour3DCmd, NULL, NULL); 5367 Tcl_CreateObjCommand(interp, "cutplane", CutplaneCmd, NULL, NULL); 5368 Tcl_CreateObjCommand(interp, "dataset", DataSetCmd, NULL, NULL); 5369 Tcl_CreateObjCommand(interp, "glyphs", GlyphsCmd, NULL, NULL); 5370 Tcl_CreateObjCommand(interp, "heightmap", HeightMapCmd, NULL, NULL); 5371 Tcl_CreateObjCommand(interp, "legend", LegendCmd, NULL, NULL); 5372 Tcl_CreateObjCommand(interp, "lic", LICCmd, NULL, NULL); 5373 Tcl_CreateObjCommand(interp, "molecule", MoleculeCmd, NULL, NULL); 5374 Tcl_CreateObjCommand(interp, "polydata", PolyDataCmd, NULL, NULL); 5375 Tcl_CreateObjCommand(interp, "pseudocolor", PseudoColorCmd, NULL, NULL); 5376 Tcl_CreateObjCommand(interp, "renderer", RendererCmd, NULL, NULL); 5377 Tcl_CreateObjCommand(interp, "screen", ScreenCmd, NULL, NULL); 5378 Tcl_CreateObjCommand(interp, "streamlines", StreamlinesCmd, NULL, NULL); 5379 Tcl_CreateObjCommand(interp, "volume", VolumeCmd, NULL, NULL); 5380 return interp; 5440 Tcl_CreateObjCommand(interp, "axis", AxisCmd, clientData, NULL); 5441 Tcl_CreateObjCommand(interp, "camera", CameraCmd, clientData, NULL); 5442 Tcl_CreateObjCommand(interp, "colormap", ColorMapCmd, clientData, NULL); 5443 Tcl_CreateObjCommand(interp, "contour2d", Contour2DCmd, clientData, NULL); 5444 Tcl_CreateObjCommand(interp, "contour3d", Contour3DCmd, clientData, NULL); 5445 Tcl_CreateObjCommand(interp, "cutplane", CutplaneCmd, clientData, NULL); 5446 Tcl_CreateObjCommand(interp, "dataset", DataSetCmd, clientData, NULL); 5447 Tcl_CreateObjCommand(interp, "glyphs", GlyphsCmd, clientData, NULL); 5448 Tcl_CreateObjCommand(interp, "heightmap", HeightMapCmd, clientData, NULL); 5449 Tcl_CreateObjCommand(interp, "imgflush", ImageFlushCmd, clientData, NULL); 5450 Tcl_CreateObjCommand(interp, "legend", LegendCmd, clientData, NULL); 5451 Tcl_CreateObjCommand(interp, "lic", LICCmd, clientData, NULL); 5452 Tcl_CreateObjCommand(interp, "molecule", MoleculeCmd, clientData, NULL); 5453 Tcl_CreateObjCommand(interp, "polydata", PolyDataCmd, clientData, NULL); 5454 Tcl_CreateObjCommand(interp, "pseudocolor", PseudoColorCmd, clientData, NULL); 5455 Tcl_CreateObjCommand(interp, "renderer", RendererCmd, clientData, NULL); 5456 Tcl_CreateObjCommand(interp, "screen", ScreenCmd, clientData, NULL); 5457 Tcl_CreateObjCommand(interp, "streamlines", StreamlinesCmd, clientData, NULL); 5458 Tcl_CreateObjCommand(interp, "volume", VolumeCmd, clientData, NULL); 5381 5459 } 5382 5460 5383 5461 /** 5384 5462 * \brief Delete Tcl commands and interpreter 5385 *5386 5463 */ 5387 5464 void Rappture::VtkVis::exitTcl(Tcl_Interp *interp) … … 5397 5474 Tcl_DeleteCommand(interp, "glyphs"); 5398 5475 Tcl_DeleteCommand(interp, "heightmap"); 5476 Tcl_DeleteCommand(interp, "imgflush"); 5399 5477 Tcl_DeleteCommand(interp, "legend"); 5400 5478 Tcl_DeleteCommand(interp, "lic"); -
trunk/packages/vizservers/vtkvis/RpVtkRendererCmd.h
r2278 r2573 11 11 #include <cstdio> 12 12 #include <tcl.h> 13 #include "ReadBuffer.h" 13 14 14 15 namespace Rappture { 15 16 namespace VtkVis { 16 17 17 extern int processCommands(Tcl_Interp *interp, FILE *fin, FILE *fout); 18 extern Tcl_Interp *initTcl(); 18 extern int processCommands(Tcl_Interp *interp, ReadBuffer *inBufPtr, 19 int fdOut); 20 extern void initTcl(Tcl_Interp *interp, ClientData clientData); 19 21 extern void exitTcl(Tcl_Interp *interp); 20 22 -
trunk/packages/vizservers/vtkvis/TGAWriter.cpp
r2260 r2573 17 17 #include "TGAWriter.h" 18 18 #include "Trace.h" 19 #ifdef USE_THREADS 20 #include "ResponseQueue.h" 21 #endif 22 23 #ifdef USE_THREADS 24 25 /** 26 * \brief Writes image command + data to supplied file descriptor. 27 * 28 * The image data must be supplied in BGR(A) order with bottom to 29 * top scanline ordering. 30 * 31 * \param[in] queue Pointer to ResponseQueue to write to 32 * \param[in] cmdName Command name to send (byte length will be appended) 33 * \param[in] data Image data 34 * \param[in] width Width of image in pixels 35 * \param[in] height Height of image in pixels 36 * \param[in] bytesPerPixel Should be 3 or 4, depending on alpha 37 */ 38 void 39 Rappture::VtkVis::queueTGA(ResponseQueue *queue, const char *cmdName, 40 const unsigned char *data, 41 int width, int height, 42 int bytesPerPixel) 43 { 44 TRACE("(%dx%d)\n", width, height); 45 46 size_t headerLength = 18; 47 48 char header[headerLength]; 49 memset(header, 0, headerLength); 50 header[2] = (char)2; // image type (2 = uncompressed true-color) 51 header[12] = (char)width; 52 header[13] = (char)(width >> 8); 53 header[14] = (char)height; 54 header[15] = (char)(height >> 8); 55 header[16] = (char)(bytesPerPixel*8); // bits per pixel 56 57 size_t dataLength = width * height * bytesPerPixel; 58 size_t cmdLength; 59 60 char command[200]; 61 cmdLength = snprintf(command, sizeof(command), "%s %lu\n", cmdName, 62 (unsigned long)headerLength + dataLength); 63 64 size_t length; 65 unsigned char *mesg = NULL; 66 67 length = headerLength + dataLength + cmdLength; 68 mesg = (unsigned char *)malloc(length); 69 if (mesg == NULL) { 70 ERROR("can't allocate %ld bytes for the image message", length); 71 return; 72 } 73 memcpy(mesg, command, cmdLength); 74 memcpy(mesg + cmdLength, header, headerLength); 75 memcpy(mesg + cmdLength + headerLength, 76 const_cast<unsigned char *>(data), dataLength); 77 78 Response *response = NULL; 79 if (strncmp(cmdName, "nv>legend", 9) == 0) { 80 response = new Response(Response::LEGEND); 81 } else { 82 response = new Response(Response::IMAGE); 83 } 84 response->setMessage(mesg, length, Response::DYNAMIC); 85 queue->enqueue(response); 86 TRACE("Leaving (%dx%d)\n", width, height); 87 } 88 #else 19 89 20 90 /** … … 79 149 TRACE("Leaving (%dx%d)\n", width, height); 80 150 } 151 #endif /*USE_THREADS*/ 81 152 82 153 /** -
trunk/packages/vizservers/vtkvis/TGAWriter.h
r2260 r2573 9 9 #define __RAPPTURE_VTKVIS_TGAWRITER_H__ 10 10 11 #ifdef USE_THREADS 12 #include "ResponseQueue.h" 13 #endif 14 11 15 namespace Rappture { 12 16 namespace VtkVis { 13 17 #ifdef USE_THREADS 14 18 extern 15 void writeTGA(int fd, const char *cmdName, const unsigned char *data, 16 int width, int height, int bytesPerPixel); 17 19 void queueTGA(ResponseQueue *queue, const char *cmdName, 20 const unsigned char *data, int width, int height, 21 int bytesPerPixel); 22 #else 18 23 extern 19 void writeTGAFile(const char *filename, const unsigned char *data, 20 int width, int height, int bytesPerPixel, 21 bool srcIsRGB = false); 22 24 void writeTGA(int fd, const char *cmdName, 25 const unsigned char *data, int width, int height, 26 int bytesPerPixel); 27 #endif 28 extern 29 void writeTGAFile(const char *filename, 30 const unsigned char *data, int width, int height, 31 int bytesPerPixel, bool srcIsRGB = false); 23 32 } 24 33 } -
trunk/packages/vizservers/vtkvis/Trace.cpp
r2506 r2573 21 21 */ 22 22 void 23 Rappture::VtkVis:: InitLog()23 Rappture::VtkVis::initLog() 24 24 { 25 25 openlog("vtkvis", LOG_CONS | LOG_PERROR | LOG_PID, LOG_USER); … … 30 30 */ 31 31 void 32 Rappture::VtkVis:: CloseLog()32 Rappture::VtkVis::closeLog() 33 33 { 34 34 closelog(); … … 39 39 */ 40 40 void 41 Rappture::VtkVis:: LogMessage(int priority, const char *funcname,41 Rappture::VtkVis::logMessage(int priority, const char *funcname, 42 42 const char *path, int lineNum, const char* fmt, ...) 43 43 { … … 64 64 syslog(priority, message, length); 65 65 } 66 67 -
trunk/packages/vizservers/vtkvis/Trace.h
r2506 r2573 14 14 namespace VtkVis { 15 15 16 extern void InitLog();16 extern void initLog(); 17 17 18 extern void CloseLog();18 extern void closeLog(); 19 19 20 extern void LogMessage(int priority, const char *funcname, const char *fileName, int lineNum,21 const char* format, ...);20 extern void logMessage(int priority, const char *funcname, const char *fileName, 21 int lineNum, const char* format, ...); 22 22 23 #define ERROR(...) LogMessage(LOG_ERR, __FUNCTION__, __FILE__, __LINE__, __VA_ARGS__)23 #define ERROR(...) Rappture::VtkVis::logMessage(LOG_ERR, __FUNCTION__, __FILE__, __LINE__, __VA_ARGS__) 24 24 #ifdef WANT_TRACE 25 #define TRACE(...) LogMessage(LOG_DEBUG, __FUNCTION__, __FILE__, __LINE__, __VA_ARGS__)25 #define TRACE(...) Rappture::VtkVis::logMessage(LOG_DEBUG, __FUNCTION__, __FILE__, __LINE__, __VA_ARGS__) 26 26 #else 27 27 #define TRACE(...) 28 #endif 29 #define WARN(...) LogMessage(LOG_WARNING, __FUNCTION__, __FILE__, __LINE__, __VA_ARGS__)30 #define INFO(...) LogMessage(LOG_INFO, __FUNCTION__, __FILE__, __LINE__, __VA_ARGS__)28 #endif /*WANT_TRACE*/ 29 #define WARN(...) Rappture::VtkVis::logMessage(LOG_WARNING, __FUNCTION__, __FILE__, __LINE__, __VA_ARGS__) 30 #define INFO(...) Rappture::VtkVis::logMessage(LOG_INFO, __FUNCTION__, __FILE__, __LINE__, __VA_ARGS__) 31 31 32 32 }
Note: See TracChangeset
for help on using the changeset viewer.