Changeset 4874 for nanovis/branches/1.1
- Timestamp:
- Dec 18, 2014, 5:45:38 PM (10 years ago)
- Location:
- nanovis/branches/1.1
- Files:
-
- 4 added
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
nanovis/branches/1.1
- Property svn:mergeinfo changed
/trunk/packages/vizservers/nanovis merged: 3607
- Property svn:mergeinfo changed
-
nanovis/branches/1.1/Command.cpp
r4830 r4874 33 33 34 34 #include <assert.h> 35 #include <errno.h> 35 36 #include <stdlib.h> 36 37 #include <unistd.h> /* Needed for getpid, gethostname, … … 44 45 #include <vrmath/Vector3f.h> 45 46 47 #include "nanovisServer.h" 46 48 #include "nanovis.h" 49 #include "ReadBuffer.h" 50 #include "Command.h" 47 51 #include "CmdProc.h" 48 52 #include "FlowCmd.h" … … 58 62 #include "Trace.h" 59 63 64 using namespace nv; 60 65 using namespace nv::graphics; 61 66 using namespace vrmath; … … 100 105 static int lastCmdStatus; 101 106 107 ssize_t 108 nv::SocketWrite(const void *bytes, size_t len) 109 { 110 size_t ofs = 0; 111 ssize_t bytesWritten; 112 while ((bytesWritten = write(g_fdOut, (const char *)bytes + ofs, len - ofs)) > 0) { 113 ofs += bytesWritten; 114 if (ofs == len) 115 break; 116 } 117 if (bytesWritten < 0) { 118 ERROR("write: %s", strerror(errno)); 119 } 120 return bytesWritten; 121 } 122 102 123 bool 103 GetBooleanFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, bool *boolPtr) 124 nv::SocketRead(char *bytes, size_t len) 125 { 126 ReadBuffer::BufferStatus status; 127 status = g_inBufPtr->followingData((unsigned char *)bytes, len); 128 TRACE("followingData status: %d", status); 129 return (status == ReadBuffer::OK); 130 } 131 132 static int 133 ExecuteCommand(Tcl_Interp *interp, Tcl_DString *dsPtr) 134 { 135 int result; 136 #ifdef WANT_TRACE 137 char *str = Tcl_DStringValue(dsPtr); 138 std::string cmd(str); 139 cmd.erase(cmd.find_last_not_of(" \n\r\t")+1); 140 TRACE("command %lu: '%s'", g_stats.nCommands+1, cmd.c_str()); 141 #endif 142 143 result = Tcl_EvalEx(interp, Tcl_DStringValue(dsPtr), 144 Tcl_DStringLength(dsPtr), 145 TCL_EVAL_DIRECT | TCL_EVAL_GLOBAL); 146 Tcl_DStringSetLength(dsPtr, 0); 147 148 if (result != TCL_OK) { 149 TRACE("Error: %d", result); 150 } 151 return result; 152 } 153 154 int 155 nv::GetBooleanFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, bool *boolPtr) 104 156 { 105 157 int value; … … 113 165 114 166 int 115 GetFloatFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, float *valuePtr)167 nv::GetFloatFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, float *valuePtr) 116 168 { 117 169 double value; … … 392 444 */ 393 445 int 394 GetAxisFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int *indexPtr)446 nv::GetAxisFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int *indexPtr) 395 447 { 396 448 return GetAxis(interp, Tcl_GetString(objPtr), indexPtr); … … 449 501 */ 450 502 int 451 GetDataStream(Tcl_Interp *interp, Rappture::Buffer &buf, int nBytes) 452 { 503 nv::GetDataStream(Tcl_Interp *interp, Rappture::Buffer &buf, int nBytes) 504 { 505 #ifdef USE_NEW_EVENT_LOOP 506 if (!SocketRead((char *)buf.bytes(), nBytes)) { 507 return TCL_ERROR; 508 } 509 buf.count(nBytes); 510 #else 453 511 char buffer[8096]; 454 512 455 clearerr( NanoVis::stdin);513 clearerr(g_fIn); 456 514 while (nBytes > 0) { 457 515 unsigned int chunk; … … 460 518 chunk = (sizeof(buffer) < (unsigned int) nBytes) ? 461 519 sizeof(buffer) : nBytes; 462 nRead = fread(buffer, sizeof(char), chunk, NanoVis::stdin);463 if (ferror( NanoVis::stdin)) {520 nRead = fread(buffer, sizeof(char), chunk, g_fIn); 521 if (ferror(g_fIn)) { 464 522 Tcl_AppendResult(interp, "while reading data stream: ", 465 523 Tcl_PosixError(interp), (char*)NULL); 466 524 return TCL_ERROR; 467 525 } 468 if (feof( NanoVis::stdin)) {526 if (feof(g_fIn)) { 469 527 Tcl_AppendResult(interp, "premature EOF while reading data stream", 470 528 (char*)NULL); … … 474 532 nBytes -= nRead; 475 533 } 476 if (NanoVis::recfile != NULL) { 477 ssize_t nWritten; 478 479 nWritten = fwrite(buf.bytes(), sizeof(char), buf.size(), 480 NanoVis::recfile); 481 assert(nWritten == (ssize_t)buf.size()); 482 fflush(NanoVis::recfile); 483 } 534 #endif 484 535 Rappture::Outcome err; 485 536 TRACE("Checking header[%.13s]", buf.bytes()); … … 785 836 /* Use the initial client key value pairs as the parts for a generating 786 837 * a unique file name. */ 787 int f = NanoVis::getStatsFile(objv[1]);838 int f = getStatsFile(objv[1]); 788 839 if (f < 0) { 789 840 Tcl_AppendResult(interp, "can't open stats file: ", … … 806 857 objPtr = Tcl_NewStringObj("pid", 3); 807 858 Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); 808 Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewLongObj((long) NanoVis::stats.pid));859 Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewLongObj((long)g_stats.pid)); 809 860 /* host */ 810 861 objPtr = Tcl_NewStringObj("host", 4); … … 821 872 /* date */ 822 873 Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("date", 4)); 823 strcpy(buf, ctime(& NanoVis::stats.start.tv_sec));874 strcpy(buf, ctime(&g_stats.start.tv_sec)); 824 875 buf[strlen(buf) - 1] = '\0'; 825 876 Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(buf, -1)); … … 828 879 Tcl_NewStringObj("date_secs", 9)); 829 880 Tcl_ListObjAppendElement(interp, listObjPtr, 830 Tcl_NewLongObj( NanoVis::stats.start.tv_sec));881 Tcl_NewLongObj(g_stats.start.tv_sec)); 831 882 /* Client arguments. */ 832 883 if (Tcl_ListObjGetElements(interp, objv[1], &numItems, &items) != TCL_OK) { … … 841 892 Tcl_DStringAppend(&ds, "\n", 1); 842 893 #ifdef KEEPSTATS 843 result = NanoVis::writeToStatsFile(f, Tcl_DStringValue(&ds),844 894 result = writeToStatsFile(f, Tcl_DStringValue(&ds), 895 Tcl_DStringLength(&ds)); 845 896 #else 846 897 TRACE("clientinfo: %s", Tcl_DStringValue(&ds)); … … 1299 1350 volume->wAxis.min(), volume->wAxis.max(), 1300 1351 Volume::valueMin, Volume::valueMax); 1301 ssize_t nWritten = write(1, info, (size_t)cmdLength); 1302 if (nWritten != (ssize_t)cmdLength) { 1303 ERROR("Short write"); 1352 if (SocketWrite(info, (size_t)cmdLength) != (ssize_t)cmdLength) { 1304 1353 return TCL_ERROR; 1305 1354 } … … 2135 2184 } 2136 2185 2137 Tcl_Interp * 2138 initTcl() 2139 { 2140 Tcl_Interp *interp = Tcl_CreateInterp(); 2186 /** 2187 * \brief Execute commands from client in Tcl interpreter 2188 * 2189 * In this threaded model, the select call is for event compression. We 2190 * want to execute render server commands as long as they keep coming. 2191 * This lets us execute a stream of many commands but render once. This 2192 * benefits camera movements, screen resizing, and opacity changes 2193 * (using a slider on the client). The down side is you don't render 2194 * until there's a lull in the command stream. If the client needs an 2195 * image, it can issue an "imgflush" command. That breaks us out of the 2196 * read loop. 2197 */ 2198 int 2199 nv::processCommands(Tcl_Interp *interp, 2200 ReadBuffer *inBufPtr, int fdOut) 2201 { 2202 int ret = 1; 2203 int status = TCL_OK; 2204 2205 Tcl_DString command; 2206 Tcl_DStringInit(&command); 2207 fd_set readFds; 2208 struct timeval tv, *tvPtr; 2209 2210 FD_ZERO(&readFds); 2211 FD_SET(inBufPtr->file(), &readFds); 2212 tvPtr = NULL; /* Wait for the first read. This is so 2213 * that we don't spin when no data is 2214 * available. */ 2215 while (inBufPtr->isLineAvailable() || 2216 (select(inBufPtr->file()+1, &readFds, NULL, NULL, tvPtr) > 0)) { 2217 size_t numBytes; 2218 unsigned char *buffer; 2219 2220 /* A short read is treated as an error here because we assume that we 2221 * will always get commands line by line. */ 2222 if (inBufPtr->getLine(&numBytes, &buffer) != ReadBuffer::OK) { 2223 /* Terminate the server if we can't communicate with the client 2224 * anymore. */ 2225 if (inBufPtr->status() == ReadBuffer::ENDFILE) { 2226 TRACE("Exiting server on EOF from client"); 2227 return -1; 2228 } else { 2229 ERROR("Exiting server, failed to read from client: %s", 2230 strerror(errno)); 2231 return -1; 2232 } 2233 } 2234 Tcl_DStringAppend(&command, (char *)buffer, numBytes); 2235 if (Tcl_CommandComplete(Tcl_DStringValue(&command))) { 2236 struct timeval start, finish; 2237 gettimeofday(&start, NULL); 2238 status = ExecuteCommand(interp, &command); 2239 gettimeofday(&finish, NULL); 2240 g_stats.cmdTime += (MSECS_ELAPSED(start, finish) / 1.0e+3); 2241 g_stats.nCommands++; 2242 if (status == TCL_BREAK) { 2243 return 1; /* This was caused by a "imgflush" 2244 * command. Break out of the read loop 2245 * and allow a new image to be 2246 * rendered. */ 2247 } else { //if (status != TCL_OK) { 2248 ret = 0; 2249 if (handleError(interp, status, fdOut) < 0) { 2250 return -1; 2251 } 2252 } 2253 } 2254 2255 tv.tv_sec = tv.tv_usec = 0L; /* On successive reads, we break out 2256 * if no data is available. */ 2257 FD_SET(inBufPtr->file(), &readFds); 2258 tvPtr = &tv; 2259 } 2260 2261 return ret; 2262 } 2263 2264 /** 2265 * \brief Send error message to client socket 2266 */ 2267 int 2268 nv::handleError(Tcl_Interp *interp, int status, int fdOut) 2269 { 2270 const char *string; 2271 int nBytes; 2272 2273 if (status != TCL_OK) { 2274 string = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY); 2275 nBytes = strlen(string); 2276 if (nBytes > 0) { 2277 TRACE("status=%d errorInfo=(%s)", status, string); 2278 2279 std::ostringstream oss; 2280 oss << "nv>viserror -type internal_error -token " << g_stats.nCommands << " -bytes " << nBytes << "\n" << string; 2281 std::string ostr = oss.str(); 2282 nBytes = ostr.length(); 2283 2284 if (write(fdOut, oss.str().c_str(), nBytes) < 0) { 2285 ERROR("write failed: %s", strerror(errno)); 2286 return -1; 2287 } 2288 } 2289 } 2290 2291 std::string msg = getUserMessages(); 2292 nBytes = msg.length(); 2293 if (nBytes > 0) { 2294 string = msg.c_str(); 2295 TRACE("userError=(%s)", string); 2296 2297 std::ostringstream oss; 2298 oss << "nv>viserror -type error -token " << g_stats.nCommands << " -bytes " << nBytes << "\n" << string; 2299 std::string ostr = oss.str(); 2300 nBytes = ostr.length(); 2301 2302 if (write(fdOut, ostr.c_str(), nBytes) < 0) { 2303 ERROR("write failed: %s", strerror(errno)); 2304 return -1; 2305 } 2306 clearUserMessages(); 2307 } 2308 2309 return 0; 2310 } 2311 2312 void 2313 nv::initTcl(Tcl_Interp *interp, ClientData clientData) 2314 { 2141 2315 Tcl_MakeSafe(interp); 2142 2316 2143 Tcl_CreateObjCommand(interp, "axis", AxisCmd, NULL, NULL); 2144 Tcl_CreateObjCommand(interp, "camera", CameraCmd, NULL, NULL); 2145 Tcl_CreateObjCommand(interp, "clientinfo", ClientInfoCmd, NULL, NULL); 2146 Tcl_CreateObjCommand(interp, "cutplane", CutplaneCmd, NULL, NULL); 2147 if (FlowCmdInitProc(interp) != TCL_OK) { 2148 return NULL; 2149 } 2150 Tcl_CreateObjCommand(interp, "grid", GridCmd, NULL, NULL); 2151 Tcl_CreateObjCommand(interp, "heightmap", HeightMapCmd, NULL, NULL); 2152 Tcl_CreateObjCommand(interp, "imgflush", ImageFlushCmd, NULL, NULL); 2153 Tcl_CreateObjCommand(interp, "legend", LegendCmd, NULL, NULL); 2154 Tcl_CreateObjCommand(interp, "screen", ScreenCmd, NULL, NULL); 2155 Tcl_CreateObjCommand(interp, "snapshot", SnapshotCmd, NULL, NULL); 2156 Tcl_CreateObjCommand(interp, "transfunc", TransfuncCmd, NULL, NULL); 2157 Tcl_CreateObjCommand(interp, "up", UpCmd, NULL, NULL); 2158 Tcl_CreateObjCommand(interp, "volume", VolumeCmd, NULL, NULL); 2317 Tcl_CreateObjCommand(interp, "axis", AxisCmd, clientData, NULL); 2318 Tcl_CreateObjCommand(interp, "camera", CameraCmd, clientData, NULL); 2319 Tcl_CreateObjCommand(interp, "clientinfo", ClientInfoCmd, clientData, NULL); 2320 Tcl_CreateObjCommand(interp, "cutplane", CutplaneCmd, clientData, NULL); 2321 FlowCmdInitProc(interp, clientData); 2322 Tcl_CreateObjCommand(interp, "grid", GridCmd, clientData, NULL); 2323 Tcl_CreateObjCommand(interp, "heightmap", HeightMapCmd, clientData, NULL); 2324 Tcl_CreateObjCommand(interp, "imgflush", ImageFlushCmd, clientData, NULL); 2325 Tcl_CreateObjCommand(interp, "legend", LegendCmd, clientData, NULL); 2326 Tcl_CreateObjCommand(interp, "screen", ScreenCmd, clientData, NULL); 2327 Tcl_CreateObjCommand(interp, "snapshot", SnapshotCmd, clientData, NULL); 2328 Tcl_CreateObjCommand(interp, "transfunc", TransfuncCmd, clientData, NULL); 2329 Tcl_CreateObjCommand(interp, "up", UpCmd, clientData, NULL); 2330 Tcl_CreateObjCommand(interp, "volume", VolumeCmd, clientData, NULL); 2159 2331 2160 2332 // create a default transfer function … … 2163 2335 Tcl_GetStringResult(interp)); 2164 2336 } 2165 return interp; 2166 } 2337 } -
nanovis/branches/1.1/Command.h
r4612 r4874 12 12 #define COMMAND_H 13 13 14 #include <unistd.h> 15 14 16 #include <tcl.h> 15 17 … … 18 20 } 19 21 class Volume; 22 23 namespace nv { 24 25 class ReadBuffer; 26 27 extern ssize_t SocketWrite(const void *bytes, size_t len); 28 29 extern bool SocketRead(char *bytes, size_t len); 30 31 extern int processCommands(Tcl_Interp *interp, 32 ReadBuffer *inBufPtr, 33 int fdOut); 34 35 extern int handleError(Tcl_Interp *interp, 36 int status, 37 int fdOut); 38 39 extern void initTcl(Tcl_Interp *interp, ClientData clientData); 20 40 21 41 extern int GetAxisFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, … … 30 50 float *floatVal); 31 51 32 extern int GetVolumeFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, 33 Volume **volume); 34 35 extern Tcl_Interp *initTcl(); 52 } 36 53 37 54 #endif -
nanovis/branches/1.1/Flow.cpp
r4612 r4874 29 29 #include "TransferFunction.h" 30 30 31 using namespace nv; 31 32 using namespace vrmath; 32 33 -
nanovis/branches/1.1/FlowCmd.cpp
r4831 r4874 25 25 #include "nvconf.h" 26 26 27 #include "nanovisServer.h" 27 28 #include "nanovis.h" 28 29 #include "CmdProc.h" … … 41 42 #include "Trace.h" 42 43 44 using namespace nv; 43 45 using namespace vrmath; 44 46 … … 296 298 sprintf(info, "nv>data tag %s min %g max %g\n", 297 299 flow->name(), dataPtr->magMin(), dataPtr->magMax()); 298 ssize_t nWritten = write(1, info, (size_t)length); 299 if (nWritten != (ssize_t)length) { 300 ERROR("Short write"); 300 if (SocketWrite(info, (size_t)length) < 0) { 301 301 return TCL_ERROR; 302 302 } … … 835 835 */ 836 836 int 837 FlowInstObjCmd(ClientData clientData, Tcl_Interp *interp, int objc,838 Tcl_Obj *const *objv)837 nv::FlowInstObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, 838 Tcl_Obj *const *objv) 839 839 { 840 840 Tcl_ObjCmdProc *proc; … … 858 858 */ 859 859 void 860 FlowInstDeleteProc(ClientData clientData)860 nv::FlowInstDeleteProc(ClientData clientData) 861 861 { 862 862 Flow *flow = (Flow *)clientData; … … 1122 1122 { 1123 1123 struct pollfd pollResults; 1124 pollResults.fd = fileno(NanoVis::stdin);1124 pollResults.fd = g_fdIn; 1125 1125 pollResults.events = POLLIN; 1126 1126 #define PENDING_TIMEOUT 10 /* milliseconds. */ … … 1232 1232 sprintf(cmd,"nv>image -type movie -token \"%s\" -bytes %lu\n", 1233 1233 token, (unsigned long)data.size()); 1234 NanoVis::sendDataToClient(cmd, data.bytes(), data.size());1234 nv::sendDataToClient(cmd, data.bytes(), data.size()); 1235 1235 return TCL_OK; 1236 1236 } … … 1345 1345 * associative array. 1346 1346 */ 1347 int 1348 FlowCmdInitProc(Tcl_Interp *interp) 1349 { 1350 Tcl_CreateObjCommand(interp, "flow", FlowCmdProc, NULL, NULL); 1351 return TCL_OK; 1352 } 1347 void 1348 nv::FlowCmdInitProc(Tcl_Interp *interp, ClientData clientData) 1349 { 1350 Tcl_CreateObjCommand(interp, "flow", FlowCmdProc, clientData, NULL); 1351 } -
nanovis/branches/1.1/FlowCmd.h
r4612 r4874 27 27 #include <tcl.h> 28 28 29 extern Tcl_AppInitProc FlowCmdInitProc; 29 namespace nv { 30 31 extern void FlowCmdInitProc(Tcl_Interp *interp, ClientData clientData); 32 30 33 extern Tcl_ObjCmdProc FlowInstObjCmd; 31 34 extern Tcl_CmdDeleteProc FlowInstDeleteProc; 32 35 36 } 37 33 38 #endif -
nanovis/branches/1.1/Grid.cpp
r3502 r4874 36 36 void Grid::render() 37 37 { 38 if (!isVisible()) 39 return; 40 38 41 glPushAttrib(GL_ENABLE_BIT); 39 42 -
nanovis/branches/1.1/HeightMap.cpp
r4612 r4874 57 57 HeightMap::render(RenderContext *renderContext) 58 58 { 59 if (!isVisible()) 60 return; 61 59 62 glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT | GL_LIGHTING_BIT); 60 63 -
nanovis/branches/1.1/Makefile.in
r4831 r4874 130 130 Plane.o \ 131 131 PlaneRenderer.o \ 132 ReadBuffer.o \ 132 133 ReaderCommon.o \ 133 134 RenderVertexArray.o \ … … 147 148 dxReader.o \ 148 149 md5.o \ 149 nanovis.o 150 nanovis.o \ 151 nanovisServer.o 150 152 151 153 resources = \ … … 271 273 Chain.o: Chain.cpp Chain.h 272 274 CmdProc.o: CmdProc.cpp CmdProc.h 273 Command.o: Command.cpp nanovis.h config.h FlowCmd.h CmdProc.h Trace.h PlaneRenderer.h PointSet.h dxReader.h Grid.h HeightMap.h NvCamera.h NvZincBlendeReconstructor.h Unirect.h Volume.h VolumeRenderer.h275 Command.o: Command.cpp nanovis.h nanovisServer.h ReadBuffer.h config.h define.h FlowCmd.h CmdProc.h Trace.h PlaneRenderer.h dxReader.h Grid.h HeightMap.h NvCamera.h NvZincBlendeReconstructor.h Unirect.h Volume.h VolumeRenderer.h 274 276 ContourLineFilter.o: ContourLineFilter.cpp ContourLineFilter.h 275 277 ConvexPolygon.o: ConvexPolygon.cpp ConvexPolygon.h $(VRMATH_DIR)/include/vrmath/Vector4f.h $(VRMATH_DIR)/include/vrmath/Matrix4x4d.h Plane.h 276 Flow.o: Flow.cpp Flow.h FlowCmd.h FlowTypes.h FlowBox.h FlowParticles.h Switch.h Trace.h278 Flow.o: Flow.cpp Flow.h FlowCmd.h FlowTypes.h FlowBox.h FlowParticles.h NvLIC.h VelocityArrowsSlice.h Switch.h Unirect.h Volume.h TransferFunction.h Trace.h 277 279 FlowBox.o: FlowBox.cpp FlowBox.h FlowTypes.h Switch.h Trace.h Volume.h $(VRMATH_DIR)/include/vrmath/Vector3f.h $(VRMATH_DIR)/include/vrmath/Vector4f.h $(VRMATH_DIR)/include/vrmath/Matrix4x4d.h 278 FlowCmd.o: FlowCmd.cpp FlowCmd.h FlowParticles.h FlowBox.h FlowTypes.h Command.h Switch.h Trace.h TransferFunction.h nanovis.h CmdProc.h NvLIC.h Unirect.h Volume.h VelocityArrowsSlice.h $(VRMATH_DIR)/include/vrmath/Vector3f.h280 FlowCmd.o: FlowCmd.cpp FlowCmd.h FlowParticles.h FlowBox.h FlowTypes.h Command.h Switch.h Trace.h TransferFunction.h nanovis.h nanovisServer.h CmdProc.h NvLIC.h Unirect.h Volume.h VelocityArrowsSlice.h $(VRMATH_DIR)/include/vrmath/Vector3f.h 279 281 FlowParticles.o: FlowParticles.cpp FlowParticles.h FlowTypes.h FlowCmd.h Switch.h Trace.h NvParticleRenderer.h Volume.h $(VRMATH_DIR)/include/vrmath/Vector3f.h $(VRMATH_DIR)/include/vrmath/Vector4f.h 280 282 GradientFilter.o: GradientFilter.cpp GradientFilter.h … … 302 304 PointSetRenderer.o: PointSetRenderer.cpp PointSetRenderer.h 303 305 PointShader.o: PointShader.cpp PointShader.h 306 ReadBuffer.o: ReadBuffer.cpp ReadBuffer.h Trace.h 304 307 ReaderCommon.o: ReaderCommon.cpp ReaderCommon.h GradientFilter.h $(VRMATH_DIR)/include/vrmath/Vector3f.h 305 308 RenderVertexArray.o: RenderVertexArray.cpp RenderVertexArray.h … … 318 321 ZincBlendeVolume.o: ZincBlendeVolume.cpp ZincBlendeVolume.h config.h define.h 319 322 dxReader.o: dxReader.cpp ReaderCommon.h config.h nanovis.h Unirect.h ZincBlendeVolume.h NvZincBlendeReconstructor.h 320 nanovis.o: nanovis.cpp nanovis.h config.h define.h Command.h Flow.h Grid.h HeightMap.h NvCamera.h NvLIC.h NvZincBlendeReconstructor.h PerfQuery.h PlaneRenderer.h PointSetRenderer.h PointSet.h Switch.h Trace.h Unirect.h VelocityArrowsSlice.h VolumeInterpolator.h VolumeRenderer.h ZincBlendeVolume.h Axis.h Chain.h321 323 md5.o: md5.h 324 nanovis.o: nanovis.cpp nanovis.h nanovisServer.h config.h define.h Command.h Flow.h Grid.h HeightMap.h NvCamera.h NvLIC.h NvZincBlendeReconstructor.h PerfQuery.h PlaneRenderer.h PointSetRenderer.h PointSet.h Switch.h Trace.h Unirect.h VelocityArrowsSlice.h VolumeInterpolator.h VolumeRenderer.h ZincBlendeVolume.h Axis.h Chain.h 325 nanovisServer.o: nanovisServer.cpp nanovisServer.h config.h nanovis.h define.h Command.h NvShader.h Trace.h -
nanovis/branches/1.1/Trace.cpp
r4612 r4874 10 10 #include <string.h> 11 11 12 #include <string> 13 #include <sstream> 14 12 15 #include <GL/glew.h> 13 16 … … 15 18 #include "Trace.h" 16 19 20 using namespace nv; 21 22 static std::ostringstream g_UserErrorString; 23 17 24 #define MSG_LEN 2047 18 25 26 /** 27 * \brief Open syslog for writing 28 */ 29 void 30 nv::initLog() 31 { 32 openlog("nanovis", LOG_CONS | LOG_PERROR | LOG_PID, LOG_USER); 33 } 34 35 /** 36 * \brief Close syslog 37 */ 38 void 39 nv::closeLog() 40 { 41 closelog(); 42 } 43 44 /** 45 * \brief Write a message to syslog 46 */ 19 47 void 20 LogMessage(int priority, const char *funcname,21 const char *path, int lineNum, const char* fmt, ...)48 nv::LogMessage(int priority, const char *funcname, 49 const char *path, int lineNum, const char* fmt, ...) 22 50 { 23 51 char message[MSG_LEN+1]; … … 42 70 43 71 syslog(priority, "%s", message); 72 } 73 74 /** 75 * \brief Write a user message to buffer 76 */ 77 void 78 nv::logUserMessage(const char* fmt, ...) 79 { 80 char message[MSG_LEN + 1]; 81 int length = 0; 82 va_list lst; 83 84 va_start(lst, fmt); 85 86 length += vsnprintf(message, MSG_LEN, fmt, lst); 87 message[MSG_LEN] = '\0'; 88 89 g_UserErrorString << message << "\n"; 90 } 91 92 std::string 93 nv::getUserMessages() 94 { 95 return g_UserErrorString.str(); 96 } 97 98 void 99 nv::clearUserMessages() 100 { 101 g_UserErrorString.str(std::string()); 44 102 } 45 103 -
nanovis/branches/1.1/Trace.h
r4612 r4874 9 9 #define __TRACE_H__ 10 10 11 #include <string> 12 11 13 #include <GL/glew.h> 12 14 #include <syslog.h> … … 18 20 #define AT __FILE__ ":" NEWSTRING(__LINE__) 19 21 22 namespace nv { 23 24 extern void logUserMessage(const char* format, ...); 25 26 extern std::string getUserMessages(); 27 28 extern void clearUserMessages(); 29 30 extern void initLog(); 31 32 extern void closeLog(); 33 20 34 extern void LogMessage(int priority, const char *funcname, const char *fileName, 21 35 int lineNum, const char* format, ...); 22 36 23 #define ERROR(...) LogMessage(LOG_ERR, __FUNCTION__, __FILE__, __LINE__, __VA_ARGS__)37 #define ERROR(...) nv::LogMessage(LOG_ERR, __FUNCTION__, __FILE__, __LINE__, __VA_ARGS__) 24 38 #ifdef WANT_TRACE 25 #define TRACE(...) LogMessage(LOG_DEBUG, __FUNCTION__, __FILE__, __LINE__, __VA_ARGS__)39 #define TRACE(...) nv::LogMessage(LOG_DEBUG, __FUNCTION__, __FILE__, __LINE__, __VA_ARGS__) 26 40 #else 27 41 #define TRACE(...) 28 42 #endif 29 #define WARN(...) LogMessage(LOG_WARNING, __FUNCTION__, __FILE__, __LINE__, __VA_ARGS__) 30 #define INFO(...) LogMessage(LOG_INFO, __FUNCTION__, __FILE__, __LINE__, __VA_ARGS__) 43 #define WARN(...) nv::LogMessage(LOG_WARNING, __FUNCTION__, __FILE__, __LINE__, __VA_ARGS__) 44 #define INFO(...) nv::LogMessage(LOG_INFO, __FUNCTION__, __FILE__, __LINE__, __VA_ARGS__) 45 46 #define USER_ERROR(...) nv::logUserMessage(__VA_ARGS__); 47 48 } 31 49 32 50 extern bool CheckFBO(GLenum *status); 33 51 extern void PrintFBOStatus(GLenum status, const char *prefix); 34 52 extern bool CheckGL(const char *prefix); 53 35 54 #endif -
nanovis/branches/1.1/Unirect.cpp
r4612 r4874 15 15 #include "Unirect.h" 16 16 #include "Trace.h" 17 18 using namespace nv; 17 19 18 20 static inline char * -
nanovis/branches/1.1/VolumeInterpolator.cpp
r4612 r4874 6 6 #include <string.h> 7 7 #include <memory.h> 8 #include <time.h>9 8 #include <sys/time.h> 10 9 #include <math.h> -
nanovis/branches/1.1/config.h
r4614 r4874 42 42 #define KEEPSTATS 43 43 44 //#define USE_NEW_EVENT_LOOP 45 44 46 /* 45 47 * Controls whether DX data is downsampled. -
nanovis/branches/1.1/nanovis.cpp
r4820 r4874 16 16 */ 17 17 18 #include <assert.h>19 #include <errno.h>20 #include <fcntl.h>21 #include <getopt.h>22 #include <memory.h>23 #include <signal.h>24 #include <sys/resource.h>25 #include <sys/stat.h>26 18 #include <sys/time.h> 27 #include <sys/times.h>28 19 #include <sys/types.h> 29 #include <sys/uio.h> // for readv/writev 30 #include <time.h> 20 #include <sys/uio.h> // for writev in ppmWrite 31 21 #include <unistd.h> 32 22 23 #include <cassert> 33 24 #include <cstdlib> 34 25 #include <cstdio> … … 36 27 #include <cmath> 37 28 38 #include <iostream>39 #include <fstream>40 #include <sstream>41 29 #include <string> 42 30 … … 44 32 #include <GL/glut.h> 45 33 46 #include <RpEncode.h>47 48 34 #include <graphics/RenderContext.h> 49 35 #include <vrmath/Vector3f.h> … … 57 43 #include "config.h" 58 44 #include "nanovis.h" 45 #include "nanovisServer.h" 59 46 #include "define.h" 60 47 … … 66 53 #include "NvShader.h" 67 54 #include "NvLIC.h" 68 #include "NvZincBlendeReconstructor.h"69 55 #include "PlaneRenderer.h" 70 56 #include "Switch.h" 71 57 #include "Trace.h" 58 #include "TransferFunction.h" 72 59 #include "Unirect.h" 73 60 #include "VelocityArrowsSlice.h" 74 61 #include "VolumeInterpolator.h" 75 62 #include "VolumeRenderer.h" 76 #include "ZincBlendeVolume.h" 77 63 64 using namespace nv; 78 65 using namespace nv::graphics; 79 66 using namespace nv::util; … … 89 76 // STATIC MEMBER DATA 90 77 91 FILE *NanoVis::stdin = NULL; 92 FILE *NanoVis::logfile = NULL; 93 FILE *NanoVis::recfile = NULL; 94 95 NanoVis::Stats NanoVis::stats; 96 int NanoVis::statsFile = -1; 78 Tcl_Interp *NanoVis::interp = NULL; 97 79 98 80 unsigned int NanoVis::flags = 0; … … 105 87 unsigned char *NanoVis::screenBuffer = NULL; 106 88 Texture2D *NanoVis::legendTexture = NULL; 107 Grid *NanoVis::grid = NULL;108 89 Fonts *NanoVis::fonts; 109 90 int NanoVis::updir = Y_POS; … … 132 113 NvLIC *NanoVis::licRenderer = NULL; 133 114 PlaneRenderer *NanoVis::planeRenderer = NULL; 134 135 Tcl_Interp *NanoVis::interp; 115 Grid *NanoVis::grid = NULL; 136 116 137 117 // Image based flow visualization slice location … … 210 190 flags |= REDRAW_PENDING; 211 191 } 212 }213 214 #ifdef KEEPSTATS215 216 #ifndef STATSDIR217 #define STATSDIR "/var/tmp/visservers"218 #endif /*STATSDIR*/219 220 int221 NanoVis::getStatsFile(Tcl_Obj *objPtr)222 {223 Tcl_DString ds;224 char fileName[33];225 char pidstr[200];226 const char *path;227 md5_state_t state;228 md5_byte_t digest[16];229 char *string;230 int length;231 232 if ((objPtr == NULL) || (statsFile >= 0)) {233 return statsFile;234 }235 /* By itself the client's key/value pairs aren't unique. Add in the236 * process id of this render server. */237 sprintf(pidstr, "%ld", (long)stats.pid);238 239 /* Create an md5 hash of the key/value pairs and use it as the file name. */240 string = Tcl_GetStringFromObj(objPtr, &length);241 md5_init(&state);242 md5_append(&state, (const md5_byte_t *)string, strlen(string));243 md5_append(&state, (const md5_byte_t *)pidstr, strlen(pidstr));244 md5_finish(&state, digest);245 for (int i = 0; i < 16; i++) {246 sprintf(fileName + i * 2, "%02x", digest[i]);247 }248 Tcl_DStringInit(&ds);249 Tcl_DStringAppend(&ds, STATSDIR, -1);250 Tcl_DStringAppend(&ds, "/", 1);251 Tcl_DStringAppend(&ds, fileName, 32);252 path = Tcl_DStringValue(&ds);253 254 statsFile = open(path, O_EXCL | O_CREAT | O_WRONLY, 0600);255 Tcl_DStringFree(&ds);256 if (statsFile < 0) {257 ERROR("can't open \"%s\": %s", fileName, strerror(errno));258 return -1;259 }260 return statsFile;261 }262 263 int264 NanoVis::writeToStatsFile(int f, const char *s, size_t length)265 {266 if (f >= 0) {267 ssize_t numWritten;268 269 numWritten = write(f, s, length);270 if (numWritten == (ssize_t)length) {271 close(dup(f));272 }273 }274 return 0;275 }276 277 static int278 serverStats(int code)279 {280 double start, finish;281 char buf[BUFSIZ];282 Tcl_DString ds;283 int result;284 285 {286 struct timeval tv;287 288 /* Get ending time. */289 gettimeofday(&tv, NULL);290 finish = CVT2SECS(tv);291 tv = NanoVis::stats.start;292 start = CVT2SECS(tv);293 }294 /*295 * Session information:296 * - Name of render server297 * - Process ID298 * - Hostname where server is running299 * - Start date of session300 * - Start date of session in seconds301 * - Number of frames returned302 * - Number of bytes total returned (in frames)303 * - Number of commands received304 * - Total elapsed time of all commands305 * - Total elapsed time of session306 * - Exit code of vizserver307 * - User time308 * - System time309 * - User time of children310 * - System time of children311 */312 313 Tcl_DStringInit(&ds);314 315 Tcl_DStringAppendElement(&ds, "render_stop");316 /* renderer */317 Tcl_DStringAppendElement(&ds, "renderer");318 Tcl_DStringAppendElement(&ds, "nanovis");319 /* pid */320 Tcl_DStringAppendElement(&ds, "pid");321 sprintf(buf, "%d", NanoVis::stats.pid);322 Tcl_DStringAppendElement(&ds, buf);323 /* host */324 Tcl_DStringAppendElement(&ds, "host");325 gethostname(buf, BUFSIZ-1);326 buf[BUFSIZ-1] = '\0';327 Tcl_DStringAppendElement(&ds, buf);328 /* date */329 Tcl_DStringAppendElement(&ds, "date");330 strcpy(buf, ctime(&NanoVis::stats.start.tv_sec));331 buf[strlen(buf) - 1] = '\0';332 Tcl_DStringAppendElement(&ds, buf);333 /* date_secs */334 Tcl_DStringAppendElement(&ds, "date_secs");335 sprintf(buf, "%ld", NanoVis::stats.start.tv_sec);336 Tcl_DStringAppendElement(&ds, buf);337 /* num_frames */338 Tcl_DStringAppendElement(&ds, "num_frames");339 sprintf(buf, "%lu", (unsigned long)NanoVis::stats.nFrames);340 Tcl_DStringAppendElement(&ds, buf);341 /* frame_bytes */342 Tcl_DStringAppendElement(&ds, "frame_bytes");343 sprintf(buf, "%lu", (unsigned long)NanoVis::stats.nBytes);344 Tcl_DStringAppendElement(&ds, buf);345 /* num_commands */346 Tcl_DStringAppendElement(&ds, "num_commands");347 sprintf(buf, "%lu", (unsigned long)NanoVis::stats.nCommands);348 Tcl_DStringAppendElement(&ds, buf);349 /* cmd_time */350 Tcl_DStringAppendElement(&ds, "cmd_time");351 sprintf(buf, "%g", NanoVis::stats.cmdTime);352 Tcl_DStringAppendElement(&ds, buf);353 /* session_time */354 Tcl_DStringAppendElement(&ds, "session_time");355 sprintf(buf, "%g", finish - start);356 Tcl_DStringAppendElement(&ds, buf);357 /* status */358 Tcl_DStringAppendElement(&ds, "status");359 sprintf(buf, "%d", code);360 Tcl_DStringAppendElement(&ds, buf);361 {362 long clocksPerSec = sysconf(_SC_CLK_TCK);363 double clockRes = 1.0 / clocksPerSec;364 struct tms tms;365 366 memset(&tms, 0, sizeof(tms));367 times(&tms);368 /* utime */369 Tcl_DStringAppendElement(&ds, "utime");370 sprintf(buf, "%g", tms.tms_utime * clockRes);371 Tcl_DStringAppendElement(&ds, buf);372 /* stime */373 Tcl_DStringAppendElement(&ds, "stime");374 sprintf(buf, "%g", tms.tms_stime * clockRes);375 Tcl_DStringAppendElement(&ds, buf);376 /* cutime */377 Tcl_DStringAppendElement(&ds, "cutime");378 sprintf(buf, "%g", tms.tms_cutime * clockRes);379 Tcl_DStringAppendElement(&ds, buf);380 /* cstime */381 Tcl_DStringAppendElement(&ds, "cstime");382 sprintf(buf, "%g", tms.tms_cstime * clockRes);383 Tcl_DStringAppendElement(&ds, buf);384 }385 Tcl_DStringAppend(&ds, "\n", -1);386 int f = NanoVis::getStatsFile(NULL);387 result = NanoVis::writeToStatsFile(f, Tcl_DStringValue(&ds),388 Tcl_DStringLength(&ds));389 close(f);390 Tcl_DStringFree(&ds);391 return result;392 }393 394 #endif395 396 static void397 initService()398 {399 TRACE("Enter");400 401 const char* user = getenv("USER");402 char* logName = NULL;403 int logNameLen = 0;404 405 if (user == NULL) {406 logNameLen = 20+1;407 logName = (char *)calloc(logNameLen, sizeof(char));408 strncpy(logName, "/tmp/nanovis_log.txt", logNameLen);409 } else {410 logNameLen = 17+1+strlen(user);411 logName = (char *)calloc(logNameLen, sizeof(char));412 strncpy(logName, "/tmp/nanovis_log_", logNameLen);413 strncat(logName, user, strlen(user));414 }415 416 //open log and map stderr to log file417 NanoVis::logfile = fopen(logName, "w");418 dup2(fileno(NanoVis::logfile), 2);419 /* dup2(2,1); */420 421 // clean up malloc'd memory422 if (logName != NULL) {423 free(logName);424 }425 426 TRACE("Leave");427 }428 429 static void430 exitService(int code)431 {432 TRACE("Enter: %d", code);433 434 NanoVis::removeAllData();435 436 NvShader::exitCg();437 438 //close log file439 if (NanoVis::logfile != NULL) {440 fclose(NanoVis::logfile);441 NanoVis::logfile = NULL;442 }443 444 #ifdef KEEPSTATS445 serverStats(code);446 #endif447 closelog();448 449 exit(code);450 }451 452 static int453 executeCommand(Tcl_Interp *interp, Tcl_DString *dsPtr)454 {455 struct timeval tv;456 double start, finish;457 int result;458 459 #ifdef WANT_TRACE460 char *str = Tcl_DStringValue(dsPtr);461 std::string cmd(str);462 cmd.erase(cmd.find_last_not_of(" \n\r\t")+1);463 TRACE("command %lu: '%s'", NanoVis::stats.nCommands+1, cmd.c_str());464 #endif465 466 gettimeofday(&tv, NULL);467 start = CVT2SECS(tv);468 469 if (NanoVis::recfile != NULL) {470 fprintf(NanoVis::recfile, "%s", Tcl_DStringValue(dsPtr));471 fflush(NanoVis::recfile);472 }473 result = Tcl_Eval(interp, Tcl_DStringValue(dsPtr));474 Tcl_DStringSetLength(dsPtr, 0);475 476 gettimeofday(&tv, NULL);477 finish = CVT2SECS(tv);478 479 NanoVis::stats.cmdTime += finish - start;480 NanoVis::stats.nCommands++;481 TRACE("Leave status=%d", result);482 return result;483 192 } 484 193 … … 615 324 planeRenderer->render(); 616 325 617 // INSOO326 //glPixelStorei(GL_PACK_ALIGNMENT, 1); 618 327 glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, screenBuffer); 619 //glReadPixels(0, 0, width, height, GL_BGR, GL_UNSIGNED_BYTE, screenBuffer); // INSOO's620 621 328 { 622 329 char prefix[200]; 623 ssize_t nWritten;624 330 625 331 TRACE("Sending ppm legend image %s min:%g max:%g", volArg, min, max); 626 332 sprintf(prefix, "nv>legend %s %g %g", volArg, min, max); 627 333 ppmWrite(prefix); 628 nWritten = write(1, "\n", 1);629 assert(nWritten == 1);630 334 } 631 335 planeRenderer->removePlane(index); … … 639 343 640 344 //initialize frame buffer objects for offscreen rendering 641 void 345 bool 642 346 NanoVis::initOffscreenBuffer() 643 347 { … … 678 382 if (!CheckFBO(&status)) { 679 383 PrintFBOStatus(status, "finalFbo"); 680 exitService(3);384 return false; 681 385 } 682 386 683 387 TRACE("Leave"); 388 return true; 684 389 } 685 390 686 391 //resize the offscreen buffer 687 void 392 bool 688 393 NanoVis::resizeOffscreenBuffer(int w, int h) 689 394 { 690 395 TRACE("Enter (%d, %d)", w, h); 691 396 if ((w == winWidth) && (h == winHeight)) { 692 return ;397 return true; 693 398 } 694 399 winWidth = w; … … 751 456 if (!CheckFBO(&status)) { 752 457 PrintFBOStatus(status, "finalFbo"); 753 exitService(3);458 return false; 754 459 } 755 460 … … 760 465 761 466 TRACE("Leave (%d, %d)", w, h); 467 return true; 762 468 } 763 469 … … 767 473 if (!NvShader::printErrorInfo()) { 768 474 TRACE("Cg error, exiting..."); 769 exit Service(-1);770 } 771 } 772 773 voidNanoVis::init(const char* path)475 exit(1); 476 } 477 } 478 479 bool NanoVis::init(const char* path) 774 480 { 775 481 // print OpenGL driver information … … 782 488 if (path == NULL) { 783 489 ERROR("No path defined for shaders or resources"); 784 exitService(1);490 return false; 785 491 } 786 492 GLenum err = glewInit(); 787 493 if (GLEW_OK != err) { 788 494 ERROR("Can't init GLEW: %s", glewGetErrorString(err)); 789 exitService(1);495 return false; 790 496 } 791 497 TRACE("Using GLEW %s", glewGetString(GLEW_VERSION)); … … 795 501 if (!GLEW_VERSION_2_1) { 796 502 ERROR("OpenGL version 2.1 or greater is required"); 797 exitService(1);503 return false; 798 504 } 799 505 … … 802 508 if (!GLEW_ARB_pixel_buffer_object) { 803 509 ERROR("Pixel buffer objects are not supported by driver, please check that the user running nanovis has permissions to create a direct rendering context (e.g. user has read/write access to /dev/nvidia* device nodes in Linux)."); 804 exitService(1);510 return false; 805 511 } 806 512 … … 810 516 if (!GLEW_EXT_framebuffer_object) { 811 517 ERROR("EXT_framebuffer_oject extension is required"); 812 exitService(1);518 return false; 813 519 } 814 520 // Rectangle textures were promoted in 3.1 … … 816 522 if (!GLEW_ARB_texture_rectangle) { 817 523 ERROR("ARB_texture_rectangle extension is required"); 818 exitService(1);524 return false; 819 525 } 820 526 #ifdef HAVE_FLOAT_TEXTURES … … 823 529 !GLEW_ARB_color_buffer_float) { 824 530 ERROR("ARB_texture_float and ARB_color_buffer_float extensions are required"); 825 exitService(1);531 return false; 826 532 } 827 533 #endif … … 830 536 !GLEW_NV_fragment_program2) { 831 537 ERROR("NV_vertex_program3 and NV_fragment_program2 extensions are required"); 832 exitService(1);538 return false; 833 539 } 834 540 835 541 if (!FilePath::getInstance()->setPath(path)) { 836 542 ERROR("can't set file path to %s", path); 837 exitService(1);543 return false; 838 544 } 839 545 … … 852 558 grid = new Grid(); 853 559 grid->setFont(fonts); 854 } 855 856 void 560 561 return true; 562 } 563 564 bool 857 565 NanoVis::initGL() 858 566 { … … 889 597 glLightfv(GL_LIGHT1, GL_SPECULAR, white_light); 890 598 891 initOffscreenBuffer(); //frame buffer object for offscreen rendering 892 893 //create volume renderer 599 //frame buffer object for offscreen rendering 600 if (!initOffscreenBuffer()) { 601 return false; 602 } 603 894 604 volRenderer = new VolumeRenderer(); 895 605 896 // create897 606 renderContext = new RenderContext(); 898 607 899 //create a 2D plane renderer900 608 planeRenderer = new PlaneRenderer(winWidth, winHeight); 901 609 … … 903 611 904 612 TRACE("leaving initGL"); 613 614 return true; 905 615 } 906 616 … … 1035 745 char string[200]; 1036 746 sprintf(string, "%s %d\n", prefix, fsize); 1037 nWritten = write( 1, string, strlen(string));747 nWritten = write(g_fdOut, string, strlen(string)); 1038 748 assert(nWritten == (ssize_t)strlen(string)); 1039 749 header[pos++] = 'B'; … … 1088 798 } 1089 799 1090 nWritten = write( 1, header, SIZEOF_BMP_HEADER);800 nWritten = write(g_fdOut, header, SIZEOF_BMP_HEADER); 1091 801 assert(nWritten == SIZEOF_BMP_HEADER); 1092 nWritten = write( 1, screenBuffer, (3*winWidth+pad)*winHeight);802 nWritten = write(g_fdOut, screenBuffer, (3*winWidth+pad)*winHeight); 1093 803 assert(nWritten == (3*winWidth+pad)*winHeight); 1094 stats.nFrames++;1095 stats.nBytes += (3*winWidth+pad)*winHeight;804 g_stats.nFrames++; 805 g_stats.nFrameBytes += (3*winWidth+pad)*winHeight; 1096 806 } 1097 807 … … 1154 864 srcRowPtr += bytesPerRow; 1155 865 } 1156 if (writev( 1, iov, nRecs) < 0) {866 if (writev(g_fdOut, iov, nRecs) < 0) { 1157 867 ERROR("write failed: %s", strerror(errno)); 1158 868 } 1159 869 free(iov); 1160 stats.nFrames++;1161 stats.nBytes += (bytesPerRow * winHeight);870 g_stats.nFrames++; 871 g_stats.nFrameBytes += (bytesPerRow * winHeight); 1162 872 TRACE("Leave (%dx%d)", winWidth, winHeight); 1163 }1164 1165 void1166 NanoVis::sendDataToClient(const char *command, const char *data, size_t dlen)1167 {1168 size_t numRecords = 2;1169 1170 struct iovec *iov = new iovec[numRecords];1171 1172 // Write the nanovisviewer command, then the image header and data.1173 // Command1174 // FIXME: shouldn't have to cast this1175 iov[0].iov_base = (char *)command;1176 iov[0].iov_len = strlen(command);1177 // Data1178 // FIXME: shouldn't have to cast this1179 iov[1].iov_base = (char *)data;1180 iov[1].iov_len = dlen;1181 if (writev(1, iov, numRecords) < 0) {1182 ERROR("write failed: %s", strerror(errno));1183 }1184 delete [] iov;1185 }1186 1187 void1188 NanoVis::idle()1189 {1190 TRACE("Enter");1191 1192 glutSetWindow(renderWindow);1193 1194 processCommands();1195 1196 TRACE("Leave");1197 873 } 1198 874 … … 1539 1215 TRACE("Setting bgcolor to %g %g %g", color[0], color[1], color[2]); 1540 1216 glClearColor(color[0], color[1], color[2], 1); 1217 } 1218 1219 void 1220 NanoVis::removeVolume(Volume *volume) 1221 { 1222 VolumeHashmap::iterator itr = volumeTable.find(volume->name()); 1223 if (itr != volumeTable.end()) { 1224 volumeTable.erase(itr); 1225 } 1226 delete volume; 1541 1227 } 1542 1228 … … 1794 1480 draw3dAxis(); 1795 1481 } 1796 if (grid->isVisible()) { 1797 grid->render(); 1798 } 1482 grid->render(); 1799 1483 if ((licRenderer != NULL) && (licRenderer->active())) { 1800 1484 licRenderer->render(); … … 1803 1487 velocityArrowsSlice->render(); 1804 1488 } 1805 if (!flowTable.empty()) { 1806 renderFlows(); 1807 } 1489 renderFlows(); 1808 1490 1809 1491 volRenderer->renderAll(); 1810 1492 1811 TRACE("Render heightmaps");1812 1493 HeightMapHashmap::iterator itr; 1813 1494 for (itr = heightMapTable.begin(); … … 1824 1505 } 1825 1506 1826 void1827 NanoVis::processCommands()1828 {1829 flags &= ~REDRAW_PENDING;1830 1831 TRACE("Enter");1832 1833 int flags = fcntl(0, F_GETFL, 0);1834 fcntl(0, F_SETFL, flags & ~O_NONBLOCK);1835 1836 int status = TCL_OK;1837 1838 // Read and execute as many commands as we can from stdin...1839 Tcl_DString cmdbuffer;1840 Tcl_DStringInit(&cmdbuffer);1841 int nCommands = 0;1842 bool isComplete = false;1843 while ((!feof(NanoVis::stdin)) && (status == TCL_OK)) {1844 //1845 // Read the next command from the buffer. First time through we1846 // block here and wait if necessary until a command comes in.1847 //1848 // BE CAREFUL: Read only one command, up to a newline. The "volume1849 // data follows" command needs to be able to read the data1850 // immediately following the command, and we shouldn't consume it1851 // here.1852 //1853 while (!feof(NanoVis::stdin)) {1854 int c = fgetc(NanoVis::stdin);1855 char ch;1856 if (c <= 0) {1857 if (errno == EWOULDBLOCK) {1858 break;1859 }1860 exitService(100);1861 }1862 ch = (char)c;1863 Tcl_DStringAppend(&cmdbuffer, &ch, 1);1864 if (ch == '\n') {1865 isComplete = Tcl_CommandComplete(Tcl_DStringValue(&cmdbuffer));1866 if (isComplete) {1867 break;1868 }1869 }1870 }1871 // no command? then we're done for now1872 if (Tcl_DStringLength(&cmdbuffer) == 0) {1873 break;1874 }1875 if (isComplete) {1876 // back to original flags during command evaluation...1877 fcntl(0, F_SETFL, flags & ~O_NONBLOCK);1878 status = executeCommand(interp, &cmdbuffer);1879 // non-blocking for next read -- we might not get anything1880 fcntl(0, F_SETFL, flags | O_NONBLOCK);1881 isComplete = false;1882 nCommands++;1883 CHECK_FRAMEBUFFER_STATUS();1884 }1885 }1886 fcntl(0, F_SETFL, flags);1887 1888 if (status != TCL_OK) {1889 char *msg;1890 char hdr[200];1891 int msgSize, hdrSize;1892 Tcl_Obj *objPtr;1893 1894 objPtr = Tcl_GetObjResult(interp);1895 msg = Tcl_GetStringFromObj(objPtr, &msgSize);1896 hdrSize = sprintf(hdr, "nv>viserror -type internal_error -bytes %d\n", msgSize);1897 {1898 struct iovec iov[2];1899 1900 iov[0].iov_base = hdr;1901 iov[0].iov_len = hdrSize;1902 iov[1].iov_base = msg;1903 iov[1].iov_len = msgSize;1904 if (writev(1, iov, 2) < 0) {1905 ERROR("write failed: %s", strerror(errno));1906 }1907 }1908 TRACE("Leaving on ERROR");1909 return;1910 }1911 if (feof(NanoVis::stdin)) {1912 TRACE("Exiting server on EOF from client");1913 exitService(90);1914 }1915 1916 update();1917 1918 bindOffscreenBuffer(); //enable offscreen render1919 render();1920 readScreen();1921 1922 if (feof(NanoVis::stdin)) {1923 exitService(90);1924 }1925 1926 ppmWrite("nv>image -type image -bytes");1927 1928 TRACE("Leave");1929 }1930 1931 int1932 main(int argc, char **argv)1933 {1934 const char *path;1935 char *newPath;1936 1937 newPath = NULL;1938 path = NULL;1939 NanoVis::stdin = stdin;1940 1941 fprintf(stdout, "NanoVis %s (build %s)\n", NANOVIS_VERSION, SVN_VERSION);1942 fflush(stdout);1943 1944 openlog("nanovis", LOG_CONS | LOG_PERROR | LOG_PID, LOG_USER);1945 memset(&NanoVis::stats, 0, sizeof(NanoVis::Stats));1946 NanoVis::stats.pid = getpid();1947 gettimeofday(&NanoVis::stats.start, NULL);1948 1949 /* Initialize GLUT here so it can parse and remove GLUT-specific1950 * command-line options before we parse the command-line below. */1951 glutInit(&argc, argv);1952 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);1953 glutInitWindowSize(NanoVis::winWidth, NanoVis::winHeight);1954 glutInitWindowPosition(10, 10);1955 NanoVis::renderWindow = glutCreateWindow("nanovis");1956 glutIdleFunc(NanoVis::idle);1957 1958 glutDisplayFunc(NanoVis::render);1959 glutReshapeFunc(NanoVis::resizeOffscreenBuffer);1960 1961 while (1) {1962 static struct option long_options[] = {1963 {"infile", required_argument, NULL, 0},1964 {"path", required_argument, NULL, 2},1965 {"debug", no_argument, NULL, 3},1966 {"record", required_argument, NULL, 4},1967 {0, 0, 0, 0}1968 };1969 int option_index = 0;1970 int c;1971 1972 c = getopt_long(argc, argv, ":dp:i:l:r:", long_options, &option_index);1973 if (c == -1) {1974 break;1975 }1976 switch (c) {1977 case '?':1978 fprintf(stderr, "unknown option -%c\n", optopt);1979 return 1;1980 case ':':1981 if (optopt < 4) {1982 fprintf(stderr, "argument missing for --%s option\n",1983 long_options[optopt].name);1984 } else {1985 fprintf(stderr, "argument missing for -%c option\n", optopt);1986 }1987 return 1;1988 case 2:1989 case 'p':1990 path = optarg;1991 break;1992 case 3:1993 case 'd':1994 NanoVis::debugFlag = true;1995 break;1996 case 0:1997 case 'i':1998 NanoVis::stdin = fopen(optarg, "r");1999 if (NanoVis::stdin == NULL) {2000 perror(optarg);2001 return 2;2002 }2003 break;2004 case 4:2005 case 'r':2006 Tcl_DString ds;2007 char buf[200];2008 2009 Tcl_DStringInit(&ds);2010 Tcl_DStringAppend(&ds, optarg, -1);2011 sprintf(buf, ".%d", getpid());2012 Tcl_DStringAppend(&ds, buf, -1);2013 NanoVis::recfile = fopen(Tcl_DStringValue(&ds), "w");2014 if (NanoVis::recfile == NULL) {2015 perror(optarg);2016 return 2;2017 }2018 break;2019 default:2020 fprintf(stderr,"unknown option '%c'.\n", c);2021 return 1;2022 }2023 }2024 if (path == NULL) {2025 char *p;2026 2027 // See if we can derive the path from the location of the program.2028 // Assume program is in the form <path>/bin/nanovis.2029 path = argv[0];2030 p = strrchr((char *)path, '/');2031 if (p != NULL) {2032 *p = '\0';2033 p = strrchr((char *)path, '/');2034 }2035 if (p == NULL) {2036 TRACE("path not specified");2037 return 1;2038 }2039 *p = '\0';2040 newPath = new char[(strlen(path) + 15) * 2 + 1];2041 sprintf(newPath, "%s/lib/shaders:%s/lib/resources", path, path);2042 path = newPath;2043 }2044 2045 FilePath::getInstance()->setWorkingDirectory(argc, (const char**) argv);2046 2047 #ifdef notdef2048 signal(SIGPIPE, SIG_IGN);2049 #endif2050 initService();2051 2052 NanoVis::init(path);2053 if (newPath != NULL) {2054 delete [] newPath;2055 }2056 NanoVis::initGL();2057 2058 NanoVis::interp = initTcl();2059 2060 NanoVis::resizeOffscreenBuffer(NanoVis::winWidth, NanoVis::winHeight);2061 2062 glutMainLoop();2063 2064 exitService(80);2065 }2066 2067 void2068 NanoVis::removeVolume(Volume *volume)2069 {2070 VolumeHashmap::iterator itr = volumeTable.find(volume->name());2071 if (itr != volumeTable.end()) {2072 volumeTable.erase(itr);2073 }2074 delete volume;2075 } -
nanovis/branches/1.1/nanovis.h
r4820 r4874 14 14 * ====================================================================== 15 15 */ 16 #ifndef NANOVIS_H 17 #define NANOVIS_H 18 19 #include <tcl.h> 20 #include <md5.h> 21 #include <GL/glew.h> 22 #include <sys/types.h> // For pid_t 23 #include <sys/time.h> // For struct timeval 16 #ifndef NV_NANOVIS_H 17 #define NV_NANOVIS_H 24 18 25 19 #include <math.h> 26 20 #include <stddef.h> // For size_t 27 21 #include <stdio.h> 22 #include <sys/time.h> // For struct timeval 23 #include <sys/types.h> // For pid_t 24 25 #include <tcl.h> 26 27 #include <GL/glew.h> 28 28 29 29 #include <vector> … … 34 34 35 35 #include "config.h" 36 37 #define NANOVIS_VERSION "1.1.3"38 36 39 37 //defines for the image based flow visualization … … 50 48 } 51 49 52 class VolumeRenderer; 53 class PointSetRenderer; 50 class NvCamera; 51 class Flow; 52 class Grid; 53 class HeightMap; 54 class NvLIC; 54 55 class NvParticleRenderer; 55 56 class PlaneRenderer; 57 class Texture2D; 58 class TransferFunction; 56 59 class VelocityArrowsSlice; 57 class NvLIC;58 class PointSet;59 class Texture2D;60 class HeightMap;61 class Grid;62 class NvCamera;63 class TransferFunction;64 60 class Volume; 65 class Flow;61 class VolumeRenderer; 66 62 67 63 class NanoVis … … 82 78 }; 83 79 84 typedef struct {85 pid_t pid;86 size_t nFrames; /**< # of frames sent to client. */87 size_t nBytes; /**< # of bytes for all frames. */88 size_t nCommands; /**< # of commands executed */89 double cmdTime; /**< Elasped time spend executing90 * commands. */91 struct timeval start; /**< Start of elapsed time. */92 } Stats;93 94 80 typedef std::string TransferFunctionId; 95 81 typedef std::string VolumeId; … … 101 87 typedef std::tr1::unordered_map<HeightMapId, HeightMap *> HeightMapHashmap; 102 88 103 static void processCommands(); 104 static void init(const char *path); 105 static void initGL(); 106 static void initOffscreenBuffer(); 107 static void resizeOffscreenBuffer(int w, int h); 89 static bool init(const char *path); 90 static bool initGL(); 91 static bool initOffscreenBuffer(); 92 static bool resizeOffscreenBuffer(int w, int h); 108 93 static void setBgColor(float color[3]); 109 94 static void render(); 110 95 static void draw3dAxis(); 111 static void idle();112 96 static void update(); 113 97 static void removeAllData(); … … 123 107 static void eventuallyRedraw(unsigned int flag = 0); 124 108 125 static void setVolumeRanges();126 static void setHeightmapRanges();127 128 #ifdef KEEPSTATS129 static int getStatsFile(Tcl_Obj *objPtr);130 static int writeToStatsFile(int f, const char *s, size_t length);131 #endif132 109 static void ppmWrite(const char *prefix); 133 static void sendDataToClient(const char *command, const char *data,134 size_t dlen);135 110 static void bmpWrite(const char *prefix); 136 111 static void bmpWriteToFile(int frame_number, const char* directory_name); … … 151 126 static void readScreen() 152 127 { 128 //glPixelStorei(GL_PACK_ALIGNMENT, 1); 153 129 glReadPixels(0, 0, winWidth, winHeight, GL_RGB, GL_UNSIGNED_BYTE, 154 130 screenBuffer); … … 159 135 } 160 136 137 static void setVolumeRanges(); 138 static void setHeightmapRanges(); 139 161 140 static Flow *getFlow(const char *name); 162 141 static Flow *createFlow(Tcl_Interp *interp, const char *name); 142 static void deleteFlows(Tcl_Interp *interp); 163 143 static void deleteFlow(const char *name); 164 static void deleteFlows(Tcl_Interp *interp);165 144 static bool mapFlows(); 166 145 static void getFlowBounds(vrmath::Vector3f& min, … … 172 151 static void advectFlows(); 173 152 174 static FILE *stdin, *logfile, *recfile; 175 static Stats stats; 176 static int statsFile; 153 static Tcl_Interp *interp; 154 177 155 static unsigned int flags; 178 156 static bool debugFlag; … … 181 159 static int winWidth; ///< Width of the render window 182 160 static int winHeight; ///< Height of the render window 183 static int renderWindow; // < GLUT handle for the render window161 static int renderWindow; ///< GLUT handle for the render window 184 162 static unsigned char *screenBuffer; 185 163 static Texture2D *legendTexture; 186 static Grid *grid;187 164 static nv::util::Fonts *fonts; 188 165 static int updir; … … 203 180 static NvLIC *licRenderer; 204 181 static PlaneRenderer *planeRenderer; 205 206 static Tcl_Interp *interp; 182 static Grid *grid; 207 183 208 184 private:
Note: See TracChangeset
for help on using the changeset viewer.