source: trunk/src/testing/app/volvis/vNet.cpp @ 4

Revision 4, 14.6 KB checked in by ajaworski, 13 years ago (diff)

Added modified SAGE sources

Line 
1/********************************************************************************
2 * Volatile - Volume Visualization Software for SAGE
3 * Copyright (C) 2004 Electronic Visualization Laboratory,
4 * University of Illinois at Chicago
5 *
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 *  * Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 *  * Redistributions in binary form must reproduce the above
14 *    copyright notice, this list of conditions and the following disclaimer
15 *    in the documentation and/or other materials provided with the distribution.
16 *  * Neither the name of the University of Illinois at Chicago nor
17 *    the names of its contributors may be used to endorse or promote
18 *    products derived from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 * Direct questions, comments etc about Volatile to www.evl.uic.edu/cavern/forum
33 *********************************************************************************/
34
35#if defined(V_DISTRIBUTED)
36#include "vNet.h"
37#include "global.h"
38#include "vGeometry.h"
39#include <string.h>
40
41char* getServerIP(int rank, const char* serverFile) {
42        string line;
43        ifstream in(serverFile); // Read
44        if (!in) {
45                cerr <<"File "<<serverFile<<" cant be read\n";
46                return NULL;
47        }
48        while(getline(in,line)) {
49                istringstream line_stream(line);
50                int tileRank;
51                string serverIP;
52                line_stream >> tileRank;
53                line_stream >> serverIP;
54                if (tileRank == rank)
55                        return (char*)serverIP.c_str();
56        }
57        return NULL;
58}
59
60
61QUANTAts_mutex_c tfMutex;
62vNet::vNet()
63{
64        master = 0;
65        cmdFlushed = 1;
66        readyToDie =0;          //dont want to die right away
67}
68
69vNet::~vNet() {
70}
71
72void vNet::init(int &argc, char** &argv)
73{
74        //init MPI
75        int rc = MPI_Init(&argc, &argv);
76        MPI_Comm comm;
77        rc = MPI_Comm_size(MPI_COMM_WORLD, &noProcs);
78        rc = MPI_Comm_rank(MPI_COMM_WORLD, &rank);
79        if (setenv("DISPLAY", ":0", 1) == -1)
80        {
81                cerr<<"\nCannot display on Tile "<<rank<<endl;
82                exit(1);
83        }
84}
85
86//Clean up and exit
87void vNet::deactivateTiles() {
88        fillExitCommand();
89}
90
91void vNet::process() {
92        if (master != rank)     //slaves
93    {
94                char* data = new char[COMMAND_SIZE];
95                bzero(data, COMMAND_SIZE);
96                cmdFlushed = 1;
97                //listen from master node for commands
98                MPI_Bcast(data, COMMAND_SIZE, MPI_BYTE, master, MPI_COMM_WORLD );
99                //fprintf(stderr, "Proc %d/%d> Receiving command\n", rank, noProcs);
100                processCmd(data);       //process the command
101                glutPostRedisplay();
102    }
103        else
104    { //master
105                //Broadcast a command that has been set appropriately
106                //fprintf(stderr, "Proc %d/%d> Sending command\n", rank, noProcs);
107                tfMutex.lock();
108                MPI_Bcast(buffer, COMMAND_SIZE, MPI_BYTE, master, MPI_COMM_WORLD );
109                tfMutex.unlock();
110
111
112                if (readyToDie == 1)
113                {
114                        int rc = MPI_Finalize(); //wait and clean up
115                        exit(0);         //All dead, We can now exit
116                }
117                fillDummyCommand(); //just to keep everyone displaying
118                //fprintf(stderr, "Proc %d/%d> After Sending command, before display\n", rank, noProcs);
119                glutPostRedisplay();
120    }
121}
122
123void vNet::processCmd(char* data)
124{
125        //Unpack data - contains command name and arguments
126        dataPack.initUnpack(data, COMMAND_SIZE);
127        char key[24];
128        int len;
129        dataPack.unpackInt(&len);   //str length of command
130        dataPack.unpack(key, len);
131        if (!strcmp(key,"DUMMY"))
132        {
133                //do nothing - ignore (this is just to synchronize display calls of all tiles with master)
134        }
135        else if (!strcmp(key,"VOL_ROTN")) {
136                //set the global transform rotn to be this one
137                for (int i=0;i<16;i++)
138                        dataPack.unpackFloat(&renderList[global.curPrimIdx]->xform.rotn[i]);
139        }
140        else if (!strcmp(key,"VOL_CUTROTN")) {
141                global.cut.update = true;
142                //set the cut rotn to be this one
143                dataPack.unpackFloat(&global.cut.angle);
144                for (int i=0;i<3;i++)
145                        dataPack.unpackFloat(&global.cut.axis[i]);
146        }
147        else if (!strcmp(key,"VOL_LOWRES")) { //use tag to distinguish messages
148                //set the global transform lowresrto be this one
149                dataPack.unpackInt(&global.volren.lowRes);
150        }
151        else if (!strcmp(key,"VOL_TRANSLATION")) { //use tag to distinguish messages
152                //set the global transform lowresrto be this one
153                for (int i=0;i<3;i++)
154                        dataPack.unpackFloat(&renderList[global.curPrimIdx]->xform.trans[i]);
155        }
156        else if (!strcmp(key,"VOL_ZOOM")) { //use tag to distinguish messages
157                //set the global transform lowresrto be this one
158                float zoomFactor;
159                dataPack.unpackFloat(&zoomFactor);
160                renderList[global.curPrimIdx]->xform.scale += zoomFactor;
161                //global.env.eye[2] += zoomFactor;
162        }
163        else if (!strcmp(key,"VOL_CUTZOOM")) { //use tag to distinguish messages
164                //set the global transform lowresrto be this one
165                float zoomFactor;
166                dataPack.unpackFloat(&zoomFactor);
167                global.cut.user[3] += zoomFactor;
168        }
169        else if (!strcmp(key,"VOL_SAMPLERATE")) { //use tag to distinguish messages
170                //set the global transform lowresrto be this one
171                float scaleSample;
172                dataPack.unpackFloat(&scaleSample);
173                global.volren.goodSamp *= scaleSample;
174                global.volren.interactSamp *= scaleSample;
175                global.volren.sampleRate = global.volren.goodSamp;
176        }
177        else if (!strcmp(key,"VOL_PRINTFPS")) {
178                global.ui.printFPS = !global.ui.printFPS;
179                if (global.ui.printFPS)
180                        glutIdleFunc(idle);
181                else
182                        glutIdleFunc(0);
183        }
184        else if (!strcmp(key,"VOL_CUTPLANE")) {
185                global.ui.cutEnabled = !global.ui.cutEnabled;
186        }
187        else if (!strcmp(key,"VOL_BOUNDBOX")) {
188                global.ui.bboxEnabled = !global.ui.bboxEnabled;
189        }
190        else if (!strcmp(key,"VOL_NAVROAM")) {
191                global.ui.navMode = V_ROAM;
192        }
193        else if (!strcmp(key,"VOL_NAVPROBE")) {
194                global.ui.navMode = V_PROBE;
195        }
196        else if (!strcmp(key,"VOL_ISOSURFACE")) {
197                int isoValue;
198                float tx, ty, scale;
199                dataPack.unpackInt(&isoValue);
200                dataPack.unpackFloat(&tx);
201                dataPack.unpackFloat(&ty);
202                dataPack.unpackFloat(&scale);
203                global.volume->setIsoValue(isoValue);
204                NetVertexBuffer* theGeom = global.volume->isoSurface();
205                vGeometry* newIso = new vGeometry(theGeom);
206                newIso->xform.trans[0] = tx;
207                newIso->xform.trans[1] = ty;
208                newIso->xform.scale = scale;
209                fprintf(stderr,"VOL_ISOSURFACE: New geom translation %f %f scale %f\n",newIso->xform.trans[0],newIso->xform.trans[1],
210                        newIso->xform.scale);
211                renderList.push_back(newIso);
212        }
213        else if (!strcmp(key,"VOL_LUT")) {
214                for (int i=0;i<256*4;i++) {
215                        dataPack.unpackChar((char*)&global.volren.deptex[i]);
216                }
217                dataPack.unpackInt(&global.volren.lowRes);
218                global.volren.loadTLUT = 1;
219        }
220        else if (!strcmp(key,"VOL_SAVEGRADIENTVOL")) {
221                global.volume->saveGradient();
222        }
223        else if (!strcmp(key,"VOL_ROAM")) {
224                int x, y, z;
225                dataPack.unpackInt(&x);
226                dataPack.unpackInt(&y);
227                dataPack.unpackInt(&z);
228                global.volume->roam(x,y,z);
229                global.volren.loadVolume = 1;
230        }
231        else if (!strcmp(key,"VOL_PROBE")) {
232                int x, y, z;
233                dataPack.unpackInt(&x);
234                dataPack.unpackInt(&y);
235                dataPack.unpackInt(&z);
236                global.volume->probe(x,y,z);
237        }
238        /*
239        else if (!strcmp(key,"VOL_POINTERPOS")) {
240                dataPack.unpackFloat(&global.pointerPos[0]);
241                dataPack.unpackFloat(&global.pointerPos[1]);
242                dataPack.unpackFloat(&global.pointerPos[2]);
243                global.curPrimIdx= 0;
244                //select each primitive to see which is selected
245                for (int i=0;i< renderList.size();i++) {
246                        if (renderList[i]->select()) {
247                                global.curPrimIdx= i;
248                                break;
249                        }
250                }
251        }
252        */
253        else if (!strcmp(key,"VOL_SELECT")) {
254                dataPack.unpackInt(&global.curPrimIdx);
255                for (int i=0;i<renderList.size();i++) {
256                        if (i==global.curPrimIdx)
257                                renderList[i]->setSelected(true);
258                        else
259                                renderList[i]->setSelected(false);
260                }
261        }
262        else if (!strcmp(key,"VOL_TOGGLEANIMATE")) {
263                for (int i=0;i<renderList.size();i++)
264                        renderList[i]->toggleAnimate();
265        }
266        else if (!strcmp(key,"VOL_UPDATEANIM")) {
267                for (int i=0;i<renderList.size();i++) {
268                        if (renderList[i]->isAnimating()) {
269                                renderList[i]->next();
270                        }
271                }
272        }
273        else if (!strcmp(key,"EXIT"))
274        {
275                int rc = MPI_Finalize(); //clean up mpi stuff
276                if (data) delete data;   //be responsible
277                deallocateAll();
278                exit(0);
279        }
280        if (data) delete data;
281}
282
283// Called when tile needs to be refreshed
284bool vNet::readTileConfig(const char* configFile) {
285        cerr << rank<<" readTileConfig : filename is "<<configFile<<endl;
286        string line;
287        ifstream in(configFile); // Read
288        if (!in) {
289                cerr <<"File "<<configFile<<" cant be read\n";
290                return false;
291        }
292        global.env.frustumList.clear();
293        global.env.viewportList.clear();
294        while(getline(in,line)) {
295                istringstream line_stream(line);
296                int tileRank;
297                float   minX, maxX, minY, maxY;
298                float   vpx, vpy, vpwidth, vpheight;
299                line_stream >> tileRank;
300                //read the tile extent
301                line_stream >> minX;
302                line_stream >> maxX;
303                line_stream >> minY;
304                line_stream >> maxY;
305
306                //read the viewport for each frustum
307                if (line_stream.eof()) { //fill in default values
308                        vpx = vpy = 0.0;
309                        vpwidth = vpheight = 1.0f;
310                }
311                else {
312                        line_stream >> vpx;
313                        line_stream >> vpy;
314                        line_stream >> vpwidth;
315                        line_stream >> vpheight;
316                }
317
318                if (tileRank == rank)  //if the rank matches, store the values
319                {
320                        //fprintf(stderr, "\nTile %d Image offsets: %d %d ", rank, xOffset, yOffset);
321                        vFrustum curFrustum;
322                        vViewport curvp;
323                        curFrustum.left = (minX - 50.0) / 50.0;
324                        curFrustum.right = (maxX - 50.0) / 50.0;
325                        curFrustum.bottom = (minY - 50.0) / 50.0;
326                        curFrustum.top = (maxY - 50.0) / 50.0;
327                        float fov = 45.0f*M_PI/180.0f;
328                        float b = global.env.clip[0] * (float) tan(fov * 0.5);
329                        fprintf(stderr,"Node %d aspect %f\n",rank,global.win.aspect);
330                        float r = b * global.win.aspect;
331                        curFrustum.left *= r;  //left
332                        curFrustum.right *= r;   //right
333                        curFrustum.bottom *= b;  //bottom
334                        curFrustum.top *= b;   //top
335
336                        //now add the current frustum to the frustum list
337                        global.env.frustumList.push_back(curFrustum);
338
339                        curvp.x = vpx;
340                        curvp.y = vpy;
341                        curvp.width = vpwidth;
342                        curvp.height = vpheight;
343                        global.env.viewportList.push_back(curvp);
344                        fprintf(stderr,"*******viewport %f %f %f %f\n",curvp.x, curvp.y, curvp.width, curvp.height);
345                }
346        }  //end while
347        return true;
348}
349void vNet::packCommand(const char* cmdString, int flushed)
350{
351        memset(buffer, 0, COMMAND_SIZE);
352        dataPack.initPack(buffer, COMMAND_SIZE);
353        char cmd[25];
354        strcpy(cmd, cmdString);
355        int len = strlen(cmd) +1;
356        dataPack.packInt(len);
357        dataPack.pack(cmd, len );
358        cmdFlushed = flushed;
359        //the command is sent during the display call
360}
361
362//send vol rotation
363void vNet::setRotn(float rotn[16]) {
364        packCommand("VOL_ROTN");
365        for (int i=0;i<16;i++)
366                dataPack.packFloat(rotn[i]);
367}
368
369//send the transfer function
370void vNet::setLUT(int size, unsigned char* data) {
371        tfMutex.lock();
372        packCommand("VOL_LUT");
373        for (int i=0;i<size;i++)
374                dataPack.packChar(data[i]);
375        tfMutex.unlock();
376}
377
378//send the cutplane rotation in axis angle
379void vNet::setCutRotation(float angle, float axis[3]) {
380        packCommand("VOL_CUTROTN");
381        dataPack.packFloat(angle);
382        for (int i=0;i<3;i++)
383                dataPack.packFloat(axis[i]);
384}
385
386//set the zoom of the cutplane
387void vNet::setCutZoom(float dzoom) {
388        packCommand("VOL_CUTZOOM");
389        dataPack.packFloat(dzoom);
390}
391
392//send lowres
393void vNet::setLowRes(int lowRes) {
394        packCommand("VOL_LOWRES");
395        dataPack.packInt(lowRes);
396        //fprintf(stderr,"In setLowRes: lowres %d\n",lowRes);
397}
398
399//save GRadient Info
400void vNet::saveGradientVolume() {
401         packCommand("VOL_SAVEGRADIENTVOL");
402}
403
404//do select
405void vNet::select(float pointerPos[3]) {
406        packCommand("VOL_POINTERPOS");
407        for (int i=0;i<3;i++)
408                dataPack.packFloat(pointerPos[i]);
409}
410
411//do select
412void vNet::select(int index) {
413        packCommand("VOL_SELECT");
414        dataPack.packInt(index);
415}
416
417//set translation
418void vNet::setTranslation(float translation[3]) {
419        packCommand("VOL_TRANSLATION");
420        for (int i=0;i<3;i++)
421                dataPack.packFloat(translation[i]);
422}
423
424//set zoom
425void vNet::setZoom(float factor) {
426        packCommand("VOL_ZOOM");
427        dataPack.packFloat(factor);
428}
429
430//scale sample rate
431void vNet::scaleSampleRate(float factor) {
432        packCommand("VOL_SAMPLERATE");
433        dataPack.packFloat(factor);
434}
435
436//animate volume
437void vNet::animateVolume() {
438        packCommand("VOL_TOGGLEANIMATE");
439}
440
441//animate volume
442void vNet::updateAnim() {
443        packCommand("VOL_UPDATEANIM");
444}
445
446
447//toggle printing frame rate
448void vNet::togglePrintFPS() {
449        packCommand("VOL_PRINTFPS");
450}
451
452//toggle printing frame rate
453void vNet::toggleCutPlane() {
454        packCommand("VOL_CUTPLANE");
455}
456
457//toggle display of bound box
458void vNet::toggleBoundBox() {
459        packCommand("VOL_BOUNDBOX");
460}
461
462//set roam
463void vNet::setRoam() {
464        packCommand("VOL_NAVROAM");
465}
466
467//set probe
468void vNet::setProbe() {
469        packCommand("VOL_NAVPROBE");
470}
471
472//send the roam factor
473void vNet::roamVolume(int roamX, int roamY, int roamZ) {
474        packCommand("VOL_ROAM");
475        dataPack.packInt(roamX);
476        dataPack.packInt(roamY);
477        dataPack.packInt(roamZ);
478}
479
480//send the roam factor
481void vNet::probeVolume(int probeX, int probeY, int probeZ) {
482        packCommand("VOL_PROBE");
483        dataPack.packInt(probeX);
484        dataPack.packInt(probeY);
485        dataPack.packInt(probeZ);
486
487}
488
489//send command to get the isosurface and display it
490void vNet::getIsosurface(int isoValue, float tx, float ty, float scale) {
491        packCommand("VOL_ISOSURFACE");
492        dataPack.packInt(isoValue);
493        dataPack.packFloat(tx);
494        dataPack.packFloat(ty);
495        dataPack.packFloat(scale);
496
497}
498
499//send command to get the isopoint and display it
500void vNet::getIsopoint(int isoValue, float tx, float ty, float scale) {
501        packCommand("VOL_ISOPOINT");
502        dataPack.packInt(isoValue);
503        dataPack.packFloat(tx);
504        dataPack.packFloat(ty);
505        dataPack.packFloat(scale);
506
507}
508
509//send empty broadcasts to clients
510void vNet::fillDummyCommand()
511{
512        packCommand("DUMMY", 1);
513}
514
515//fill up a command to do MPI_Finalize (clean up MPI)
516void vNet::fillExitCommand()
517{
518        packCommand("EXIT");
519        readyToDie =1;          //set flag -ready to exit now
520}
521
522
523#endif
Note: See TracBrowser for help on using the repository browser.