15#define _USE_MATH_DEFINES
18#include "arcane/SimpleSVGMeshExporter.h"
20#include "arcane/utils/Iostream.h"
21#include "arcane/ItemGroup.h"
22#include "arcane/IMesh.h"
23#include "arcane/VariableTypes.h"
41 Impl(ostream& ofile) : m_ofile(ofile){}
42 void _writeText(Real x,Real y,
StringView color,
StringView text,
double rotation,
bool do_background);
46 double m_font_size = 3.0;
52void SimpleSVGMeshExporter::Impl::
57 m_ofile <<
"<text x='" << x <<
"' y='" << y <<
"' dominant-baseline='central' text-anchor='middle'"
58 <<
" style='stroke:white; stroke-width:0.6em'";
60 m_ofile <<
" transform='rotate(" << rotation <<
"," << x <<
"," << y <<
")'";
61 m_ofile <<
" font-size='" << m_font_size <<
"'>" << text <<
"</text>\n";
63 m_ofile <<
"<text x='" << x <<
"' y='" << y <<
"' dominant-baseline='central' text-anchor='middle'"
64 <<
" fill='" << color <<
"'";
66 m_ofile <<
" transform='rotate(" << rotation <<
"," << x <<
"," << y <<
")'";
67 m_ofile <<
" font-size='" << m_font_size <<
"'>" << text <<
"</text>\n";
73void SimpleSVGMeshExporter::Impl::
78 IMesh* mesh = cells.mesh();
79 Int32 mesh_dim = mesh->dimension();
81 ARCANE_FATAL(
"Invalid dimension ({0}) for mesh. Only 2D mesh is allowed", mesh_dim);
89 ostream& ofile = m_ofile;
90 Real mul_value = 1000.0;
91 const Real min_val = std::numeric_limits<Real>::lowest();
92 const Real max_val = std::numeric_limits<Real>::max();
93 Real2 min_bbox(max_val, max_val);
94 Real2 max_bbox(min_val, min_val);
96 std::map<Int32, Real2> cells_center;
100 Integer nb_node = cell.nbNode();
102 for (Integer i = 0; i < nb_node; ++i) {
103 Real3 node_coord_3d = nodes_coord[cell.node(i)] * mul_value;
104 Real2 node_coord(node_coord_3d.x, -node_coord_3d.y);
105 min_bbox =
math::min(min_bbox, node_coord);
106 max_bbox =
math::max(max_bbox, node_coord);
107 center += node_coord_3d;
111 Real2 center_2d(center.x, -center.y);
112 cells_center[cell.localId()] = center_2d;
115 Real bbox_width = math::abs(max_bbox.x - min_bbox.x);
116 Real bbox_height = math::abs(max_bbox.y - min_bbox.y);
118 m_font_size = max_dim / 80.0;
122 ofile <<
"<?xml version=\"1.0\"?>\n";
124 <<
" viewBox='" << min_bbox.x - bbox_width * 0.1 <<
"," << min_bbox.y - bbox_height * 0.1 <<
"," << bbox_width * 1.2 <<
"," << bbox_height * 1.2 <<
"'"
125 <<
" xmlns='http://www.w3.org/2000/svg' version='1.1'>\n";
126 ofile <<
"<!-- V3 bbox min_x=" << min_bbox.x <<
" min_y=" << min_bbox.y <<
" max_x=" << max_bbox.x <<
" max_y=" << max_bbox.y <<
" -->";
127 ofile <<
"<title>Mesh</title>\n";
128 ofile <<
"<desc>MeshExample</desc>\n";
137 Real2 cell_pos = cells_center[cell.localId()];
138 Integer nb_node = cell.nbNode();
139 ofile <<
"<path d='";
140 for (Integer i = 0; i < nb_node; ++i) {
141 Real3 node_coord_3d = nodes_coord[cell.node(i)];
142 Real2 node_coord(node_coord_3d.x, -node_coord_3d.y);
143 node_coord *= mul_value;
149 Real2 coord = cell_pos + (node_coord - cell_pos) * 0.98;
150 ofile << coord.x <<
" " << coord.y <<
" ";
154 ofile <<
" fill='yellow'";
156 ofile <<
" fill='orange'";
157 ofile <<
" stroke='black'";
158 ofile <<
" stroke-width='1'/>\n";
159 _writeText(cell_pos.x, cell_pos.y,
"blue", String::fromNumber(cell.uniqueId().asInt64()), 0.0,
false);
165 std::set<Int32> nodes_done;
168 Integer nb_node = cell.nbNode();
169 for (Integer i = 0; i < nb_node; ++i) {
170 Node node = cell.node(i);
171 Int32 lid = node.localId();
172 if (nodes_done.find(lid) != nodes_done.end())
174 nodes_done.insert(lid);
175 Real3 coord_3d = nodes_coord[node];
176 Real2 coord(coord_3d.x, -coord_3d.y);
178 _writeText(coord.x, coord.y,
"green", String::fromNumber(node.uniqueId().asInt64()), 0.0,
true);
188 std::set<Int32> faces_done;
191 Integer nb_face = cell.nbFace();
192 for (Integer i = 0; i < nb_face; ++i) {
193 Face face = cell.face(i);
194 Int32 lid = face.localId();
195 if (faces_done.find(lid) != faces_done.end())
197 faces_done.insert(lid);
199 Real3 node0_coord = nodes_coord[face.node(0)];
200 Real3 node1_coord = nodes_coord[face.node(1)];
201 Real3 face_coord_3d = (node0_coord + node1_coord) / 2.0;
202 Real2 face_coord(face_coord_3d.x, -face_coord_3d.y);
203 face_coord *= mul_value;
204 Real3 direction = node1_coord - node0_coord;
205 direction = direction.normalize();
209 double angle = math::abs(std::asin(direction.y)) / M_PI * 180.0;
210 Real2 cell_center = cells_center[cell.localId()];
211 Real2 coord = cell_center + (face_coord - cell_center) * 0.92;
212 _writeText(coord.x, coord.y,
"red", String::fromNumber(face.uniqueId().asInt64()), angle,
true);
226: m_p(new
Impl(ofile))
233SimpleSVGMeshExporter::
234~SimpleSVGMeshExporter()
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
SimpleSVGMeshExporter(std::ostream &ofile)
Créé une instance associée au flux ofile.
void write(const CellGroup &cells)
Exporte les entités du groupe cells.
Vue sur une chaîne de caractères UTF-8.
__host__ __device__ Real2 min(Real2 a, Real2 b)
Retourne le minimum de deux Real2.
T max(const T &a, const T &b, const T &c)
Retourne le maximum de trois éléments.
ItemGroupT< Cell > CellGroup
Groupe de mailles.
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Grandeur au noeud de type coordonnées.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
double Real
Type représentant un réel.
Int32 Integer
Type représentant un entier.