File: x5.cpp

package info (click to toggle)
gmsh 4.14.0%2Bds1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 96,556 kB
  • sloc: cpp: 438,695; ansic: 114,912; f90: 15,477; python: 14,025; yacc: 7,333; java: 3,491; lisp: 3,194; lex: 631; perl: 571; makefile: 497; sh: 439; xml: 414; javascript: 113; pascal: 35; modula3: 32
file content (121 lines) | stat: -rw-r--r-- 4,741 bytes parent folder | download | duplicates (2)
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
// -----------------------------------------------------------------------------
//
//  Gmsh C++ extended tutorial 5
//
//  Additional geometrical data: parametrizations, normals, curvatures
//
// -----------------------------------------------------------------------------

#include <set>
#include <algorithm>
#include <gmsh.h>

int main(int argc, char **argv)
{
  gmsh::initialize(argc, argv);

  // The API provides access to geometrical data in a CAD kernel agnostic
  // manner.

  // Let's create a simple CAD model by fusing a sphere and a cube, then mesh
  // the surfaces:
  gmsh::model::add("x5");
  int s = gmsh::model::occ::addSphere(0, 0, 0, 1);
  int b = gmsh::model::occ::addBox(0.5, 0, 0, 1.3, 2, 3);
  std::vector<std::pair<int, int> > ov;
  std::vector<std::vector<std::pair<int, int> > > ovv;
  gmsh::model::occ::fuse({{3, s}}, {{3, b}}, ov, ovv);
  gmsh::model::occ::synchronize();
  gmsh::model::mesh::generate(2);

  // We can for example retrieve the exact normals and the curvature at all the
  // mesh nodes (i.e. not normals and curvatures computed from the mesh, but
  // directly evaluated on the geometry), by querying the CAD kernels at the
  // corresponding parametric coordinates.
  std::vector<double> normals, curvatures;

  // For each surface in the model:
  std::vector<std::pair<int, int> > entities;
  gmsh::model::getEntities(entities, 2);
  for(auto e : entities) {
    // Retrieve the surface tag
    int s = e.second;

    // Get the mesh nodes on the surface, including those on the boundary
    // (contrary to internal nodes, which store their parametric coordinates,
    // boundary nodes will be reparametrized on the surface in order to compute
    // their parametric coordinates, the result being different when
    // reparametrized on another adjacent surface)
    std::vector<std::size_t> tags;
    std::vector<double> coord, param;
    gmsh::model::mesh::getNodes(tags, coord, param, 2, s, true);

    // Get the surface normals on all the points on the surface corresponding to
    // the parametric coordinates of the nodes
    std::vector<double> norm;
    gmsh::model::getNormal(s, param, norm);

    // In the same way, get the curvature
    std::vector<double> curv;
    gmsh::model::getCurvature(2, s, param, curv);

    // Store the normals and the curvatures so that we can display them as
    // list-based post-processing views
    for(std::size_t i = 0; i < coord.size(); i += 3) {
      normals.push_back(coord[i]);
      normals.push_back(coord[i + 1]);
      normals.push_back(coord[i + 2]);
      normals.push_back(norm[i]);
      normals.push_back(norm[i + 1]);
      normals.push_back(norm[i + 2]);
      curvatures.push_back(coord[i]);
      curvatures.push_back(coord[i + 1]);
      curvatures.push_back(coord[i + 2]);
      curvatures.push_back(curv[i / 3]);
    }
  }

  // Create a list-based vector view on points to display the normals, and a
  // scalar view on points to display the curvatures
  int vn = gmsh::view::add("normals");
  gmsh::view::addListData(vn, "VP", normals.size() / 6, normals);
  gmsh::view::option::setNumber(vn, "ShowScale", 0);
  gmsh::view::option::setNumber(vn, "ArrowSizeMax", 30);
  gmsh::view::option::setNumber(vn, "ColormapNumber", 19);

  int vc = gmsh::view::add("curvatures");
  gmsh::view::addListData(vc, "SP", curvatures.size() / 4, curvatures);
  gmsh::view::option::setNumber(vc, "ShowScale", 0);

  // We can also retrieve the parametrization bounds of model entities, e.g. of
  // curve 5, and evaluate the parametrization for several parameter values:
  std::vector<double> bounds[2], t, xyz1;
  gmsh::model::getParametrizationBounds(1, 5, bounds[0], bounds[1]);
  int N = 20;
  for(int i = 0; i < N; i++)
    t.push_back(bounds[0][0] + i * (bounds[1][0] - bounds[0][0]) / N);
  gmsh::model::getValue(1, 5, t, xyz1);

  // We can also reparametrize curve 5 on surface 1, and evaluate the points in
  // the parametric plane of the surface:
  std::vector<double> uv, xyz2;
  gmsh::model::reparametrizeOnSurface(1, 5, t, 1, uv);
  gmsh::model::getValue(2, 1, uv, xyz2);

  // Hopefully we get the same x, y, z coordinates!
  std::vector<double> diff(xyz1.size());
  std::transform(xyz1.begin(), xyz1.end(), xyz2.begin(), diff.begin(),
                 [](double a, double b){ return std::abs(a - b); });
  if(*std::max_element(diff.begin(), diff.end()) < 1e-12)
    gmsh::logger::write("Evaluation on curve and surface match!");
  else
    gmsh::logger::write("Evaluation on curve and surface do not match!",
                        "error");

  // Launch the GUI to see the results:
  std::set<std::string> args(argv, argv + argc);
  if(!args.count("-nopopup")) gmsh::fltk::run();

  gmsh::finalize();
  return 0;
}