DOLFIN
DOLFIN C++ interface
X3DOM.h
1 // Copyright (C) 2016 Quang T. Ha, Chris Richardson and Garth N. Wells
2 //
3 // This file is part of DOLFIN.
4 //
5 // DOLFIN is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU Lesser General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // DOLFIN is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public License
16 // along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
17 
18 #ifndef __DOLFIN_X3DOM_H
19 #define __DOLFIN_X3DOM_H
20 
21 #include <array>
22 #include <set>
23 #include <string>
24 #include <utility>
25 #include <vector>
26 #include <boost/multi_array.hpp>
27 
28 #include <dolfin/geometry/Point.h>
29 
30 // TODO:
31 // - Can we order vertices so that attribute 'solid' can be set to true?
32 // - Add ambient intensity parameter
33 // - Test and add more sanity checks for Functions
34 // - Add support for GenericFunction
35 // - Add support for MeshFunctions
36 // - Add support for DG1 Functions
37 // - Add vector support (arrows) - including correct placement for RT0
38 // etc. - advanced
39 // - Document all class methods below properly
40 
41 namespace pugi
42 {
43  class xml_node;
44  class xml_document;
45 }
46 
47 namespace dolfin
48 {
49 
52  {
53  // Developer note: X3DOMParameters is declared outside the X3DOM
54  // class because SWIG cannot wrap nested classes.
55 
56  public:
57 
59  enum class Representation {surface, surface_with_edges, wireframe};
60 
63 
66  void set_representation(Representation representation);
67 
70  Representation get_representation() const;
71 
73  std::array<double, 2> get_viewport_size() const;
74 
76  void set_diffuse_color(std::array<double, 3> rgb);
77 
79  std::array<double, 3> get_diffuse_color() const;
80 
82  void set_emissive_color(std::array<double, 3> rgb);
83 
85  std::array<double, 3> get_emissive_color() const;
86 
88  void set_specular_color(std::array<double, 3> rgb);
89 
91  std::array<double, 3> get_specular_color() const;
92 
94  void set_background_color(std::array<double, 3> rgb);
95 
97  std::array<double, 3> get_background_color() const;
98 
100  void set_ambient_intensity(double intensity);
101 
103  double get_ambient_intensity() const;
104 
106  void set_shininess(double shininess);
107 
109  double get_shininess() const;
110 
112  void set_transparency(double transparency);
113 
115  double get_transparency() const;
116 
120  void set_color_map(const std::vector<double>& color_data);
121 
124  std::vector<double> get_color_map() const;
125 
127  boost::multi_array<float, 2> get_color_map_array() const;
128 
130  void set_x3d_stats(bool show);
131 
133  bool get_x3d_stats() const;
134 
136  void set_menu_display(bool show);
137 
139  bool get_menu_display() const;
140 
141  private:
142 
143  // Check that RGB colors are valid. Throws error if value is not
144  // invalid.
145  static void check_rgb(std::array<double, 3>& rgb);
146 
147  // Check that value is valid. Throws error if value is not
148  // invalid.
149  static void check_value_range(double value, double lower, double upper);
150 
151  // Surface, surface with edges or wireframe
152  Representation _representation;
153 
154  // Dimensions of viewing area
155  std::array<double, 2> _size;
156 
157  // TODO: document
158  // RGB colours, see http://doc.x3dom.org/author/Shape/Material.html
159  std::array<double, 3> _diffuse_color, _emissive_color, _specular_color,
160  _background_color;
161 
162  // TODO: document
163  double _ambient_intensity, _shininess, _transparency;
164 
165  // RGB color map (256 values)
166  boost::multi_array<float, 2> _color_map;
167 
168  // Turn X3D stats on/off
169  bool _show_x3d_stats;
170 
171  // Turn menu on/off
172  bool _menu_display;
173  };
174 
175  // Forward declarations
176  class Function;
177  class Mesh;
178  class Point;
179 
183  //
184  // Developer note: pugixml is used to created X3DOM and HTML5. By
185  // using pugixml, we produce valid XML, but care must be taken that
186  // the XML is also valid HTML. This includes not letting pugixml
187  // create self-closing elements, in cases. E.g., <foo
188  // bar="foobar"></foo> is fine, but the self-closing syntax <foo
189  // bar="foobar" /> while being valid XML is is not valid HTML5. See
190  // https://github.com/x3dom/x3dom/issues/600.
191  //
192 
193  class X3DOM
194  {
195  public:
196 
198  static std::string str(const Mesh& mesh,
200 
202  static std::string str(const Function& u,
204 
206  static std::string html(const Mesh& mesh,
208 
209 
211  static std::string html(const Function& u,
213 
214 
216  static void
217  build_x3dom_tree(pugi::xml_document& xml_doc,
218  const Mesh& mesh,
220 
222  static void
223  build_x3dom_tree(pugi::xml_document& xml_doc,
224  const Function& u,
226 
227  private:
228 
229  // FIXME: This should be a C++11 style enum (enum Viewpoint class
230  // {...};), but a Swig bug needs fixing
231  // (https://github.com/swig/swig/issues/594)
232  enum Viewpoint {top, bottom, left, right, back, front, default_view};
233 
234  // Build X3DOM pugixml tree
235  static void x3dom(pugi::xml_document& xml_doc, const Mesh& mesh,
236  const std::vector<double>& vertex_values,
237  const std::vector<double>& facet_values,
238  const X3DOMParameters& parameters);
239 
240  // Build HTML pugixml tree
241  static void html(pugi::xml_document& xml_doc, const Mesh& mesh,
242  const std::vector<double>& vertex_values,
243  const std::vector<double>& facet_values,
244  const X3DOMParameters& parameters);
245 
246  // Add HTML preamble (HTML) to XML doc and return 'html' node
247  static pugi::xml_node add_html_preamble(pugi::xml_node& xml_node);
248 
249  // Add X3D doctype (an XML document should have no more than one
250  // doc_type node)
251  static void add_x3dom_doctype(pugi::xml_node& xml_node);
252 
253  // Add HTML doctype (an XML document should have no more than one
254  // doc_type node)
255  static void add_html_doctype(pugi::xml_node& xml_node);
256 
257  // Add X3D node and attributes, and return handle to node (x3D)
258  static pugi::xml_node add_x3d_node(pugi::xml_node& xml_node,
259  std::array<double, 2> size,
260  bool show_stats);
261 
262  // Add X3DOM Mesh data to XML node (X3D)
263  static void add_x3dom_data(pugi::xml_node& xml_node, const Mesh& mesh,
264  const std::vector<double>& vertex_values,
265  const std::vector<double>& facet_values,
266  const X3DOMParameters& parameters);
267 
268  // Add mesh topology and geometry to XML. 'surface' flag controls
269  // surface vs wireframe representation (X3D)
270  static void add_mesh_data(pugi::xml_node& xml_node, const Mesh& mesh,
271  const std::vector<double>& vertex_values,
272  const std::vector<double>& facet_values,
273  const X3DOMParameters& parameters,
274  bool surface);
275 
276 
277  // Add a collection viewpoint nodes (X3D)
278  static void add_viewpoint_nodes(pugi::xml_node& xml_scene,
279  const Point p, double d,
280  bool show_viewpoint_buttons);
281 
282  // Add a single viewpoint node (X3D)
283  static void add_viewpoint_node(pugi::xml_node& xml_scene,
284  Viewpoint viewpoint,
285  const Point p,
286  const double s);
287 
288  // Add the menu display and the desired subsections
289  static void add_menu_display(pugi::xml_node& xml_node, const Mesh& mesh,
290  const X3DOMParameters& parameters);
291 
292  // Add the button for a tab to be added to the menu
293  static void add_menu_tab_button(pugi::xml_node& xml_node, std::string name,
294  bool checked);
295 
296  // Create a generic content node to hold specific menu content
297  static pugi::xml_node create_menu_content_node(pugi::xml_node& xml_node,
298  std::string name, bool show);
299 
300  // Add the options tab in the menu display
301  static void add_menu_options_tab(pugi::xml_node& xml_node);
302 
303  // Add an option to the options tab in menu display
304  static void add_menu_options_option(pugi::xml_node& xml_node,
305  std::string name);
306 
307  // Add the summary tab in the menu display
308  static void add_menu_summary_tab(pugi::xml_node& xml_node,
309  const Mesh& mesh);
310 
311  // Add the color tab in the menu display
312  static void add_menu_color_tab(pugi::xml_node& xml_node);
313 
314  // Add the warp tab in the menu display
315  static void add_menu_warp_tab(pugi::xml_node& xml_node);
316 
317  // Add the viewpoint tab in the menu display
318  static void add_menu_viewpoint_tab(pugi::xml_node& xml_node);
319 
320  // Add a viewpoint button to the appropriate parent
321  static void add_menu_viewpoint_button(pugi::xml_node& xml_node,
322  std::string name);
323 
324  // Get centre point of mesh bounds, and a reasonable viewpoint
325  // distance from it
326  static std::pair<Point, double> mesh_centre_and_distance(const Mesh& mesh);
327 
328  // Get list of vertex indices which are on surface
329  static std::set<int> surface_vertex_indices(const Mesh& mesh);
330 
331  // Get the values of a function at vertices, (or on facets for P0)
332  static void get_function_values(const Function& u,
333  std::vector<double>& vertex_values,
334  std::vector<double>& facet_values);
335 
336  // Build topology and geometry data from a Mesh ready for X3DOM
337  // output
338  static void build_mesh_data(std::vector<int>& topology,
339  std::vector<double>& geometry,
340  std::vector<double>& value_data,
341  const Mesh& mesh,
342  const std::vector<double>& vertex_values,
343  const std::vector<double>& facet_values,
344  bool surface);
345 
346  // Return "x[0] x[1] x[2]" string from array of color RGB
347  static std::string array_to_string3(std::array<double, 3> x);
348 
349  // Utility to convert pugi::xml_document into a std::string
350  static std::string to_string(pugi::xml_document& xml_doc,
351  unsigned int flags);
352 
353  };
354 
355 }
356 
357 #endif
std::string to_string(const double *x, std::size_t n)
Return string representation of given array.
Definition: utils.cpp:42
Definition: adapt.h:29
Representation
X3DOM representation type.
Definition: X3DOM.h:59
Definition: Point.h:40
Definition: X3DOM.h:193
Class data to store X3DOM view parameters.
Definition: X3DOM.h:51
Definition: Function.h:65
Definition: VTKFile.h:27
GlobalParameters parameters
The global parameter database.
Definition: GlobalParameters.cpp:32
Definition: Mesh.h:82