46 #include <QVBoxLayout> 47 #include <QPushButton> 49 #ifdef ENABLE_HEXAHEDRALMESH_SUPPORT 51 #ifdef ENABLE_POLYHEDRALMESH_SUPPORT 57 void remove_duplicated_vertices(std::vector<quint32>& _indices)
59 std::vector<quint32>::iterator endIter = _indices.end();
60 for (std::vector<quint32>::iterator iter = _indices.begin(); iter != endIter; ++iter)
61 endIter = std::remove(iter+1, endIter, *(iter));
63 _indices.erase(endIter,_indices.end());
70 forceTriangleMesh_(false),
71 forcePolyMesh_(false),
75 saveVertexNormals_(0),
76 saveVertexTexCoords_(0),
77 savePrecisionLabel_(0),
90 userWriteOptions_ |= BINARY;
92 userWriteOptions_ |= FACENORMALS;
94 userWriteOptions_ |= VERTEXNORMALS;
96 userWriteOptions_ |= VERTEXTEXCOORDS;
102 return QString( tr(
"Visualization Toolkit ASCII ( *.vtk )") );
108 return QString( tr(
"Visualization Toolkit ASCII ( *.vtk )") );
116 #ifdef ENABLE_POLYHEDRALMESH_SUPPORT 119 #ifdef ENABLE_HEXAHEDRALMESH_SUPPORT 122 #ifdef ENABLE_TETRAHEDRALMESH_SUPPORT 139 if (saveOptions_ == 0){
141 saveOptions_ =
new QWidget();
142 QVBoxLayout* layout =
new QVBoxLayout();
143 layout->setAlignment(Qt::AlignTop);
145 saveBinary_ =
new QCheckBox(
"Save Binary");
146 layout->addWidget(saveBinary_);
147 saveBinary_->setCheckable(
false);
149 saveFaceNormals_ =
new QCheckBox(
"Save Face Normals");
150 layout->addWidget(saveFaceNormals_);
152 saveVertexNormals_ =
new QCheckBox(
"Save Vertex Normals");
153 layout->addWidget(saveVertexNormals_);
155 saveVertexTexCoords_ =
new QCheckBox(
"Save Vertex TexCoords");
156 layout->addWidget(saveVertexTexCoords_);
158 savePrecisionLabel_ =
new QLabel(
"Writer Precision");
159 layout->addWidget(savePrecisionLabel_);
161 savePrecision_ =
new QSpinBox();
162 savePrecision_->setMinimum(1);
163 savePrecision_->setMaximum(12);
164 savePrecision_->setValue(6);
165 layout->addWidget(savePrecision_);
167 saveDefaultButton_ =
new QPushButton(
"Make Default");
168 layout->addWidget(saveDefaultButton_);
170 saveOptions_->setLayout(layout);
172 connect(saveBinary_, SIGNAL(clicked(
bool)), savePrecision_, SLOT(setDisabled(
bool)));
173 connect(saveDefaultButton_, SIGNAL(clicked()),
this, SLOT(
slotSaveDefault()));
175 saveBinary_->setChecked(
OpenFlipperSettings().value(
"FileVtk/Save/Binary",
false).toBool() );
176 saveFaceNormals_->setChecked(
OpenFlipperSettings().value(
"FileVtk/Save/FaceNormals",
true).toBool() );
177 saveVertexNormals_->setChecked(
OpenFlipperSettings().value(
"FileVtk/Save/VertexNormals",
true).toBool() );
178 saveVertexTexCoords_->setChecked(
OpenFlipperSettings().value(
"FileVtk/Save/VertexTexCoords",
true).toBool() );
203 template <
typename MeshT>
206 emit log(
LOGWARN,tr(
"Unsupported Cell Type TETRA") );
210 template <
typename MeshT>
213 emit log(
LOGWARN,tr(
"Unsupported Cell Type HEXAHEDRON") );
217 template <
typename MeshT>
220 emit log(
LOGWARN,tr(
"Unsupported Cell Type WEDGE") );
224 template <
typename MeshT>
227 emit log(
LOGWARN,tr(
"Unsupported Cell Type PYRAMID") );
231 template <
typename MeshT>
234 std::vector<OpenMesh::VertexHandle> handles;
235 for (std::vector<quint32>::const_iterator it = _indices.begin(); it != _indices.end(); ++it)
236 handles.push_back(_mesh->vertex_handle(*it));
243 std::vector< OpenMesh::VertexHandle > inverseHandles;
244 for (
int i = handles.size()-1 ; i >= 0 ; --i)
245 inverseHandles.push_back(handles[i]);
247 fh = _mesh->add_face(inverseHandles);
256 template <
typename MeshT>
262 return _mesh->add_face(v1,v2,v3).
idx();
265 template <
typename MeshT>
268 _mesh->update_face_normals();
275 template <
typename MeshT>
278 _mesh->update_vertex_normals();
281 template <
typename MeshT>
286 if (! _mesh->get_property_handle(originalVertexIdx,
"FileVTKPlugin_originalVertexIdx")) {
287 _mesh->remove_property( originalVertexIdx );
291 template <
typename MeshT>
296 _mesh->set_normal( vh , _normal );
300 template <
typename MeshT>
305 _mesh->set_normal( fh, _normal );
308 template <
typename MeshT>
311 if ((_cell.type <= 4) || (_cell.type >= 10))
314 emit log(
LOGWARN,tr(
"Normals not supported for type %1").arg(_cell.type) );
316 else if (_cell.type == 5)
321 else if (_cell.type == 6)
324 int numberOfTriangles = _cell.indices.size() - 2;
326 for (
int i = 0; i < numberOfTriangles; i++)
329 else if ((_cell.type >= 7) && (_cell.type <= 9))
332 if (forceTriangleMesh_)
338 int numberOfTriangles = _cell.indices.size() - 2;
339 for (
int i = 0; i < numberOfTriangles; i++)
351 template <
typename MeshT>
356 if (! _mesh->get_property_handle(originalVertexIdx,
"FileVTKPlugin_originalVertexIdx")) {
363 typename MeshT::VertexIter vit = _mesh->vertices_begin();
364 typename MeshT::VertexIter vend = _mesh->vertices_end();
366 for(; vit != vend; ++vit) {
367 if ( _mesh->property(originalVertexIdx, *vit).is_valid() ) {
369 _mesh->set_normal( *vit, _mesh->normal(_mesh->property (originalVertexIdx, *vit) ) );
374 template<
class MeshT >
377 if ( !OpenFlipper::Options::savingSettings() && saveOptions_ != 0)
378 _out.precision(savePrecision_->value());
380 _out <<
"DATASET POLYDATA\n";
382 typename MeshT::Point p;
383 typename MeshT::Normal n;
387 typename MeshT::VertexIter vit = _mesh.vertices_begin();
388 typename MeshT::VertexIter end_vit = _mesh.vertices_end();
389 typename MeshT::FaceIter fit = _mesh.faces_begin();
390 typename MeshT::FaceIter end_fit = _mesh.faces_end();
391 typename MeshT::FaceVertexIter fvit;
393 int total_face_vertices = _mesh.n_faces();
394 for (; fit != end_fit; ++fit) {
395 total_face_vertices += _mesh.valence(*fit);
398 _out <<
"POINTS " << _mesh.n_vertices() <<
" float\n";
399 for (; vit != end_vit; ++vit) {
401 p = _mesh.point(*vit);
402 _out << p[0] <<
" " << p[1] <<
" " << p[2];
407 _out <<
"POLYGONS "<< _mesh.n_faces() <<
" " << total_face_vertices <<
"\n";
408 for (fit = _mesh.faces_begin(); fit != end_fit; ++fit) {
410 _out << _mesh.valence(*fit);
413 fvit = _mesh.fv_iter(*fit);
416 for (;fvit.is_valid(); ++fvit) {
417 _out <<
" " << fvit->idx();
427 _out <<
"CELL_DATA "<< _mesh.n_faces() <<
"\n";
430 if (_mesh.has_face_normals() && (userWriteOptions_ & FileVTKPlugin::FACENORMALS)) {
431 _out <<
"NORMALS faceNormals float\n";
432 for (fit = _mesh.faces_begin(); fit != end_fit; ++fit) {
433 n = _mesh.normal(*fit);
434 _out << n[0] <<
" " << n[1] <<
" " << n[2];
440 _out <<
"POINT_DATA "<< _mesh.n_vertices() <<
"\n";
443 if (_mesh.has_vertex_normals() && (userWriteOptions_ & FileVTKPlugin::VERTEXNORMALS)) {
444 _out <<
"NORMALS vertexNormals float\n";
445 for (vit = _mesh.vertices_begin(); vit != end_vit; ++vit) {
446 n = _mesh.normal(*vit);
447 _out << n[0] <<
" " << n[1] <<
" " << n[2];
453 if (_mesh.has_vertex_texcoords2D() && (userWriteOptions_ & FileVTKPlugin::VERTEXTEXCOORDS)) {
454 _out <<
"TEXTURE_COORDINATES vertexTexcoords 2 float\n";
455 for (vit = _mesh.vertices_begin(); vit != end_vit; ++vit) {
456 t = _mesh.texcoord2D(*vit);
457 _out << t[0] <<
" " << t[1];
502 #if defined(ENABLE_HEXAHEDRALMESH_SUPPORT) || defined(ENABLE_POLYHEDRALMESH_SUPPORT) || defined(ENABLE_TETRAHEDRALMESH_SUPPORT) 504 template <
typename MeshT>
505 int FileVTKPlugin::addTetraCellToOpenVolumeMesh(MeshT _mesh, std::vector<quint32> _indices)
507 if (_indices.size() != 4)
510 std::vector< std::vector<OpenVolumeMesh::VertexHandle> > faces;
511 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
515 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
519 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
523 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
528 std::vector<OpenVolumeMesh::HalfFaceHandle> halffacehandles;
529 for (
unsigned int i = 0; i < faces.size(); i++)
530 halffacehandles.push_back(_mesh->halfface(faces[i]));
532 for (
unsigned int i = 0; i < halffacehandles.size(); i++)
537 halffacehandles[i] = _mesh->halfface_handle(fh, 0);
540 return _mesh->add_cell(halffacehandles).idx();
544 template <
typename MeshT>
545 int FileVTKPlugin::addHexaCellToOpenVolumeMesh(MeshT _mesh, std::vector<quint32> _indices)
547 if (_indices.size() != 8)
548 { emit log(
LOGWARN,tr(
"Expected 8 indices to add Hexahedron but got %1").arg(_indices.size()) ); }
550 std::vector< std::vector<OpenVolumeMesh::VertexHandle> > faces;
551 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
556 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
561 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
566 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
571 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
576 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
582 std::vector<OpenVolumeMesh::HalfFaceHandle> halffacehandles;
583 for (
unsigned int i = 0; i < faces.size(); i++)
584 halffacehandles.push_back(_mesh->halfface(faces[i]));
586 for (
unsigned int i = 0; i < halffacehandles.size(); i++)
591 halffacehandles[i] = _mesh->halfface_handle(fh, 0);
594 return _mesh->add_cell(halffacehandles).idx();
597 template <
typename MeshT>
598 int FileVTKPlugin::addWedgeCellToOpenVolumeMesh(MeshT _mesh, std::vector<quint32> _indices)
600 if (_indices.size() != 6)
601 { emit log(
LOGWARN,tr(
"Expected 6 indices to add Hexahedron but got %1").arg(_indices.size()) ); }
603 std::vector< std::vector<OpenVolumeMesh::VertexHandle> > faces;
604 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
609 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
613 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
617 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
622 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
628 std::vector<OpenVolumeMesh::HalfFaceHandle> halffacehandles;
629 for (
unsigned int i = 0; i < faces.size(); i++)
630 halffacehandles.push_back(_mesh->halfface(faces[i]));
632 for (
unsigned int i = 0; i < halffacehandles.size(); i++)
637 halffacehandles[i] = _mesh->halfface_handle(fh, 0);
640 return _mesh->add_cell(halffacehandles).idx();
643 template <
typename MeshT>
644 int FileVTKPlugin::addPyramidCellToOpenVolumeMesh(MeshT _mesh, std::vector<quint32> _indices)
646 if (_indices.size() != 6)
647 { emit log(
LOGWARN,tr(
"Expected 6 indices to add Hexahedron but got %1").arg(_indices.size()) ); }
649 std::vector< std::vector<OpenVolumeMesh::VertexHandle> > faces;
650 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
655 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
659 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
663 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
667 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
672 std::vector<OpenVolumeMesh::HalfFaceHandle> halffacehandles;
673 for (
unsigned int i = 0; i < faces.size(); i++)
674 halffacehandles.push_back(_mesh->halfface(faces[i]));
676 for (
unsigned int i = 0; i < halffacehandles.size(); i++)
681 halffacehandles[i] = _mesh->halfface_handle(fh, 0);
684 return _mesh->add_cell(halffacehandles).idx();
687 template <
typename MeshT>
688 int FileVTKPlugin::addFaceToOpenVolumeMesh(MeshT*& _mesh, std::vector<quint32> _indices)
690 if (_indices.size() < 3)
691 { emit log(
LOGWARN,tr(
"Expected at least 3 indices to add a face but got %1").arg(_indices.size()) ); }
693 std::vector<OpenVolumeMesh::VertexHandle> face;
694 for (
unsigned int i = 0; i < _indices.size(); i++)
699 halffacehandle = _mesh->halfface(face);
700 if (!halffacehandle.is_valid())
703 halffacehandle = _mesh->halfface_handle(fh, 0);
705 return halffacehandle.idx();
708 template <
typename MeshT>
709 int FileVTKPlugin::addFaceToOpenVolumeMesh(MeshT*& _mesh, quint32 _index1, quint32 _index2, quint32 _index3)
711 std::vector<OpenVolumeMesh::VertexHandle> face;
717 halffacehandle = _mesh->halfface(face);
718 if (!halffacehandle.is_valid())
721 halffacehandle = _mesh->halfface_handle(fh, 0);
723 return halffacehandle.idx();
726 template <
typename MeshT>
727 void FileVTKPlugin::addVertexNormalToOpenVolumeMesh(MeshT _mesh, quint32 _index,
OpenMesh::Vec3d _normal)
733 template <
typename MeshT>
734 void FileVTKPlugin::addFaceNormalToOpenVolumeMesh(MeshT _mesh, quint32 _index,
OpenMesh::Vec3d _normal)
740 if (hfh == _mesh->halfface_handle(fh, 0))
741 faceNormals[fh] = _normal;
743 faceNormals[fh] = -_normal;
747 template <
typename MeshT>
750 int incidentFaces = _mesh.cell(_cellHandle).halffaces().
size();
751 int incidentVertices = 0;
755 if ((incidentFaces == 4) && (incidentVertices == 4))
757 else if ((incidentFaces == 6) && (incidentVertices == 8))
759 else if ((incidentFaces == 5) && (incidentVertices == 6))
761 else if ((incidentFaces == 5) && (incidentVertices == 5))
767 template <
typename MeshT>
770 std::vector<OpenVolumeMesh::HalfEdgeHandle> halfedges = _mesh.face(_faceHandle).halfedges();
771 if (halfedges.size() == 3)
777 template <
typename MeshT>
786 std::vector<OpenVolumeMesh::HalfEdgeHandle> halfedges = face.halfedges();
787 std::vector<int> indices;
788 for (
unsigned int i = 0; i < halfedges.size(); i++)
789 indices.push_back(_mesh.halfedge(halfedges[i]).from_vertex().idx());
791 if ((cvit->idx() != indices[0]) && ((*cvit).idx() != indices[1]) && ((*cvit).idx() != indices[2]))
792 indices.push_back(cvit->idx());
795 else if (_cellType == 12)
802 std::vector<int> indices;
803 for (
unsigned int i = 0; i < 4; i++)
806 indices.push_back(edge.from_vertex().idx());
807 heh = _mesh.next_halfedge_in_halfface(heh, hfh);
812 heh = _mesh.opposite_halfedge_handle(heh);
813 heh = _mesh.next_halfedge_in_halfface(heh, intermediateHalfFaceHandle);
814 heh = _mesh.next_halfedge_in_halfface(heh, intermediateHalfFaceHandle);
816 heh = _mesh.opposite_halfedge_handle(heh);
819 for (
unsigned int i = 0; i < 4; i++)
822 indices.push_back(edge.to_vertex().idx());
823 heh = _mesh.prev_halfedge_in_halfface(heh, oppositeHalfFaceHandle);
827 else if (_cellType == 13)
832 for (
unsigned int i = 0; i < cell.halffaces().size(); i++)
833 if (_mesh.halfface(cell.halffaces()[i]).halfedges().size() == 3)
834 hfh = cell.halffaces()[i];
837 std::vector<int> indices;
838 for (
unsigned int i = 0; i < 3; i++)
841 indices.push_back(edge.from_vertex().idx());
842 heh = _mesh.prev_halfedge_in_halfface(heh, hfh);
847 heh = _mesh.opposite_halfedge_handle(heh);
848 heh = _mesh.next_halfedge_in_halfface(heh, intermediateHalfFaceHandle);
849 heh = _mesh.next_halfedge_in_halfface(heh, intermediateHalfFaceHandle);
851 heh = _mesh.opposite_halfedge_handle(heh);
854 for (
unsigned int i = 0; i < 3; i++)
857 indices.push_back(edge.to_vertex().idx());
858 heh = _mesh.next_halfedge_in_halfface(heh, oppositeHalfFaceHandle);
863 else if (_cellType == 14)
868 std::vector<OpenVolumeMesh::HalfFaceHandle> halffaces = cell.halffaces();
870 for (
unsigned int i = 0; i < halffaces.size(); i++)
871 if (_mesh.halfface(halffaces[i]).halfedges().size() == 4)
872 face = _mesh.halfface(halffaces[i]);
873 std::vector<OpenVolumeMesh::HalfEdgeHandle> halfedges = face.halfedges();
874 std::vector<int> indices;
875 for (
unsigned int i = 0; i < halfedges.size(); i++)
876 indices.push_back(_mesh.halfedge(halfedges[i]).from_vertex().idx());
878 if ((cvit->idx() != indices[0]) && ((*cvit).idx() != indices[1]) && ((*cvit).idx() != indices[2]) && ((*cvit).idx() != indices[3]))
879 indices.push_back(cvit->idx());
883 return std::vector<int>();
886 template <
typename MeshT>
887 bool FileVTKPlugin::writeASCIIDataOfOpenVolumeMesh(std::ostream& _out, MeshT& _mesh)
889 if ( !OpenFlipper::Options::savingSettings() && saveOptions_ != 0)
890 _out.precision(savePrecision_->value());
892 _out <<
"DATASET UNSTRUCTURED_GRID\n";
899 _out <<
"POINTS " << _mesh.n_vertices() <<
" float\n";
900 for (; vit != end_vit; ++vit) {
903 _out << p[0] <<
" " << p[1] <<
" " << p[2];
919 quint32 listSize = 0;
922 int cellType = getCellType(_mesh, *cit);
926 else if (cellType == 12 )
928 else if (cellType == 13 )
930 else if (cellType == 14 )
937 std::vector<OpenVolumeMesh::HalfFaceHandle> halffaces = _mesh.cell(*cit).halffaces();
938 for (
unsigned int i = 0; i < halffaces.size(); i++)
941 if (!(fpAlreadyStored[fh]))
945 if (!(userWriteOptions_ & FileVTKPlugin::FACENORMALS))
946 fpAlreadyStored[fh] =
true;
949 for (std::vector<OpenVolumeMesh::HalfEdgeHandle>::const_iterator heit = face.halfedges().begin();
950 heit != face.halfedges().end();
953 epAlreadyStored[_mesh.edge_handle(*heit)] =
true;
961 if (!(fpAlreadyStored[*fit]))
964 std::vector<OpenVolumeMesh::HalfEdgeHandle> halfedges = _mesh.face(*fit).halfedges();
965 for (
unsigned int i = 0; i < halfedges.size(); i++)
966 epAlreadyStored[_mesh.edge_handle(halfedges[i])] =
true;
969 listSize += 1 + halfedges.size();
977 if (!(epAlreadyStored[*eit]))
984 _out <<
"CELLS " << cellCount <<
" " << listSize <<
"\n";
993 int cellType = getCellType(_mesh, *cit);
998 else if (cellType == 12 )
1000 else if (cellType == 13 )
1002 else if (cellType == 14 )
1011 std::vector<int> indices = getCellVertexIndices(_mesh, *cit, cellType);
1012 _out << indices.size();
1013 for (
unsigned int i = 0; i < indices.size(); i++)
1014 _out <<
" " << indices[i];
1024 if (!(fpAlreadyStored[*fit]))
1026 std::vector<OpenVolumeMesh::HalfEdgeHandle> halfedges = _mesh.face(*fit).halfedges();
1028 _out << halfedges.size();
1029 for (
unsigned int i = 0; i < halfedges.size(); i++)
1033 _out <<
" " << edge.from_vertex().idx();
1045 if (!(epAlreadyStored[*eit]))
1049 _out <<
" " << edge.from_vertex().idx();
1050 _out <<
" " << edge.to_vertex().idx();
1059 _out <<
"CELL_TYPES " << cellCount <<
"\n";
1064 int cellType = getCellType(_mesh, *cit);
1068 _out << cellType <<
"\n";
1075 if (!(fpAlreadyStored[*fit]))
1077 int cellType = getCellType(_mesh,*fit);
1081 _out << cellType <<
"\n";
1089 if (!(epAlreadyStored[*eit]))
1106 if ((userWriteOptions_ & FileVTKPlugin::VERTEXNORMALS))
1108 _out <<
"POINT_DATA "<< _mesh.n_vertices() <<
"\n";
1111 _out <<
"NORMALS vertex_normals float\n";
1114 _out << n[0] <<
" " << n[1] <<
" " << n[2];
1121 if ((userWriteOptions_ & FileVTKPlugin::FACENORMALS))
1123 _out <<
"CELL_DATA "<< cellCount <<
"\n";
1124 _out <<
"NORMALS face_normals float\n";
1129 int cellType = getCellType(_mesh, *cit);
1131 if (cellType == -1 )
1135 _out << 1 <<
" " << 0 <<
" " << 0;
1146 _out << n[0] <<
" " << n[1] <<
" " << n[2];
1154 if (!(epAlreadyStored[*eit]))
1156 _out << 1 <<
" " << 0 <<
" " << 0;
1167 #endif //ENABLE_OPENVOLUMEMESH_SUPPORT 1169 #ifdef ENABLE_HEXAHEDRALMESH_SUPPORT 1179 #endif //ENABLE_HEXAHEDRALMESH_SUPPORT 1182 #ifdef ENABLE_POLYHEDRALMESH_SUPPORT 1192 #endif //ENABLE_POLYHEDRALMESH_SUPPORT 1195 #ifdef ENABLE_TETRAHEDRALMESH_SUPPORT 1205 #endif //ENABLE_TETRAHEDRALMESH_SUPPORT 1215 QFile file(_filename);
1217 if ( !file.open(QIODevice::ReadOnly) ) {
1221 QTextStream in(&file);
1223 QString line = in.readLine();
1226 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) 1227 QStringList header = line.split(
" ",QString::SkipEmptyParts);
1229 QStringList header = line.split(
" ",Qt::SkipEmptyParts);
1232 if ( header.size() != 5 ) {
1236 QString version = header[4];
1238 header.removeLast();
1240 QString magic = header.join(
" ");
1242 if ( magic !=
"# vtk DataFile Version" ) {
1248 QString fileTypeStr = in.readLine();
1250 fileTypeStr = fileTypeStr.simplified();
1252 if ( fileTypeStr.toLower() ==
"binary" ) {
1254 }
else if ( fileTypeStr.toLower() ==
"ascii" ) {
1262 while ( line.simplified() ==
"" )
1263 line = in.readLine();
1265 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) 1266 QStringList datasetList = line.split(
" ",QString::SkipEmptyParts);
1268 QStringList datasetList = line.split(
" ",Qt::SkipEmptyParts);
1273 if ( datasetList.size() != 2 ) {
1279 datasetList[1] = datasetList[1].simplified();
1281 if ( datasetList[1] ==
"STRUCTURED_POINTS" )
1282 dataset = STRUCTURED_POINTS;
1283 else if ( datasetList[1] ==
"STRUCTURED_GRID" )
1284 dataset = STRUCTURED_GRID;
1285 else if ( datasetList[1] ==
"RECTILINEAR_GRID" )
1286 dataset = RECTILINEAR_GRID;
1287 else if ( datasetList[1] ==
"POLYDATA" )
1289 else if ( datasetList[1] ==
"UNSTRUCTURED_GRID" )
1290 dataset = UNSTRUCTURED_GRID;
1296 if ((dataset == STRUCTURED_POINTS) || (dataset == STRUCTURED_GRID) || (dataset == RECTILINEAR_GRID) )
1301 else if (dataset == POLYDATA)
1308 line = in.readLine();
1311 while ( !line.contains(
"POLYGONS") ) {
1319 line = in.readLine();
1322 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) 1323 QStringList polygonsLine = line.split(
" ",QString::SkipEmptyParts);
1325 QStringList polygonsLine = line.split(
" ",Qt::SkipEmptyParts);
1330 if ( polygonsLine.size() != 3 ) {
1331 emit log(
LOGERR,tr(
"Expected to get Points line with exactly 3 entries, but %1 found!").arg(polygonsLine.size()));
1338 quint32 polygoncount = polygonsLine[1].toUInt(&ok);
1341 emit log(
LOGERR,tr(
"Expected to get number of points and entries, but read %1 !").arg(polygonsLine.join(
" ")));
1346 while ( read < polygoncount) {
1353 in.device()->read((
char*)&valence,
sizeof(quint32));
1358 return BMT_PolyMesh;
1364 for (
unsigned int i = 0 ; i < valence; ++i ) {
1370 in.device()->read((
char*)&valence,
sizeof(quint32));
1386 line = in.readLine();
1389 while ( !line.contains(
"CELL_TYPES") ) {
1397 line = in.readLine();
1401 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) 1402 QStringList cellLine = line.split(
" ",QString::SkipEmptyParts);
1404 QStringList cellLine = line.split(
" ",Qt::SkipEmptyParts);
1409 if ( cellLine.size() != 2 ) {
1410 emit log(
LOGERR,tr(
"Expected to get CELL_TYPES line with exactly 2 entries, but %1 found!").arg(cellLine.size()));
1417 quint32 cellCountTypes = cellLine[1].toUInt(&ok);
1420 emit log(
LOGERR,tr(
"Expected to get number of cell types, but read %1 !").arg(cellLine[1]));
1424 bool triMeshPossible =
true;
1425 bool polyMeshPossible =
true;
1427 #ifndef ENABLE_HEXAHEDRALMESH_SUPPORT 1428 bool hexahedralMeshPossible =
false;
1430 bool hexahedralMeshPossible =
true;
1432 #ifndef ENABLE_POLYHEDRALMESH_SUPPORT 1433 bool polyhedralMeshPossible =
false;
1435 bool polyhedralMeshPossible =
true;
1437 #ifndef ENABLE_TETRAHEDRALMESH_SUPPORT 1438 bool tetrahedralMeshPossible =
false;
1440 bool tetrahedralMeshPossible =
true;
1444 while ( read < cellCountTypes) {
1451 in.device()->read((
char*)&type,
sizeof(quint32));
1454 if (( 1 <= type ) && (type <= 6 ))
1458 hexahedralMeshPossible =
false;
1459 tetrahedralMeshPossible =
false;
1461 else if (( 7 <= type ) && (type <= 9 ))
1466 triMeshPossible =
false;
1467 hexahedralMeshPossible =
false;
1468 tetrahedralMeshPossible =
false;
1471 else if ( 10 == type )
1474 triMeshPossible =
false;
1475 polyMeshPossible =
false;
1476 hexahedralMeshPossible =
false;
1478 else if (( 13 == type ) || (type == 14 ))
1482 triMeshPossible =
false;
1483 polyMeshPossible =
false;
1484 hexahedralMeshPossible =
false;
1485 tetrahedralMeshPossible =
false;
1488 else if (( 11 == type ) || ( 12 == type ))
1492 triMeshPossible =
false;
1493 polyMeshPossible =
false;
1497 if ( in.status() != QTextStream::Ok ) {
1498 emit log(
LOGERR,tr(
"Read corrupted cell type data!"));
1504 if (triMeshPossible)
1506 else if (polyMeshPossible)
1507 return BMT_PolyMesh;
1508 else if (hexahedralMeshPossible)
1509 return BMT_HexahedralMesh;
1510 else if (tetrahedralMeshPossible)
1511 return BMT_TetrahedralMesh;
1512 else if (polyhedralMeshPossible)
1513 return BMT_PolyhedralMesh;
1524 std::cerr <<
"Loading vtk file" << std::endl;
1528 QFile file(_filename);
1530 if ( !file.open(QIODevice::ReadOnly) ) {
1531 emit log(
LOGERR,
"Unable to open vtk file!");
1535 QTextStream in(&file);
1537 std::cerr <<
"File is open!" << std::endl;
1539 QString line = in.readLine();
1541 std::cerr <<
"Got line: " << std::endl;
1542 std::cerr << line.toStdString() << std::endl;
1543 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) 1544 QStringList header = line.split(
" ",QString::SkipEmptyParts);
1546 QStringList header = line.split(
" ",Qt::SkipEmptyParts);
1550 if ( header.size() != 5 ) {
1551 emit log(
LOGERR,tr(
"Bad VTK header? ") + line);
1555 QString version = header[4];
1557 header.removeLast();
1559 QString magic = header.join(
" ");
1561 if ( magic !=
"# vtk DataFile Version" ) {
1562 emit log(
LOGERR,tr(
"Bad VTK header magic? ") + magic);
1568 QString fileTypeStr = in.readLine();
1570 fileTypeStr = fileTypeStr.simplified();
1572 if ( fileTypeStr.toLower() ==
"binary" ) {
1574 emit log(
LOGINFO,tr(
"Loading VTK binary file of version %1.").arg(version));
1575 emit log(
LOGERR,tr(
"Not yet implemented!"));
1576 }
else if ( fileTypeStr.toLower() ==
"ascii" ) {
1578 emit log(
LOGINFO,tr(
"Loading VTK ascii file of version %1.").arg(version));
1580 emit log(
LOGERR,tr(
"Bad VTK type? ") + fileTypeStr);
1584 emit log(
LOGINFO,description);
1588 while ( line.simplified() ==
"" )
1589 line = in.readLine();
1591 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) 1592 QStringList datasetList = line.split(
" ",QString::SkipEmptyParts);
1594 QStringList datasetList = line.split(
" ",Qt::SkipEmptyParts);
1596 if ( datasetList.size() != 2 ) {
1597 emit log(
LOGERR,tr(
"Bad dataset specification!"));
1603 datasetList[1] = datasetList[1].simplified();
1605 if ( datasetList[1] ==
"STRUCTURED_POINTS" )
1606 dataset = STRUCTURED_POINTS;
1607 else if ( datasetList[1] ==
"STRUCTURED_GRID" )
1608 dataset = STRUCTURED_GRID;
1609 else if ( datasetList[1] ==
"RECTILINEAR_GRID" )
1610 dataset = RECTILINEAR_GRID;
1611 else if ( datasetList[1] ==
"POLYDATA" )
1613 else if ( datasetList[1] ==
"UNSTRUCTURED_GRID" )
1614 dataset = UNSTRUCTURED_GRID;
1616 emit log(
LOGERR,tr(
"Unknown dataset specification! %1").arg(datasetList[1]));
1621 bool is_OpenVolumeMesh =
false;
1623 if ( (forceTriangleMesh_) || (bestType == BMT_TriMesh) ){
1637 if ( !loadMesh(in,_mesh,dataset) ) {
1638 emit log(
LOGERR,
"Unable to load mesh!");
1642 emit log(
LOGERR,
"Unable to add empty triangle mesh!");
1652 else if ((bestType == BMT_PolyMesh) || (bestType == BMT_None))
1667 if ( !loadMesh(in,_mesh,dataset) ) {
1668 emit log(
LOGERR,
"Unable to load mesh!");
1672 emit log(
LOGERR,
"Unable to add empty poly mesh!");
1682 #ifdef ENABLE_POLYHEDRALMESH_SUPPORT 1683 else if (bestType == BMT_PolyhedralMesh)
1686 is_OpenVolumeMesh =
true;
1698 if ( !loadMesh(in,_mesh,dataset) ) {
1699 emit log(
LOGERR,
"Unable to load mesh!");
1703 emit log(
LOGERR,
"Unable to add empty polyhedral mesh!");
1711 #endif //ENABLE_POLYHEDRALMESH_SUPPORT 1712 #ifdef ENABLE_HEXAHEDRALMESH_SUPPORT 1713 else if (bestType == BMT_HexahedralMesh)
1716 is_OpenVolumeMesh =
true;
1728 if ( !loadMesh(in,_mesh,dataset) ) {
1729 emit log(
LOGERR,
"Unable to load mesh!");
1733 emit log(
LOGERR,
"Unable to add empty hexahedral mesh!");
1740 #endif //ENABLE_HEXAHEDRALMESH_SUPPORT 1741 #ifdef ENABLE_TETRAHEDRALMESH_SUPPORT 1742 else if (bestType == BMT_TetrahedralMesh)
1745 is_OpenVolumeMesh =
true;
1757 if ( !loadMesh(in,_mesh,dataset) ) {
1758 emit log(
LOGERR,
"Unable to load mesh!");
1762 emit log(
LOGERR,
"Unable to add empty tetrahedral mesh!");
1769 #endif //ENABLE_TETRAHEDRALMESH_SUPPORT 1776 if (is_OpenVolumeMesh)
1785 emit openedFile( baseObj->
id() );
1787 return baseObj->
id();
1790 emit log(
LOGERR,tr(
"Error in load mesh!"));
1797 template <
typename MeshT>
1800 std::cerr <<
"loadMeshPoints" << std::endl;
1805 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) 1806 QStringList pointsLine = _spec.split(
" ",QString::SkipEmptyParts);
1808 QStringList pointsLine = _spec.split(
" ",Qt::SkipEmptyParts);
1813 if ( pointsLine.size() != 3 ) {
1814 emit log(
LOGERR,tr(
"Expected to get Points line with exactly 3 entries, but %1 found!").arg(pointsLine.size()));
1819 quint32 points = pointsLine[1].toUInt(&ok);
1822 emit log(
LOGERR,tr(
"Expected to get number of points, but read %1 !").arg(pointsLine[1]));
1830 while ( read < points ) {
1836 if ( pointsLine[2] ==
"float" ) {
1839 _in.device()->read((
char*)&vecf[0],
sizeof(
float));
1840 _in.device()->read((
char*)&vecf[1],
sizeof(
float));
1841 _in.device()->read((
char*)&vecf[2],
sizeof(
float));
1846 emit log(
LOGERR,tr(
"Not implemented data type %1 !").arg(pointsLine[2]));
1852 _in >> vec[0] >> vec[1] >> vec[2];
1859 if ( _in.status() == QTextStream::Ok ) {
1860 _mesh->add_vertex(vec);
1862 emit log(
LOGERR,tr(
"Read corrupted point data!"));
1869 if ( pointsLine[2] ==
"float" ) {
1872 _in.seek(_in.pos() + read * 3 *
sizeof(float) /
sizeof(
char) );
1880 template <
typename MeshT>
1882 std::cerr <<
"loadMeshLines" << std::endl;
1887 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) 1888 QStringList linesLine = _spec.split(
" ",QString::SkipEmptyParts);
1890 QStringList linesLine = _spec.split(
" ",Qt::SkipEmptyParts);
1895 if ( linesLine.size() != 3 ) {
1896 emit log(
LOGERR,tr(
"Expected to get LINES line with exactly 3 entries, but %1 found!").arg(linesLine.size()));
1901 quint32 linecount = linesLine[1].toUInt(&ok);
1904 quint32 entrycount = linesLine[2].toUInt(&ok);
1907 emit log(
LOGERR,tr(
"Expected to get number of lines and entries, but read %1 !").arg(linesLine.join(
" ")));
1913 while ( read < linecount) {
1921 _in.device()->read((
char*)&valence,
sizeof(quint32));
1926 if ( _in.status() == QTextStream::Ok ) {
1929 for (
unsigned int i = 0 ; i < valence; ++i )
1932 for (
unsigned int i = 0 ; i < valence; ++i )
1933 _in.device()->read((
char*)&valence,
sizeof(quint32));
1936 if ( _in.status() == QTextStream::Ok ) {
1941 emit log(
LOGERR,tr(
"Read corrupted face data!"));
1946 emit log(
LOGERR,tr(
"Read corrupted POLYGONS data!"));
1956 _in.seek(_in.pos() + entrycount *
sizeof(quint32) /
sizeof(
char) );
1959 emit log(
LOGWARN,tr(
"Lines not supported yet ... skipped!"));
1964 template <
typename MeshT>
1966 std::cerr <<
"loadMeshPolygons" << std::endl;
1971 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) 1972 QStringList polygonsLine = _spec.split(
" ",QString::SkipEmptyParts);
1974 QStringList polygonsLine = _spec.split(
" ",Qt::SkipEmptyParts);
1979 if ( polygonsLine.size() != 3 ) {
1980 emit log(
LOGERR,tr(
"Expected to get Points line with exactly 3 entries, but %1 found!").arg(polygonsLine.size()));
1985 quint32 polygoncount = polygonsLine[1].toUInt(&ok);
1988 quint32 entrycount = polygonsLine[2].toUInt(&ok);
1991 emit log(
LOGERR,tr(
"Expected to get number of points and entries, but read %1 !").arg(polygonsLine.join(
" ")));
1996 bool errorEnabled = omerr().is_enabled();
2000 while ( read < polygoncount) {
2007 _in.device()->read((
char*)&valence,
sizeof(quint32));
2011 std::vector< quint32 > indices;
2013 for (
unsigned int i = 0 ; i < valence; ++i ) {
2019 _in.device()->read((
char*)&valence,
sizeof(quint32));
2022 indices.push_back( index );
2025 if ( _in.status() == QTextStream::Ok ) {
2028 remove_duplicated_vertices(indices);
2030 if (indices.size() >= 3)
2034 cell.indices = indices;
2035 cell.index =
addFace(_mesh, indices);
2036 _cells.push_back(cell);
2039 emit log(
LOGERR,tr(
"Read corrupted face data!"));
2057 _in.seek(_in.pos() + entrycount *
sizeof(qint32) /
sizeof(
char) );
2063 template <
typename MeshT>
2068 if (_vhandles.empty())
return -1;
2071 if (! _mesh->get_property_handle(originalVertexIdx,
"FileVTKPlugin_originalVertexIdx")) {
2072 _mesh->add_property( originalVertexIdx,
"FileVTKPlugin_originalVertexIdx" );
2075 typename MeshT::VertexIter vit = _mesh->vertices_begin();
2076 typename MeshT::VertexIter vend = _mesh->vertices_end();
2077 for(; vit != vend; ++vit) {
2083 for (
unsigned int j = 0; j < _vhandles.size(); ++j)
2085 typename MeshT::Point p = _mesh->point(_vhandles[j]);
2087 _vhandles[j] = _mesh->add_vertex(p);
2092 if (_mesh->has_vertex_status()) {
2093 _mesh->status(_vhandles[j]).set_fixed_nonmanifold(
true);
2096 _mesh->property (originalVertexIdx, _vhandles[j]) = original_handle;
2103 if (_mesh->has_face_status())
2104 _mesh->status(fh).set_fixed_nonmanifold(
true);
2107 if (_mesh->has_edge_status()) {
2108 typename MeshT::FaceEdgeIter fe_it = _mesh->fe_iter(fh);
2109 for (; fe_it.is_valid(); ++fe_it) {
2110 _mesh->status(*fe_it).set_fixed_nonmanifold(
true);
2118 template <
typename MeshT>
2120 std::cerr <<
"loadMeshTriangleStrips" << std::endl;
2125 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) 2126 QStringList triStripsLine = _spec.split(
" ",QString::SkipEmptyParts);
2128 QStringList triStripsLine = _spec.split(
" ",Qt::SkipEmptyParts);
2133 if ( triStripsLine.size() != 3 ) {
2134 emit log(
LOGERR,tr(
"Expected to get TRIANGLE_STRIPS line with exactly 3 entries, but %1 found!").arg(triStripsLine.size()));
2139 quint32 stripcount = triStripsLine[1].toUInt(&ok);
2142 quint32 entrycount = triStripsLine[2].toUInt(&ok);
2145 emit log(
LOGERR,tr(
"Expected to get number of strips and entries, but read %1 !").arg(triStripsLine.join(
" ")));
2150 while ( read < stripcount) {
2157 _in.device()->read((
char*)&valence,
sizeof(quint32));
2161 QList< quint32 > indices;
2164 for (
unsigned int i = 0 ; i < 2; ++i ) {
2170 _in.device()->read((
char*)&valence,
sizeof(quint32));
2173 indices.push_back( index );
2177 for (
unsigned int i = 2 ; i < valence; ++i ) {
2183 _in.device()->read((
char*)&valence,
sizeof(quint32));
2186 indices.push_back( index );
2188 if ( _in.status() == QTextStream::Ok ) {
2192 cell.indices.resize(3);
2193 cell.indices[0] = indices[i];
2194 cell.indices[1] = indices[i-1];
2195 cell.indices[2] = indices[i-2];
2197 std::swap(cell.indices[1],cell.indices[2]);
2198 cell.index =
addFace(_mesh, cell.indices);
2199 _cells.push_back(cell);
2201 emit log(
LOGERR,tr(
"Read corrupted face data!"));
2215 _in.seek(_in.pos() + entrycount *
sizeof(qint32) /
sizeof(
char) );
2221 template <
typename MeshT>
2223 std::cerr <<
"loadMeshNormals" << std::endl;
2226 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) 2227 QStringList normalsLine = _spec.split(
" ",QString::SkipEmptyParts);
2229 QStringList normalsLine = _spec.split(
" ",Qt::SkipEmptyParts);
2235 if ( normalsLine.size() != 3 ) {
2236 emit log(
LOGERR,tr(
"Expected to get NORMALS line with exactly 3 entries, but %1 found!").arg(normalsLine.size()));
2244 while ( read < _count) {
2249 if ( normalsLine[2] ==
"float" ) {
2253 _in.device()->read((
char*)&vecf[0],
sizeof(
float));
2254 _in.device()->read((
char*)&vecf[1],
sizeof(
float));
2255 _in.device()->read((
char*)&vecf[2],
sizeof(
float));
2260 emit log(
LOGERR,tr(
"Not implemented data type %1 !").arg(normalsLine[2]));
2266 _in >> normal[0] >> normal[1] >> normal[2];
2270 if ( _in.status() == QTextStream::Ok ) {
2272 if ( _pointNormal ) {
2280 emit log(
LOGERR,tr(
"Read corrupted point data!"));
2289 if ( normalsLine[2] ==
"float" ) {
2292 _in.seek(_in.pos() + read * 3 *
sizeof(float) /
sizeof(
char) );
2302 template <
typename MeshT>
2305 std::cerr <<
"loadMeshCells" << std::endl;
2308 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) 2309 QStringList cellLine = _spec.split(
" ",QString::SkipEmptyParts);
2311 QStringList cellLine = _spec.split(
" ",Qt::SkipEmptyParts);
2316 if ( cellLine.size() != 3 ) {
2317 emit log(
LOGERR,tr(
"Expected to get CELLS line with exactly 3 entries, but %1 found!").arg(cellLine.size()));
2324 quint32 cellCount = cellLine[1].toUInt(&ok);
2327 quint32 entryCount = cellLine[2].toUInt(&ok);
2331 emit log(
LOGERR,tr(
"Expected to get number of cells and entries, but read %1 !").arg(cellLine.join(
" ")));
2336 while ( read < cellCount) {
2345 _in.device()->read((
char*)&valence,
sizeof(quint32));
2350 for (
unsigned int i = 0 ; i < valence; ++i ) {
2356 _in.device()->read((
char*)&valence,
sizeof(quint32));
2359 currentCell.indices.push_back( index );
2362 if ( _in.status() == QTextStream::Ok ) {
2363 _cells.push_back(currentCell);
2365 emit log(
LOGERR,tr(
"Read corrupted face data!"));
2375 _in.seek(_in.pos() + entryCount *
sizeof(quint32) /
sizeof(
char) );
2387 while ( _spec.simplified().size() == 0 ) {
2390 if ( _in.atEnd() ) {
2391 emit log(
LOGERR,tr(
"File end when reading cell specification!"));
2395 _spec = _in.readLine();
2398 if ( ! _spec.contains(
"CELL_TYPES") ) {
2399 emit log(
LOGERR,tr(
"Wrong token! Expected CELL_TYPES but got : %1").arg(_spec));
2404 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) 2405 cellLine = _spec.split(
" ",QString::SkipEmptyParts);
2407 cellLine = _spec.split(
" ",Qt::SkipEmptyParts);
2412 if ( cellLine.size() != 2 ) {
2413 emit log(
LOGERR,tr(
"Expected to get CELL_TYPES line with exactly 2 entries, but %1 found!").arg(cellLine.size()));
2418 quint32 cellCountTypes = cellLine[1].toUInt(&ok);
2421 emit log(
LOGERR,tr(
"Expected to get number of cell types, but read %1 !").arg(cellLine[1]));
2425 if (cellCountTypes != cellCount ) {
2426 emit log(
LOGERR,tr(
"cellCountTypes != cellCount !").arg(cellLine.size()));
2431 while ( read < cellCount) {
2438 _in.device()->read((
char*)&type,
sizeof(quint32));
2442 _cells[read].type = type;
2444 if ( _in.status() != QTextStream::Ok ) {
2445 emit log(
LOGERR,tr(
"Read corrupted cell type data!"));
2454 _in.seek(_in.pos() + read *
sizeof(quint32) /
sizeof(
char) );
2462 for (
unsigned int i = 0 ; i < _cells.size() ; ++i ) {
2463 if ( _cells[i].type == 1 ) {
2468 }
else if ( _cells[i].type == 2 ) {
2473 }
else if ( _cells[i].type == 3 ) {
2476 emit log(
LOGWARN,tr(
"Unsupported Cell Type LINE") );
2478 }
else if ( _cells[i].type == 4 ) {
2481 emit log(
LOGWARN,tr(
"Unsupported Cell Type POLY_LINE") );
2483 }
else if ( _cells[i].type == 5 ) {
2485 _cells[i].index =
addFace(_mesh, _cells[i].indices);
2486 }
else if ( _cells[i].type == 6 ) {
2489 for (
unsigned int j = 2 ; j < _cells[i].indices.size() ; ++j) {
2491 _cells[i].index =
addFace(_mesh, _cells[i].indices[j-2],_cells[i].indices[j],_cells[i].indices[j-1]);
2493 _cells[i].index =
addFace(_mesh, _cells[i].indices[j-2],_cells[i].indices[j-1],_cells[i].indices[j]);
2498 }
else if ( _cells[i].type == 7 ) {
2501 _cells[i].index =
addFace(_mesh, _cells[i].indices);
2503 }
else if ( _cells[i].type == 8 ) {
2506 emit log(
LOGWARN,tr(
"Unsupported Cell Type PIXEL") );
2508 }
else if ( _cells[i].type == 9 ) {
2511 _cells[i].index =
addFace(_mesh, _cells[i].indices);
2513 }
else if ( _cells[i].type == 10 ) {
2515 _cells[i].index =
addTetraCell(_mesh, _cells[i].indices);
2517 }
else if ( _cells[i].type == 11 ) {
2520 emit log(
LOGWARN,tr(
"Unsupported Cell Type VOXEL") );
2522 }
else if ( _cells[i].type == 12 ) {
2525 _cells[i].index =
addHexaCell(_mesh, _cells[i].indices);
2526 }
else if ( _cells[i].type == 13 ) {
2529 _cells[i].index =
addWedgeCell(_mesh, _cells[i].indices);
2530 }
else if ( _cells[i].type == 14 ) {
2536 emit log(
LOGERR,tr(
"Unknown cell type").arg(_cells[i].type) );
2540 std::cerr <<
"Read " << read <<
" Cells " << std::endl;
2541 std::cerr <<
"Vector has size: " << _cells.size() << std::endl;
2547 template <
typename MeshT>
2548 bool FileVTKPlugin::loadMesh(QTextStream& _in,MeshT*& _mesh, Dataset _type){
2551 if ( _type != POLYDATA && _type != UNSTRUCTURED_GRID ) {
2552 emit log(
LOGERR,
"Unsupported DATASET" );
2561 bool pointNormalsRead =
false;
2562 bool faceNormalsRead =
false;
2565 bool pointData =
false;
2568 quint32 pointDataSize = 0;
2571 bool cellData =
false;
2574 quint32 cellDataSize = 0;
2576 std::vector<CellType> cells;
2580 line = _in.readLine();
2583 while ( line.simplified().size() == 0 ) {
2586 if ( _in.atEnd() ) {
2588 std::cerr <<
"atEnd" << std::endl;
2592 line = _in.readLine();
2599 std::cerr <<
"Line is: " << line.toStdString() << std::endl;
2602 if ( line.contains(
"POINTS") ) {
2605 }
else if ( line.contains(
"POINT_DATA") ) {
2608 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) 2609 QStringList pointDataLine = line.split(
" ",QString::SkipEmptyParts);
2611 QStringList pointDataLine = line.split(
" ",Qt::SkipEmptyParts);
2616 if ( pointDataLine.size() != 2 ) {
2617 emit log(
LOGERR,tr(
"Expected to get POINT_DATA line with exactly 2 entries, but %1 found!").arg(line.size()));
2622 pointDataSize = pointDataLine[1].toUInt(&ok);
2627 std::cerr <<
"Point data mode with " << pointDataSize <<
"Elements" << std::endl;
2629 }
else if ( line.contains(
"CELL_DATA") ) {
2632 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) 2633 QStringList cellDataLine = line.split(
" ",QString::SkipEmptyParts);
2635 QStringList cellDataLine = line.split(
" ",Qt::SkipEmptyParts);
2639 if ( cellDataLine.size() != 2 ) {
2640 emit log(
LOGERR,tr(
"Expected to get CELL_DATA line with exactly 2 entries, but %1 found!").arg(line.size()));
2645 cellDataSize = cellDataLine[1].toUInt(&ok);
2650 std::cerr <<
"Cell data mode with " << cellDataSize <<
"Elements" << std::endl;
2652 }
else if ( line.contains(
"VERTICES") ) {
2653 std::cerr <<
"Vertices will be skipped as they are already added!" << std::endl;
2654 }
else if ( line.contains(
"LINES") ) {
2656 }
else if ( line.contains(
"POLYGONS") ) {
2658 }
else if ( line.contains(
"TRIANGLE_STRIPS") ) {
2660 }
else if ( line.contains(
"CELL") ) {
2662 }
else if ( line.contains(
"NORMALS") ) {
2666 pointNormalsRead =
true;
2667 }
else if (cellData) {
2669 faceNormalsRead =
true;
2671 emit log(
LOGERR,tr(
"Got normals keyword but we are neither in pointdata nor celldata mode") );
2676 std::cerr <<
"Unrecognized keyword : " << line.toStdString() << std::endl;
2681 if ( !faceNormalsRead )
2684 if ( !pointNormalsRead )
2698 forceTriangleMesh_ =
true;
2700 forcePolyMesh_ =
true;
2707 bool FileVTKPlugin::saveObject(
int _id, QString _filename) {
2711 emit log(
LOGERR, tr(
"saveObject : cannot get object id %1 for save name %2").arg(_id).arg(_filename) );
2715 std::string filename = std::string( _filename.toUtf8() );
2717 std::fstream ofs( filename.c_str(), std::ios_base::out );
2721 emit log(
LOGERR, tr(
"saveObject : Cannot not open file %1 for writing!").arg(_filename) );
2730 object->setFromFileName(_filename);
2731 object->setName(object->
filename());
2736 emit log(
LOGINFO, tr(
"Saved object to ") + _filename );
2740 emit log(
LOGERR, tr(
"Unable to save ") + _filename);
2746 object->setFromFileName(_filename);
2747 object->setName(object->
filename());
2752 emit log(
LOGINFO, tr(
"Saved object to ") + _filename );
2756 emit log(
LOGERR, tr(
"Unable to save ") + _filename);
2761 #ifdef ENABLE_POLYHEDRALMESH_SUPPORT 2765 object->setFromFileName(_filename);
2766 object->setName(object->
filename());
2771 emit log(
LOGINFO, tr(
"Saved object to ") + _filename );
2775 emit log(
LOGERR, tr(
"Unable to save ") + _filename);
2781 #ifdef ENABLE_HEXAHEDRALMESH_SUPPORT 2785 object->setFromFileName(_filename);
2786 object->setName(object->
filename());
2791 emit log(
LOGINFO, tr(
"Saved object to ") + _filename );
2795 emit log(
LOGERR, tr(
"Unable to save ") + _filename);
2801 #ifdef ENABLE_TETRAHEDRALMESH_SUPPORT 2805 object->setFromFileName(_filename);
2806 object->setName(object->
filename());
2811 emit log(
LOGINFO, tr(
"Saved object to ") + _filename );
2815 emit log(
LOGERR, tr(
"Unable to save ") + _filename);
2823 emit log(
LOGERR, tr(
"Unable to save (object is not a compatible mesh type)"));
2832 template<
class MeshT >
2839 _out <<
"# vtk DataFile Version 2.0\n";
2841 _out <<
"Mesh saved from OpenFlipper - www.openflipper.org\n";
2861 if( OpenFlipper::Options::nogui() )
2866 if(saveBinary_->isChecked()) userWriteOptions_ |= BINARY;
2867 else {
if(userWriteOptions_ & BINARY) userWriteOptions_ -= BINARY; }
2869 if(saveFaceNormals_) {
2870 if(saveFaceNormals_->isChecked()) userWriteOptions_ |= FACENORMALS;
2871 else {
if(userWriteOptions_ & FACENORMALS) userWriteOptions_ -= FACENORMALS; }
2873 if(saveVertexNormals_) {
2874 if(saveVertexNormals_->isChecked()) userWriteOptions_ |= VERTEXNORMALS;
2875 else {
if(userWriteOptions_ & VERTEXNORMALS) userWriteOptions_ -= VERTEXNORMALS; }
2877 if(saveVertexTexCoords_) {
2878 if(saveVertexTexCoords_->isChecked()) userWriteOptions_ |= VERTEXTEXCOORDS;
2879 else {
if(userWriteOptions_ & VERTEXTEXCOORDS) userWriteOptions_ -= VERTEXTEXCOORDS; }
Handle for a face entity.
bool writeMesh(std::ostream &_out, MeshT &_mesh)
Writes the header of the VTK file, then calls writeASCIIData (binary VTK is currently unsupported) ...
void slotSaveDefault()
Slot called when user wants to save the given Save options as default.
bool writeASCIIDataOfOpenMesh(std::ostream &_out, MeshT &_mesh)
Writes the data of the VTK file in ASCII format.
#define DATA_POLYHEDRAL_MESH
bool binary_
Reading binary file?
#define DATA_TRIANGLE_MESH
bool loadMeshLines(QString _spec, QTextStream &_in, MeshT *&_mesh)
Reads lines from the stream and adds them to the mesh.
void setNormalsOfDuplicatedVerticesOfOpenMesh(MeshT *&_mesh)
Sets normals of duplicated vertices that were created for non-manifold meshes.
virtual void setName(QString _name) override
path to the file from which the object is loaded ( defaults to "." )
const UpdateType UPDATE_ALL(UpdateTypeSet(1))
Identifier for all updates.
bool loadMeshNormals(QString _spec, QTextStream &_in, MeshT *&_mesh, std::vector< CellType > &_cells, bool _pointNormal, quint32 _count)
Reads Normals from the stream and adds them to the mesh.
Type for a Meshobject containing a poly mesh.
void removeTemporaryPropertiesOfOpenMesh(MeshT *&_mesh)
Removed temporary properties that might have been added during file reading.
int addTetraCell(TriMesh *&_mesh, const std::vector< quint32 > &_indices)
Adds a tetra cell to the mesh. (Does nothing, yet)
void updateVertexNormalsOfOpenMesh(MeshT *&_mesh)
Updates vertex normals.
int idx() const
Get the underlying index of this handle.
bool getObject(const int _identifier, BaseObject *&_object)
Get the object which has the given identifier.
void addFaceNormal(TriMesh *&_mesh, quint32 _index, OpenMesh::Vec3d _normal)
Adds a face normal.
int addPyramidCellToOpenMesh(MeshT _mesh, std::vector< quint32 > _indices)
Adds a pyramid cell to the mesh. (Does nothing, yet)
HexahedralMesh * hexahedralMesh(BaseObjectData *_object)
Get an HexahedralMesh from an object.
#define DATA_TETRAHEDRAL_MESH
bool loadMeshPoints(QString _spec, QTextStream &_in, MeshT *&_mesh)
Reads points from the stream and adds them to the mesh.
#define DATA_HEXAHEDRAL_MESH
QWidget * saveOptionsWidget(QString)
bool loadMeshPolygons(QString _spec, QTextStream &_in, MeshT *&_mesh, std::vector< CellType > &_cells)
Reads polygons from the stream and adds them to the mesh.
const DataType DATA_GROUP(1)
Items used for Grouping.
Add 2D texture coordinates (vertices, halfedges)
Handle for a vertex entity.
void updateFaceNormalsOfOpenMesh(MeshT *&_mesh)
Updates face normals.
QString filename() const
return the filename of the object
bool loadMeshTriangleStrips(QString _spec, QTextStream &_in, MeshT *&_mesh, std::vector< CellType > &_cells)
Reads triangle strips from the stream and adds them to the mesh.
void addCellNormal(MeshT *&_mesh, const CellType &_cell, OpenMesh::Vec3d _normal)
Adds a normal to the cell.
int addFaceToOpenMesh(MeshT *&_mesh, std::vector< quint32 > _indices)
Adds a face to the mesh.
MeshT * mesh()
return a pointer to the mesh
bool is_valid() const
The handle is valid iff the index is not negative.
BestMeshType findBestObjectType(QString _filename)
Reads the file to check for present primitives and returns the object type that fits best...
bool dataType(DataType _type) const
void addFaceNormalToOpenMesh(MeshT _mesh, quint32 _index, OpenMesh::Vec3d _normal)
Adds a face normal.
QWidget * loadOptionsWidget(QString)
QString description()
Return a description of what the plugin is doing.
int addHexaCell(TriMesh *&_mesh, const std::vector< quint32 > &_indices)
Adds a hexa cell to the mesh. (Does nothing, yet)
int loadObject(QString _filename)
Loads Object and converts it to a triangle mesh if possible.
static constexpr size_t size()
returns dimension of the vector
const DrawMode & getDrawMode(const std::string &_name)
Get a custom DrawMode.
void addVertexNormalToOpenMesh(MeshT _mesh, quint32 _index, OpenMesh::Vec3d _normal)
Adds a vertex normal.
void setObjectDrawMode(const ACG::SceneGraph::DrawModes::DrawMode &_mode, const bool &_force=false)
Set the draw mode for the object.
void updateVertexNormals(TriMesh *&_mesh)
Updates vertex normals.
void addVertexNormal(TriMesh *&_mesh, quint32 _index, OpenMesh::Vec3d _normal)
Adds a vertex normal.
Type for a MeshObject containing a triangle mesh.
TetrahedralMesh * tetrahedralMesh(BaseObjectData *_object)
Get an TetrahedralMesh from an object.
FileVTKPlugin()
Constructor.
int addWedgeCell(TriMesh *&_mesh, const std::vector< quint32 > &_indices)
Adds a wedge cell to the mesh. (Does nothing, yet)
int addFace(TriMesh *&_mesh, const std::vector< quint32 > &_indices)
Adds a face to the mesh.
DataType supportedType()
Return your supported object type( e.g. DATA_TRIANGLE_MESH )
PolyhedralMesh * polyhedralMesh(BaseObjectData *_object)
Get an PolyhedralMesh from an object.
MeshT * mesh()
return a pointer to the mesh
bool getMesh(int _identifier, PolyMesh *&_mesh)
Get the Poly Mesh which has the given identifier.
int add_non_manifold_face(MeshT *&_mesh, std::vector< OpenMesh::VertexHandle > &_vhandles)
Helper function for loadMeshPolygons() that takes care of adding non-manifold faces.
void setValue(const QString &key, const QVariant &value)
Wrapper function which makes it possible to enable Debugging output with -DOPENFLIPPER_SETTINGS_DEBUG...
void removeTemporaryProperties(TriMesh *&_mesh)
Removed temporary properties that might have been added during file reading.
int addTetraCellToOpenMesh(MeshT _mesh, std::vector< quint32 > _indices)
Adds a tetra cell to the mesh. (Does nothing, yet)
DLLEXPORT OpenFlipperQSettings & OpenFlipperSettings()
QSettings object containing all program settings of OpenFlipper.
int addPyramidCell(TriMesh *&_mesh, const std::vector< quint32 > &_indices)
Adds a pyramid cell to the mesh. (Does nothing, yet)
int addHexaCellToOpenMesh(MeshT _mesh, std::vector< quint32 > _indices)
Adds a hexa cell to the mesh. (Does nothing, yet)
void initializePlugin()
Initialize Plugin.
void updateFaceNormals(TriMesh *&_mesh)
Updates face normals.
bool writeASCIIData(std::ostream &_out, TriMesh &_mesh)
Writes the data of the VTK file in ASCII format.
void setNormalsOfDuplicatedVertices(TriMesh *&_mesh)
Sets normals of duplicated vertices that were created for non-manifold meshes.
bool loadMeshCells(QString _spec, QTextStream &_in, MeshT *&_mesh, std::vector< CellType > &_cells)
Reads unstructured grid data from the stream and adds it to the mesh.
void setFromFileName(const QString &_filename)
int addWedgeCellToOpenMesh(MeshT _mesh, std::vector< quint32 > _indices)
Adds a wedge cell to the mesh. (Does nothing, yet)