35 #include <SMESH_Gen.hxx> 36 #include <SMESH_Group.hxx> 37 #include <SMESH_Mesh.hxx> 38 #include <SMESHDS_Group.hxx> 39 #include <SMESHDS_Mesh.hxx> 41 #include <vtkCellIterator.h> 42 #include <vtkCellType.h> 43 #include <vtkDataSet.h> 44 #include <vtkStringArray.h> 45 #include <vtkUnstructuredGrid.h> 51 void insertWithGroup(
const std::vector<SMDS_MeshNode *> &smdsNodes,
52 SMESHDS_Mesh *meshDS, SMESH_Mesh &outMesh,
53 vtkDataSet *dataset, vtkDataArray *entArr,
54 vtkStringArray *groupNames) {
55 std::vector<vtkIdType> pointIdBuffer;
56 std::map<int, SMESH_Group *> groups;
58 vtkSmartPointer<vtkCellIterator>::Take(dataset->NewCellIterator());
59 !cellIter->IsDoneWithTraversal(); cellIter->GoToNextCell()) {
60 pointIdBuffer.clear();
61 auto vtkPointIds = cellIter->GetPointIds();
62 auto cellDim = cellIter->GetCellDimension();
63 SMDS_MeshCell *outCell;
65 outCell = meshDS->Add0DElement(smdsNodes[vtkPointIds->GetId(0)]);
66 }
else if (cellDim == 1) {
67 auto cellType = cellIter->GetCellType();
69 outCell = meshDS->AddEdge(smdsNodes[vtkPointIds->GetId(0)],
70 smdsNodes[vtkPointIds->GetId(1)]);
71 }
else if (
cellType == VTK_QUADRATIC_EDGE) {
72 outCell = meshDS->AddEdge(smdsNodes[vtkPointIds->GetId(0)],
73 smdsNodes[vtkPointIds->GetId(1)],
74 smdsNodes[vtkPointIds->GetId(2)]);
76 }
else if (cellDim == 2 || cellDim == 3) {
77 for (
int i = 0; i < vtkPointIds->GetNumberOfIds(); ++i) {
78 pointIdBuffer.emplace_back(
79 smdsNodes[vtkPointIds->GetId(i)]->GetVtkID());
82 outCell = meshDS->AddFaceFromVtkIds(pointIdBuffer);
85 outCell = meshDS->AddVolumeFromVtkIds(pointIdBuffer);
89 std::cerr <<
"Failed to add cell with vtk type " 90 << cellIter->GetCellType() <<
'\n';
94 static_cast<int>(entArr->GetComponent(cellIter->GetCellId(), 0));
95 auto &group = groups[gmGroupId];
97 std::string groupName;
98 if (groupNames && gmGroupId >= 0 &&
99 gmGroupId < groupNames->GetNumberOfValues()) {
100 groupName = groupNames->GetValue(gmGroupId);
102 if (groupName.empty()) {
103 groupName =
"Group " + std::to_string(gmGroupId);
105 group = outMesh.AddGroup(SMDSAbs_All, groupName.c_str());
107 if (
auto manualGroup =
108 dynamic_cast<SMESHDS_Group *>(group->GetGroupDS())) {
109 manualGroup->Add(outCell);
129 std::cerr <<
"Currently unsupported.\n";
137 gen_.reset(
new SMESH_Gen{});
143 std::shared_ptr<SMESH_Gen> gen) {
145 gen_ = std::move(gen);
152 auto grid = geoMesh.
mesh;
153 if (grid->GetNumberOfCells() == 0) {
return; }
154 auto linkArr = grid->GetCellData()->GetArray(geoMesh.
link.c_str());
155 auto points = grid->GetPoints();
156 auto meshDS = outMesh.GetMeshDS();
157 std::vector<SMDS_MeshNode *> smdsNodes;
158 smdsNodes.reserve(
points->GetNumberOfPoints());
160 std::array<double, 3> pointBuffer{};
161 for (vtkIdType i = 0; i <
points->GetNumberOfPoints(); ++i) {
162 grid->GetPoint(i, pointBuffer.data());
163 smdsNodes.emplace_back(
164 meshDS->AddNode(pointBuffer[0], pointBuffer[1], pointBuffer[2]));
167 insertWithGroup(smdsNodes, meshDS, outMesh, grid, linkArr,
168 vtkStringArray::SafeDownCast(
169 grid->GetFieldData()->GetArray(
"Group Names")));
170 insertWithGroup(smdsNodes, meshDS, outMesh, geoMesh.
sideSet.
sides,
177 vtkNew<vtkUnstructuredGrid> gmGrid;
178 vtkNew<vtkPolyData> sideSetSides;
181 if ((numGMCells = mesh.NbVolumes()) > 0) {
183 }
else if ((numGMCells = mesh.NbFaces()) > 0) {
185 }
else if ((numGMCells = mesh.NbEdges()) > 0) {
188 return {gmGrid, {}, {}, {}};
190 auto smeshGrid = mesh.GetMeshDS()->GetGrid();
191 gmGrid->Allocate(numGMCells);
192 gmGrid->SetPoints(smeshGrid->GetPoints());
193 sideSetSides->Allocate();
194 sideSetSides->SetPoints(smeshGrid->GetPoints());
195 vtkNew<vtkStringArray> groupNamesGrid;
196 groupNamesGrid->SetName(
"Group Names");
197 vtkNew<vtkStringArray> groupNamesSides;
199 std::vector<int> groups(smeshGrid->GetNumberOfCells(), -1);
201 auto groupId = group->GetID();
205 auto vtkId = elem->GetVtkID();
207 auto &cellGroup = groups[vtkId];
208 if (cellGroup >= 0) {
210 std::cerr <<
"Warning! SMESH Element found on multiple groups. " 211 "Behavior is undefined.\n";
216 auto elemType = group->GetGroupDS()->GetType();
218 elemType == SMDSAbs_Volume ? 3
219 : elemType == SMDSAbs_Face ? 2
220 : (elemType == SMDSAbs_Node || elemType == SMDSAbs_0DElement) ? 1
222 if (groupDim == maxDim || groupDim == -1) {
223 groupNamesGrid->InsertValue(groupId, group->GetName());
225 if (groupDim == maxDim - 1 || groupDim == -1) {
226 groupNamesSides->InsertValue(groupId, group->GetName());
230 vtkNew<vtkIntArray> groupsArr;
231 groupsArr->SetName(
"GeoEnt");
232 groupsArr->SetNumberOfComponents(1);
233 groupsArr->SetNumberOfTuples(numGMCells);
234 groupsArr->FillComponent(0, -1);
235 vtkNew<vtkIntArray> sideSetEntArr;
238 vtkSmartPointer<vtkCellIterator>::Take(smeshGrid->NewCellIterator());
239 !cellIter->IsDoneWithTraversal(); cellIter->GoToNextCell()) {
240 auto cellDim = cellIter->GetCellDimension();
241 if (cellDim == maxDim) {
242 auto gmId = gmGrid->InsertNextCell(cellIter->GetCellType(),
243 cellIter->GetPointIds());
244 auto group = groups[cellIter->GetCellId()];
246 geoMeshHasLink =
true;
247 groupsArr->SetComponent(gmId, 0, group);
249 }
else if (cellDim == maxDim - 1) {
250 auto group = groups[cellIter->GetCellId()];
252 sideSetSides->InsertNextCell(cellIter->GetCellType(),
253 cellIter->GetPointIds());
254 sideSetEntArr->InsertNextValue(group);
259 if (geoMeshHasLink) {
260 gmGrid->GetCellData()->AddArray(groupsArr);
261 gmGrid->GetFieldData()->AddArray(groupNamesGrid);
262 link = groupsArr->GetName();
267 sideSetSides->GetNumberOfCells() > 0
268 ?
SideSet(sideSetSides, sideSetEntArr,
nullptr,
nullptr,
static void GMToSMESH(const GeoMesh &geoMesh, SMESH_Mesh &outMesh)
virtual void report(std::ostream &out) const =0
Print a report about the mesh.
vtkSmartPointer< vtkUnstructuredGrid > mesh
static GeoMesh SmeshToGM(SMESH_Mesh &mesh)
void resetNative() override
void setGeoMesh(const geoMeshBase::GeoMesh &geoMesh)
Set the underlying geometry object.
void setSMeshMesh(std::unique_ptr< SMESH_Mesh > &&mesh, std::shared_ptr< SMESH_Gen > gen)
vtkSmartPointer< vtkPolyData > sides
Cells represent edges/faces of some GeoMesh.
std::shared_ptr< meshBase > mesh
SM_StdContainerWrapperFromIter< typename std::decay< PtrSMDSIterator >::type, VALUE, EqualVALUE > containerWrapper(PtrSMDSIterator &&iter)
std::vector< vtkIdType > points
points given by id in .inp file
vtkSmartPointer< vtkIntArray > getGeoEntArr() const
vtkStandardNewMacro(exoGeoMesh)
mesh_(gen_->CreateMesh(false))
std::unique_ptr< SMESH_Mesh > mesh_
std::shared_ptr< SMESH_Gen > gen_
virtual void write(const std::string &fileName)=0
Write mesh to file.
const SMESH_Mesh & getSMESHMesh() const
abstract class to specify geometry and mesh data
vtkSmartPointer< vtkStringArray > getSideSetNames() const
const GeoMesh & getGeoMesh() const
Get the underlying geometry object.