diff --git a/Common/GmshDaemon.cpp b/Common/GmshDaemon.cpp index 48c307c9abef0376c4de6bccc545e5d1753191c7..a78e6fbfdf0fb7496a482c942163113e15da711f 100644 --- a/Common/GmshDaemon.cpp +++ b/Common/GmshDaemon.cpp @@ -7,6 +7,8 @@ #include "GmshMessage.h" #include "OS.h" #include "GmshSocket.h" +#include "PView.h" +#include "VertexArray.h" int GmshDaemon(std::string socket) { @@ -42,6 +44,19 @@ int GmshDaemon(std::string socket) stop = true; } break; + case GmshSocket::GMSH_VERTEX_ARRAY: + { + // create and send a vertex array + if(PView::list.size()){ + PView *view = PView::list[0]; + view->fillVertexArrays(); + int len; + char *ss = view->va_triangles->toChar(view->getNum(), len); + client.SendMessage(GmshSocket::GMSH_VERTEX_ARRAY, len, ss); + delete [] ss; + } + } + break; case GmshSocket::GMSH_SPEED_TEST: { std::string huge(500000000, 'a'); diff --git a/Common/GmshSocket.h b/Common/GmshSocket.h index 7686c333ab65a15e2a326667dd0a049a7e0b3069..9d188b0b86318c28ce428c332c765b7cf8726d2b 100644 --- a/Common/GmshSocket.h +++ b/Common/GmshSocket.h @@ -48,6 +48,7 @@ class GmshSocket{ GMSH_PROGRESS = 13, GMSH_MERGE_FILE = 20, GMSH_PARSE_STRING = 21, + GMSH_VERTEX_ARRAY = 22, GMSH_SPEED_TEST = 30, GMSH_OPTION_1 = 100, GMSH_OPTION_2 = 101, @@ -138,14 +139,17 @@ class GmshSocket{ // minus 1... hence the +1 below return select(s + 1, &rfds, NULL, NULL, &tv); } - void SendString(int type, const char *str) + void SendMessage(int type, int length, const void *msg) { // send header (type + length) _SendData(&type, sizeof(int)); - int len = strlen(str); - _SendData(&len, sizeof(int)); + _SendData(&length, sizeof(int)); // send body - _SendData(str, len); + _SendData(msg, length); + } + void SendString(int type, const char *str) + { + SendMessage(type, strlen(str), str); } void Info(const char *str){ SendString(GMSH_INFO, str); } void Warning(const char *str){ SendString(GMSH_WARNING, str); } diff --git a/Common/VertexArray.cpp b/Common/VertexArray.cpp index a2f4c1684ab15e63a7360e8492d0e74deebd07ec..c0284877f9e4532c936a36fd34d4c23920c14aa9 100644 --- a/Common/VertexArray.cpp +++ b/Common/VertexArray.cpp @@ -4,6 +4,7 @@ // bugs and problems to <gmsh@geuz.org>. #include <algorithm> +#include "GmshMessage.h" #include "VertexArray.h" #include "Context.h" #include "Numeric.h" @@ -214,3 +215,63 @@ int VertexArray::getMemoryUsage() _colors.size() * sizeof(unsigned char); return bytes / 1024 / 1024; } + +char *VertexArray::toChar(int num, int &len) +{ + int vn = _vertices.size(), nn = _normals.size(), cn = _colors.size(); + int vs = vn * sizeof(float), ns = nn * sizeof(char), cs = cn * sizeof(unsigned char); + int is = sizeof(int); + + FILE *fp = fopen("toChar.txt", "w"); + for(unsigned int i = 0; i < _vertices.size(); i++) + fprintf(fp, "toChar vertex %d = %f\n", i, _vertices[i]); + fclose(fp); + + len = 5 * is + vs + ns + cs; + char *data = new char[len]; + int index = 0; + memcpy(&data[index], &num, is); index += is; + memcpy(&data[index], &_numVerticesPerElement, is); index += is; + memcpy(&data[index], &vn, is); index += is; + memcpy(&data[index], &_vertices[0], vs); index + vs; + memcpy(&data[index], &nn, is); index += is; + memcpy(&data[index], &_normals[0], ns); index += ns; + memcpy(&data[index], &cn, is); index += is; + memcpy(&data[index], &_colors[0], cs); index += cs; + return data; +} + +void VertexArray::fromChar(const char *data, bool swap) +{ + if(swap){ + Msg::Error("Byte swapping not implemented in VertexArray::fromChar"); + return; + } + int is = sizeof(int), index = 0; + + int num; memcpy(&num, &data[index], is); index += is; + int tmp; memcpy(&tmp, &data[index], is); index += is; + if(tmp != _numVerticesPerElement){ + Msg::Error("Incompatible raw data for vertex array (%d != %d)", + tmp, _numVerticesPerElement); + return; + } + + int vn; memcpy(&vn, &data[index], is); index += is; + _vertices.resize(vn); int vs = vn * sizeof(float); + memcpy(&_vertices[0], &data[index], vs); index += vs; + + int nn; memcpy(&nn, &data[index], is); index += is; + _normals.resize(nn); int ns = nn * sizeof(char); + memcpy(&_normals[0], &data[index], ns); index += ns; + + int cn; memcpy(&cn, &data[index], is); index += is; + _colors.resize(cn); int cs = cn * sizeof(unsigned char); + memcpy(&_colors[0], &data[index], cs); index += cs; + + + FILE *fp = fopen("fromChar.txt", "w"); + for(unsigned int i = 0; i < _vertices.size(); i++) + fprintf(fp, "from char vertex %d = %f\n", i, _vertices[i]); + fclose(fp); +} diff --git a/Common/VertexArray.h b/Common/VertexArray.h index 7e05c2ce02dfb3cc11cd249cd47d627e1418f291..6c8fc165ae01c8239d1d5b1a89f5c9e3569c0d52 100644 --- a/Common/VertexArray.h +++ b/Common/VertexArray.h @@ -161,6 +161,10 @@ class VertexArray{ void sort(double x, double y, double z); // estimate the size of the vertex array in megabytes int getMemoryUsage(); + // serialize the vertex array into a string (for sending over the + // network) + char *toChar(int num, int &len); + void fromChar(const char *data, bool swap=false); }; #endif diff --git a/Fltk/menuWindow.cpp b/Fltk/menuWindow.cpp index 9fee975112ca61fcf6437a738d122e0bd7f22bf3..a3e7908c0f847ef3d874e9a359a575182bdddc0e 100644 --- a/Fltk/menuWindow.cpp +++ b/Fltk/menuWindow.cpp @@ -159,7 +159,9 @@ static void file_remote_cb(Fl_Widget *w, void *data) GmshRemote::get(99)->name = "Remote"; GmshRemote::get(99)->socketSwitch = "-socket %s"; const char *exe = fl_input - ("Remote command:", "ssh ace25 /Users/geuzaine/src/gmsh/bin/gmsh"); + ("Command:", + //"ssh ace25 /Users/geuzaine/src/gmsh/bin/gmsh"); + "./gmsh ../tutorial/view3.pos"); if(exe){ GmshRemote::get(99)->executable = exe; GmshRemote::get(99)->run(""); @@ -196,6 +198,16 @@ static void file_remote_cb(Fl_Widget *w, void *data) Msg::Error("Cannot test remote Gmsh: server not running"); } } + else if(str == "test3"){ + if(GmshRemote::get(99)->getServer()){ + Msg::Info("Testing remote Gmsh server"); + GmshRemote::get(99)->getServer()->SendString + (GmshSocket::GMSH_VERTEX_ARRAY, "Send me a vertex array!"); + } + else{ + Msg::Error("Cannot test remote Gmsh: server not running"); + } + } } static void file_window_cb(Fl_Widget *w, void *data) @@ -2209,6 +2221,7 @@ static Fl_Menu_Item bar_table[] = { {"Test server", 0, 0, 0, FL_SUBMENU}, {"Send small parsed view", 0, (Fl_Callback *)file_remote_cb, (void*)"test1"}, {"Send large dummy data", 0, (Fl_Callback *)file_remote_cb, (void*)"test2"}, + {"Send a vertex array", 0, (Fl_Callback *)file_remote_cb, (void*)"test3"}, {0}, {"Stop server", 0, (Fl_Callback *)file_remote_cb, (void*)"stop", FL_MENU_DIVIDER}, #endif @@ -2261,6 +2274,7 @@ static Fl_Menu_Item sysbar_table[] = { {"Test server", 0, 0, 0, FL_SUBMENU}, {"Send small parsed view", 0, (Fl_Callback *)file_remote_cb, (void*)"test1"}, {"Send large dummy data", 0, (Fl_Callback *)file_remote_cb, (void*)"test2"}, + {"Send a vertex array", 0, (Fl_Callback *)file_remote_cb, (void*)"test3"}, {0}, {"Stop server", 0, (Fl_Callback *)file_remote_cb, (void*)"stop", FL_MENU_DIVIDER}, #endif diff --git a/Fltk/solverWindow.cpp b/Fltk/solverWindow.cpp index 6aa02706053bee078f5b66f7535014b89feb185d..d82d5e317a95cfe16f2fe324675b50a467c5288e 100644 --- a/Fltk/solverWindow.cpp +++ b/Fltk/solverWindow.cpp @@ -191,6 +191,9 @@ void GmshRemote::run(std::string args) Msg::Info("got %d Mb message in %g seconds", strlen(message) / 1024 / 1024, GetTimeInSeconds() - timer); break; + case GmshSocket::GMSH_VERTEX_ARRAY: + PView::fillVertexArray(length, message); + break; default: Msg::Warning("Unknown message type"); Msg::Direct("%-8.8s: %s", name.c_str(), message); diff --git a/Post/PView.h b/Post/PView.h index b51315c8b5b4c50dec776f9a2e95cfb3aa7de8d9..d445a593eefe93f882bea721347d56af3dd33963 100644 --- a/Post/PView.h +++ b/Post/PView.h @@ -115,6 +115,9 @@ class PView{ // fill the vertex arrays, given the current option and data void fillVertexArrays(); + // fill a vertex array using a raw stream of bytes + static void fillVertexArray(int length, const char *data); + // smoothed normals smooth_normals *normals; }; diff --git a/Post/PViewData.h b/Post/PViewData.h index 7b28e2d2eb0d01c6849cbb7bea0eef08a5240987..a80ce3150ff93fc40e2adb76b423eafc5c3b3702 100644 --- a/Post/PViewData.h +++ b/Post/PViewData.h @@ -86,44 +86,44 @@ class PViewData { virtual int getNumPyramids(int step=-1){ return 0; } // return the number of geometrical entities in the view - virtual int getNumEntities(int step=-1) = 0; + virtual int getNumEntities(int step=-1){ return 0; } // return the number of elements in the ent-th entity, or the total // number of elements if ent < 0 - virtual int getNumElements(int step=-1, int ent=-1) = 0; + virtual int getNumElements(int step=-1, int ent=-1){ return 0; } // return the geometrical dimension of the ele-th element in the // ent-th entity - virtual int getDimension(int step, int ent, int ele) = 0; + virtual int getDimension(int step, int ent, int ele){ return 0; } // return the number of nodes of the ele-th element in the ent-th // entity - virtual int getNumNodes(int step, int ent, int ele) = 0; + virtual int getNumNodes(int step, int ent, int ele){ return 0; } // get/set the coordinates and tag of the nod-th node from the // ele-th element in the ent-th entity (if the node has a tag, // getNode returns it) virtual int getNode(int step, int ent, int ele, int nod, - double &x, double &y, double &z) = 0; + double &x, double &y, double &z){ return 0; } virtual void setNode(int step, int ent, int ele, int nod, double x, double y, double z); virtual void tagNode(int step, int ent, int ele, int nod, int tag){} // return the number of componts available for the ele-th element in // the ent-th entity - virtual int getNumComponents(int step, int ent, int ele) = 0; + virtual int getNumComponents(int step, int ent, int ele){ return 0; } // return the number of values available for the ele-th element in // the ent-th entity - virtual int getNumValues(int step, int ent, int ele) = 0; + virtual int getNumValues(int step, int ent, int ele){ return 0; } // get the idx'th value for the ele-th element in the ent-th entity - virtual void getValue(int step, int ent, int ele, int idx, double &val) = 0; + virtual void getValue(int step, int ent, int ele, int idx, double &val){} // gets/set the comp-th component (at the step-th time step) // associated with the node-th node from the ele-th element in the // ent-th entity - virtual void getValue(int step, int ent, int ele, int nod, int comp, double &val) = 0; + virtual void getValue(int step, int ent, int ele, int nod, int comp, double &val){} virtual void setValue(int step, int ent, int ele, int nod, int comp, double val); // return a scalar value (same as value for scalars, norm for @@ -133,10 +133,10 @@ class PViewData { // return the number of edges of the ele-th element in the ent-th // entity - virtual int getNumEdges(int step, int ent, int ele) = 0; + virtual int getNumEdges(int step, int ent, int ele){ return 0; } // return the type of the ele-th element in the ent-th entity - virtual int getType(int step, int ent, int ele) = 0; + virtual int getType(int step, int ent, int ele){ return 0; } // return the number of 2D/3D strings in the view virtual int getNumStrings2D(){ return 0; } diff --git a/Post/PViewDataRemote.h b/Post/PViewDataRemote.h new file mode 100644 index 0000000000000000000000000000000000000000..57308a8bc4fbc658b6112ce05ae9c5c118fdd737 --- /dev/null +++ b/Post/PViewDataRemote.h @@ -0,0 +1,37 @@ +// Gmsh - Copyright (C) 1997-2009 C. Geuzaine, J.-F. Remacle +// +// See the LICENSE.txt file for license information. Please report all +// bugs and problems to <gmsh@geuz.org>. + +#ifndef _PVIEW_DATA_REMOTE_H_ +#define _PVIEW_DATA_REMOTE_H_ + +#include <vector> +#include <string> +#include "PViewData.h" +#include "SBoundingBox3d.h" + +// The container for a remote dataset (does not contain any actual +// data!) +class PViewDataRemote : public PViewData { + private: + int _numTimeSteps; + double _min, _max; + std::vector<double> _timeStepMin, _timeStepMax; + SBoundingBox3d _bbox; + std::vector<double> _time; + public: + PViewDataRemote() : _numTimeSteps(1), _min(0.), _max(2.2) + { + _bbox += SPoint3(-1, -1, -1); + _bbox += SPoint3(1, 1, 1); + } + ~PViewDataRemote(){} + bool finalize(){} + int getNumTimeSteps(){ return _numTimeSteps; } + double getMin(int step=-1){ return _min; } + double getMax(int step=-1){ return _max; } + SBoundingBox3d getBoundingBox(int step=-1){ return _bbox; } +}; + +#endif diff --git a/Post/PViewVertexArrays.cpp b/Post/PViewVertexArrays.cpp index c8fc387798a203f17120a2546bf8cfc37706c842..5e342e3a36397183bab3112407649ee226aabf19 100644 --- a/Post/PViewVertexArrays.cpp +++ b/Post/PViewVertexArrays.cpp @@ -9,6 +9,7 @@ #include "PView.h" #include "PViewOptions.h" #include "PViewData.h" +#include "PViewDataRemote.h" #include "Numeric.h" #include "VertexArray.h" #include "SmoothData.h" @@ -1111,3 +1112,54 @@ void PView::fillVertexArrays() initPView init; init(this); } + +void PView::fillVertexArray(int length, const char *bytes) +{ + int is = sizeof(int), num, numVerticesPerElement; + + if(length < 2 * is){ + Msg::Error("Too few bytes to create vertex array: %d", length); + return; + } + + memcpy(&num, &bytes[0], is); + memcpy(&numVerticesPerElement, &bytes[is], is); + + Msg::Info("Filling vertex array (type %d) in view num %d", + numVerticesPerElement, num); + + PView *view; + if(num >= 0 && num < (int)list.size()){ + view = PView::list[num]; + } + else{ + Msg::Info("View num %d does not exist: creating new view"); + view = new PView(new PViewDataRemote); + } + + VertexArray *va; + switch(numVerticesPerElement){ + case 1: + if(view->va_points) delete view->va_points; + view->va_points = new VertexArray(1, 100); + va = view->va_points; + break; + case 2: + if(view->va_lines) delete view->va_lines; + view->va_lines = new VertexArray(2, 100); + va = view->va_lines; + break; + case 3: + if(view->va_triangles) delete view->va_triangles; + view->va_triangles = new VertexArray(3, 100); + va = view->va_triangles; + break; + default: + Msg::Error("Cannot fill vertex array of type %d", numVerticesPerElement); + return; + } + + va->fromChar(bytes); + view->setChanged(false); + view->getData()->setDirty(false); +}