15#define _USE_MATH_DEFINES
18#include "arcane/cartesianmesh/SimpleHTMLMeshAMRPatchExporter.h"
20#include "arcane/cartesianmesh/AMRPatchPosition.h"
22#include "arcane/utils/Iostream.h"
23#include "arcane/utils/StringBuilder.h"
25#include "arcane/core/ItemGroup.h"
26#include "arcane/core/IMesh.h"
27#include "arcane/core/VariableTypes.h"
48 void write(ostream& ofile);
52 void _writeJs(ostream& ofile);
53 void _writeCss(ostream& ofile);
54 void _writeBodyHtml(ostream& ofile);
62 bool m_has_ground =
false;
63 bool m_has_patch =
false;
74void SimpleHTMLMeshAMRPatchExporter::Impl::
80 if (patch.
level() == 0) {
84 _writeHeaderSvg(patch);
90 m_patches += String::format(
"<g class='level-{0}' id='patch-{1}'>\n", level, index);
92 m_patches +=
"</g>\n";
99void SimpleHTMLMeshAMRPatchExporter::Impl::
108 ofile <<
"<!DOCTYPE html>\n";
114 ofile <<
"</head>\n";
117 _writeBodyHtml(ofile);
118 ofile <<
"</body>\n";
120 ofile <<
"</html>\n";
126void SimpleHTMLMeshAMRPatchExporter::Impl::
127_writeJs(ostream& ofile)
129 ofile <<
"<script>\n";
131 ofile <<
"</script>\n";
137void SimpleHTMLMeshAMRPatchExporter::Impl::
138_writeCss(ostream& ofile)
140 ofile <<
"<style>\n";
142 ofile <<
".uid-text {font-size: " << m_font_size <<
"px;}\n";
144 ofile <<
"</style>\n";
150void SimpleHTMLMeshAMRPatchExporter::Impl::
151_writeBodyHtml(ostream& ofile)
153 ofile << m_header_svg;
162void SimpleHTMLMeshAMRPatchExporter::Impl::
163_writeHeaderSvg(
const CartesianPatch& ground_patch)
165 CellGroup cells = ground_patch.patchInterface()->cells();
166 if (ground_patch.level() != 0) {
172 IMesh* mesh = cells.
mesh();
175 ARCANE_FATAL(
"Invalid dimension ({0}) for mesh. Only 2D mesh is allowed", mesh_dim);
183 Real mul_value = 1000.0;
184 const Real min_val = std::numeric_limits<Real>::lowest();
185 const Real max_val = std::numeric_limits<Real>::max();
186 Real2 min_bbox(max_val, max_val);
187 Real2 max_bbox(min_val, min_val);
189 std::map<Int32, Real2> cells_center;
193 Integer nb_node = cell.nbNode();
195 for (
Integer i = 0; i < nb_node; ++i) {
196 Real3 node_coord_3d = nodes_coord[cell.node(i)] * mul_value;
197 Real2 node_coord(node_coord_3d.x, -node_coord_3d.y);
198 min_bbox =
math::min(min_bbox, node_coord);
199 max_bbox =
math::max(max_bbox, node_coord);
200 center += node_coord_3d;
204 Real2 center_2d(center.x, -center.y);
205 cells_center[cell.localId()] = center_2d;
208 Real bbox_width = math::abs(max_bbox.x - min_bbox.x);
209 Real bbox_height = math::abs(max_bbox.y - min_bbox.y);
211 m_font_size = max_dim / 80.0;
215 m_header_svg +=
"<?xml version=\"1.0\"?>\n";
216 m_header_svg += String::format(
"<svg viewBox='{0},{1},{2},{3}' xmlns='http://www.w3.org/2000/svg' version='1.1'>\n",
217 (min_bbox.x - bbox_width * 0.1),
218 (min_bbox.y - bbox_height * 0.1),
220 (bbox_height * 1.2));
221 m_header_svg += String::format(
"<!-- V3 bbox min_x={0} min_y={1} max_x={2} max_y={3} -->",
227 m_header_svg +=
"<title>Mesh</title>\n";
228 m_header_svg +=
"<desc>MeshExample</desc>\n";
232 m_header_svg +=
"<g>\n";
238void SimpleHTMLMeshAMRPatchExporter::Impl::
239_writeText(
Real x,
Real y, StringView color, StringView text,
Real rotation,
bool do_background)
243 m_patches += String::format(
"<text class='uid-text' x='{0}' y='{1}' dominant-baseline='central' text-anchor='middle' style='stroke:white; stroke-width:0.6em'", x, y);
244 if (rotation != 0.0) {
245 m_patches += String::format(
" transform='rotate({0}, {1}, {2})'", rotation, x, y);
247 m_patches += String::format(
">{0}</text>\n", text);
250 m_patches += String::format(
"<text class='uid-text' x='{0}' y='{1}' dominant-baseline='central' text-anchor='middle' fill='{2}'", x, y, color);
252 if (rotation != 0.0) {
253 m_patches += String::format(
" transform='rotate({0}, {1}, {2})'", rotation, x, y);
255 m_patches += String::format(
">{0}</text>\n", text);
261void SimpleHTMLMeshAMRPatchExporter::Impl::
262_writePatch(
const CartesianPatch& patch)
264 CellGroup cells = patch.patchInterface()->cells();
267 IMesh* mesh = cells.
mesh();
270 ARCANE_FATAL(
"Invalid dimension ({0}) for mesh. Only 2D mesh is allowed", mesh_dim);
278 Real mul_value = 1000.0;
279 const Real min_val = std::numeric_limits<Real>::lowest();
280 const Real max_val = std::numeric_limits<Real>::max();
281 Real2 min_bbox(max_val, max_val);
282 Real2 max_bbox(min_val, min_val);
285 std::map<Int32, Real2> cells_center;
289 Integer nb_node = cell.nbNode();
291 for (
Integer i = 0; i < nb_node; ++i) {
292 Real3 node_coord_3d = nodes_coord[cell.node(i)] * mul_value;
293 Real2 node_coord(node_coord_3d.x, -node_coord_3d.y);
294 min_bbox =
math::min(min_bbox, node_coord);
295 max_bbox =
math::max(max_bbox, node_coord);
296 center += node_coord_3d;
300 Real2 center_2d(center.x, -center.y);
301 cells_center[cell.localId()] = center_2d;
307 Real2 cell_pos = cells_center[cell.localId()];
308 Integer nb_node = cell.nbNode();
309 m_patches +=
"<path d='";
310 nb_node = cell.typeInfo()->linearTypeInfo()->nbLocalNode();
311 for (
Integer i = 0; i < nb_node; ++i) {
312 Real3 node_coord_3d = nodes_coord[cell.node(i)];
313 Real2 node_coord(node_coord_3d.x, -node_coord_3d.y);
314 node_coord *= mul_value;
320 Real2 coord = cell_pos + (node_coord - cell_pos) * 0.98;
321 m_patches += String::format(
"{0} {1} ", coord.x, coord.y);
326 m_patches +=
" fill='magenta'";
328 m_patches +=
" fill='darkmagenta'";
332 m_patches +=
" fill='orange'";
334 m_patches +=
" fill='darkorange'";
338 m_patches +=
" fill='yellow'";
340 m_patches +=
" fill='gold'";
342 m_patches +=
" stroke='black'";
343 m_patches +=
" stroke-width='1'/>\n";
344 _writeText(cell_pos.x, cell_pos.y,
"blue", String::fromNumber(cell.uniqueId().asInt64()), 0.0,
false);
350 std::set<Int32> nodes_done;
353 Integer nb_node = cell.nbNode();
354 for (
Integer i = 0; i < nb_node; ++i) {
355 Node node = cell.node(i);
356 Int32 lid = node.localId();
357 if (nodes_done.find(lid) != nodes_done.end())
359 nodes_done.insert(lid);
360 Real3 coord_3d = nodes_coord[node];
361 Real2 coord(coord_3d.x, -coord_3d.y);
363 _writeText(coord.x, coord.y,
"green", String::fromNumber(node.uniqueId().asInt64()), 0.0,
true);
373 std::set<Int32> faces_done;
376 Integer nb_face = cell.nbFace();
377 for (
Integer i = 0; i < nb_face; ++i) {
378 Face face = cell.face(i);
379 Int32 lid = face.localId();
380 if (faces_done.find(lid) != faces_done.end())
382 faces_done.insert(lid);
385 if (face.nbNode() < 2)
387 Real3 node0_coord = nodes_coord[face.node(0)];
388 Real3 node1_coord = nodes_coord[face.node(1)];
389 Real3 face_coord_3d = (node0_coord + node1_coord) / 2.0;
391 Real2 face_coord(face_coord_3d.x, -face_coord_3d.y);
392 face_coord *= mul_value;
393 Real3 direction = node1_coord - node0_coord;
398 double angle = math::abs(std::asin(direction.y)) / M_PI * 180.0;
399 Real2 cell_center = cells_center[cell.localId()];
400 Real2 coord = cell_center + (face_coord - cell_center) * 0.92;
401 _writeText(coord.x, coord.y,
"red", String::fromNumber(face.uniqueId().asInt64()), angle,
true);
413SimpleHTMLMeshAMRPatchExporter::
414SimpleHTMLMeshAMRPatchExporter()
421SimpleHTMLMeshAMRPatchExporter::
422~SimpleHTMLMeshAMRPatchExporter()
430void SimpleHTMLMeshAMRPatchExporter::
431addPatch(
const CartesianPatch& patch)
433 m_p->addPatch(patch);
439void SimpleHTMLMeshAMRPatchExporter::
440write(std::ostream& ofile)
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
bool isNull() const
Method to know if the patch is null.
AMR Patch of a Cartesian mesh.
Integer index() const
Index of the patch in the patch array.
AMRPatchPosition position() const
Method to retrieve the patch position in the Cartesian mesh.
Integer level() const
Patch level.
virtual Integer dimension()=0
Mesh dimension (1D, 2D, or 3D).
@ II_Overlap
[AMR Patch] The entity is marked as overlapping with at least one AMR patch.
@ II_InPatch
[AMR Patch] The entity is marked as being in an AMR patch.
IMesh * mesh() const
Mesh to which this group belongs (0 for the null group).
Unicode character string constructor.
View of a UTF-8 character string.
__host__ __device__ Real2 min(Real2 a, Real2 b)
Returns the minimum of two Real2.
T max(const T &a, const T &b, const T &c)
Returns the maximum of three elements.
ItemGroupT< Cell > CellGroup
Group of cells.
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Coordinate type quantity at node.
Real2 & mutableNormalize(Real2 &v)
Normalizes the pair.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Int32 Integer
Type representing an integer.
double Real
Type representing a real number.
@ Cell
The mesh is AMR by cell.
std::int32_t Int32
Signed integer type of 32 bits.