1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
|
// -----------------------------------------------------------------------------
//
// Gmsh C++ tutorial 8
//
// Post-processing and animations
//
// -----------------------------------------------------------------------------
#include <set>
#include <gmsh.h>
// In addition to creating geometries and meshes, the C++ API can also be used
// to manipulate post-processing datasets (called "views" in Gmsh).
int main(int argc, char **argv)
{
gmsh::initialize();
gmsh::model::add("t8");
// We first create a simple geometry
double lc = 1e-2;
gmsh::model::geo::addPoint(0, 0, 0, lc, 1);
gmsh::model::geo::addPoint(.1, 0, 0, lc, 2);
gmsh::model::geo::addPoint(.1, .3, 0, lc, 3);
gmsh::model::geo::addPoint(0, .3, 0, lc, 4);
gmsh::model::geo::addLine(1, 2, 1);
gmsh::model::geo::addLine(3, 2, 2);
gmsh::model::geo::addLine(3, 4, 3);
gmsh::model::geo::addLine(4, 1, 4);
gmsh::model::geo::addCurveLoop({4, 1, -2, 3}, 1);
gmsh::model::geo::addPlaneSurface({1}, 1);
gmsh::model::geo::synchronize();
// We merge some post-processing views to work on
try {
gmsh::merge("../view1.pos");
gmsh::merge("../view1.pos");
gmsh::merge("../view4.pos"); // contains 2 views inside
} catch(...) {
gmsh::logger::write("Could not load post-processing views: bye!");
gmsh::finalize();
return 0;
}
// Gmsh can read post-processing views in various formats. Here the
// `view1.pos' and `view4.pos' files are in the Gmsh "parsed" format, which is
// interpreted by the GEO script parser. The parsed format should only be used
// for relatively small datasets of course: for larger datasets using e.g. MSH
// files is much more efficient. Post-processing views can also be created
// directly from the C++ API.
// We then set some general options:
gmsh::option::setNumber("General.Trackball", 0);
gmsh::option::setNumber("General.RotationX", 0);
gmsh::option::setNumber("General.RotationY", 0);
gmsh::option::setNumber("General.RotationZ", 0);
int white[3] = {255, 255, 255};
int black[3] = {0, 0, 0};
gmsh::option::setColor("General.Background", white[0], white[1], white[2]);
gmsh::option::setColor("General.Foreground", black[0], black[1], black[2]);
gmsh::option::setColor("General.Text", black[0], black[1], black[2]);
gmsh::option::setNumber("General.Orthographic", 0);
gmsh::option::setNumber("General.Axes", 0);
gmsh::option::setNumber("General.SmallAxes", 0);
// Show the GUI:
std::set<std::string> args(argv, argv + argc);
if(!args.count("-nopopup")) gmsh::fltk::initialize();
// We also set some options for each post-processing view:
// If we were to follow the geo example blindly, we would read the number of
// views from the relevant option value, and use the gmsh::option::setNumber()
// and gmsh::option::setString() functions. A nicer way is to use
// gmsh::view::getTags() and to use the gmsh::view::option::setNumber() and
// gmsh::view::option::setString() functions.
std::vector<int> v;
gmsh::view::getTags(v);
if(v.size() != 4) {
gmsh::logger::write("Wrong number of views!", "error");
gmsh::finalize();
return 1;
}
gmsh::view::option::setNumber(v[0], "IntervalsType", 2);
gmsh::view::option::setNumber(v[0], "OffsetZ", 0.05);
gmsh::view::option::setNumber(v[0], "RaiseZ", 0);
gmsh::view::option::setNumber(v[0], "Light", 1);
gmsh::view::option::setNumber(v[0], "ShowScale", 0);
gmsh::view::option::setNumber(v[0], "SmoothNormals", 1);
gmsh::view::option::setNumber(v[1], "IntervalsType", 1);
// Note that we can't yet set the ColorTable through the API
gmsh::view::option::setNumber(v[1], "NbIso", 10);
gmsh::view::option::setNumber(v[1], "ShowScale", 0);
gmsh::view::option::setString(v[2], "Name", "Test...");
gmsh::view::option::setNumber(v[2], "Axes", 1);
gmsh::view::option::setNumber(v[2], "IntervalsType", 2);
gmsh::view::option::setNumber(v[2], "Type", 2);
gmsh::view::option::setNumber(v[2], "AutoPosition", 0);
gmsh::view::option::setNumber(v[2], "PositionX", 85);
gmsh::view::option::setNumber(v[2], "PositionY", 50);
gmsh::view::option::setNumber(v[2], "Width", 200);
gmsh::view::option::setNumber(v[2], "Height", 130);
gmsh::view::option::setNumber(v[3], "Visible", 0);
// You can save an MPEG movie directly by selecting `File->Export' in the
// GUI. Several predefined animations are setup, for looping on all the time
// steps in views, or for looping between views.
// But the API can be used to build much more complex animations, by changing
// options at run-time and re-rendering the graphics. Each frame can then be
// saved to disk as an image, and multiple frames can be encoded to form a
// movie. Below is an example of such a custom animation.
int t = 0; // Initial step
for(int num = 1; num <= 3; num++) {
double nbt;
gmsh::view::option::getNumber(v[0], "NbTimeStep", nbt);
t = (t < nbt - 1) ? t + 1 : 0;
// Set time step
for(auto vv : v) gmsh::view::option::setNumber(vv, "TimeStep", t);
double max;
gmsh::view::option::getNumber(v[0], "Max", max);
gmsh::view::option::setNumber(v[0], "RaiseZ", 0.01 / max * t);
if(num == 3) {
// Resize the graphics when num == 3, to create 640x480 frames
double mw;
gmsh::option::getNumber("General.MenuWidth", mw);
gmsh::option::setNumber("General.GraphicsWidth", mw + 640);
gmsh::option::setNumber("General.GraphicsHeight", 480);
}
int frames = 50;
for(int num2 = 1; num2 <= frames; num2++) {
// Incrementally rotate the scene
double rotx;
gmsh::option::getNumber("General.RotationX", rotx);
gmsh::option::setNumber("General.RotationX", rotx + 10);
gmsh::option::setNumber("General.RotationY", (rotx + 10) / 3.);
double rotz;
gmsh::option::getNumber("General.RotationZ", rotz);
gmsh::option::setNumber("General.RotationZ", rotz + 0.1);
// Draw the scene
gmsh::graphics::draw();
if(num == 3) {
// Uncomment the following lines to save each frame to an image file
// gmsh::write("t8-" + std::to_string(num2) + ".gif");
// gmsh::write("t8-" + std::to_string(num2) + ".ppm");
// gmsh::write("t8-" + std::to_string(num2) + ".jpg");
}
}
if(num == 3) {
// Here we could make a system call to generate a movie...
}
}
if(!args.count("-nopopup")) gmsh::fltk::run();
gmsh::finalize();
return 0;
}
|