21#include <vtkUnstructuredGrid.h>
22#include <vtkUnstructuredGridReader.h>
24#include <vtkCellIterator.h>
25#include <vtkIdTypeArray.h>
26#include <vtkCellData.h>
27#include <vtkPointData.h>
28#include <vtkDataSetAttributes.h>
29#include <vtkArrayDispatch.h>
30#include <vtkDataArrayAccessor.h>
31#include <vtkPolyDataReader.h>
32#include <vtkPolyData.h>
35#include <arccore/base/String.h>
36#include <arccore/base/FatalErrorException.h>
37#include <vtkXMLUnstructuredGridReader.h>
38#include <vtkXMLPolyDataReader.h>
41#include "arcane/core/AbstractService.h"
42#include "arcane/core/ICaseMeshReader.h"
44#include "arcane/core/IMeshBuilder.h"
45#include "arcane/core/MeshBuildInfo.h"
46#include "arcane/core/IPrimaryMesh.h"
48#include "arcane/core/IMeshInitialAllocator.h"
49#include "arcane/core/IVariableMng.h"
51#include "arcane/utils/ITraceMng.h"
52#include "arcane/utils/UniqueArray.h"
53#include "arcane/utils/Real3.h"
54#include "arcane/mesh/CellFamily.h"
55#include "arcane/core/MeshVariableScalarRef.h"
56#include "arcane/core/MeshVariableArrayRef.h"
58#include "arcane/core/ItemAllocationInfo.h"
59#include "arcane/core/VariableBuildInfo.h"
61#include "arcane/utils/OStringStream.h"
63#include "arcane/core/IXmlDocumentHolder.h"
64#include "arcane/core/XmlNode.h"
65#include "arcane/core/internal/IVariableMngInternal.h"
66#include "arcane/core/datatype/DataTypeTraits.h"
68#include "arcane/std/VtkPolyhedralMeshIO_axl.h"
76namespace VtkPolyhedralTools
87 bool print_mesh_info =
false;
88 bool print_debug_info =
false;
111 static String supportedVtkExtensions()
noexcept {
return "vtk,vtu";};
158 bool readHasFailed()
const noexcept {
return m_read_status.failure; }
165 bool isEmpty()
const noexcept {
return m_is_empty; }
166 bool doRead()
const noexcept {
return m_do_read; }
170 bool m_is_empty =
true;
171 bool m_do_read =
false;
200 void _printMeshInfos()
const;
203 template <
typename Connectivity2DArray>
205 void _readPlainTextVtkGrid(
const String& filename);
206 void _readXlmVtkGrid(
const String& filename);
207 void _checkVtkGrid()
const;
222 if (
do_read) reader = std::make_unique<VtkReader>( filename, m_print_info_level );
223 if (reader->readHasFailed())
224 return reader->readStatus();
229 _readVariablesAndGroups(mesh, *reader);
230 return reader->readStatus();
240 bool is_array =
false;
275 build_info.addFactoryName(
"ArcanePolyhedralMeshFactory");
278 mk.setMeshStructure(eMeshStructure::Polyhedral);
285 m_trace_mng->
info() <<
"---Create Polyhedral mesh: " << pm->name() <<
"---";
286 m_trace_mng->
info() <<
"--Read mesh file " << m_read_info.fileName();
310 if (VtkPolyhedralMeshIOService::VtkReader::supportedVtkExtensions().contains(
read_info.format()))
312 return makeRef(builder);
320 ServiceProperty(
"VtkPolyhedralCaseMeshReader",
ST_CaseOption),
326void VtkPolyhedralMeshIOService::
327_fillItemAllocationInfo(ItemAllocationInfo& item_allocation_info, VtkReader& vtk_reader)
329 auto nb_item_family = 4;
330 auto nb_connected_family = 3;
331 item_allocation_info.family_infos.resize(nb_item_family);
332 for (
auto& family_info : item_allocation_info.family_infos) {
333 family_info.connected_family_info.resize(nb_connected_family);
336 auto& cell_family_info = item_allocation_info.family_infos[0];
337 cell_family_info.name =
"Cell";
338 cell_family_info.item_kind =
IK_Cell;
339 cell_family_info.item_uids = vtk_reader.cellUids();
340 auto& node_family_info = item_allocation_info.family_infos[1];
341 node_family_info.name =
"Node";
342 node_family_info.item_kind =
IK_Node;
343 node_family_info.item_uids = vtk_reader.nodeUids();
344 auto& face_family_info = item_allocation_info.family_infos[2];
345 face_family_info.name =
"Face";
346 face_family_info.item_kind =
IK_Face;
347 face_family_info.item_uids = vtk_reader.faceUids();
348 auto& edge_family_info = item_allocation_info.family_infos[3];
349 edge_family_info.name =
"Edge";
350 edge_family_info.item_kind =
IK_Edge;
351 edge_family_info.item_uids = vtk_reader.edgeUids();
353 auto cell_connected_family_index = 0;
354 auto& cell_connected_node_family_info = cell_family_info.connected_family_info[cell_connected_family_index++];
355 cell_connected_node_family_info.name = node_family_info.name;
356 cell_connected_node_family_info.item_kind = node_family_info.item_kind;
357 cell_connected_node_family_info.connectivity_name =
"CellToNodes";
358 cell_connected_node_family_info.nb_connected_items_per_item = vtk_reader.cellNbNodes();
359 cell_connected_node_family_info.connected_items_uids = vtk_reader.cellNodes();
361 auto& cell_connected_face_family_info = cell_family_info.connected_family_info[cell_connected_family_index++];
362 cell_connected_face_family_info.name = face_family_info.name;
363 cell_connected_face_family_info.item_kind = face_family_info.item_kind;
364 cell_connected_face_family_info.connectivity_name =
"CellToFaces";
365 cell_connected_face_family_info.nb_connected_items_per_item = vtk_reader.cellNbFaces();
366 cell_connected_face_family_info.connected_items_uids = vtk_reader.cellFaces();
368 auto& cell_connected_edge_family_info = cell_family_info.connected_family_info[cell_connected_family_index++];
369 cell_connected_edge_family_info.name = edge_family_info.name;
370 cell_connected_edge_family_info.item_kind = edge_family_info.item_kind;
371 cell_connected_edge_family_info.connectivity_name =
"CellToEdges";
372 cell_connected_edge_family_info.nb_connected_items_per_item = vtk_reader.cellNbEdges();
373 cell_connected_edge_family_info.connected_items_uids = vtk_reader.cellEdges();
375 auto face_connected_family_index = 0;
376 auto& face_connected_cell_family_info = face_family_info.connected_family_info[face_connected_family_index++];
377 face_connected_cell_family_info.name = cell_family_info.name;
378 face_connected_cell_family_info.item_kind = cell_family_info.item_kind;
379 face_connected_cell_family_info.connectivity_name =
"FaceToCells";
380 face_connected_cell_family_info.nb_connected_items_per_item = vtk_reader.faceNbCells();
381 face_connected_cell_family_info.connected_items_uids = vtk_reader.faceCells();
383 auto& face_connected_node_family_info = face_family_info.connected_family_info[face_connected_family_index++];
384 face_connected_node_family_info.name = node_family_info.name;
385 face_connected_node_family_info.item_kind = node_family_info.item_kind;
386 face_connected_node_family_info.connectivity_name =
"FaceToNodes";
387 face_connected_node_family_info.nb_connected_items_per_item = vtk_reader.faceNbNodes();
388 face_connected_node_family_info.connected_items_uids = vtk_reader.faceNodes();
390 auto& face_connected_edge_family_info = face_family_info.connected_family_info[face_connected_family_index];
391 face_connected_edge_family_info.name = edge_family_info.name;
392 face_connected_edge_family_info.item_kind = edge_family_info.item_kind;
393 face_connected_edge_family_info.connectivity_name =
"FaceToEdges";
394 face_connected_edge_family_info.nb_connected_items_per_item = vtk_reader.faceNbEdges();
395 face_connected_edge_family_info.connected_items_uids = vtk_reader.faceEdges();
397 auto edge_connected_family_index = 0;
398 auto& edge_connected_cell_family_info = edge_family_info.connected_family_info[edge_connected_family_index++];
399 edge_connected_cell_family_info.name = cell_family_info.name;
400 edge_connected_cell_family_info.item_kind = cell_family_info.item_kind;
401 edge_connected_cell_family_info.connectivity_name =
"EdgeToCells";
402 edge_connected_cell_family_info.nb_connected_items_per_item = vtk_reader.edgeNbCells();
403 edge_connected_cell_family_info.connected_items_uids = vtk_reader.edgeCells();
405 auto& edge_connected_face_family_info = edge_family_info.connected_family_info[edge_connected_family_index++];
406 edge_connected_face_family_info.name = face_family_info.name;
407 edge_connected_face_family_info.item_kind = face_family_info.item_kind;
408 edge_connected_face_family_info.connectivity_name =
"EdgeToFaces";
409 edge_connected_face_family_info.nb_connected_items_per_item = vtk_reader.edgeNbFaces();
410 edge_connected_face_family_info.connected_items_uids = vtk_reader.edgeFaces();
412 auto& edge_connected_node_family_info = edge_family_info.connected_family_info[edge_connected_family_index++];
413 edge_connected_node_family_info.name = node_family_info.name;
414 edge_connected_node_family_info.item_kind = node_family_info.item_kind;
415 edge_connected_node_family_info.connectivity_name =
"EdgeToNodes";
416 edge_connected_node_family_info.nb_connected_items_per_item = vtk_reader.edgeNbNodes();
417 edge_connected_node_family_info.connected_items_uids = vtk_reader.edgeNodes();
419 auto node_connected_family_index = 0;
420 auto& node_connected_cell_family_info = node_family_info.connected_family_info[node_connected_family_index++];
421 node_connected_cell_family_info.name = cell_family_info.name;
422 node_connected_cell_family_info.item_kind = cell_family_info.item_kind;
423 node_connected_cell_family_info.connectivity_name =
"NodeToCells";
424 node_connected_cell_family_info.nb_connected_items_per_item = vtk_reader.nodeNbCells();
425 node_connected_cell_family_info.connected_items_uids = vtk_reader.nodeCells();
427 auto& node_connected_face_family_info = node_family_info.connected_family_info[node_connected_family_index++];
428 node_connected_face_family_info.name = face_family_info.name;
429 node_connected_face_family_info.item_kind = face_family_info.item_kind;
430 node_connected_face_family_info.connectivity_name =
"NodeToFaces";
431 node_connected_face_family_info.nb_connected_items_per_item = vtk_reader.nodeNbFaces();
432 node_connected_face_family_info.connected_items_uids = vtk_reader.nodeFaces();
434 auto& node_connected_edge_family_info = node_family_info.connected_family_info[node_connected_family_index++];
435 node_connected_edge_family_info.name = edge_family_info.name;
436 node_connected_edge_family_info.item_kind = edge_family_info.item_kind;
437 node_connected_edge_family_info.connectivity_name =
"NodeToEdges";
438 node_connected_edge_family_info.nb_connected_items_per_item = vtk_reader.nodeNbEdges();
439 node_connected_edge_family_info.connected_items_uids = vtk_reader.nodeEdges();
441 node_family_info.item_coordinates_variable_name =
"NodeCoord";
442 node_family_info.item_coordinates = vtk_reader.nodeCoords();
448void VtkPolyhedralMeshIOService::
449_readVariablesAndGroups(IPrimaryMesh* mesh, VtkReader& reader)
452 OStringStream created_infos_str;
453 created_infos_str() <<
"<?xml version='1.0' ?>\n";
454 created_infos_str() <<
"<infos>";
456 if (
auto* cell_data = reader.cellData(); cell_data) {
459 std::iota(vtk_to_arcane_lids.begin(), vtk_to_arcane_lids.end(), 0);
461 for (
auto array_index = 0; array_index < cell_data->GetNumberOfArrays(); ++array_index) {
462 auto* cell_array = cell_data->GetArray(array_index);
465 if (String name = cell_array->GetName(); name.substring(0, 6) ==
"GROUP_") {
466 _createGroup(cell_array, name.substring(6), mesh, mesh->cellFamily(), vtk_to_arcane_lids.constSpan());
467 created_infos_str() <<
"<cell-group name='" << name.substring(6) <<
"'/>";
470 auto var_info = _createVariable(cell_array, name, mesh, mesh->cellFamily(), arcane_to_vtk_lids);
471 created_infos_str() <<
"<cell-variable name='" << name <<
"' "
472 <<
" data-type='" <<
dataTypeName(var_info.m_type) <<
"' "
473 <<
" is_array='" << std::boolalpha << var_info.is_array <<
"'/>";
475 if (m_print_info_level.print_debug_info) {
477 for (
auto tuple_index = 0; tuple_index < cell_array->GetNumberOfTuples(); ++tuple_index) {
478 for (
auto component_index = 0; component_index < cell_array->GetNumberOfComponents(); ++component_index) {
479 debug(
Trace::High) << cell_array->GetName() <<
"[" << tuple_index <<
"][" << component_index <<
"] = " << cell_array->GetComponent(tuple_index, component_index);
486 if (
auto* point_data = reader.pointData(); point_data) {
489 std::iota(vtk_to_arcane_lids.begin(), vtk_to_arcane_lids.end(), 0);
491 for (
auto array_index = 0; array_index < point_data->GetNumberOfArrays(); ++array_index) {
492 auto* point_array = point_data->GetArray(array_index);
493 if (String name = point_array->GetName(); name.substring(0, 6) ==
"GROUP_") {
494 _createGroup(point_array, name.substring(6), mesh, mesh->nodeFamily(), vtk_to_arcane_lids.constSpan());
495 created_infos_str() <<
"<node-group name='" << name.substring(6) <<
"'/>";
498 auto var_info = _createVariable(point_array, name, mesh, mesh->nodeFamily(), arcane_to_vtk_lids);
499 created_infos_str() <<
"<node-variable name='" << name <<
"' "
500 <<
" data-type='" <<
dataTypeName(var_info.m_type) <<
"' "
501 <<
" is_array='" << std::boolalpha << var_info.is_array <<
"'/>";
503 if (m_print_info_level.print_debug_info) {
505 for (
auto tuple_index = 0; tuple_index < point_array->GetNumberOfTuples(); ++tuple_index) {
506 for (
auto component_index = 0; component_index < point_array->GetNumberOfComponents(); ++component_index) {
507 debug(
Trace::High) << point_array->GetName() <<
"[" << tuple_index <<
"][" << component_index <<
"] = " << point_array->GetComponent(tuple_index, component_index);
514 if (
auto* face_data = reader.faceData(); face_data) {
518 _computeFaceVtkArcaneLidConversion(vtk_to_Arcane_lids, arcane_to_vtk_lids, reader, mesh);
519 for (
auto array_index = 0; array_index < face_data->GetNumberOfArrays(); ++array_index) {
520 auto* face_array = face_data->GetArray(array_index);
521 if (String name = face_array->GetName(); name.substring(0, 6) ==
"GROUP_") {
522 _createGroup(face_array, name.substring(6), mesh, mesh->faceFamily(), vtk_to_Arcane_lids);
523 created_infos_str() <<
"<face-group name='" << name <<
"'/>";
526 auto var_info = _createVariable(face_array, name, mesh, mesh->faceFamily(), arcane_to_vtk_lids);
527 created_infos_str() <<
"<face-variable name='" << name <<
"' "
528 <<
" data-type='" <<
dataTypeName(var_info.m_type) <<
"' "
529 <<
" is_array='" << std::boolalpha << var_info.is_array <<
"'/>";
531 if (m_print_info_level.print_debug_info) {
533 for (
auto tuple_index = 0; tuple_index < face_array->GetNumberOfTuples(); ++tuple_index) {
534 for (
auto component_index = 0; component_index < face_array->GetNumberOfComponents(); ++component_index) {
535 debug(
Trace::High) << face_array->GetName() <<
"[" << tuple_index <<
"][" << component_index <<
"] = " << face_array->GetComponent(tuple_index, component_index);
541 created_infos_str() <<
"</infos>";
544 auto* pm = mesh->parallelMng();
546 String str = created_infos_str.str();
549 bytes.resize(len + 1);
553 if (reader.isEmpty()) {
555 XmlNode doc_node = doc->documentNode();
556 _createEmptyVariablesAndGroups(mesh,doc_node);
564void VtkPolyhedralMeshIOService::
565_createGroup(vtkDataArray* group_items,
const String& group_name, IPrimaryMesh* mesh, IItemFamily* item_family,
Int32ConstSpan vtkToArcaneLid)
const
570 if (group_items->GetNumberOfComponents() != 1)
571 fatal() << String::format(
"Cannot create item group {0}. Group information in data property must be a scalar", group_name);
572 debug() <<
"Create group " << group_name;
574 arcane_lids.
reserve((
int)group_items->GetNumberOfValues());
575 using GroupDispatcher = vtkArrayDispatch::DispatchByValueType<vtkArrayDispatch::Integrals>;
576 auto group_creator = [&arcane_lids, &vtkToArcaneLid](
auto* array) {
577 vtkIdType numTuples = array->GetNumberOfTuples();
578 vtkDataArrayAccessor<std::remove_pointer_t<
decltype(array)>> array_accessor{ array };
580 for (vtkIdType tupleIdx = 0; tupleIdx < numTuples; ++tupleIdx) {
581 auto value = array_accessor.Get(tupleIdx, 0);
583 arcane_lids.push_back(vtkToArcaneLid[local_id]);
587 if (!GroupDispatcher::Execute(group_items, group_creator))
588 ARCANE_FATAL(
"Cannot create item group {0}. Group information in data property must be an integral type", group_name);
589 debug() <<
" local ids for item group " << group_name <<
" " << arcane_lids;
590 item_family->createGroup(group_name, arcane_lids);
596template <
typename vtkType>
624 ARCANE_FATAL(
"Cannot create variable {0}, {1} values are given for {2} items in {3} family",
630 using ValueType =
typename std::remove_pointer_t<
decltype(values)>::ValueType;
631 auto* var =
new ItemVariableScalarRefT<to_arcane_type_t<ValueType>>{ vbi, item_family->itemKind() };
632 mesh->
variableMng()->_internalApi()->addAutoDestroyVariable(var);
633 vtkDataArrayAccessor<std::remove_pointer_t<
decltype(values)>> values_accessor{ values };
635 (*var)[item] = (to_arcane_type_t<ValueType>)values_accessor.Get(arcane_to_vtk_lids[item.localId()], 0);
637 var_info.m_type = DataTypeTraitsT<to_arcane_type_t<ValueType>>::type();
638 var_info.is_array =
false;
640 auto array_variable_creator = [mesh, variable_name, item_family, arcane_to_vtk_lids,
this, &var_info](
auto* values) {
641 VariableBuildInfo vbi{ mesh, variable_name };
642 using ValueType =
typename std::remove_pointer_t<
decltype(values)>::ValueType;
643 auto* var =
new ItemVariableArrayRefT<to_arcane_type_t<ValueType>>{ vbi, item_family->itemKind() };
644 mesh->
variableMng()->_internalApi()->addAutoDestroyVariable(var);
645 vtkDataArrayAccessor<std::remove_pointer_t<
decltype(values)>> values_accessor{ values };
646 var->resize(values->GetNumberOfComponents());
649 for (
auto& var_value : (*var)[item]) {
650 var_value = (to_arcane_type_t<ValueType>)values_accessor.Get(arcane_to_vtk_lids[item.localId()], index++);
653 var_info.m_type = DataTypeTraitsT<to_arcane_type_t<ValueType>>::type();
654 var_info.is_array =
true;
657 using ValueTypes = vtkTypeList_Create_6(
double,
float,
int,
long,
long long,
short);
658 using ArrayDispatcher = vtkArrayDispatch::DispatchByValueType<ValueTypes>;
660 bool is_variable_created =
false;
661 if (item_values->GetNumberOfComponents() == 1) {
662 is_variable_created = ArrayDispatcher::Execute(item_values, variable_creator);
666 is_variable_created = ArrayDispatcher::Execute(item_values, array_variable_creator);
668 if (!is_variable_created)
669 ARCANE_FATAL(
"Cannot create variable {0}, it's data type is not supported. Only real and integral types are supported", variable_name);
676void VtkPolyhedralMeshIOService::
677_computeFaceVtkArcaneLidConversion(
Int32Span face_vtk_to_arcane_lids,
Int32Span arcane_to_vtk_lids, VtkPolyhedralMeshIOService::VtkReader& reader, IPrimaryMesh* mesh)
const
679 auto face_nodes_unique_ids = reader.faceNodes();
680 auto face_nb_nodes = reader.faceNbNodes();
681 auto current_face_index = 0;
682 auto current_face_index_in_face_nodes = 0;
684 mesh->nodeFamily()->itemsUniqueIdToLocalId(face_nodes_local_ids, face_nodes_unique_ids);
685 for (
auto current_face_nb_node : face_nb_nodes) {
686 auto current_face_nodes = face_nodes_local_ids.subConstView(current_face_index_in_face_nodes, current_face_nb_node);
687 current_face_index_in_face_nodes += current_face_nb_node;
688 Node face_first_node{ mesh->nodeFamily()->view()[current_face_nodes[0]] };
689 face_vtk_to_arcane_lids[current_face_index] = mesh_utils::getFaceFromNodesLocal(face_first_node, current_face_nodes).localId();
690 ++current_face_index;
693 for (
auto arcane_lid : face_vtk_to_arcane_lids) {
694 arcane_to_vtk_lids[arcane_lid] = vtk_lid;
702template <
template <
class>
class VariableRootType>
703VariableRef* _createVar(IMesh* mesh,
const String& var_name,
const String& var_data_type_name,
eItemKind var_kind)
705 bool has_error =
false;
708 ARCANE_FATAL(
"Invalid data type name {0} for Variable creation in VtkPolyhedralMeshIOService");
710 switch (var_data_type){
712 return new VariableRootType<Int32>{VariableBuildInfo{mesh,var_name},var_kind};
715 return new VariableRootType<Int64>{VariableBuildInfo{mesh,var_name},var_kind};
718 return new VariableRootType<Real>{VariableBuildInfo{mesh,var_name},var_kind};
721 ARCANE_FATAL(
"Handle only DT_Int32, DT_Int64, DT_Real in VtkPolyhedralMeshIOService");
728template <
template <
class>
class VariableRootType ,
template <
class>
class ArrayVariableRootType>
729void VtkPolyhedralMeshIOService::
730_createEmptyVariables(IMesh* mesh,
const XmlNodeList& item_variables_node,
eItemKind item_kind)
const
732 ARCANE_CHECK_PTR(mesh);
734 for (XmlNode xnode : item_variables_node) {
735 String name = xnode.attrValue(
"name");
736 debug() <<
"Create mesh variable: " << name;
737 String data_type_name = xnode.attrValue(
"data-type");
738 bool is_array = xnode.attrValue(
"is_array") ==
"true";
739 VariableRef* var =
nullptr;
741 var = _createVar<ArrayVariableRootType>(mesh,name,data_type_name,item_kind);
744 var = _createVar<VariableRootType>(mesh,name, data_type_name,item_kind);
746 mesh->variableMng()->_internalApi()->addAutoDestroyVariable(var);
754void VtkPolyhedralMeshIOService::
755_createEmptyGroups(IMesh* mesh,
const XmlNodeList& groups_node, IItemFamily* item_family)
const
757 for (XmlNode xnode : groups_node) {
758 String name = xnode.attrValue(
"name");
759 info() <<
"Building group: " << name;
760 item_family->createGroup(name);
769void VtkPolyhedralMeshIOService::
772 ARCANE_CHECK_PTR(mesh);
773 auto document_node = variable_and_group_info.documentElement();
774 _createEmptyVariables<ItemVariableScalarRefT,ItemVariableArrayRefT>(mesh, document_node.children(
"cell-variable"),
IK_Cell);
775 _createEmptyVariables<ItemVariableScalarRefT,ItemVariableArrayRefT>(mesh, document_node.children(
"node-variable"),
IK_Node);
776 _createEmptyVariables<ItemVariableScalarRefT,ItemVariableArrayRefT>(mesh, document_node.children(
"face-variable"),
IK_Face);
778 _createEmptyGroups(mesh, document_node.children(
"cell-group"), mesh->itemFamily(
IK_Cell));
779 _createEmptyGroups(mesh, document_node.children(
"node-group"), mesh->itemFamily(
IK_Node));
780 _createEmptyGroups(mesh, document_node.children(
"face-group"), mesh->itemFamily(
IK_Face));
786VtkPolyhedralMeshIOService::VtkReader::
787VtkReader(
const String& filename, VtkPolyhedralTools::PrintInfoLevel print_info_level)
788: m_filename{ filename }
789, m_print_info_level{ print_info_level }
793 if (filename.empty()) {
794 m_read_status.failure =
true;
795 m_read_status.failure_message =
"filename for polyhedral vtk mesh is empty.";
798 if (filename.endsWith(
"vtk"))
799 _readPlainTextVtkGrid(filename);
800 else if (filename.endsWith(
"vtu"))
801 _readXlmVtkGrid(filename);
803 m_read_status.failure =
true;
804 m_read_status.failure_message = String::format(
"Unsupported vtk extension for file {0}. Supported vtk extension for Polyhedral meshes are {1}",
805 filename,VtkReader::supportedVtkExtensions());
809 m_read_status.failure =
true;
810 m_read_status.failure_message = String::format(
"Cannot read vtk polyhedral file {0}. Vtk grid was not created.", filename);
813 if (m_vtk_grid->GetNumberOfCells() == 0) {
814 m_read_status.failure =
true;
815 m_read_status.failure_message = String::format(
"Cannot read vtk polyhedral file {0}. No cells were found.", filename);
818 if (!m_vtk_grid->GetFaces()) {
819 m_read_status.failure =
true;
820 m_read_status.failure_message = String::format(
"The given mesh vtk file {0} is not a polyhedral mesh, cannot read it", filename);
824 m_cell_data = m_vtk_grid->GetCellData();
825 m_point_data = m_vtk_grid->GetPointData();
828 String faces_filename = m_filename +
"faces.vtk";
829 std::ifstream ifile(faces_filename.localstr());
831 _readPlainTextVtkFaceGrid(faces_filename);
834 faces_filename = m_filename +
"faces.vtu";
835 ifile = std::ifstream{ faces_filename.localstr() };
837 _readXmlVtkFaceGrid(faces_filename);
842 faces_filename.split(faces_filename_and_extension,
'.');
845 m_read_status.info_message = String::format(
"Information no face mesh given {0}{1} (.vtk or .vtu) to define face variables or groups on faces.",
846 faces_filename_and_extension[0],
847 faces_filename_and_extension[1]);
850 if (m_vtk_face_grid) {
851 if (m_vtk_face_grid->GetNumberOfCells() == 0) {
852 m_read_status.failure =
true;
853 m_read_status.failure_message = m_read_status.failure_message + String::format(
" Error in reading face information for groups in mesh file {0} ", faces_filename);
856 m_face_data = m_vtk_face_grid->GetCellData();
860 m_read_status.failure =
true;
861 m_read_status.failure_message = m_read_status.failure_message + String::format(
"Face data could not be built from file {0}{1} (.vtk or .vtu).",
862 faces_filename_and_extension[0],
863 faces_filename_and_extension[1]);
867 if (m_print_info_level.print_mesh_info)
877 if (!doRead())
return m_cell_uids;
878 if (m_cell_uids.
empty()) {
880 m_cell_uids.
reserve(m_vtk_grid->GetNumberOfCells());
881 m_cell_nb_nodes.
reserve(m_vtk_grid->GetNumberOfCells());
882 m_cell_node_uids.
reserve(10 * m_vtk_grid->GetNumberOfCells());
883 auto* cell_iter = m_vtk_grid->NewCellIterator();
884 cell_iter->InitTraversal();
885 while (!cell_iter->IsDoneWithTraversal()) {
886 m_cell_uids.
push_back(cell_iter->GetCellId());
888 ArrayView<vtkIdType> cell_nodes{
Integer(cell_iter->GetNumberOfPoints()), cell_iter->GetPointIds()->GetPointer(0) };
889 std::for_each(cell_nodes.begin(), cell_nodes.end(), [
this](
auto uid) { this->m_cell_node_uids.push_back(uid); });
890 cell_iter->GoToNextCell();
902 if (!doRead())
return m_node_uids;
903 if (m_node_uids.empty()) {
905 auto nb_nodes = m_vtk_grid->GetNumberOfPoints();
906 m_node_uids.resize(nb_nodes);
907 m_node_nb_cells.resize(nb_nodes);
908 m_node_cell_uids.reserve(8 * nb_nodes);
909 m_node_uid_to_index.resize(nb_nodes);
910 for (
int node_index = 0; node_index < nb_nodes; ++node_index) {
911 Int64 node_uid = node_index;
912 m_node_uids[node_index] = node_uid;
913 auto cell_nodes = vtkIdList::New();
914 m_vtk_grid->GetPointCells(node_index, cell_nodes);
915 Int64Span cell_nodes_view((
Int64*)cell_nodes->GetPointer(0), cell_nodes->GetNumberOfIds());
916 m_node_cell_uids.addRange(cell_nodes_view);
917 m_node_nb_cells[node_index] = (
Int32)cell_nodes->GetNumberOfIds();
920 m_node_uid_to_index[node_uid] = node_index;
935 if (!doRead())
return m_face_uids;
936 if (!m_face_uids.empty())
939 auto* cell_iter = m_vtk_grid->NewCellIterator();
940 cell_iter->InitTraversal();
941 vtkIdType nb_face_estimation = 0;
942 while (!cell_iter->IsDoneWithTraversal()) {
943 vtkIdType cell_nb_faces = 0;
944 vtkIdType* points{
nullptr };
945 m_vtk_grid->GetFaceStream(cell_iter->GetCellId(), cell_nb_faces, points);
946 nb_face_estimation += cell_nb_faces;
947 cell_iter->GoToNextCell();
949 m_face_uids.reserve(nb_face_estimation);
950 auto const* faces = m_vtk_grid->GetFaces();
955 ARCANE_FATAL(
"Mesh {0} is not polyhedral: faces are not defined", m_filename);
958 auto face_info_size = faces->GetNumberOfValues();
959 m_face_node_uids.reserve(face_info_size);
960 m_face_nb_nodes.reserve(nb_face_estimation);
961 m_face_cell_uids.reserve(2 * nb_face_estimation);
962 m_face_nb_cells.reserve(nb_face_estimation);
963 m_cell_face_uids.reserve(8 * m_cell_uids.size());
964 m_cell_nb_faces.resize(m_cell_uids.size(), 0);
965 m_cell_face_indexes.resize(m_cell_uids.size(), -1);
966 m_face_uid_indexes.resize(2 * nb_face_estimation, -1);
968 current_face_nodes.
reserve(10);
969 sorted_current_face_nodes.reserve(10);
970 UniqueArray<UniqueArray<Int64>> node_faces(m_node_uids.size());
971 UniqueArray<Int32> face_offsets;
972 face_offsets.reserve(nb_face_estimation);
973 face_offsets.push_back(0);
974 FaceUidToIndexMap face_uid_to_index;
975 face_uid_to_index.reserve(nb_face_estimation);
977 auto cell_face_index = 0;
978 auto global_face_index = 0;
979 auto face_uid_index = 0;
980 for (
int face_info_index = 0; face_info_index < face_info_size; cell_index++) {
981 auto current_cell_nb_faces =
Int32(faces->GetValue(face_info_index++));
982 m_cell_face_indexes[m_cell_uids[cell_index]] = cell_face_index;
983 for (
auto face_index = 0; face_index < current_cell_nb_faces; ++face_index, ++global_face_index) {
984 auto current_face_nb_nodes =
Int32(faces->GetValue(face_info_index++));
985 m_cell_nb_faces[m_cell_uids[cell_index]] += 1;
986 for (
int node_index = 0; node_index < current_face_nb_nodes; ++node_index) {
987 current_face_nodes.push_back(faces->GetValue(face_info_index++));
989 sorted_current_face_nodes.resize(current_face_nodes.size());
990 auto is_front_cell = mesh_utils::reorderNodesOfFace(current_face_nodes, sorted_current_face_nodes);
991 auto [is_face_found, existing_face_index] = _findFace(sorted_current_face_nodes, node_faces,
992 m_node_uid_to_index, m_face_nb_nodes,
993 face_uid_to_index, face_offsets, m_face_node_uids);
994 if (!is_face_found) {
995 for (
auto node_uid : current_face_nodes) {
996 node_faces[m_node_uid_to_index[node_uid]].push_back(face_uid);
998 m_cell_face_uids.push_back(face_uid);
999 m_face_uids.push_back(face_uid);
1000 m_face_nb_nodes.push_back(current_face_nb_nodes);
1001 m_face_node_uids.addRange(sorted_current_face_nodes);
1002 m_face_nb_cells.push_back(1);
1003 m_face_uid_indexes[global_face_index] = face_uid_index;
1004 face_uid_to_index.push_back(face_uid_index);
1005 auto previous_offset = face_offsets.back();
1006 face_offsets.push_back(previous_offset + sorted_current_face_nodes.size());
1009 if (is_front_cell) {
1010 m_face_cell_uids.push_back(NULL_ITEM_UNIQUE_ID);
1011 m_face_cell_uids.push_back(m_cell_uids[cell_index]);
1014 m_face_cell_uids.push_back(m_cell_uids[cell_index]);
1015 m_face_cell_uids.push_back(NULL_ITEM_UNIQUE_ID);
1019 m_cell_face_uids.push_back(m_face_uids[existing_face_index]);
1020 m_face_nb_cells[existing_face_index] += 1;
1021 m_face_uid_indexes[global_face_index] = existing_face_index;
1023 if (is_front_cell) {
1024 if (m_face_cell_uids[2 * existing_face_index + 1] != NULL_ITEM_UNIQUE_ID) {
1025 ARCANE_FATAL(
"Problem in face orientation, face uid {0}, nodes {1}, same orientation in cell {2} and {3}. Change mesh file.",
1026 m_face_uids[existing_face_index],
1028 m_face_cell_uids[2 * existing_face_index + 1],
1029 m_cell_uids[cell_index]);
1031 m_face_cell_uids[2 * existing_face_index + 1] = m_cell_uids[cell_index];
1034 if (m_face_cell_uids[2 * existing_face_index] != NULL_ITEM_UNIQUE_ID) {
1035 ARCANE_FATAL(
"Problem in face orientation, face uid {0}, nodes {1}, same orientation in cell {2} and {3}. Change mesh file.",
1036 m_face_uids[existing_face_index],
1038 m_face_cell_uids[2 * existing_face_index],
1039 m_cell_uids[cell_index]);
1041 m_face_cell_uids[2 * existing_face_index] = m_cell_uids[cell_index];
1044 current_face_nodes.clear();
1045 sorted_current_face_nodes.clear();
1047 cell_face_index += m_cell_nb_faces[m_cell_uids[cell_index]];
1050 m_node_nb_faces.resize(m_node_uids.size(), 0);
1051 _flattenConnectivity(node_faces.constSpan(), m_node_nb_faces, m_node_face_uids);
1053 if (m_print_info_level.print_debug_info) {
1054 std::cout <<
"================FACE NODES ==============" << std::endl;
1055 std::copy(m_face_node_uids.begin(), m_face_node_uids.end(), std::ostream_iterator<Int64>(std::cout,
" "));
1056 std::cout << std::endl;
1057 std::copy(m_face_nb_nodes.begin(), m_face_nb_nodes.end(), std::ostream_iterator<Int64>(std::cout,
" "));
1058 std::cout << std::endl;
1059 std::copy(m_cell_face_indexes.begin(), m_cell_face_indexes.end(), std::ostream_iterator<Int64>(std::cout,
" "));
1060 std::cout << std::endl;
1072 if (!doRead())
return m_edge_uids;
1073 if (!m_edge_uids.empty())
1079 m_edge_uids.reserve(2 * m_vtk_grid->GetNumberOfPoints());
1080 auto const* faces = m_vtk_grid->GetFaces();
1085 ARCANE_FATAL(
"Mesh {0} is not polyhedral: faces are not defined", m_filename);
1088 auto nb_edge_estimation = 2 * m_edge_uids.capacity();
1089 m_edge_node_uids.reserve(nb_edge_estimation);
1090 auto face_info_size = faces->GetNumberOfValues();
1091 auto cell_index = 0;
1092 auto global_face_index = 0;
1093 auto new_edge_index = 0;
1094 UniqueArray<std::set<Int64>> edge_cells;
1095 UniqueArray<Int64UniqueArray> edge_faces;
1096 edge_cells.reserve(m_edge_uids.capacity());
1097 edge_faces.reserve(m_edge_uids.capacity());
1098 m_cell_nb_edges.resize(m_cell_uids.size(), 0);
1099 m_cell_edge_uids.reserve(20 * m_cell_uids.size());
1100 UniqueArray<std::set<Int64>> face_edges;
1101 face_edges.resize(m_face_uids.size());
1102 UniqueArray<std::set<Int64>> cell_edges;
1103 cell_edges.resize(m_cell_uids.size());
1104 UniqueArray<Int64UniqueArray> node_edges;
1105 node_edges.resize(m_node_uids.size());
1106 EdgeUidToIndexMap edge_uid_to_index;
1107 edge_uid_to_index.reserve(nb_edge_estimation);
1109 edge_offsets.
reserve(nb_edge_estimation);
1110 edge_offsets.push_back(0);
1111 m_edge_nb_nodes.reserve(nb_edge_estimation);
1112 for (
int face_info_index = 0; face_info_index < face_info_size; ++cell_index) {
1113 auto current_cell_nb_faces =
Int32(faces->GetValue(face_info_index++));
1114 for (
auto face_index = 0; face_index < current_cell_nb_faces; ++face_index, ++global_face_index) {
1115 auto current_face_nb_nodes =
Int32(faces->GetValue(face_info_index++));
1116 auto first_face_node_uid =
Int32(faces->GetValue(face_info_index));
1117 UniqueArray<Int64> current_edge(2), sorted_edge(2);
1118 for (
int node_index = 0; node_index < current_face_nb_nodes - 1; ++node_index) {
1119 current_edge = UniqueArray<Int64>{ faces->GetValue(face_info_index++), faces->GetValue(face_info_index) };
1120 mesh_utils::reorderNodesOfFace(current_edge, sorted_edge);
1121 auto [is_edge_found, existing_edge_index] = _findFace(sorted_edge, node_edges,
1122 m_node_uid_to_index,
1124 edge_uid_to_index, edge_offsets, m_edge_node_uids);
1125 if (!is_edge_found) {
1126 m_cell_nb_edges[cell_index] += 1;
1127 face_edges[m_face_uid_indexes[global_face_index]].insert(edge_uid);
1128 cell_edges[cell_index].insert(edge_uid);
1129 for (
auto node : current_edge) {
1130 node_edges[node].push_back(edge_uid);
1132 edge_cells.push_back(std::set{ m_cell_uids[cell_index] });
1133 edge_faces.push_back(
Int64UniqueArray{ m_cell_face_uids[m_cell_face_indexes[cell_index] + face_index] });
1134 m_edge_uids.push_back(edge_uid++);
1135 m_edge_node_uids.addRange(sorted_edge);
1136 edge_uid_to_index.push_back(new_edge_index);
1137 auto current_offset = edge_offsets.back();
1138 edge_offsets.push_back(current_offset + 2);
1139 m_edge_nb_nodes.push_back(2);
1143 edge_cells[existing_edge_index].insert(m_cell_uids[cell_index]);
1144 edge_faces[existing_edge_index].push_back(m_cell_face_uids[m_cell_face_indexes[cell_index] + face_index]);
1145 face_edges[m_face_uid_indexes[global_face_index]].insert(m_edge_uids[existing_edge_index]);
1146 cell_edges[cell_index].insert(m_edge_uids[existing_edge_index]);
1149 current_edge = UniqueArray<Int64>{ faces->GetValue(face_info_index++), first_face_node_uid };
1150 mesh_utils::reorderNodesOfFace(current_edge, sorted_edge);
1151 auto [is_edge_found, existing_edge_index] = _findFace(sorted_edge, node_edges,
1152 m_node_uid_to_index,
1154 edge_uid_to_index, edge_offsets, m_edge_node_uids);
1155 if (!is_edge_found) {
1156 m_cell_nb_edges[cell_index] += 1;
1157 edge_cells.push_back(std::set{ m_cell_uids[cell_index] });
1158 edge_faces.push_back(
Int64UniqueArray{ m_cell_face_uids[m_cell_face_indexes[cell_index] + face_index] });
1159 face_edges[m_face_uid_indexes[global_face_index]].insert(edge_uid);
1160 cell_edges[cell_index].insert(edge_uid);
1161 for (
auto node : current_edge) {
1162 node_edges[node].push_back(edge_uid);
1164 m_edge_uids.push_back(edge_uid++);
1165 m_edge_node_uids.addRange(sorted_edge);
1166 edge_uid_to_index.push_back(new_edge_index);
1167 auto current_offset = edge_offsets.back();
1168 edge_offsets.push_back(current_offset + 2);
1169 m_edge_nb_nodes.push_back(2);
1173 edge_cells[existing_edge_index].insert(m_cell_uids[cell_index]);
1174 edge_faces[existing_edge_index].push_back(m_cell_face_uids[m_cell_face_indexes[cell_index] + face_index]);
1175 face_edges[m_face_uid_indexes[global_face_index]].insert(m_edge_uids[existing_edge_index]);
1176 cell_edges[cell_index].insert(m_edge_uids[existing_edge_index]);
1181 m_edge_nb_cells.resize(m_edge_uids.size(), 0);
1182 _flattenConnectivity(edge_cells.constSpan(), m_edge_nb_cells, m_edge_cell_uids);
1185 m_edge_nb_faces.resize(m_edge_uids.size(), 0);
1186 _flattenConnectivity(edge_faces.constSpan(), m_edge_nb_faces, m_edge_face_uids);
1189 m_face_nb_edges.resize(m_face_uids.size(), 0);
1190 _flattenConnectivity(face_edges.constSpan(), m_face_nb_edges, m_face_edge_uids);
1193 m_cell_nb_edges.resize(m_cell_uids.size(), 0);
1194 _flattenConnectivity(cell_edges, m_cell_nb_edges, m_cell_edge_uids);
1197 m_node_nb_edges.resize(m_node_uids.size(), 0);
1198 _flattenConnectivity(node_edges, m_node_nb_edges, m_node_edge_uids);
1200 if (m_print_info_level.print_debug_info) {
1201 std::cout <<
"================EDGE NODES ==============" << std::endl;
1202 std::copy(m_edge_node_uids.begin(), m_edge_node_uids.end(), std::ostream_iterator<Int64>(std::cout,
" "));
1203 std::cout << std::endl;
1204 std::cout <<
"================FACE EDGES ==============" << std::endl;
1205 std::copy(m_face_nb_edges.begin(), m_face_nb_edges.end(), std::ostream_iterator<Int32>(std::cout,
" "));
1206 std::cout << std::endl;
1207 std::copy(m_face_edge_uids.begin(), m_face_edge_uids.end(), std::ostream_iterator<Int64>(std::cout,
" "));
1208 std::cout << std::endl;
1209 std::cout <<
"================CELL EDGES ==============" << std::endl;
1210 std::copy(m_cell_nb_edges.begin(), m_cell_nb_edges.end(), std::ostream_iterator<Int32>(std::cout,
" "));
1211 std::cout << std::endl;
1212 std::copy(m_cell_edge_uids.begin(), m_cell_edge_uids.end(), std::ostream_iterator<Int64>(std::cout,
" "));
1213 std::cout << std::endl;
1221std::pair<bool, Int32> VtkPolyhedralMeshIOService::VtkReader::
1223 const UniqueArray<Int64UniqueArray>& node_face_uids,
1224 const NodeUidToIndexMap& node_uid_to_index,
1226 const FaceUidToIndexMap& face_uid_to_index,
1227 const UniqueArray<Int32>& face_offsets,
1230 auto first_node_uid = sorted_face_nodes[0];
1231 auto first_node_index = node_uid_to_index[first_node_uid];
1233 for (
auto face_uid : node_face_uids[first_node_index]) {
1234 auto face_index = face_uid_to_index[face_uid];
1235 auto face_offset = face_offsets[face_index];
1236 auto face_nb_node = face_nb_nodes[face_index];
1237 if (face_nb_node == sorted_face_nodes.size()) {
1238 bool is_same_face =
true;
1239 for (
auto index = 0; index < face_nb_node; ++index) {
1240 if (sorted_face_nodes[index] != face_node_uids[face_offset + index]) {
1241 is_same_face =
false;
1245 return {
true, face_index };
1248 return {
false, -1 };
1254Integer VtkPolyhedralMeshIOService::VtkReader::
1257 if (m_node_uids.empty())
1259 return m_node_uids.size();
1268 if (m_cell_node_uids.empty())
1270 return m_cell_node_uids;
1279 if (m_cell_nb_nodes.empty())
1281 return m_cell_nb_nodes;
1290 if (m_face_node_uids.empty())
1292 return m_face_node_uids;
1301 if (m_face_nb_nodes.empty())
1303 return m_face_nb_nodes;
1312 if (m_edge_node_uids.empty())
1314 return m_edge_nb_nodes;
1323 if (m_edge_node_uids.empty())
1325 return m_edge_node_uids;
1334 if (m_face_cell_uids.empty())
1337 if (m_print_info_level.print_debug_info) {
1338 std::cout <<
"=================FACE CELLS================="
1340 std::copy(m_face_cell_uids.begin(), m_face_cell_uids.end(), std::ostream_iterator<Int64>(std::cout,
" "));
1342 std::cout <<
"=================END FACE CELLS================="
1345 return m_face_cell_uids;
1354 if (m_face_nb_cells.empty())
1356 return m_face_nb_cells;
1365 if (m_edge_nb_cells.empty())
1367 return m_edge_nb_cells;
1376 if (m_edge_cell_uids.empty())
1378 return m_edge_cell_uids;
1387 if (m_cell_nb_faces.empty())
1389 return m_cell_nb_faces;
1398 if (m_cell_face_uids.empty())
1400 return m_cell_face_uids;
1409 if (m_edge_nb_faces.empty())
1411 return m_edge_nb_faces;
1420 if (m_edge_face_uids.empty())
1422 return m_edge_face_uids;
1431 if (m_cell_nb_edges.empty())
1433 return m_cell_nb_edges;
1442 if (m_cell_edge_uids.empty())
1444 return m_cell_edge_uids;
1453 if (m_face_nb_edges.empty())
1455 return m_face_nb_edges;
1464 if (m_face_edge_uids.empty())
1466 return m_face_edge_uids;
1472template <
typename Connectivity2DArray>
1473void VtkPolyhedralMeshIOService::VtkReader::
1474_flattenConnectivity(Connectivity2DArray connected_item_2darray,
1475 Int32Span nb_connected_item_per_source_item,
1479 std::transform(connected_item_2darray.begin(), connected_item_2darray.end(), nb_connected_item_per_source_item.begin(), [](
auto const& connected_items) {
1480 return connected_items.size();
1483 connected_item_array.reserve(std::accumulate(nb_connected_item_per_source_item.begin(), nb_connected_item_per_source_item.end(), 0));
1484 std::for_each(connected_item_2darray.begin(), connected_item_2darray.end(), [&connected_item_array](
auto const& connected_items) {
1485 for (auto const& connected_item : connected_items) {
1486 connected_item_array.push_back(connected_item);
1497 if (m_node_nb_cells.
empty())
1499 return m_node_nb_cells;
1508 if (m_node_cell_uids.empty())
1510 return m_node_cell_uids;
1519 if (m_node_nb_faces.empty())
1521 return m_node_nb_faces;
1530 if (m_node_face_uids.empty())
1532 return m_node_face_uids;
1541 if (m_node_nb_edges.empty())
1543 return m_node_nb_edges;
1552 if (m_node_edge_uids.empty())
1554 return m_node_edge_uids;
1563 if (!doRead())
return m_node_coordinates;
1564 if (m_node_coordinates.empty()) {
1566 auto point_coords = m_vtk_grid->GetPoints()->GetData();
1567 if (m_print_info_level.print_debug_info) {
1568 std::cout <<
"======= Point COORDS ====" << std::endl;
1569 std::ostringstream oss;
1570 point_coords->PrintSelf(oss, vtkIndent{ 2 });
1571 std::cout << oss.str() << std::endl;
1573 auto nb_nodes = m_vtk_grid->GetNumberOfPoints();
1574 for (
int i = 0; i < nb_nodes; ++i) {
1575 if (m_print_info_level.print_debug_info) {
1576 std::cout <<
"==========current point coordinates : ( ";
1577 std::cout << *(point_coords->GetTuple(i)) <<
" , ";
1578 std::cout << *(point_coords->GetTuple(i) + 1) <<
" , ";
1579 std::cout << *(point_coords->GetTuple(i) + 2) <<
" ) ===" << std::endl;
1581 m_node_coordinates.add({ *(point_coords->GetTuple(i)),
1582 *(point_coords->GetTuple(i) + 1),
1583 *(point_coords->GetTuple(i) + 2) });
1586 return m_node_coordinates;
1592vtkCellData* VtkPolyhedralMeshIOService::VtkReader::
1601vtkPointData* VtkPolyhedralMeshIOService::VtkReader::
1604 return m_point_data;
1610void VtkPolyhedralMeshIOService::VtkReader::
1611_printMeshInfos()
const
1614 std::cout <<
"-- VTK GRID READ "
1615 <<
" NB CELLS " << m_vtk_grid->GetNumberOfCells() << std::endl;
1617 auto* cell_iter = m_vtk_grid->vtkDataSet::NewCellIterator();
1618 cell_iter->InitTraversal();
1619 vtkIdType* cell_faces{
nullptr };
1620 vtkIdType nb_faces = 0;
1621 while (!cell_iter->IsDoneWithTraversal()) {
1622 std::cout <<
"---- visiting cell id " << cell_iter->GetCellId() << std::endl;
1623 std::cout <<
"---- cell number of faces " << cell_iter->GetNumberOfFaces() << std::endl;
1624 std::cout <<
"---- cell number of points " << cell_iter->GetNumberOfPoints() << std::endl;
1625 m_vtk_grid->GetFaceStream(cell_iter->GetCellId(), nb_faces, cell_faces);
1626 for (
auto iface = 0; iface < nb_faces; ++iface) {
1627 auto face_nb_nodes = *cell_faces++;
1628 std::cout <<
"---- has face with " << face_nb_nodes <<
" nodes. Node ids : ";
1629 for (
int inode = 0; inode < face_nb_nodes; ++inode) {
1630 std::cout << *cell_faces++ <<
" ";
1632 std::cout << std::endl;
1634 cell_iter->GoToNextCell();
1641vtkCellData* VtkPolyhedralMeshIOService::VtkReader::faceData()
1651void VtkPolyhedralMeshIOService::VtkReader::
1652_readPlainTextVtkGrid(
const String& filename)
1654 m_vtk_grid_reader->SetFileName(filename.localstr());
1655 m_vtk_grid_reader->ReadAllScalarsOn();
1656 m_vtk_grid_reader->Update();
1657 m_vtk_grid = m_vtk_grid_reader->GetOutput();
1663void VtkPolyhedralMeshIOService::VtkReader::
1664_readXlmVtkGrid(
const String& filename)
1666 m_vtk_xml_grid_reader->SetFileName(filename.localstr());
1667 m_vtk_xml_grid_reader->Update();
1668 m_vtk_grid = m_vtk_xml_grid_reader->GetOutput();
1674void VtkPolyhedralMeshIOService::VtkReader::
1675_readPlainTextVtkFaceGrid(
const String& faces_filename)
1677 m_vtk_face_grid_reader->SetFileName(faces_filename.localstr());
1678 m_vtk_face_grid_reader->ReadAllScalarsOn();
1679 m_vtk_face_grid_reader->Update();
1680 m_vtk_face_grid = m_vtk_face_grid_reader->GetOutput();
1686void VtkPolyhedralMeshIOService::VtkReader::
1687_readXmlVtkFaceGrid(
const String& faces_filename)
1689 m_vtk_xml_face_grid_reader->SetFileName(faces_filename.localstr());
1690 m_vtk_xml_face_grid_reader->Update();
1691 m_vtk_face_grid = m_vtk_xml_face_grid_reader->GetOutput();
1697void VtkPolyhedralMeshIOService::VtkReader::
1698_checkVtkGrid()
const
1701 ARCANE_FATAL(
"Polyhedral vtk grid not loaded. Cannot continue.");
Fichier de configuration d'Arcane.
#define ARCANE_CHECK_POINTER(ptr)
Macro retournant le pointeur ptr s'il est non nul ou lancant une exception s'il est nul.
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Déclarations des types généraux de Arcane.
Fonctions utilitaires sur le maillage.
Ce fichier contient les différentes fabriques de services et macro pour enregistrer les services.
#define ARCANE_SERVICE_INTERFACE(ainterface)
Macro pour déclarer une interface lors de l'enregistrement d'un service.
Gestion des références à une classe C++.
Generation de la classe de base du Service.
CaseOptionsVtkPolyhedralMeshIO * options() const
Options du jeu de données du service.
Informations nécessaires pour la lecture d'un fichier de maillage.
Interface d'une famille d'entités.
Interface d'un service de création/lecture du maillage.
virtual IParallelMng * parallelMng()=0
Gestionnaire de parallèlisme.
virtual IVariableMng * variableMng() const =0
Gestionnaire de variable associé
virtual void broadcastMemoryBuffer(ByteArray &bytes, Int32 rank)=0
Effectue un broadcast d'une zone mémoire.
virtual bool isMasterIO() const =0
true si l'instance est un gestionnaire maître des entrées/sorties.
virtual Integer masterIORank() const =0
Rang de l'instance gérant les entrées/sorties (pour laquelle isMasterIO() est vrai)
virtual IMeshInitialAllocator * initialAllocator()
Allocateur initial spécifique.
static IXmlDocumentHolder * loadFromBuffer(Span< const Byte > buffer, const String &name, ITraceMng *tm)
Charge un document XML.
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Paramètres nécessaires à la construction d'un maillage.
Caractéristiques d'un maillage.
Structure contenant les informations pour créer un service.
Paramètres nécessaires à la construction d'une variable.
Infos caractérisant une variable.
void fillMeshBuildInfo(MeshBuildInfo &build_info) override
Remplit build_info avec les informations nécessaires pour créer le maillage.
void allocateMeshItems(IPrimaryMesh *pm) override
Alloue les entités du maillage géré par ce service.
Ref< IMeshBuilder > createBuilder(const CaseMeshReaderReadInfo &read_info) const override
Retourne un builder pour créer et lire le maillage dont les informations sont spécifiées dans read_in...
Liste de noeuds d'un arbre DOM.
const value_type & const_reference
Type référence constante d'un élément du tableau.
bool empty() const
Capacité (nombre d'éléments alloués) du vecteur.
Vue modifiable d'un tableau d'un type T.
void reserve(Int64 new_capacity)
Réserve le mémoire pour new_capacity éléments.
void push_back(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
Vue constante d'un tableau de type T.
Interface du gestionnaire de traces.
virtual TraceMessage info()=0
Flot pour un message d'information.
Vue d'un tableau d'éléments de type T.
Chaîne de caractères unicode.
Classe d'accès aux traces.
ITraceMng * traceMng() const
Gestionnaire de trace.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flot pour un message de debug.
TraceMessage info() const
Flot pour un message d'information.
TraceMessage fatal() const
Flot pour un message d'erreur fatale.
Vecteur 1D de données avec sémantique par valeur (style STL).
#define ARCANE_REGISTER_SERVICE(aclass, a_service_property,...)
Macro pour enregistrer un service.
Integer len(const char *s)
Retourne la longueur de la chaîne s.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Span< Int32 > Int32Span
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Span< Int64 > Int64Span
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
UniqueArray< Int64 > Int64UniqueArray
Tableau dynamique à une dimension d'entiers 64 bits.
ArrayView< Real3 > Real3ArrayView
Equivalent C d'un tableau à une dimension de Real3.
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
@ ST_CaseOption
Le service s'utilise au niveau du jeu de données.
UniqueArray< Byte > ByteUniqueArray
Tableau dynamique à une dimension de caractères.
SharedArray< Int32 > Int32SharedArray
Tableau dynamique à une dimension d'entiers 32 bits.
ConstArrayView< Byte > ByteConstArrayView
Equivalent C d'un tableau à une dimension de caractères.
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
eItemKind
Genre d'entité de maillage.
@ IK_Node
Entité de maillage de genre noeud.
@ IK_Cell
Entité de maillage de genre maille.
@ IK_Face
Entité de maillage de genre face.
@ IK_Edge
Entité de maillage de genre arête.
UniqueArray< String > StringUniqueArray
Tableau dynamique à une dimension de chaînes de caractères.
Span< const Int32 > Int32ConstSpan
Vue en lecture seule d'un tableau à une dimension d'entiers 32 bits.
eDataType
Type d'une donnée.
@ DT_Int32
Donnée de type entier 32 bits.
@ DT_Int64
Donnée de type entier 64 bits.
@ DT_Unknown
Donnée de type inconnue ou non initialisée.
@ DT_Real
Donnée de type réel.
ConstArrayView< Int64 > Int64ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
ARCANE_DATATYPE_EXPORT eDataType dataTypeFromName(const char *name, bool &has_error)
Trouve le type associé à name.
const char * dataTypeName(eDataType type)
Nom du type de donnée.
Int32 Integer
Type représentant un entier.